Skip to content

Instantly share code, notes, and snippets.

@ededejr
Last active December 22, 2023 21:15
Show Gist options
  • Save ededejr/f7804f746b3609892d27154ec704bb6a to your computer and use it in GitHub Desktop.
Save ededejr/f7804f746b3609892d27154ec704bb6a to your computer and use it in GitHub Desktop.
quick hack for a responsive dialog-drawer built on components from ui.shadcn.com
import * as React from 'react';
import { useMediaQuery } from '@/lib/hooks';
import * as DialogParts from '@/ui/dialog';
import * as DrawerParts from '@/ui/drawer';
type ResponsiveDialogPartsKey =
| ''
| 'Portal'
| 'Overlay'
| 'Trigger'
| 'Close'
| 'Content'
| 'Header'
| 'Footer'
| 'Title'
| 'Description';
const makeResponsivePart = (type: ResponsiveDialogPartsKey) => {
type PartKey = typeof type;
type DialogTypeProps = React.ComponentPropsWithoutRef<
(typeof DialogParts)[`Dialog${PartKey}`]
>;
type DrawerTypeProps = React.ComponentPropsWithoutRef<
(typeof DrawerParts)[`Drawer${PartKey}`]
>;
type Props = DialogTypeProps | DrawerTypeProps;
const c = function ResponsiveComponent(props: Props) {
const isDesktop = useMediaQuery('(min-width: 768px)');
const Component = isDesktop
? DialogParts[`Dialog${type}`]
: DrawerParts[`Drawer${type}`];
// @ts-expect-error - needs to be typed properly
return <Component {...props} />;
};
c.displayName = `ResponsiveDialog${type}`;
return c as React.FC<Props>;
};
export const ResponsiveDialog = makeResponsivePart('');
export const ResponsiveDialogPortal = makeResponsivePart('Portal');
export const ResponsiveDialogOverlay = makeResponsivePart('Overlay');
export const ResponsiveDialogTrigger = makeResponsivePart('Trigger');
export const ResponsiveDialogClose = makeResponsivePart('Close');
export const ResponsiveDialogContent = makeResponsivePart('Content');
export const ResponsiveDialogHeader = makeResponsivePart('Header');
export const ResponsiveDialogFooter = makeResponsivePart('Footer');
export const ResponsiveDialogTitle = makeResponsivePart('Title');
export const ResponsiveDialogDescription = makeResponsivePart('Description');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment