From 5ff2f3ed73c2b30a39fae4f2bcc5f5780fd2ac43 Mon Sep 17 00:00:00 2001 From: qkrdmstlr3 Date: Wed, 21 Aug 2024 01:57:59 +0900 Subject: [PATCH 1/2] fix --- src/app/(sidebar)/(my-info)/page.tsx | 2 ++ src/system/components/Dropdown/Dropdown.tsx | 14 ++++++++++ src/system/components/Dropdown/anatomy.ts | 1 + .../Dropdown/compounds/CheckboxItem.tsx | 28 +++++++++++++++++++ .../components/Dropdown/compounds/Content.tsx | 14 ++++++++++ .../components/Dropdown/compounds/Root.tsx | 26 +++++++++++++++++ .../Dropdown/compounds/Separator.tsx | 9 ++++++ .../components/Dropdown/compounds/Trigger.tsx | 10 +++++++ .../Dropdown/compounds/TriggerArrow.tsx | 22 +++++++++++++++ src/system/components/Dropdown/context.tsx | 14 ++++++++++ .../Dropdown/logics/useDropdownLogics.ts | 18 ++++++++++++ .../Dropdown/styles/useDropdownStyles.ts | 24 ++++++++++++++++ src/system/components/index.ts | 1 + 13 files changed, 183 insertions(+) create mode 100644 src/system/components/Dropdown/Dropdown.tsx create mode 100644 src/system/components/Dropdown/anatomy.ts create mode 100644 src/system/components/Dropdown/compounds/CheckboxItem.tsx create mode 100644 src/system/components/Dropdown/compounds/Content.tsx create mode 100644 src/system/components/Dropdown/compounds/Root.tsx create mode 100644 src/system/components/Dropdown/compounds/Separator.tsx create mode 100644 src/system/components/Dropdown/compounds/Trigger.tsx create mode 100644 src/system/components/Dropdown/compounds/TriggerArrow.tsx create mode 100644 src/system/components/Dropdown/context.tsx create mode 100644 src/system/components/Dropdown/logics/useDropdownLogics.ts create mode 100644 src/system/components/Dropdown/styles/useDropdownStyles.ts diff --git a/src/app/(sidebar)/(my-info)/page.tsx b/src/app/(sidebar)/(my-info)/page.tsx index a8fd70fd..4e3187b7 100644 --- a/src/app/(sidebar)/(my-info)/page.tsx +++ b/src/app/(sidebar)/(my-info)/page.tsx @@ -1,3 +1,5 @@ +'use client'; + import { Icon } from '@/system/components'; import { InfoCardList } from './components/InfoCardList'; diff --git a/src/system/components/Dropdown/Dropdown.tsx b/src/system/components/Dropdown/Dropdown.tsx new file mode 100644 index 00000000..43a47c7b --- /dev/null +++ b/src/system/components/Dropdown/Dropdown.tsx @@ -0,0 +1,14 @@ +import { CheckboxItem } from './compounds/CheckboxItem'; +import { Content } from './compounds/Content'; +import { Root } from './compounds/Root'; +import { Separator } from './compounds/Separator'; +import { Trigger } from './compounds/Trigger'; +import { TriggerArrow } from './compounds/TriggerArrow'; + +export const Dropdown = Object.assign(Root, { + Trigger, + TriggerArrow, + Content, + Separator, + CheckboxItem, +}); diff --git a/src/system/components/Dropdown/anatomy.ts b/src/system/components/Dropdown/anatomy.ts new file mode 100644 index 00000000..81416eae --- /dev/null +++ b/src/system/components/Dropdown/anatomy.ts @@ -0,0 +1 @@ +export type DropdownAnatomy = 'trigger-arrow' | 'content' | 'separator' | 'checkbox-item'; diff --git a/src/system/components/Dropdown/compounds/CheckboxItem.tsx b/src/system/components/Dropdown/compounds/CheckboxItem.tsx new file mode 100644 index 00000000..6b712419 --- /dev/null +++ b/src/system/components/Dropdown/compounds/CheckboxItem.tsx @@ -0,0 +1,28 @@ +'use client'; + +import { If } from '@/system/utils/If'; +import { Icon } from '../..'; +import { ComponentProps, forwardRef } from 'react'; +import { mergeProps } from '@/utils/mergeProps'; +import { color } from '@/system/token/color'; +import { useDropdownContext } from '../context'; + +interface Props extends ComponentProps<'button'> { + checked?: boolean; +} + +export const CheckboxItem = forwardRef(function CheckboxItem( + { checked, disabled, children, ...restProps }, + ref, +) { + const { styles, logics } = useDropdownContext(); + + return ( + + ); +}); diff --git a/src/system/components/Dropdown/compounds/Content.tsx b/src/system/components/Dropdown/compounds/Content.tsx new file mode 100644 index 00000000..fed6bab2 --- /dev/null +++ b/src/system/components/Dropdown/compounds/Content.tsx @@ -0,0 +1,14 @@ +'use client'; + +import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu'; +import { ComponentProps } from 'react'; +import { mergeProps } from '@/utils/mergeProps'; +import { useDropdownContext } from '../context'; + +type ContentProps = ComponentProps; + +export function Content(props: ContentProps) { + const { styles } = useDropdownContext(); + + return ; +} diff --git a/src/system/components/Dropdown/compounds/Root.tsx b/src/system/components/Dropdown/compounds/Root.tsx new file mode 100644 index 00000000..f7254d78 --- /dev/null +++ b/src/system/components/Dropdown/compounds/Root.tsx @@ -0,0 +1,26 @@ +'use client'; + +import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu'; +import { PropsWithChildren, useState } from 'react'; +import { DropdownProvider } from '../context'; +import { useDropdownStyles } from '../styles/useDropdownStyles'; +import { useDropdownLogics } from '../logics/useDropdownLogics'; + +interface RootProps { + defaultOpen?: boolean; +} + +// 추후 Controlled방식도 지원 +export function Root({ defaultOpen = false, children }: PropsWithChildren) { + const [open, setOpen] = useState(defaultOpen); + const dropdownStyles = useDropdownStyles(); + const dropdownLogics = useDropdownLogics({ onOpenChange: setOpen }); + + return ( + + + {children} + + + ); +} diff --git a/src/system/components/Dropdown/compounds/Separator.tsx b/src/system/components/Dropdown/compounds/Separator.tsx new file mode 100644 index 00000000..a6d831e8 --- /dev/null +++ b/src/system/components/Dropdown/compounds/Separator.tsx @@ -0,0 +1,9 @@ +'use client'; + +import { useDropdownContext } from '../context'; + +export function Separator() { + const { styles } = useDropdownContext(); + + return
; +} diff --git a/src/system/components/Dropdown/compounds/Trigger.tsx b/src/system/components/Dropdown/compounds/Trigger.tsx new file mode 100644 index 00000000..d0e8b521 --- /dev/null +++ b/src/system/components/Dropdown/compounds/Trigger.tsx @@ -0,0 +1,10 @@ +'use client'; + +import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu'; +import { ComponentProps } from 'react'; + +export type TriggerProps = ComponentProps; + +export function Trigger({ children }: TriggerProps) { + return {children}; +} diff --git a/src/system/components/Dropdown/compounds/TriggerArrow.tsx b/src/system/components/Dropdown/compounds/TriggerArrow.tsx new file mode 100644 index 00000000..21474cd6 --- /dev/null +++ b/src/system/components/Dropdown/compounds/TriggerArrow.tsx @@ -0,0 +1,22 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { Icon } from '../..'; +import { useDropdownContext } from '../context'; +import { color } from '@/system/token/color'; + +export function TriggerArrow() { + const { open } = useDropdownContext(); + + return ( + + + + ); +} diff --git a/src/system/components/Dropdown/context.tsx b/src/system/components/Dropdown/context.tsx new file mode 100644 index 00000000..cb59acfd --- /dev/null +++ b/src/system/components/Dropdown/context.tsx @@ -0,0 +1,14 @@ +import { generateContext } from '@/lib'; +import { DropdownStyles } from './styles/useDropdownStyles'; +import { DropdownLogics } from './logics/useDropdownLogics'; + +interface DropdownContext { + open: boolean; + styles: DropdownStyles; + logics: DropdownLogics; + onOpenChange: (open: boolean) => void; +} + +export const [DropdownProvider, useDropdownContext] = generateContext({ + name: 'Dropdown', +}); diff --git a/src/system/components/Dropdown/logics/useDropdownLogics.ts b/src/system/components/Dropdown/logics/useDropdownLogics.ts new file mode 100644 index 00000000..fbdee987 --- /dev/null +++ b/src/system/components/Dropdown/logics/useDropdownLogics.ts @@ -0,0 +1,18 @@ +import { DropdownAnatomy } from '../anatomy'; + +export type DropdownLogics = Record; + +interface Props { + onOpenChange: (open: boolean) => void; +} + +export function useDropdownLogics({ onOpenChange }: Props): DropdownLogics { + return { + content: {}, + separator: {}, + 'trigger-arrow': {}, + 'checkbox-item': { + onClick: () => onOpenChange(false), + }, + }; +} diff --git a/src/system/components/Dropdown/styles/useDropdownStyles.ts b/src/system/components/Dropdown/styles/useDropdownStyles.ts new file mode 100644 index 00000000..b687e82c --- /dev/null +++ b/src/system/components/Dropdown/styles/useDropdownStyles.ts @@ -0,0 +1,24 @@ +import { DropdownAnatomy } from '../anatomy'; + +interface DropdownStyle { + className?: string; +} + +export type DropdownStyles = Record; + +export function useDropdownStyles(): Record { + return { + content: { + className: + 'flex flex-col py-[8px] shadow-[0px_2px_8px_0px_rgba(0,0,0,0.12),0px_0px_1px_0px_rgba(0,0,0,0.08)] min-w-[170px] bg-white rounded-[12px] border-[1px] hover:border-neutral-20', + }, + separator: { + className: 'h-[8px] bg-nuetral-3 w-full', + }, + 'trigger-arrow': {}, + 'checkbox-item': { + className: + 'flex justify-between items-center mx-[8px] my-[4px] px-[8px] py-[4px] text-label1 font-medium text-neutral-80 rounded-[6px] hover:bg-neutral-3 disabled:text-neutral-30 disabled:bg-white', + }, + }; +} diff --git a/src/system/components/index.ts b/src/system/components/index.ts index 41b6007d..ed86e633 100644 --- a/src/system/components/index.ts +++ b/src/system/components/index.ts @@ -1,5 +1,6 @@ export { Button } from './Button/Button'; export type { ButtonProps } from './Button/Button'; +export { Dropdown } from './Dropdown/Dropdown'; export { Icon } from './Icon/Icon'; export type { IconProps } from './Icon/Icon'; export { Text } from './Text/Text'; From d08e70667edd130cc044f1b07265e5fce0ad81fe Mon Sep 17 00:00:00 2001 From: qkrdmstlr3 Date: Wed, 21 Aug 2024 22:59:09 +0900 Subject: [PATCH 2/2] review --- src/system/components/Dropdown/Dropdown.tsx | 4 ++-- .../Dropdown/compounds/{CheckboxItem.tsx => CheckedItem.tsx} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/system/components/Dropdown/compounds/{CheckboxItem.tsx => CheckedItem.tsx} (89%) diff --git a/src/system/components/Dropdown/Dropdown.tsx b/src/system/components/Dropdown/Dropdown.tsx index 43a47c7b..234fac45 100644 --- a/src/system/components/Dropdown/Dropdown.tsx +++ b/src/system/components/Dropdown/Dropdown.tsx @@ -1,4 +1,4 @@ -import { CheckboxItem } from './compounds/CheckboxItem'; +import { CheckedItem } from './compounds/CheckedItem'; import { Content } from './compounds/Content'; import { Root } from './compounds/Root'; import { Separator } from './compounds/Separator'; @@ -10,5 +10,5 @@ export const Dropdown = Object.assign(Root, { TriggerArrow, Content, Separator, - CheckboxItem, + CheckedItem, }); diff --git a/src/system/components/Dropdown/compounds/CheckboxItem.tsx b/src/system/components/Dropdown/compounds/CheckedItem.tsx similarity index 89% rename from src/system/components/Dropdown/compounds/CheckboxItem.tsx rename to src/system/components/Dropdown/compounds/CheckedItem.tsx index 6b712419..32a55016 100644 --- a/src/system/components/Dropdown/compounds/CheckboxItem.tsx +++ b/src/system/components/Dropdown/compounds/CheckedItem.tsx @@ -11,7 +11,7 @@ interface Props extends ComponentProps<'button'> { checked?: boolean; } -export const CheckboxItem = forwardRef(function CheckboxItem( +export const CheckedItem = forwardRef(function CheckedItem( { checked, disabled, children, ...restProps }, ref, ) {