I am using the Material UI Autocomplete component and would like to have multiline chips. I am using chips to display some text, where there can be up to around 10 words in that text. I am aware that is not the intended purpose of chips but this generally fits really nicely into my UI so I'd like to stick with them.
That said, on mobile (e.g. iPhone 8), a chip with around 10 words will display something like "The first few words...", where there will be ellipsis instead of the remainder of the text.
I have looked into using the renderTags property (with a Typography element using word-wrap for the chip label) and have tried that out but haven't made any forward progress using that. Does anyone have any advice/code snippets where they have gotten this working?
I figured out how to do it. Here is example code with multiline chips working (https://codesandbox.io/s/material-demo-eg6mb?file=/demo.tsx:332-1082). The key features that allow this multiline functionality to work are setting the chip's height to be 100% and using a Typography element for the label with whitespace: normal:
<Autocomplete
multiple
id="fixed-tags-demo"
options={top100Films}
getOptionLabel={option => option.title}
defaultValue={[top100Films[6], top100Films[13], top100Films[0]]}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
label={<Typography style={{whiteSpace: 'normal'}}>{option.title}</Typography>}
{...getTagProps({ index })}
disabled={index === 0}
style={{height:"100%"}}
/>
))
}
style={{ width: 300 }}
renderInput={params => (
<TextField
{...params}
label="Fixed tag"
variant="outlined"
placeholder="Favorites"
/>
)}
/>
Related
I started using MUI recently for its Dialog specifically, I am wondering if there is any way I can set the dialog width to fit its content, so far I found this in docs which is not what i needed, because dialog could be smaller or larger and not on fitting the contents inside of it exactly, Here is part of the code:
<div className="toggle-div" id="tdiv" style={{ display: disp.display,backgroundColor:theme,color:textColor}}>
<Dialog PaperProps={{
style:{
backgroundColor:theme,color:buttonColor
}
}} open={open} onClose={() => handleClose()} className="dialog">
</div>
I am trying to write a React App that has text lined up in a row, and I want the last item to be aligned to the far right. I am using Material UI with a Box API to contain all my elements, with each item being a Typography element.
<Box display="flex" flexDirection="row" alignItems="flex-start">
<Typography align='left' className={classes.currentlyPrinting}>
Currently printing:
</Typography>
<Typography align='left' className={classes.filenameText}>
Filenamjoojpe
</Typography>
<Typography className={classes.completion}>
(3 of 4 completed)
</Typography>
<Box justifyContent="flex-end">
<Typography className={classes.percentage}
style={{display: 'inline-block'}}>30%
</Typography>
</Box>
</Box>
So I tried putting the last Typography element within a box container, and used "justifyConent = flex-end" but it did not work out. The following image shows what I want to happen:
So I want the text that says "30%" to be aligned with the right side of that progress bar I have. The reason for this is that the other three typography elements can have varying characters of text, so I cant just use padding for it. Any ideas?
I am working on a web app, and I am trying to make it responsive, but I am running into a few problems. I am using media queries to detect if the screen width is > than a certain amount or < than a certain amount. Based on that, I would want to change the layout of my component, so that it does not cram and move everything out of alignment. However, it seems like if my goal is to reorder the child components within my component using conditional rendering based on the media query result, then my code would be repeated multiple times. Hence, I am checking to see if there are any other ways to accomplish this.
Below is a screenshot of the browser when the screen size gets smaller, the contents get too cramped up, and hence it messes up the alignment.
Below is a snippet of my code (this code represents the right side of the image -> Revenue and Revenue KPI)
<Row justify="space-around">
<Col span={11}>
<Statistic
title="Revenue"
value={data[metric].revenue}
valueStyle={{ color: '#3f8600' }}
/>
</Col>
<Divider type="vertical" />
<Col span={11}>
Revenue KPI
<Button shape='circle' size='small' onClick={() => handleClick('rev', metric, 'post')} style={{ marginLeft: '5%' }}>
<PlusOutlined />
</Button>
<Statistic
value={data[metric].rev_kpi}
valueStyle={{ color: '#3f8600' }}
/>
</Col>
</Row>
What I would want to do, is to change the grid layout once the screen width is smaller than a certain amount, and instead of the components above being in the same Row, I would want each to be in their Row (stacking on top of each other). However, if I were to do this using conditional rendering, it seems like I would have to repeat the code quite a fair bit, which seems tedious and messy. Hence, I am hoping if there are any more efficient methods to achieve what I would want to make.
The UI package I am using is AntD (where I got the components for Row, Col, Statistic, Button)
https://ant.design/components/grid/
this is my media query function (I use this function to return a boolean based on the query I pass in)
import { useEffect, useState } from "react";
function useMediaQuery(
query,
defaultMatches = window.matchMedia(query).matches
) {
const [matches, setMatches] = useState(defaultMatches);
useEffect(() => {
const media = window.matchMedia(query);
if (media.matches !== matches) setMatches(media.matches);
const listener = () => setMatches(media.matches);
media.addListener(listener);
return () => media.removeListener(listener);
}, [query, matches]);
return matches;
}
export default useMediaQuery;
All help is appreciated, thanks all! Do guide me along as I am new to React and especially new to implementing responsive websites!
Since Row and Col in ant design seems to be based on flex you should try to use the CSS order property to re-arrange your elements
https://developer.mozilla.org/en-US/docs/Web/CSS/order
It is also available as a prop on the Col component:
https://ant.design/components/grid/#Col
CSS order demo (use media query to change order value for various screen sizes):
div {
display: flex;
flex-direction: column;
}
#reverse:checked ~ div>p:first-child {
order: 2;
}
<input type="checkbox" id="reverse"/>
<label for="reverse">reverse</label>
<div>
<p>First text element in HTML</p>
<p>Second text element in HTML</p>
<div>
For even more complex rearrangement of your elements you could use CSS Grid:
grid-template-areas: give custom names to areas in your grid
grid-area: place element in the grid using one of your custom names
use media-queries to change grid-template-areas and it should work nicely
https://css-tricks.com/snippets/css/complete-guide-grid/
I am trying to scroll to div when clicking on Tab with Material UI Tabs, UseRef and ScrollTo.
Sand box Link: https://codesandbox.io/s/exciting-sound-mrw2v
when clicked on Tab 2, I am expecting to scroll onto Tab2 Contents and Tab 1 contents visible on scrolling.Currently it requires two clicks to scroll onto the div, I am wondering why its behind one click. Any leads appreciated. Thanks!
I edited your example and I added a useEffect hook and if you press a tab 2 is scrolling into this content.
https://codesandbox.io/s/lingering-voice-y45cg
use this syntax
<Tabs
classes={{ root: classes.root, scroller: classes.scroller }}
value={active}
onChange={(event, newValue) => {
setActive(newValue);
}}
indicatorColor="primary"
textColor="primary"
variant={"scrollable"}
scrollButtons={"on"}
>
{cities.map((city, index) => (
<Tab key={index} label={city} value={city} />
))}
</Tabs>
this two line of properties important
variant={"scrollable"}
scrollButtons={"on"}
full example link: https://codesandbox.io/s/material-ui-centered-scrollable-tabs-ud26w?file=/index.js:645-1048
I'm displaying some data on a page using TextField of #material-ui .
The problem is every record of data has different length of data, so most of the values being presented looks ugly (only 10% of the textfield width is used)
I'm currently using fullWidth attribute , but it doesn't do what I want . I want the underline to match the length of the content .
<Grid item sm={2}>
<TextField
margin="normal"
fullWidth
inputProps={{ disabled: true }}
label={labels.brokerId}
value={props.brokerDetails.id}
/>
</Grid>
How can I achieve it ?
You should try with multiline property of TextArea component.
https://github.com/mui-org/material-ui/blob/master/docs/src/pages/demos/text-fields/TextFields.js