Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions public/r/data-table-action-bar.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
],
"files": [
{
"path": "src/components/data-table-action-bar.tsx",
"content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport type { Table } from \"@tanstack/react-table\";\nimport { Loader } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\ninterface DataTableActionBarProps<TData>\n extends React.ComponentProps<typeof motion.div> {\n table: Table<TData>;\n visible?: boolean;\n container?: Element | DocumentFragment | null;\n}\n\nfunction DataTableActionBar<TData>({\n table,\n visible: visibleProp,\n container: containerProp,\n children,\n className,\n ...props\n}: DataTableActionBarProps<TData>) {\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n table.toggleAllRowsSelected(false);\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [table]);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const visible =\n visibleProp ?? table.getFilteredSelectedRowModel().rows.length > 0;\n\n return ReactDOM.createPortal(\n <AnimatePresence>\n {visible && (\n <motion.div\n role=\"toolbar\"\n aria-orientation=\"horizontal\"\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 20 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className={cn(\n \"fixed inset-x-0 bottom-6 z-50 mx-auto flex w-fit flex-wrap items-center justify-center gap-2 rounded-md border bg-background p-2 text-foreground shadow-sm\",\n className,\n )}\n {...props}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>,\n container,\n );\n}\n\ninterface DataTableActionBarActionProps\n extends React.ComponentProps<typeof Button> {\n tooltip?: string;\n isPending?: boolean;\n}\n\nfunction DataTableActionBarAction({\n size = \"sm\",\n tooltip,\n isPending,\n disabled,\n className,\n children,\n ...props\n}: DataTableActionBarActionProps) {\n const trigger = (\n <Button\n variant=\"secondary\"\n size={size}\n className={cn(\n \"gap-1.5 border border-secondary bg-secondary/50 hover:bg-secondary/70 [&>svg]:size-3.5\",\n size === \"icon\" ? \"size-7\" : \"h-7\",\n className,\n )}\n disabled={disabled || isPending}\n {...props}\n >\n {isPending ? <Loader className=\"animate-spin\" /> : children}\n </Button>\n );\n\n if (!tooltip) return trigger;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{trigger}</TooltipTrigger>\n <TooltipContent\n sideOffset={6}\n className=\"border bg-accent font-semibold text-foreground dark:bg-zinc-900 [&>span]:hidden\"\n >\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n );\n}\n\nexport { DataTableActionBar, DataTableActionBarAction };\n",
"type": "registry:component"
"path": "src/components/data-table/data-table-action-bar.tsx",
"content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Separator } from \"@/components/ui/separator\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport type { Table } from \"@tanstack/react-table\";\nimport { Loader, X } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\ninterface DataTableActionBarProps<TData>\n extends React.ComponentProps<typeof motion.div> {\n table: Table<TData>;\n visible?: boolean;\n container?: Element | DocumentFragment | null;\n}\n\nfunction DataTableActionBar<TData>({\n table,\n visible: visibleProp,\n container: containerProp,\n children,\n className,\n ...props\n}: DataTableActionBarProps<TData>) {\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => {\n setMounted(true);\n }, []);\n\n React.useEffect(() => {\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n table.toggleAllRowsSelected(false);\n }\n }\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [table]);\n\n const container =\n containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n const visible =\n visibleProp ?? table.getFilteredSelectedRowModel().rows.length > 0;\n\n return ReactDOM.createPortal(\n <AnimatePresence>\n {visible && (\n <motion.div\n role=\"toolbar\"\n aria-orientation=\"horizontal\"\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 20 }}\n transition={{ duration: 0.2, ease: \"easeInOut\" }}\n className={cn(\n \"fixed inset-x-0 bottom-6 z-50 mx-auto flex w-fit flex-wrap items-center justify-center gap-2 rounded-md border bg-background p-2 text-foreground shadow-sm\",\n className,\n )}\n {...props}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>,\n container,\n );\n}\n\ninterface DataTableActionBarActionProps\n extends React.ComponentProps<typeof Button> {\n tooltip?: string;\n isPending?: boolean;\n}\n\nfunction DataTableActionBarAction({\n size = \"sm\",\n tooltip,\n isPending,\n disabled,\n className,\n children,\n ...props\n}: DataTableActionBarActionProps) {\n const trigger = (\n <Button\n variant=\"secondary\"\n size={size}\n className={cn(\n \"gap-1.5 border border-secondary bg-secondary/50 hover:bg-secondary/70 [&>svg]:size-3.5\",\n size === \"icon\" ? \"size-7\" : \"h-7\",\n className,\n )}\n disabled={disabled || isPending}\n {...props}\n >\n {isPending ? <Loader className=\"animate-spin\" /> : children}\n </Button>\n );\n\n if (!tooltip) return trigger;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{trigger}</TooltipTrigger>\n <TooltipContent\n sideOffset={6}\n className=\"border bg-accent font-semibold text-foreground dark:bg-zinc-900 [&>span]:hidden\"\n >\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n );\n}\n\ninterface DataTableActionBarSelectionProps<TData> {\n table: Table<TData>;\n}\n\nfunction DataTableActionBarSelection<TData>({\n table,\n}: DataTableActionBarSelectionProps<TData>) {\n const onClearSelection = React.useCallback(() => {\n table.toggleAllRowsSelected(false);\n }, [table]);\n\n return (\n <div className=\"flex h-7 items-center rounded-md border pr-1 pl-2.5\">\n <span className=\"whitespace-nowrap text-xs\">\n {table.getFilteredSelectedRowModel().rows.length} selected\n </span>\n <Separator\n orientation=\"vertical\"\n className=\"mr-1 ml-2 data-[orientation=vertical]:h-4\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-5\"\n onClick={onClearSelection}\n >\n <X className=\"size-3.5\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent\n sideOffset={10}\n className=\"flex items-center gap-2 border bg-accent px-2 py-1 font-semibold text-foreground dark:bg-zinc-900 [&>span]:hidden\"\n >\n <p>Clear selection</p>\n <kbd className=\"select-none rounded border bg-background px-1.5 py-px font-mono font-normal text-[0.7rem] text-foreground shadow-xs\">\n <abbr title=\"Escape\" className=\"no-underline\">\n Esc\n </abbr>\n </kbd>\n </TooltipContent>\n </Tooltip>\n </div>\n );\n}\n\nexport {\n DataTableActionBar,\n DataTableActionBarAction,\n DataTableActionBarSelection,\n};\n",
"type": "registry:component",
"target": "src/components/data-table/data-table-action-bar.tsx"
}
]
}
25 changes: 15 additions & 10 deletions public/r/data-table-filter-list.json

Large diffs are not rendered by default.

19 changes: 11 additions & 8 deletions public/r/data-table-filter-menu.json

Large diffs are not rendered by default.

Loading