diff --git a/packages/ui/src/components/Drawer/Drawer.stories.tsx b/packages/ui/src/components/Drawer/Drawer.stories.tsx index e10b94b..a8a6463 100644 --- a/packages/ui/src/components/Drawer/Drawer.stories.tsx +++ b/packages/ui/src/components/Drawer/Drawer.stories.tsx @@ -16,11 +16,17 @@ export const Controlled: Story = { return (<> - + +

Drawer content

+ +
); }, args: { - name: 'example' + id: 'example', + title: 'Example Drawer', + dismissable: true, + direction: 'right', } }; diff --git a/packages/ui/src/components/Drawer/Drawer.tsx b/packages/ui/src/components/Drawer/Drawer.tsx index 471481c..4937d87 100644 --- a/packages/ui/src/components/Drawer/Drawer.tsx +++ b/packages/ui/src/components/Drawer/Drawer.tsx @@ -6,12 +6,26 @@ import type { DrawerProps } from './Drawer.types'; import { nop } from '@do-ob/core'; import { dialogActions } from '@do-ob/ui/reducer'; import { useDebounce } from '@do-ob/ui/hooks'; -import { use, useEffect } from 'react'; +import { use, useCallback, useEffect } from 'react'; import { DialogContext, DialogDispatchContext } from '@do-ob/ui/context'; +import { cn } from '@do-ob/ui/utility'; + +/** + * Map of direction tailwind classes. + */ +const directionStyles = { + top: 'top-0 left-0 right-0 entering:translate-y-[-100%] exiting:translate-y-[-100%]', + right: 'top-0 right-0 bottom-0 entering:translate-x-full exiting:translate-x-full', + bottom: 'left-0 right-0 bottom-0 entering:translate-y-full exiting:translate-y-full', + left: 'top-0 left-0 bottom-0 entering:translate-x-[-100%] exiting:translate-x-[-100%]', +}; export function Drawer({ - name, + id, + title, dismissable = true, + length = '33%', + direction = 'right', onClose = nop, onOpen = nop, onOpenChange = nop, @@ -20,12 +34,11 @@ export function Drawer({ // ...props }: DrawerProps & React.HTMLAttributes) { - const id = name; const drawer = use(DialogContext).items[id] ?? { id, open: false }; const dispatch = use(DialogDispatchContext); const isOpen = useDebounce(!!drawer.open, 300); - const handleOpenChange = (next: boolean) => { + const handleOpenChange = useCallback((next: boolean) => { onOpenChange(next); if (!next) { if (dismissable && drawer.open) { @@ -35,7 +48,11 @@ export function Drawer({ } else { onOpen(); } - }; + }, [ onOpenChange, onClose, onOpen, dismissable, drawer.open, dispatch, id ]); + + useEffect(() => { + console.log('rerender drawer', id); + }); useEffect(() => { dispatch(dialogActions.register(id)); @@ -54,15 +71,17 @@ export function Drawer({ onOpenChange={handleOpenChange} > - - {name} + + {title} {children} diff --git a/packages/ui/src/components/Drawer/Drawer.types.ts b/packages/ui/src/components/Drawer/Drawer.types.ts index d5be9c5..b55ba95 100644 --- a/packages/ui/src/components/Drawer/Drawer.types.ts +++ b/packages/ui/src/components/Drawer/Drawer.types.ts @@ -1,14 +1,31 @@ +import type { CSSProperties } from 'react'; + export interface DrawerProps { /** - * Required name of the dialog used for controls. + * Required id of the dialog used for controls. */ - name: string; + id: string; + + /** + * The title of the drawer. + */ + title: string; /** * If the drawer can be dismissed by clicking outside of it. */ dismissable?: boolean; + /** + * Width of the drawer. As React Style CSS + */ + length?: CSSProperties['width']; + + /** + * Direction of the drawer. + */ + direction?: 'top' | 'right' | 'bottom' | 'left'; + onClose?: () => void; onOpen?: () => void; diff --git a/packages/ui/src/hooks/useDialogControl.ts b/packages/ui/src/hooks/useDialogControl.ts index 22b0986..97d7bdb 100644 --- a/packages/ui/src/hooks/useDialogControl.ts +++ b/packages/ui/src/hooks/useDialogControl.ts @@ -2,10 +2,11 @@ import { dialogActions } from '@do-ob/ui/reducer'; import { use, useCallback } from 'react'; import { DialogDispatchContext } from '@do-ob/ui/context'; -export function useDialogControl(name: string = '') { +export function useDialogControl(name?: string) { const dispatch = use(DialogDispatchContext); const onPress = useCallback(() => { + if(!name) return; dispatch(dialogActions.toggle(name)); }, [ dispatch, name ]);