Skip to content

Commit d0527b1

Browse files
authored
Add checkbox list component (#433)
Signed-off-by: Seddik Yengui <[email protected]>
1 parent 764924a commit d0527b1

16 files changed

+789
-78
lines changed

demo/src/app.jsx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ import {
1515
FormControlLabel,
1616
FormGroup,
1717
Grid,
18+
IconButton,
1819
StyledEngineProvider,
1920
Tab,
2021
Tabs,
2122
TextField,
2223
ThemeProvider,
2324
Typography,
2425
} from '@mui/material';
26+
import CommentIcon from '@mui/icons-material/Comment';
2527
import { styled } from '@mui/system';
2628
import { useMatch } from 'react-router';
2729
import { IntlProvider, useIntl } from 'react-intl';
@@ -102,6 +104,7 @@ import inputs_en from '../../src/components/translations/inputs-en';
102104
import inputs_fr from '../../src/components/translations/inputs-fr';
103105
import { EquipmentSearchDialog } from './equipment-search';
104106
import { InlineSearch } from './inline-search';
107+
import MultipleSelectionDialog from '../../src/components/MultipleSelectionDialog/MultipleSelectionDialog';
105108

106109
const messages = {
107110
en: {
@@ -311,6 +314,10 @@ function AppContent({ language, onLanguageClick }) {
311314
const [equipmentLabelling, setEquipmentLabelling] = useState(false);
312315

313316
const [openReportViewer, setOpenReportViewer] = useState(false);
317+
318+
const [openMultiChoiceDialog, setOpenMultiChoiceDialog] = useState(false);
319+
const [openDraggableMultiChoiceDialog, setOpenDraggableMultiChoiceDialog] = useState(false);
320+
314321
const [openTreeViewFinderDialog, setOpenTreeViewFinderDialog] = useState(false);
315322
const [openTreeViewFinderDialogCustomDialog, setOpenTreeViewFinderDialogCustomDialog] = useState(false);
316323

@@ -540,6 +547,22 @@ function AppContent({ language, onLanguageClick }) {
540547
);
541548
}
542549

550+
const [checkBoxListOption, setCheckBoxListOption] = useState([
551+
{ id: 'kiki', label: 'Kylian Mbappe' },
552+
{ id: 'ney', label: 'Neymar' },
553+
{ id: 'lapulga', label: 'Lionel Messi' },
554+
{ id: 'ibra', label: 'Zlatan Ibrahimovic' },
555+
{
556+
id: 'john',
557+
label: 'Johannes Vennegoor of Hesselink is the football player with the longest name in history',
558+
},
559+
]);
560+
561+
const secondaryAction = () => (
562+
<IconButton aria-label="comment">
563+
<CommentIcon />
564+
</IconButton>
565+
);
543566
const defaultTab = (
544567
<div>
545568
<Box mt={3}>
@@ -557,6 +580,65 @@ function AppContent({ language, onLanguageClick }) {
557580
<SnackWarningButton />
558581
<SnackInfoButton />
559582

583+
<Button
584+
variant="contained"
585+
style={{
586+
float: 'left',
587+
margin: '5px',
588+
}}
589+
onClick={() => setOpenMultiChoiceDialog(true)}
590+
>
591+
Checkbox list
592+
</Button>
593+
<MultipleSelectionDialog
594+
items={checkBoxListOption}
595+
selectedItems={[]}
596+
open={openMultiChoiceDialog}
597+
getItemLabel={(o) => o.label}
598+
getItemId={(o) => o.id}
599+
handleClose={() => setOpenMultiChoiceDialog(false)}
600+
handleValidate={() => setOpenMultiChoiceDialog(false)}
601+
titleId="Checkbox list"
602+
divider
603+
secondaryAction={secondaryAction}
604+
addSelectAllCheckbox
605+
isCheckboxClickableOnly
606+
enableSecondaryActionOnHover
607+
/>
608+
609+
<Button
610+
variant="contained"
611+
style={{
612+
float: 'left',
613+
margin: '5px',
614+
}}
615+
onClick={() => setOpenDraggableMultiChoiceDialog(true)}
616+
>
617+
Draggable checkbox list
618+
</Button>
619+
<MultipleSelectionDialog
620+
items={checkBoxListOption}
621+
selectedItems={[]}
622+
open={openDraggableMultiChoiceDialog}
623+
getItemLabel={(o) => o.label}
624+
getItemId={(o) => o.id}
625+
handleClose={() => setOpenDraggableMultiChoiceDialog(false)}
626+
handleValidate={() => setOpenDraggableMultiChoiceDialog(false)}
627+
titleId="Draggable checkbox list"
628+
divider
629+
secondaryAction={secondaryAction}
630+
isDndDragAndDropActive
631+
enableSecondaryActionOnHover
632+
onDragEnd={({ source, destination }) => {
633+
if (destination !== null && source.index !== destination.index) {
634+
const res = [...checkBoxListOption];
635+
const [item] = res.splice(source.index, 1);
636+
res.splice(destination ? destination.index : checkBoxListOption.length, 0, item);
637+
setCheckBoxListOption(res);
638+
}
639+
}}
640+
/>
641+
560642
<Button
561643
variant="contained"
562644
style={{

package-lock.json

Lines changed: 100 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"memoize-one": "^6.0.0",
3838
"oidc-client": "^1.11.5",
3939
"prop-types": "^15.8.1",
40+
"react-beautiful-dnd": "^13.1.1",
4041
"react-csv-downloader": "^3.1.0",
4142
"react-dnd": "^16.0.1",
4243
"react-dnd-html5-backend": "^16.0.1",
@@ -89,6 +90,7 @@
8990
"@types/node": "^18.19.31",
9091
"@types/prop-types": "^15.7.12",
9192
"@types/react": "^18.2.75",
93+
"@types/react-beautiful-dnd": "^13.1.8",
9294
"@types/react-dom": "^18.2.24",
9395
"@types/react-resizable": "^3.0.7",
9496
"@types/react-virtualized": "^9.21.29",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
8+
import { useState } from 'react';
9+
import { ListItem } from '@mui/material';
10+
import { CheckBoxListItemProps } from './check-box-list-type';
11+
import { ClickableCheckBoxItem } from './clickable-check-box-item';
12+
import { ClickableRowItem } from './clickable-row-item';
13+
14+
export function CheckBoxListItem<T>({
15+
item,
16+
sx,
17+
secondaryAction,
18+
getItemId,
19+
divider,
20+
isCheckboxClickableOnly,
21+
...props
22+
}: CheckBoxListItemProps<T>) {
23+
const [hover, setHover] = useState<string>('');
24+
return (
25+
<ListItem
26+
secondaryAction={secondaryAction?.(item, hover)}
27+
sx={{ minWidth: 0, ...sx?.checkboxList }}
28+
onMouseEnter={() => setHover(getItemId(item))}
29+
onMouseLeave={() => setHover('')}
30+
disablePadding={!isCheckboxClickableOnly}
31+
disableGutters
32+
divider={divider}
33+
>
34+
{isCheckboxClickableOnly ? <ClickableCheckBoxItem {...props} /> : <ClickableRowItem {...props} />}
35+
</ListItem>
36+
);
37+
}
38+
39+
export default CheckBoxListItem;

0 commit comments

Comments
 (0)