From 1ff3fe165cc284a3254d1eb3c8c926a375b2b0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20DOREAU?= Date: Tue, 8 Sep 2020 00:13:15 +0200 Subject: [PATCH 001/110] feat(core): add single select component --- .../src/components/Select/Select.stories.tsx | 42 ++++++ .../core/src/components/Select/Select.tsx | 137 ++++++++++++++++++ packages/core/src/components/Select/index.tsx | 17 +++ .../Select/static/ClosedDropdown.tsx | 42 ++++++ .../Select/static/OpenedDropdown.tsx | 42 ++++++ 5 files changed, 280 insertions(+) create mode 100644 packages/core/src/components/Select/Select.stories.tsx create mode 100644 packages/core/src/components/Select/Select.tsx create mode 100644 packages/core/src/components/Select/index.tsx create mode 100644 packages/core/src/components/Select/static/ClosedDropdown.tsx create mode 100644 packages/core/src/components/Select/static/OpenedDropdown.tsx diff --git a/packages/core/src/components/Select/Select.stories.tsx b/packages/core/src/components/Select/Select.stories.tsx new file mode 100644 index 0000000000..5102947207 --- /dev/null +++ b/packages/core/src/components/Select/Select.stories.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Select } from '.'; + +export default { + title: 'Select', + component: Select, +}; + +const SELECT_ITEMS = [ + { + label: "test 1", + value: "test_1" + }, + { + label: "test 2", + value: "test_2" + }, + { + label: "test 3", + value: "test_3" + } +] + +export const Default = () => ( + setOpening(false)} + onClose={() => setOpening(true)} + input={} + IconComponent={() => ( + isOpen ? : + )} + MenuProps={{ + anchorOrigin: { + vertical: 'bottom', + horizontal: 'left', + }, + transformOrigin: { + vertical: 'top', + horizontal: 'left', + }, + getContentAnchorEl: null, + }} + > + {items && + items.map(item => ( + + {item.label} + + ))} + + + ); +}; diff --git a/packages/core/src/components/Select/index.tsx b/packages/core/src/components/Select/index.tsx new file mode 100644 index 0000000000..977ebc88eb --- /dev/null +++ b/packages/core/src/components/Select/index.tsx @@ -0,0 +1,17 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { SelectComponent as Select } from './Select'; diff --git a/packages/core/src/components/Select/static/ClosedDropdown.tsx b/packages/core/src/components/Select/static/ClosedDropdown.tsx new file mode 100644 index 0000000000..25ef5aaca5 --- /dev/null +++ b/packages/core/src/components/Select/static/ClosedDropdown.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { SvgIcon, makeStyles, createStyles } from '@material-ui/core'; + +const useStyles = makeStyles(() => + createStyles({ + icon: { + position: 'absolute', + right: '4px', + pointerEvents: "none" + }, + }), +); + +const ClosedDropdown = () => { + const classes = useStyles(); + return ( + + + + ); +}; + +export default ClosedDropdown; diff --git a/packages/core/src/components/Select/static/OpenedDropdown.tsx b/packages/core/src/components/Select/static/OpenedDropdown.tsx new file mode 100644 index 0000000000..b6205a6e44 --- /dev/null +++ b/packages/core/src/components/Select/static/OpenedDropdown.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { SvgIcon, makeStyles, createStyles } from '@material-ui/core'; + +const useStyles = makeStyles(() => + createStyles({ + icon: { + position: 'absolute', + right: '4px', + pointerEvents: 'none', + }, + }), +); + +const OpenedDropdown = () => { + const classes = useStyles(); + return ( + + + + ); +}; + +export default OpenedDropdown; From 5f2e659bea5647d6f0d8394cf7d768ba3f2d4a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20DOREAU?= Date: Tue, 8 Sep 2020 00:14:08 +0200 Subject: [PATCH 002/110] fix(core): prettier on select component --- .../src/components/Select/Select.stories.tsx | 20 +++++++++---------- .../core/src/components/Select/Select.tsx | 4 +--- .../Select/static/ClosedDropdown.tsx | 7 +++++-- .../Select/static/OpenedDropdown.tsx | 7 +++++-- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/core/src/components/Select/Select.stories.tsx b/packages/core/src/components/Select/Select.stories.tsx index 5102947207..d26f689d34 100644 --- a/packages/core/src/components/Select/Select.stories.tsx +++ b/packages/core/src/components/Select/Select.stories.tsx @@ -24,19 +24,17 @@ export default { const SELECT_ITEMS = [ { - label: "test 1", - value: "test_1" + label: 'test 1', + value: 'test_1', }, { - label: "test 2", - value: "test_2" + label: 'test 2', + value: 'test_2', }, { - label: "test 3", - value: "test_3" - } -] + label: 'test 3', + value: 'test_3', + }, +]; -export const Default = () => ( - ; diff --git a/packages/core/src/components/Select/Select.tsx b/packages/core/src/components/Select/Select.tsx index 55b5f7aebd..be07ee6010 100644 --- a/packages/core/src/components/Select/Select.tsx +++ b/packages/core/src/components/Select/Select.tsx @@ -110,9 +110,7 @@ export const SelectComponent = (props: Props) => { onOpen={() => setOpening(false)} onClose={() => setOpening(true)} input={} - IconComponent={() => ( - isOpen ? : - )} + IconComponent={() => (isOpen ? : )} MenuProps={{ anchorOrigin: { vertical: 'bottom', diff --git a/packages/core/src/components/Select/static/ClosedDropdown.tsx b/packages/core/src/components/Select/static/ClosedDropdown.tsx index 25ef5aaca5..235a91963b 100644 --- a/packages/core/src/components/Select/static/ClosedDropdown.tsx +++ b/packages/core/src/components/Select/static/ClosedDropdown.tsx @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => icon: { position: 'absolute', right: '4px', - pointerEvents: "none" + pointerEvents: 'none', }, }), ); @@ -34,7 +34,10 @@ const ClosedDropdown = () => { fill="none" xmlns="http://www.w3.org/2000/svg" > - + ); }; diff --git a/packages/core/src/components/Select/static/OpenedDropdown.tsx b/packages/core/src/components/Select/static/OpenedDropdown.tsx index b6205a6e44..e4a8021017 100644 --- a/packages/core/src/components/Select/static/OpenedDropdown.tsx +++ b/packages/core/src/components/Select/static/OpenedDropdown.tsx @@ -30,11 +30,14 @@ const OpenedDropdown = () => { const classes = useStyles(); return ( - + ); }; From 834e5573b044e46571534311b4321ee63bf70f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20DOREAU?= Date: Tue, 8 Sep 2020 16:01:45 +0200 Subject: [PATCH 003/110] feat(core): add multiple select component --- .../src/components/Select/Select.stories.tsx | 13 +++- .../core/src/components/Select/Select.tsx | 70 +++++++++++++++++-- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/packages/core/src/components/Select/Select.stories.tsx b/packages/core/src/components/Select/Select.stories.tsx index d26f689d34..38acb46c10 100644 --- a/packages/core/src/components/Select/Select.stories.tsx +++ b/packages/core/src/components/Select/Select.stories.tsx @@ -37,4 +37,15 @@ const SELECT_ITEMS = [ }, ]; -export const Default = () => +); + +export const Multiple = () => ( + setOpening(false)} - onClose={() => setOpening(true)} + onClick={selectHandleOnOpen} + open={canOpen} input={} - IconComponent={() => (isOpen ? : )} + renderValue={selected => + multiple && (value as any[]).length !== 0 ? ( +
+ {(selected as string[]).map(selectedValue => ( + el.value === selectedValue)?.label} + label={items.find(el => el.value === selectedValue)?.label} + clickable + onDelete={handleDelete(selectedValue)} + className={classes.chip} + /> + ))} +
+ ) : ( + + {(value as any[]).length === 0 + ? placeholder || '' + : items.find(el => el.value === selected)?.label} + + ) + } + IconComponent={() => + !canOpen ? : + } MenuProps={{ anchorOrigin: { vertical: 'bottom', @@ -123,9 +169,21 @@ export const SelectComponent = (props: Props) => { getContentAnchorEl: null, }} > + {placeholder && ( + + {placeholder} + + )} {items && items.map(item => ( + {multiple && ( + + )} {item.label} ))} From 039c743d2c93b1f4cc8b9e3c1b8dd576ba73204f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20DOREAU?= Date: Fri, 11 Sep 2020 23:54:19 +0200 Subject: [PATCH 004/110] feat(core): add CheckboxTree component --- .../CheckboxTree/CheckboxTree.stories.tsx | 69 +++++ .../components/CheckboxTree/CheckboxTree.tsx | 252 ++++++++++++++++++ .../src/components/CheckboxTree/index.tsx | 17 ++ 3 files changed, 338 insertions(+) create mode 100644 packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx create mode 100644 packages/core/src/components/CheckboxTree/CheckboxTree.tsx create mode 100644 packages/core/src/components/CheckboxTree/index.tsx diff --git a/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx b/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx new file mode 100644 index 0000000000..04d4c41451 --- /dev/null +++ b/packages/core/src/components/CheckboxTree/CheckboxTree.stories.tsx @@ -0,0 +1,69 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { CheckboxTree } from '.'; + +const CHECKBOX_TREE_ITEMS = [ + { + label: 'Genereic subcategory name 1', + options: [ + { + label: 'Option 1', + value: 1, + }, + { + label: 'Option 2', + value: 2, + }, + ], + }, + { + label: 'Genereic subcategory name 2', + options: [ + { + label: 'Option 1', + value: 1, + }, + { + label: 'Option 2', + value: 2, + }, + ], + }, + { + label: 'Genereic subcategory name 3', + options: [ + { + label: 'Option 1', + value: 1, + }, + { + label: 'Option 2', + value: 2, + }, + ], + }, +]; + +export default { + title: 'CheckboxTree', + component: CheckboxTree, +}; + +export const Default = () => ( + +); diff --git a/packages/core/src/components/CheckboxTree/CheckboxTree.tsx b/packages/core/src/components/CheckboxTree/CheckboxTree.tsx new file mode 100644 index 0000000000..386b02053a --- /dev/null +++ b/packages/core/src/components/CheckboxTree/CheckboxTree.tsx @@ -0,0 +1,252 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useReducer } from 'react'; +import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; +import { + List, + ListItem, + ListItemIcon, + Checkbox, + ListItemText, + Collapse, +} from '@material-ui/core'; +import ExpandLess from '@material-ui/icons/ExpandLess'; +import ExpandMore from '@material-ui/icons/ExpandMore'; + +type IndexedObject = { + [key: string]: T; +}; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + }, + nested: { + paddingLeft: theme.spacing(4), + }, + }), +); + +/* SUB_CATEGORY */ + +type SubCategory = { + label: string; + isChecked?: boolean; + isOpen?: boolean; + options?: Option[]; +}; + +type SubCategoryWithIndexedOptions = { + label: string; + isChecked?: boolean; + isOpen?: boolean; + options: IndexedObject