MultiSelect box popover keeps jumping when scroll or select items - reactjs

MultiSelect box popover keeps jumping when scroll or select items
Codepen https://codesandbox.io/s/material-demo-e5j8h
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import ListItemText from "#material-ui/core/ListItemText";
import Select from "#material-ui/core/Select";
import Checkbox from "#material-ui/core/Checkbox";
const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
}
};
const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];
export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);
const handleChange = event => {
setPersonName(event.target.value);
};
return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}

The cause of the jumping is related to the "content anchor" functionality of the Menu.
From https://material-ui.com/components/menus/#selected-menus (emphasis mine):
If used for item selection, when opened, simple menus attempt to vertically align the currently selected menu item with the anchor element, and the initial focus will be placed on the selected menu item. The currently selected menu item is set using the selected property (from ListItem). To use a selected menu item without impacting the initial focus or the vertical positioning of the menu, set the variant property to menu.
You can also find a similar note in the documentation of the variant prop.
The other relevant portion of the documentation is the description of the getContentAnchorEl prop of Popover:
This function is called in order to retrieve the content anchor element. It's the opposite of the anchorEl prop. The content anchor element should be an element inside the popover. It's used to correctly scroll and set the position of the popover. The positioning strategy tries to make the content anchor element just above the anchor element.
The default behavior of the Select element is to use the Select input element (the part that shows the selected item(s) when closed) as the "anchor element" and the last selected menu item as the "content anchor element". This means that when the Popover is open, it tries to align the last selected menu item (within the Popover) with the Select input element (behind the Popover).
In the case of using the multiple property on the Select, you have the potential to change the last selected item while the Popover is open (for single select, it would typically close immediately after selecting something). Additionally, since not all the menu items fit at once, the last selected item is sometimes scrolled out of view which forces the Popover to use slightly different logic for the vertical alignment.
The net effect of all this is the weird jumping demonstrated in your sandbox. You can fix this by forcing Popover to use a contentAnchorOffset of zero by specifying getContentAnchorEl: null as follows:
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
getContentAnchorEl: null
};
You may also want to add variant: "menu" to get rid of some auto focus behavior which will cause it to automatically scroll to the last selected item. This is nice behavior for single select, but less useful and somewhat disorienting in a multi-select.
Setting variant: "menu" is not sufficient (without getContentAnchorEl: null) to get rid of the jumping. This would cause it to always use the first menu item as the content anchor which would result in less jumping, but it would still do some jumping due to the first menu item sometimes being scrolled out of view when changing selections.
Below is the full code for the modified version of your sandbox that no longer has any weird jumping (the only changes are to the MenuProps):
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import ListItemText from "#material-ui/core/ListItemText";
import Select from "#material-ui/core/Select";
import Checkbox from "#material-ui/core/Checkbox";
const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
variant: "menu",
getContentAnchorEl: null
};
const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];
export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);
const handleChange = event => {
setPersonName(event.target.value);
};
return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}

First, thank you Ryan Cogswell, for great explanation on why this is happening and also how to solve it. I was trying to solve the issue of Select jumping during multiple selection, and was able to implement fix thanks to your answer. One thing I wanted to add was for other developers using typescript like myself, if you implement the above solution directly you will run into
" Type '{ PaperProps: { style: { float: string; minWidth: number; display: string; flexWrap: string; flexDirection: string; }; }; variant: string; getContentAnchorEl: null; }' is not assignable to type 'Partial'.
Types of property 'variant' are incompatible.
Type 'string' is not assignable to type '"menu" | "selectedMenu" | undefined'. TS2322 "
if you are having this type compatibility issue, declaring the MenuProps directly like below will fix it.
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={{
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
variant: "menu",
getContentAnchorEl: null
}}>
This, worked for my project, but please let me know if there are better solutions to this type compatibility issue.

Related

How to convert simple CSS into makeStyles for React?

How to convert simple CSS into makeStyles for React?
I have added style to the TextField to make it stretchable vertically, by using the attribute resize. It is working, actually. Below is the original code I have that I need to refactor.
<div className="mb-4 stretchable">
<style>{"\
.stretchable textarea{\
resize:vertical;\
}\
"}
</style>
<TextField
multiline
label="取材メモ"
className={classes.meetingLogContent}
rows={8}
name='content'
value={meetingLogData.content}
onChange={handleChange}
variant="outlined"
fullWidth
/>
</div>
It is just that our client wanted the style I added to be converted into makeStyle. And it could not target the TextField and does not make it stretchable.
const useStyles = makeStyles(() => ({
meetingLogContent: {
resize: 'vertical',
},
}))
After that I instantiated it into classes.
const classes = useStyles()
And applied the newly instantiated variable to the textfield.
<TextField className={classes.meetingLogContent} />
Am I missing something here? Thanks in advance for your help.
You should apply resize to a div that contains TextArea and not to the TextArea itself. Something like:
<div className={classes.meetingLogContent}>
<TextField
multiline
label="取材メモ"
rows={8}
name='content'
value={meetingLogData.content}
onChange={handleChange}
variant="outlined"
fullWidth
/>
</div>
Then your useStyles:
const useStyles = makeStyles(() => ({
meetingLogContent: {
resize: 'vertical',
overflow: 'auto' //<-- don't forget overflow to auto
},
}))
The result is:
Here a codesandbox example.

Disable "Select By Typing" in Material UI Menu Component

I'm trying to make a pop-up menu that has a couple different filters (buttons, selects, and text fields). I'm using the Material UI Menu component, but have run into an issue when trying to use the text fields. Because the Menu component is acting like a <Select />, when I type something in the text fields, it tries to select different MenuItems instead of staying focused on the text box.
So using the example found in the sandbox below, users wouldn't be able to type anything in the "search for a different food" textbox if it started with an "A", "B", or "C". If you wanted to type in "apricots", the menu would change focus from the textbox to the "Apples" MenuItem.
I don't see any props for this in the Menu API, so I'm curious to know if there is any work arounds, or even a different component that is more suited for this.
Thanks!
Here's a codesandbox: https://codesandbox.io/s/wizardly-mccarthy-zy2b7
import { useState } from "react";
import "./styles.css";
import { Button, Menu, MenuItem, TextField } from "#material-ui/core";
export default function App() {
const [menu, setMenu] = useState(null);
const [text, setText] = useState("");
return (
<div className="App">
<Button variant="outlined" onClick={(e) => setMenu(e.currentTarget)}>
Filters
</Button>
<Menu
anchorEl={menu}
open={Boolean(menu)}
getContentAnchorEl={null}
anchorOrigin={{
vertical: "bottom",
horizontal: "left"
}}
onClose={() => setMenu(null)}
>
<MenuItem>Apples</MenuItem>
<MenuItem>Bananas</MenuItem>
<MenuItem>Carrots</MenuItem>
<MenuItem>
<TextField
value={text}
onChange={(e) => setText(e.target.value)}
variant={"outlined"}
label={"search a different food..."}
/>
</MenuItem>
</Menu>
</div>
);
}
Use e.stopPropagation() in the onKeyDown event for the MenuItem containing the TextField. This will prevent the key down event from propagating to the Menu component.
<MenuItem onKeyDown={(e) => e.stopPropagation()}>
<TextField
value={text}
onChange={(e) => setText(e.target.value)}
variant={"outlined"}
label={"search a different food..."}
/>
</MenuItem>
Reference: How to disable the selection of an item when the first letter of the option is pressed in the Select component?

Showing a VisX graph inside a Semantic-UI-React Modal causes problems with z-index

I'm adding a VisX graph inside Semantic-UI-React Modal.
The graph by itself shows the tooltip, crosshair and series glyphs correctly:
But when it's in a modal, all those appear beneath the modal:
I can reconstruct the tooltip with a higher z-index in the component I supply for the renderTooltip property, but it's lacking the crosshair and series glyph:
As these elements are added to the DOM on hover, it's impossible for me to catch them int he devtools and see what styles they have and inherit.
Is there some way I can set their z-index or fix this in some other way?
const Visx: FC = () => {
return (
<Modal open>
<Modal.Content>
<XYChart width={900} height={500} xScale={{ type: 'time' }} yScale={{ type: 'linear' }}>
<Grid rows numTicks={maxCount + 1} />
<Axis
orientation="left"
label="Play count"
numTicks={maxCount + 1}
tickFormat={(value) => {
return value;
}}
/>
<Axis orientation="bottom" label="Date" />
<LineSeries dataKey="plays" data={data} {...accessors} />
<Tooltip
showHorizontalCrosshair
showVerticalCrosshair
snapTooltipToDatumX
snapTooltipToDatumY
showSeriesGlyphs
showDatumGlyph
renderTooltip={({ tooltipData }) => {
const datum = tooltipData.nearestDatum?.datum as DataPoint | null;
return (
<div>
{datum?.count || 'no'} plays on {moment(datum?.date).format('MMM D, YYYY')}
</div>
);
}}
/>
</XYChart>
</Modal.Content>
</Modal>
);
};
Fixed it by adding this global CSS style:
.visx-tooltip {
z-index: 9999; /* or whatever height is appropriate */
}

Stop Material-UI's Select Popover from changing position [duplicate]

MultiSelect box popover keeps jumping when scroll or select items
Codepen https://codesandbox.io/s/material-demo-e5j8h
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import ListItemText from "#material-ui/core/ListItemText";
import Select from "#material-ui/core/Select";
import Checkbox from "#material-ui/core/Checkbox";
const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
}
};
const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];
export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);
const handleChange = event => {
setPersonName(event.target.value);
};
return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
The cause of the jumping is related to the "content anchor" functionality of the Menu.
From https://material-ui.com/components/menus/#selected-menus (emphasis mine):
If used for item selection, when opened, simple menus attempt to vertically align the currently selected menu item with the anchor element, and the initial focus will be placed on the selected menu item. The currently selected menu item is set using the selected property (from ListItem). To use a selected menu item without impacting the initial focus or the vertical positioning of the menu, set the variant property to menu.
You can also find a similar note in the documentation of the variant prop.
The other relevant portion of the documentation is the description of the getContentAnchorEl prop of Popover:
This function is called in order to retrieve the content anchor element. It's the opposite of the anchorEl prop. The content anchor element should be an element inside the popover. It's used to correctly scroll and set the position of the popover. The positioning strategy tries to make the content anchor element just above the anchor element.
The default behavior of the Select element is to use the Select input element (the part that shows the selected item(s) when closed) as the "anchor element" and the last selected menu item as the "content anchor element". This means that when the Popover is open, it tries to align the last selected menu item (within the Popover) with the Select input element (behind the Popover).
In the case of using the multiple property on the Select, you have the potential to change the last selected item while the Popover is open (for single select, it would typically close immediately after selecting something). Additionally, since not all the menu items fit at once, the last selected item is sometimes scrolled out of view which forces the Popover to use slightly different logic for the vertical alignment.
The net effect of all this is the weird jumping demonstrated in your sandbox. You can fix this by forcing Popover to use a contentAnchorOffset of zero by specifying getContentAnchorEl: null as follows:
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
getContentAnchorEl: null
};
You may also want to add variant: "menu" to get rid of some auto focus behavior which will cause it to automatically scroll to the last selected item. This is nice behavior for single select, but less useful and somewhat disorienting in a multi-select.
Setting variant: "menu" is not sufficient (without getContentAnchorEl: null) to get rid of the jumping. This would cause it to always use the first menu item as the content anchor which would result in less jumping, but it would still do some jumping due to the first menu item sometimes being scrolled out of view when changing selections.
Below is the full code for the modified version of your sandbox that no longer has any weird jumping (the only changes are to the MenuProps):
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormControl from "#material-ui/core/FormControl";
import ListItemText from "#material-ui/core/ListItemText";
import Select from "#material-ui/core/Select";
import Checkbox from "#material-ui/core/Checkbox";
const useStyles = makeStyles(theme => ({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300
},
chips: {
display: "flex",
flexWrap: "wrap"
},
chip: {
margin: 2
},
noLabel: {
marginTop: theme.spacing(3)
}
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
variant: "menu",
getContentAnchorEl: null
};
const names = [
"Oliver Hansen",
"Van Henry",
"April Tucker",
"Ralph Hubbard",
"Omar Alexander",
"Carlos Abbott",
"Miriam Wagner",
"Bradley Wilkerson",
"Virginia Andrews",
"Kelly Snyder"
];
export default function MultipleSelect() {
const classes = useStyles();
const [personName, setPersonName] = React.useState([]);
const handleChange = event => {
setPersonName(event.target.value);
};
return (
<div>
long text <br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
long text
<br />
<FormControl className={classes.formControl}>
<InputLabel id="demo-mutiple-checkbox-label">Tag</InputLabel>
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
First, thank you Ryan Cogswell, for great explanation on why this is happening and also how to solve it. I was trying to solve the issue of Select jumping during multiple selection, and was able to implement fix thanks to your answer. One thing I wanted to add was for other developers using typescript like myself, if you implement the above solution directly you will run into
" Type '{ PaperProps: { style: { float: string; minWidth: number; display: string; flexWrap: string; flexDirection: string; }; }; variant: string; getContentAnchorEl: null; }' is not assignable to type 'Partial'.
Types of property 'variant' are incompatible.
Type 'string' is not assignable to type '"menu" | "selectedMenu" | undefined'. TS2322 "
if you are having this type compatibility issue, declaring the MenuProps directly like below will fix it.
<Select
labelId="demo-mutiple-checkbox-label"
id="demo-mutiple-checkbox"
multiple
value={personName}
onChange={handleChange}
input={<Input />}
renderValue={selected => selected.join(", ")}
MenuProps={{
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250
}
},
variant: "menu",
getContentAnchorEl: null
}}>
This, worked for my project, but please let me know if there are better solutions to this type compatibility issue.

React Semantic UI - How to disable a child component based on parent

How does one disable the input box here, depending on whether a checkbox has been checked or not?
I have verified the checked property - it is in working order (shows true or false boolean values).
However, I can't seem to get the disabled property in Input to work.
Below is my code:
import React from 'react';
import { Button, Checkbox, Input, List } from 'semantic-ui-react'
import PropTypes from 'prop-types';
const CategoryCheckBox = ({ type = 'checkbox', name, mylabel, checked, onChange }) => (
<React.Fragment>
<List horizontal relaxed>
<List.Item>
<Checkbox style={{ paddingLeft:"1em", paddingBottom: "1em" }} label={mylabel} checked={checked} onChange={onChange} />
<List.Content>
<Input style={{ maxWidth:"9em", paddingLeft:"1em" }} size='mini' focus placeholder='Min' disabled={checked === true ? true : false} />
<Input style={{ maxWidth:"9em", paddingLeft:"1em" }} size='mini' focus placeholder='Max' />
</List.Content>
</List.Item>
</List>
</React.Fragment>
);
CategoryCheckBox.propTypes = {
type: PropTypes.string,
name: PropTypes.string.isRequired,
mylabel: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func.isRequired,
}
export default CategoryCheckBox;
From the main program,
The component is called with the below parameters:
<CategoryCheckBox name={item.value} mylabel={item.text} checked={this.state.checkedItems.get(item.value)} onChange={this.handleChange} />
Below is my screenshot for the component along with React debugger showing the checked value.
Any Help will be highly appreciated.
Tried to set up most of the important code - Newbie to React myself. Can't get the index.js in the working order. But it gives you a good idea of my code https://codesandbox.io/embed/2pyoxpr6rn?fontsize=14
Changes:
1- You are not assigning the name to CheckBox element in CategoryCheckBox, add name here:
<Checkbox
style={{ paddingLeft: "1em", paddingBottom: "1em" }}
label={mylabel}
// ↓↓↓↓↓↓↓↓ here
name={name}
checked={checked}
onChange={onChange}
/>
2- Add disable condition for Max input field also:
<Input
style={{ maxWidth: "9em", paddingLeft: "1em" }}
size="mini"
focus
placeholder="Max"
// ↓↓↓↓↓↓↓↓ here
disabled={!checked}
/>
3- Most importantly, You are storing data in states in App component so it needs to be a class component.
Check Working Codesandbox with all these changes.
After looking at your code the problem is with your app component. Your app component has a state and therefore cannot be a stateless functional component. Your App component should look something like this.
import React from "react";
import ReactDOM from "react-dom";
import { Checkbox, Label, Header, Card, Form, Button, Container, Icon, Step, Select, Dropdown, List } from 'semantic-ui-react';
import womensBoutiqueOptions from "./womensBoutiqueOptions";
import CategoryCheckBox from "./CategoryCheckBox";
import "./styles.css";
class App() extends React.Component {
state = {
date: new Date(),
time: '10:00',
checkedItems: new Map()
}
handleChange(e) {
const item = e.target.name;
const isChecked = e.target.checked;
this.setState(prevState => ({ checkedItems: prevState.checkedItems.set(item, isChecked) }));
}
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Form size="large" key="large">
<h4 className="ui dividing header">Womens Information</h4>
<Form.Group widths='equal'>
<Form.Field>
<React.Fragment>
<List horizontal >
{
womensBoutiqueOptions.map(item => (
<List.Item key={item.key}>
<List.Content>
<CategoryCheckBox name={item.value} mylabel={item.text} checked={this.state.checkedItems.get(item.value)} onChange={this.handleChange} />
</List.Content>
</List.Item>
))
}
</List>
</React.Fragment>
</Form.Field>
</Form.Group>
</Form>
</div>
)
}
);
}
Check out the react documentation for some more information on why

Resources