From 38a95950905ab11416ec7774d6c170ba19a26fde Mon Sep 17 00:00:00 2001 From: nuria1110 Date: Fri, 6 Sep 2024 15:37:01 +0100 Subject: [PATCH] docs(duelling-picklist): fix storybook docs page not displaying in production --- .../duelling-picklist/duelling-picklist.mdx | 3 +- .../duelling-picklist.stories.tsx | 163 +++++++++++++++++- 2 files changed, 155 insertions(+), 11 deletions(-) diff --git a/src/components/duelling-picklist/duelling-picklist.mdx b/src/components/duelling-picklist/duelling-picklist.mdx index befbb1445f..7eed9f7429 100644 --- a/src/components/duelling-picklist/duelling-picklist.mdx +++ b/src/components/duelling-picklist/duelling-picklist.mdx @@ -1,6 +1,5 @@ import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; -import { Default } from "./duelling-picklist-test.stories"; import * as PickListStories from "./picklist/picklist.stories"; import * as PicklistItemStories from "./picklist-item/picklist-item.stories"; import * as PicklistPlaceholderStories from "./picklist-placeholder/picklist-placeholder.stories"; @@ -55,7 +54,7 @@ import { Example of composed Duelling Picklist components with order preservation and search implemented. - + ### Alternative search placement diff --git a/src/components/duelling-picklist/duelling-picklist.stories.tsx b/src/components/duelling-picklist/duelling-picklist.stories.tsx index 814e69e9ff..bbb0bde20b 100644 --- a/src/components/duelling-picklist/duelling-picklist.stories.tsx +++ b/src/components/duelling-picklist/duelling-picklist.stories.tsx @@ -17,13 +17,15 @@ import { Checkbox } from "../checkbox"; import Box from "../box"; import Button from "../button"; import Typography from "../typography"; -import { Default } from "./duelling-picklist-test.stories"; import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; +import isChromatic from "../../../.storybook/isChromatic"; const styledSystemProps = generateStyledSystemProps({ margin: true, }); +const defaultOpenState = isChromatic(); + const meta: Meta = { title: "Duelling Picklist", component: DuellingPicklist, @@ -38,6 +40,154 @@ type Story = StoryObj; type Item = { key: string; title: string; description: string }; type AllItems = { [key: string]: Item }; +export const Default = () => { + const mockData: Item[] = useMemo(() => { + const arr = []; + for (let i = 0; i < 20; i++) { + const data = { + key: i.toString(), + title: `Content ${i + 1}`, + description: `Description ${i + 1}`, + }; + arr.push(data); + } + return arr; + }, []); + + const allItems = useMemo(() => { + return mockData.reduce((obj, item) => { + obj[item.key] = item; + return obj; + }, {} as { [key: string]: Item }); + }, [mockData]); + + const [isEachItemSelected, setIsEachItemSelected] = useState(false); + const [order] = useState(mockData.map(({ key }) => key)); + const [notSelectedItems, setNotSelectedItems] = useState(allItems); + const [notSelectedSearch, setNotSelectedSearch] = useState({}); + const [selectedItems, setSelectedItems] = useState({}); + const [searchQuery, setSearchQuery] = useState(""); + const isSearchMode = Boolean(searchQuery.length); + + const onAdd = useCallback( + (item) => { + const { [item.key]: removed, ...rest } = notSelectedItems; + setNotSelectedItems(rest); + setSelectedItems({ ...selectedItems, [item.key]: item }); + const { [item.key]: removed2, ...rest2 } = notSelectedSearch; + setNotSelectedSearch(rest2); + }, + [notSelectedItems, notSelectedSearch, selectedItems] + ); + + const onRemove = useCallback( + (item) => { + const { [item.key]: removed, ...rest } = selectedItems; + setSelectedItems(rest); + setNotSelectedItems({ ...notSelectedItems, [item.key]: item }); + if (isSearchMode && item.title.includes(searchQuery)) { + setNotSelectedSearch({ ...notSelectedSearch, [item.key]: item }); + } + }, + [ + isSearchMode, + notSelectedItems, + notSelectedSearch, + searchQuery, + selectedItems, + ] + ); + + const handleSearch = useCallback( + (ev) => { + setSearchQuery(ev.target.value); + const tempNotSelectedItems = Object.keys(notSelectedItems).reduce( + (items, key) => { + const item = notSelectedItems[key]; + if (item.title.includes(ev.target.value)) { + items[item.key] = item; + } + return items; + }, + {} as AllItems + ); + setNotSelectedSearch(tempNotSelectedItems); + }, + [notSelectedItems] + ); + + const renderItems = ( + list: AllItems, + type: PicklistItemProps["type"], + handler: PicklistItemProps["onChange"] + ) => + order.reduce((items, key) => { + const item = list[key]; + if (item) { + items.push( + +
+
+

+ {item.title} +

+
+
+

{item.description}

+
+
+
+ ); + } + return items; + }, [] as JSX.Element[]); + + return ( + <> + setIsEachItemSelected(!isEachItemSelected)} + checked={isEachItemSelected} + label="Example checkbox" + /> + + } + disabled={isEachItemSelected} + > + Your own placeholder} + > + {renderItems( + isSearchMode ? notSelectedSearch : notSelectedItems, + "add", + onAdd + )} + + + } + > + {renderItems(selectedItems, "remove", onRemove)} + + + + ); +}; + +Default.storyName = "Default"; + export const AlternativeSearch: Story = () => { const mockData = useMemo(() => { const arr = []; @@ -323,9 +473,9 @@ export const Grouped: Story = () => { Grouped.storyName = "Grouped"; export const InDialog: Story = () => { - const [isDialogOpen, setIsDialogOpen] = useState(false); + const [isDialogOpen, setIsDialogOpen] = useState(defaultOpenState); return ( - <> + @@ -337,15 +487,10 @@ export const InDialog: Story = () => { > - + ); }; InDialog.storyName = "In Dialog"; -InDialog.parameters = { - chromatic: { - disableSnapshot: true, - }, -}; export const AddItem: Story = () => (