Skip to content

Commit

Permalink
feat: Added directions are drawer modal
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-crowell committed Jun 29, 2024
1 parent 1677ce5 commit d65bf86
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 16 deletions.
10 changes: 8 additions & 2 deletions packages/ui/src/components/Drawer/Drawer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ export const Controlled: Story = {

return (<>
<Button dialog="example">Click me</Button>
<Drawer {...args} />
<Drawer {...args}>
<p>Drawer content</p>
<Button dialog="example">Click me to close</Button>
</Drawer>
</>);
},
args: {
name: 'example'
id: 'example',
title: 'Example Drawer',
dismissable: true,
direction: 'right',
}
};

41 changes: 30 additions & 11 deletions packages/ui/src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -20,12 +34,11 @@ export function Drawer({
// ...props
}: DrawerProps & React.HTMLAttributes<HTMLElement>) {

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) {
Expand All @@ -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));
Expand All @@ -54,15 +71,17 @@ export function Drawer({
onOpenChange={handleOpenChange}
>
<Modal
className="fixed w-1/3 min-w-80 bg-white shadow-md transition-all duration-500 entering:translate-x-full exiting:translate-x-full"
className={cn(
'fixed min-w-80 transform-gpu bg-white shadow-md transition-all duration-500',
directionStyles[direction],
)}
style={{
top: 0,
right: 0,
bottom: 0,
width: direction === 'top' || direction === 'bottom' ? '100%' : length,
height: direction === 'top' || direction === 'bottom' ? length : '100%',
}}
>
<Dialog>
<Heading slot="title">{name}</Heading>
<Dialog className="p-4 focus-visible:outline-none">
<Heading slot="title" className="text-lg">{title}</Heading>
{children}
</Dialog>
</Modal>
Expand Down
21 changes: 19 additions & 2 deletions packages/ui/src/components/Drawer/Drawer.types.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/hooks/useDialogControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]);

Expand Down

0 comments on commit d65bf86

Please sign in to comment.