From cdd7bcb7a5f9dc05e56300143e2b5103d15bdcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20Miesi=C4=85c?= <tadeusz.miesiac@gmail.com> Date: Thu, 5 Oct 2023 17:15:13 +0800 Subject: [PATCH] feat(accordion component): added accordion component and example --- package-lock.json | 10 ++++++ package.json | 5 +-- pages/accordion-test.tsx | 32 +++++++++++++++++++ pages/index.tsx | 1 - pages/redux-api-poc.tsx | 26 --------------- src/shared/Accordion/Accordion.component.tsx | 31 ++++++++++++++++++ .../AccordionItem/AccordionItem.component.tsx | 25 +++++++++++++++ src/shared/Accordion/AccordionItem/index.ts | 1 + .../AccordionItemButton.component.tsx | 14 ++++++++ .../AccordionItemButton.style.css | 3 ++ .../Accordion/AccordionItemButton/index.ts | 1 + .../AccordionItemHeading.component.tsx | 9 ++++++ .../Accordion/AccordionItemHeading/index.ts | 1 + .../AccordionItemPanel.component.tsx | 9 ++++++ .../Accordion/AccordionItemPanel/index.ts | 1 + src/shared/Accordion/index.ts | 5 +++ 16 files changed, 145 insertions(+), 29 deletions(-) create mode 100644 pages/accordion-test.tsx delete mode 100644 pages/redux-api-poc.tsx create mode 100644 src/shared/Accordion/Accordion.component.tsx create mode 100644 src/shared/Accordion/AccordionItem/AccordionItem.component.tsx create mode 100644 src/shared/Accordion/AccordionItem/index.ts create mode 100644 src/shared/Accordion/AccordionItemButton/AccordionItemButton.component.tsx create mode 100644 src/shared/Accordion/AccordionItemButton/AccordionItemButton.style.css create mode 100644 src/shared/Accordion/AccordionItemButton/index.ts create mode 100644 src/shared/Accordion/AccordionItemHeading/AccordionItemHeading.component.tsx create mode 100644 src/shared/Accordion/AccordionItemHeading/index.ts create mode 100644 src/shared/Accordion/AccordionItemPanel/AccordionItemPanel.component.tsx create mode 100644 src/shared/Accordion/AccordionItemPanel/index.ts create mode 100644 src/shared/Accordion/index.ts diff --git a/package-lock.json b/package-lock.json index 80bd76c5..790d099b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "next": "13.4.19", "postcss": "8.4.29", "react": "18.2.0", + "react-accessible-accordion": "^5.0.0", "react-dom": "18.2.0", "react-redux": "^8.1.2", "tailwind-merge": "^1.14.0", @@ -10308,6 +10309,15 @@ "node": ">=0.10.0" } }, + "node_modules/react-accessible-accordion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-accessible-accordion/-/react-accessible-accordion-5.0.0.tgz", + "integrity": "sha512-MT2obYpTgLIIfPr9d7hEyvPB5rg8uJcHpgA83JSRlEUHvzH48+8HJPvzSs+nM+XprTugDgLfhozO5qyJpBvYRQ==", + "peerDependencies": { + "react": "^16.3.2 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.3.3 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", diff --git a/package.json b/package.json index ba33ffe0..c4ee3467 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "next": "13.4.19", "postcss": "8.4.29", "react": "18.2.0", + "react-accessible-accordion": "^5.0.0", "react-dom": "18.2.0", "react-redux": "^8.1.2", "tailwind-merge": "^1.14.0", @@ -79,9 +80,9 @@ "lint-staged": "^14.0.1", "prettier": "^3.0.3", "prettier-2": "npm:prettier@^2", + "prettier-plugin-tailwindcss": "^0.5.4", "typescript": "^5.2.2", - "zod-fixture": "^2.5.0", - "prettier-plugin-tailwindcss": "^0.5.4" + "zod-fixture": "^2.5.0" }, "config": { "commitizen": { diff --git a/pages/accordion-test.tsx b/pages/accordion-test.tsx new file mode 100644 index 00000000..2050582d --- /dev/null +++ b/pages/accordion-test.tsx @@ -0,0 +1,32 @@ +import { + Accordion, + AccordionItem, + AccordionItemHeading, + AccordionItemButton, + AccordionItemPanel, +} from '@/shared/Accordion'; + +const AccordionPage = (): JSX.Element => ( + <div> + <div className="w-52 bg-primary-100 p-10"> + <div className="bg-white"> + <Accordion allowZeroExpanded> + <AccordionItem> + <AccordionItemHeading> + <AccordionItemButton>What harsh truths do you prefer to ignore?</AccordionItemButton> + </AccordionItemHeading> + <AccordionItemPanel> + <p> + Exercitation in fugiat est ut ad ea cupidatat ut in cupidatat occaecat ut occaecat + consequat est minim minim esse tempor laborum consequat esse adipisicing eu + reprehenderit enim. + </p> + </AccordionItemPanel> + </AccordionItem> + </Accordion> + </div> + </div> + </div> +); + +export default AccordionPage; diff --git a/pages/index.tsx b/pages/index.tsx index 929f1328..0c103a3f 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,4 +1,3 @@ import { MinervaSPA } from '@/components/SPA'; -import '@/styles/index.css'; export default MinervaSPA; diff --git a/pages/redux-api-poc.tsx b/pages/redux-api-poc.tsx deleted file mode 100644 index 2811cf8a..00000000 --- a/pages/redux-api-poc.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { useSelector } from 'react-redux'; -import { selectSearchValue } from '@/redux/search/search.selectors'; -import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; -import { getDrugs } from '@/redux/drugs/drugs.thunks'; -import { getMirnas } from '@/redux/mirnas/mirnas.thunks'; - -const ReduxPage = (): JSX.Element => { - const dispatch = useAppDispatch(); - const searchValue = useSelector(selectSearchValue); - - const triggerSyncUpdate = (): void => { - dispatch(getDrugs('aspirin')); - dispatch(getMirnas('hsa-miR-302b-3p')); - }; - - return ( - <div> - {searchValue} - <button type="button" onClick={triggerSyncUpdate}> - sync update - </button> - </div> - ); -}; - -export default ReduxPage; diff --git a/src/shared/Accordion/Accordion.component.tsx b/src/shared/Accordion/Accordion.component.tsx new file mode 100644 index 00000000..f0de2a3e --- /dev/null +++ b/src/shared/Accordion/Accordion.component.tsx @@ -0,0 +1,31 @@ +import { Accordion as Ac } from 'react-accessible-accordion'; +import { DivAttributes } from 'react-accessible-accordion/dist/types/helpers/types'; + +type ID = string | number; + +type AccordionProps = Pick<DivAttributes, Exclude<keyof DivAttributes, 'onChange'>> & { + children: React.ReactNode; + preExpanded?: ID[]; + allowMultipleExpanded?: boolean; + allowZeroExpanded?: boolean; + onChange?(args: ID[]): void; +}; + +export const Accordion = ({ + children, + preExpanded, + allowMultipleExpanded, + allowZeroExpanded, + onChange, + ...rest +}: AccordionProps): JSX.Element => ( + <Ac + preExpanded={preExpanded} + allowMultipleExpanded={allowMultipleExpanded} + allowZeroExpanded={allowZeroExpanded} + onChange={onChange} + {...rest} + > + {children} + </Ac> +); diff --git a/src/shared/Accordion/AccordionItem/AccordionItem.component.tsx b/src/shared/Accordion/AccordionItem/AccordionItem.component.tsx new file mode 100644 index 00000000..a5ca5060 --- /dev/null +++ b/src/shared/Accordion/AccordionItem/AccordionItem.component.tsx @@ -0,0 +1,25 @@ +import { AccordionItem as AccItem } from 'react-accessible-accordion'; + +interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> { + uuid?: string | number; + activeClassName?: string; + dangerouslySetExpanded?: boolean; + children: React.ReactNode; +} + +export const AccordionItem = ({ + uuid: customUuid, + dangerouslySetExpanded, + children, + ...rest +}: AccordionItemProps): JSX.Element => ( + <AccItem + uuid={customUuid} + dangerouslySetExpanded={dangerouslySetExpanded} + {...rest} + className="border-b" + activeClassName="" + > + {children} + </AccItem> +); diff --git a/src/shared/Accordion/AccordionItem/index.ts b/src/shared/Accordion/AccordionItem/index.ts new file mode 100644 index 00000000..4940ad37 --- /dev/null +++ b/src/shared/Accordion/AccordionItem/index.ts @@ -0,0 +1 @@ +export { AccordionItem } from './AccordionItem.component'; diff --git a/src/shared/Accordion/AccordionItemButton/AccordionItemButton.component.tsx b/src/shared/Accordion/AccordionItemButton/AccordionItemButton.component.tsx new file mode 100644 index 00000000..32942ae9 --- /dev/null +++ b/src/shared/Accordion/AccordionItemButton/AccordionItemButton.component.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@/shared/Icon'; +import { AccordionItemButton as AIB } from 'react-accessible-accordion'; +import './AccordionItemButton.style.css'; + +interface AccordionItemButtonProps { + children: React.ReactNode; +} + +export const AccordionItemButton = ({ children }: AccordionItemButtonProps): JSX.Element => ( + <AIB className="accordion-button flex flex-row flex-nowrap justify-between"> + {children} + <Icon name="chevron-down" className="arrow-button h-6 w-6 fill-font-500" /> + </AIB> +); diff --git a/src/shared/Accordion/AccordionItemButton/AccordionItemButton.style.css b/src/shared/Accordion/AccordionItemButton/AccordionItemButton.style.css new file mode 100644 index 00000000..ee300f20 --- /dev/null +++ b/src/shared/Accordion/AccordionItemButton/AccordionItemButton.style.css @@ -0,0 +1,3 @@ +.accordion-button[aria-expanded='true'] > .arrow-button { + @apply rotate-180; +} diff --git a/src/shared/Accordion/AccordionItemButton/index.ts b/src/shared/Accordion/AccordionItemButton/index.ts new file mode 100644 index 00000000..24541a1a --- /dev/null +++ b/src/shared/Accordion/AccordionItemButton/index.ts @@ -0,0 +1 @@ +export { AccordionItemButton } from './AccordionItemButton.component'; diff --git a/src/shared/Accordion/AccordionItemHeading/AccordionItemHeading.component.tsx b/src/shared/Accordion/AccordionItemHeading/AccordionItemHeading.component.tsx new file mode 100644 index 00000000..a2e1af34 --- /dev/null +++ b/src/shared/Accordion/AccordionItemHeading/AccordionItemHeading.component.tsx @@ -0,0 +1,9 @@ +import { AccordionItemHeading as AIH } from 'react-accessible-accordion'; + +interface AccordionItemHeadingProps { + children: React.ReactNode; +} + +export const AccordionItemHeading = ({ children }: AccordionItemHeadingProps): JSX.Element => ( + <AIH className="py-4">{children}</AIH> +); diff --git a/src/shared/Accordion/AccordionItemHeading/index.ts b/src/shared/Accordion/AccordionItemHeading/index.ts new file mode 100644 index 00000000..9eb4999c --- /dev/null +++ b/src/shared/Accordion/AccordionItemHeading/index.ts @@ -0,0 +1 @@ +export { AccordionItemHeading } from './AccordionItemHeading.component'; diff --git a/src/shared/Accordion/AccordionItemPanel/AccordionItemPanel.component.tsx b/src/shared/Accordion/AccordionItemPanel/AccordionItemPanel.component.tsx new file mode 100644 index 00000000..d0ef686d --- /dev/null +++ b/src/shared/Accordion/AccordionItemPanel/AccordionItemPanel.component.tsx @@ -0,0 +1,9 @@ +import { AccordionItemPanel as AIP } from 'react-accessible-accordion'; + +interface AccordionItemPanelProps { + children: React.ReactNode; +} + +export const AccordionItemPanel = ({ children }: AccordionItemPanelProps): JSX.Element => ( + <AIP className="pb-4">{children}</AIP> +); diff --git a/src/shared/Accordion/AccordionItemPanel/index.ts b/src/shared/Accordion/AccordionItemPanel/index.ts new file mode 100644 index 00000000..d45a4338 --- /dev/null +++ b/src/shared/Accordion/AccordionItemPanel/index.ts @@ -0,0 +1 @@ +export { AccordionItemPanel } from './AccordionItemPanel.component'; diff --git a/src/shared/Accordion/index.ts b/src/shared/Accordion/index.ts new file mode 100644 index 00000000..244e2026 --- /dev/null +++ b/src/shared/Accordion/index.ts @@ -0,0 +1,5 @@ +export { AccordionItem } from '@/shared/Accordion/AccordionItem'; +export { AccordionItemButton } from '@/shared/Accordion/AccordionItemButton'; +export { AccordionItemHeading } from '@/shared/Accordion/AccordionItemHeading'; +export { Accordion } from './Accordion.component'; +export { AccordionItemPanel } from '@/shared/Accordion/AccordionItemPanel'; -- GitLab