I an working on Card from antd. I want to get the rest of title to the next line if it is long. For eg, title is displayed as "This title needs to go to ne..." but I want it to be displayed in two lines. "This title needs to go to" in the first line and "next line" in the next line. I know we can make use of inline size to get to the next line but I don't want to make use of pixel as width since I want to make it interactive. This is the code I have written :
<Row gutter={24}>
<Col xs={24} md={10}>
<Card
title={<span>This title name should go to next line if instead of displaying ...</span>}
bodyStyle={{ paddingTop: 5 }}
>
<p>Card description</p>
</Card>
</Col>
</Row>
How do I get it to the next line using inline size and make it interactive?
You can simply use break in your span tag.
<Card
title={<span> first line <br/> second line</span>}
bodyStyle={{ paddingTop: 5 }}
/>
or target card header using css
.ant-card-head-title {
text-overflow: unset !important;
white-space: unset !important;
}
Related
I am using 2 internal company related components Row and Column which I can't change but they both take in style property thus could pass in any css styling.
Note that I have to use these components for other purposes.
This is currently how it looks which is incorrect.
Can see 2 issues.
Due to product subtile on the first, the second one mis aligned.
Due to more text on the description on the second, again mis aligned.
I am looking to achieve this.
Is there a way to do this. Was attempting with flex box but due to the way the divs are nested, struggling with it.
It would work if I switch it around and create by row.
Meaning don't create a column one short like this.
But go for row by row like this.
But I can't do this due to accessibility. The screen reader should read column by column. But ends up reading row by row if I do this.
Example: Product Title 1 Product Title 2 and then coming back to Cost $1000 switching between the 2 products which is incorrect.
Thus I wish to stick with creating 1 column at a time as what I have now but how can I achieve the desired row alignment? Please help. Thanks.
My code.
This is the main Row for both items.
<Row style={'I can pass styling here'}>
{products}
</Row>
This is where I am looping and creating column by column for the products.
const products = productsList.slice(0, 3) // screenshot above shows 2 but can go up to 3
.map((p, index) => (
<Column style={'I can pass styling here'}>
{/* The image, title and subtitle all come from here */}
<SelectedProduct/>
{/* price description section*/}
{price(p, index)}
{/* button and links here.
These are not having alignment issues. Fixing subtitle and description alignments should take care of this
*/}
{links(p)}
</Column>
));
Condensed SelectedProduct component.
const SelectedProduct = () => {
return (
<div className={styles.product}>
<div style={{ position: 'relative' }}>
<div>
<Link to={redirectTo}>
<Art src={url} />
</Link>
</div>
<TrackedRemoveButton type="button"/>
</div>
<Typography>
{title}
</Typography>
<Typography>
{subtitle}
</Typography>
</div>
);
};
styling in SelectedProduct
.product {
display: flex;
flex-direction: column;
align-items: center;
}
Condensed price component.
const price = (p) => {
return (
<div>
<Typography>
<span
dangerouslySetInnerHTML={{
__html: p.content,
}}
/>
</Typography>
</div>
);
}
This is a surprisingly difficult problem. Here is my solution: https://codepen.io/dlwalsh/pen/gOdayNQ
It uses flexbox with column direction. The important bits are:
The parent declaration align-items: stretch so that each item extends to the full height.
The button declaration margin-top: auto so that it (and everything beneath it) anchors to the bottom.
It works, but it relies on everything else having a fixed height. i.e.
The title and subtitle are always one line
A blank subtitle inserted when missing
There are always exactly two product links
Every time I add content to the MUI Textfield it outputs it without any line breaks.
Is there a better solution to use?
<Stack direction="row" alignItems="start" justifyContent="start" mb={5}>
<TextField
name="Content" placeholder="Content" multiline={true}
value={content}
rows={18}
sx={{width: '100%'}}
onChange={(e) => setContent(e.target.value)}
/>
<div style={{maxWidth:"50%", paddingLeft:"10px"}} dangerouslySetInnerHTML={{__html: generateContent(content)}}></div>
</Stack>
Here's an example:
https://codesandbox.io/s/festive-dewdney-crxls
<Stack direction="row">
<TextField multiline value={state} onChange={handleChange} />
<Box sx={{ whiteSpace: "pre-wrap" }}>{state}</Box>
</Stack>
I used the whiteSpace: "pre-wrap" sx prop on the box where I am previewing the text, and I used the multiline prop on the textfield to make it a textarea input, and it worked.
I think the problem lies in your CSS and not in MUI. Use the white-space CSS property like this:
<div style={{maxWidth:"50%", paddingLeft:"10px", whiteSpace: "pre-wrap"}}...
Read more about pre-wrap and the other values here
If this does not work then there are two similar questions but I doubt you will need them.
Best way to preserve new lines when I post data from a Multi Line Text Field
New line '\n' not recognized inside TextField in React
There is a lot to read here, but there is no other way to explain the issue I have.
I have four files, App.js, Intakes.js, IntakeDetails.js and Sizing.js. I start on the Intakes page where the user is presented with a table of data. The user clicks on a row and is taken to IntakeDetails. In IntakeDetails, there are four MUI tabs, one of which is Sizing.
The user never actually goes to a Sizing page. They only get to IntakeDetails. From IntakeDetails, the user can view, edit, and create data based on what tab they are in. If the user wants to create or update Sizing data, they navigate to the sizing tab and click the edit icon on the row of their choice from the Sizing table. The Dialog then pops up and its TextFields are populated with the data from the row the user clicked.
Sizing.js is 600+ lines long. 211 lines in this file are taken up by the MUI dialog which displays the data from the table row the user has clicked. The dialog is so long because of 19 TextFields. I want to make a short function with a parameter for id, value and label. This way I wont need to have lots of multiline TextFields. All of the TextFields in the Dialog take up 8 lines. With a function, this could be just one or two lines.
I have made a function to shorten the file previously, but it introduces a new problem. If I have a TextField that is populated with the word 'Hello', and I edit it, the Dialog disappears, reappears, and focus is lost on the TextField I edited, but, the change I made is persistent. I can only enter or remove one character at a time before having to click on the TextField again to enter another. I can copy and paste full words and sentences at once, but again the Dialog disappears and comes back.
I can't use .map because my data is not divided into groups or objects. It is all one object and needs to be presented in the dialog in a specific order, which is why they are hardcoded. When I type in a TextField, there is a long delay between the time I press a key on the keyboard and the time the character appears in the TextField. This delay gets longer when I type faster.
The return in IntakeDetails is here:
import Sizing from "./Sizing";
...
return (
<div class="aspectwrapper">
<div class="content">
<Container>
<Paper>
<Box sx={{ width: "100%" }}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs value={value} onChange={handleChange}>
<Tab label="Intake Details" {...a11yProps(0)} />
<Tab label="Sizing" {...a11yProps(1)} />
</Tabs>
</Box>
<TabPanel value={value} index={0}>
** Intake Details Stuff **
</TabPanel>
<TabPanel value={value} index={1}>
<Sizing />
</TabPanel>
</Box>
</Paper>
</Container>
</div>
</div>
)
The return in Sizing. There are 19 TextFields, all structured as seen below. There are also buttons in a <DialogActions> tag which I have not included here.
const onTextChange = (e) => {
const id = e.target.id;
var value = e.target.value;
setSingleSizing({ ...singleSizing, [id]: value });
};
...
return(
<div id="sizing-container">
<Dialog open={open} onClose={handleClose} maxWidth={"xl"}>
<DialogTitle id="form-dialog-title">Edit estimation</DialogTitle>
<DialogContent>
<Box>
<TextField
id="SizingComments"
value={singleSizing?.SizingComments}
label={"Estimation Comments"}
onChange={onTextChange}
variant="outlined"
style={{ margin: "1em", minHeight: "1em", minWidth: "15em" }}
/>
</Box>
</Box>
</DialogContent>
</Dialog>
</div>
)
I create a dashboard with reactJs and react bootstrap. Due to the different size of the card on my dashboard, it's resulting the gap on my dashboard. This is the screenshot :
I want to fill the gap on my dashboard. According to the bootstrap flex documentation, I used d-flex align-items-stretch to fill the gap. Like this :
<Row>
<Col lg="6" md="6" sm="12" className="d-flex align-items-stretch"> //I placed it on Col
<FrequentUsers />
</Col>
<Col lg="6" md="6" sm="12" className="d-flex align-items-stretch">
//Other content
</Col>
</Row>
Placing the d-flex align-items-stretch on the <Col> tag is the
only way that I found worked in my case. If I place it in <Row> tag
or in <div> tag as a container outside it, it didn't work.
The result is the y-axis stretched well as I expected, but the x-axis suddenly shrink :
So I manage my grid layout to make it wider. The grid layout is still working but it didn't affecting the card, it is only affecting the gap like there is a invisible container in it. So I'm assuming that the grid system at this point is "broken"
I'm guessing that this is because the d-flex. But as I read the documentation, it should've instead make the content fully extended to the side. Please check it on the documentation here
Based on #ChewySalmon's comment. I try to adjusting flex-basis on my card. The reason I do it directly on my card is because as I provided in a code sample in my question above, I stretched my item on a <Col> tag, which is stretch the conten vertically (as my screenshoot shown above). So I need to do it on my card (also because this is the only way that worked in my case), so it stretched horizontally. And it work perfectly. Here is the implementation code :
<Card style={{flexBasis: "100em"}}>
//my content
<Card>
I use 100em because it's the only way besides 100px that worked for me. I hard coded it like that because the value is the same in all card, which is 100em. But I recommend you using props in JSX attribute. Hope that help you who have a same problem with me in the future. Thanks to #ChewySalmon.
I have this material-ui list:
<List dense>
{this.state.issues.map((item, i) => {
return <Link target="_blank" to={item.issue_url} key={i}>
<ListItem button>
<ListItemText primary={item.issue_state}/>
<ListItemSecondaryAction>
<IconButton>
<ArrowForward/>
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</Link>
})
}
</List>
issue_state is obtained from MongoDB. Can I add another column to my list showing another field from the database? I tried:
<ListItemText primary={item.issue_state}/>
<ListItemText primary={item.issue_title}/>
This displays what I want but the issue_title test is centered. I'd like it left aligned. Can this be done?
ListItemText component renders with the following CSS style that allows it to be flexible to grow and shrink according as the width and height of its content.
flex: 1 1 auto;
Its ancestor ListItem component renders as an inline-flex.
AFAICT, the results you're looking to achieve can't be done without overriding these styles. Not to worry, there are other ways to go that uses available APIs exposed in the component.
Never mind that the name for the component seems to be misleading that its usage is specific for rendering text in the list item.
A closer look in the ListItemText component API documentation shows that the primary property is of the node type.
That implies that the ListItemText can be used to render string, function, and React.Element in a manner similar to the snippet below.
<ListItemText primary={<div>Foo<br/>Bar<br/>Baz</div>} />
There is also the secondary property that renders the elements with textual emphasis.
<ListItemText primary="Foo" secondary={<div>Bar<br/>Baz</div>} />
If you need more control over the children of the ListItemText, the API allows for the flexibility to write it this way
<ListItemText>
<Typography variant="subheading">Foo</Typography>
<Typography variant="body1" color="textSecondary">Bar</Typography>
<Typography variant="body1" color="textSecondary">Baz</Typography>
</ListItemText>