@simpleapps-com/augur-web 2.4.0 → 2026.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXPORTS.md +18 -189
- package/README.md +18 -364
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.d.ts +4 -5
- package/dist/accordion.d.ts.map +1 -0
- package/dist/add-to-cart-button.cjs.map +1 -1
- package/dist/add-to-cart-button.d.ts +5 -8
- package/dist/add-to-cart-button.d.ts.map +1 -0
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.d.ts +5 -7
- package/dist/breadcrumb.d.ts.map +1 -0
- package/dist/breadcrumbs.cjs.map +1 -1
- package/dist/breadcrumbs.d.ts +4 -4
- package/dist/breadcrumbs.d.ts.map +1 -0
- package/dist/button.cjs.map +1 -1
- package/dist/button.d.ts +7 -9
- package/dist/button.d.ts.map +1 -0
- package/dist/card.cjs.map +1 -1
- package/dist/card.d.ts +3 -4
- package/dist/card.d.ts.map +1 -0
- package/dist/checkbox.cjs.map +1 -1
- package/dist/checkbox.d.ts +3 -4
- package/dist/checkbox.d.ts.map +1 -0
- package/dist/chunk-32XB3REY.cjs.map +1 -1
- package/dist/chunk-5VMEEKZ5.cjs.map +1 -1
- package/dist/chunk-5ZITWMV4.cjs.map +1 -1
- package/dist/chunk-76RSVRGB.cjs.map +1 -1
- package/dist/chunk-7EXXNELX.cjs.map +1 -1
- package/dist/chunk-BXMTQGKV.cjs.map +1 -1
- package/dist/{chunk-DCXYO3RB.js → chunk-C6K7FZNX.js} +7 -3
- package/dist/chunk-C6K7FZNX.js.map +1 -0
- package/dist/{chunk-AE4GLYJE.cjs → chunk-DMWSWL4B.cjs} +7 -3
- package/dist/chunk-DMWSWL4B.cjs.map +1 -0
- package/dist/chunk-GSR6SMQ2.cjs.map +1 -1
- package/dist/chunk-IO77MGHW.js +220 -0
- package/dist/chunk-IO77MGHW.js.map +1 -0
- package/dist/chunk-JXW4XE2P.cjs.map +1 -1
- package/dist/{chunk-OJ5G4BLS.js → chunk-KVHOMD4T.js} +15 -18
- package/dist/chunk-KVHOMD4T.js.map +1 -0
- package/dist/chunk-MAENILZP.cjs.map +1 -1
- package/dist/chunk-NEY26NNF.cjs.map +1 -1
- package/dist/chunk-QKWXJM4Q.cjs +220 -0
- package/dist/chunk-QKWXJM4Q.cjs.map +1 -0
- package/dist/chunk-T52J3SHP.cjs.map +1 -1
- package/dist/{chunk-I5NVZORX.cjs → chunk-TFP5RICB.cjs} +15 -18
- package/dist/chunk-TFP5RICB.cjs.map +1 -0
- package/dist/chunk-UFL6PVLI.cjs.map +1 -1
- package/dist/chunk-VL6L4GDA.cjs.map +1 -1
- package/dist/chunk-WJUDOEVB.cjs.map +1 -1
- package/dist/chunk-XGKBDPGD.cjs.map +1 -1
- package/dist/chunk-Z57QBVUC.cjs.map +1 -1
- package/dist/command.cjs +1 -0
- package/dist/command.cjs.map +1 -1
- package/dist/command.d.ts +13 -15
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +1 -0
- package/dist/command.js.map +1 -1
- package/dist/confirm-dialog.cjs.map +1 -1
- package/dist/confirm-dialog.d.ts +4 -6
- package/dist/confirm-dialog.d.ts.map +1 -0
- package/dist/data-table.cjs +35 -23
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.d.ts +9 -11
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +34 -22
- package/dist/data-table.js.map +1 -1
- package/dist/detail-panel.cjs.map +1 -1
- package/dist/detail-panel.d.ts +6 -8
- package/dist/detail-panel.d.ts.map +1 -0
- package/dist/dialog.cjs.map +1 -1
- package/dist/dialog.d.ts +6 -8
- package/dist/dialog.d.ts.map +1 -0
- package/dist/dropdown-menu.cjs.map +1 -1
- package/dist/dropdown-menu.d.ts +5 -7
- package/dist/dropdown-menu.d.ts.map +1 -0
- package/dist/financing-widget.cjs +1 -3
- package/dist/financing-widget.cjs.map +1 -1
- package/dist/financing-widget.d.ts +5 -6
- package/dist/financing-widget.d.ts.map +1 -0
- package/dist/financing-widget.js +1 -3
- package/dist/financing-widget.js.map +1 -1
- package/dist/form-field.cjs.map +1 -1
- package/dist/form-field.d.ts +4 -5
- package/dist/form-field.d.ts.map +1 -0
- package/dist/form-input.cjs.map +1 -1
- package/dist/form-input.d.ts +4 -5
- package/dist/form-input.d.ts.map +1 -0
- package/dist/form-select.cjs.map +1 -1
- package/dist/form-select.d.ts +4 -5
- package/dist/form-select.d.ts.map +1 -0
- package/dist/form-textarea.cjs.map +1 -1
- package/dist/form-textarea.d.ts +4 -5
- package/dist/form-textarea.d.ts.map +1 -0
- package/dist/gtm.cjs +3 -2
- package/dist/gtm.cjs.map +1 -1
- package/dist/gtm.d.ts +12 -15
- package/dist/gtm.d.ts.map +1 -0
- package/dist/gtm.js +2 -1
- package/dist/input.cjs.map +1 -1
- package/dist/input.d.ts +4 -5
- package/dist/input.d.ts.map +1 -0
- package/dist/label.cjs.map +1 -1
- package/dist/label.d.ts +5 -7
- package/dist/label.d.ts.map +1 -0
- package/dist/list-view.cjs.map +1 -1
- package/dist/list-view.d.ts +5 -7
- package/dist/list-view.d.ts.map +1 -0
- package/dist/mdx-components.cjs +5 -2
- package/dist/mdx-components.cjs.map +1 -1
- package/dist/mdx-components.d.ts +11 -6
- package/dist/mdx-components.d.ts.map +1 -0
- package/dist/mdx-components.js +5 -2
- package/dist/mdx-components.js.map +1 -1
- package/dist/navigation-menu.cjs.map +1 -1
- package/dist/navigation-menu.d.ts +5 -7
- package/dist/navigation-menu.d.ts.map +1 -0
- package/dist/pagination.cjs +3 -2
- package/dist/pagination.cjs.map +1 -1
- package/dist/pagination.d.ts +10 -14
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +2 -1
- package/dist/payment-modal.cjs +20 -19
- package/dist/payment-modal.cjs.map +1 -1
- package/dist/payment-modal.d.ts +5 -7
- package/dist/payment-modal.d.ts.map +1 -0
- package/dist/payment-modal.js +19 -18
- package/dist/payment-modal.js.map +1 -1
- package/dist/popover.cjs.map +1 -1
- package/dist/popover.d.ts +4 -5
- package/dist/popover.d.ts.map +1 -0
- package/dist/price-format.cjs.map +1 -1
- package/dist/price-format.d.ts +4 -5
- package/dist/price-format.d.ts.map +1 -0
- package/dist/price.cjs +4 -1
- package/dist/price.cjs.map +1 -1
- package/dist/price.d.ts +8 -22
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +4 -1
- package/dist/price.js.map +1 -1
- package/dist/provider.cjs +4 -2
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.ts +7 -10
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +3 -1
- package/dist/provider.js.map +1 -1
- package/dist/quantity-input.cjs +27 -40
- package/dist/quantity-input.cjs.map +1 -1
- package/dist/quantity-input.d.ts +4 -5
- package/dist/quantity-input.d.ts.map +1 -0
- package/dist/quantity-input.js +27 -40
- package/dist/quantity-input.js.map +1 -1
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.d.ts +3 -4
- package/dist/radio-group.d.ts.map +1 -0
- package/dist/resource-tabs.cjs +1 -0
- package/dist/resource-tabs.cjs.map +1 -1
- package/dist/resource-tabs.d.ts +6 -8
- package/dist/resource-tabs.d.ts.map +1 -0
- package/dist/resource-tabs.js +1 -0
- package/dist/resource-tabs.js.map +1 -1
- package/dist/rules.d.ts +210 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/select.cjs.map +1 -1
- package/dist/select.d.ts +4 -5
- package/dist/select.d.ts.map +1 -0
- package/dist/separator.cjs.map +1 -1
- package/dist/separator.d.ts +3 -4
- package/dist/separator.d.ts.map +1 -0
- package/dist/session-replay.cjs +4 -2
- package/dist/session-replay.cjs.map +1 -1
- package/dist/session-replay.d.ts +4 -5
- package/dist/session-replay.d.ts.map +1 -0
- package/dist/session-replay.js +4 -2
- package/dist/session-replay.js.map +1 -1
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.d.ts +2 -4
- package/dist/skeleton.d.ts.map +1 -0
- package/dist/spinner.cjs.map +1 -1
- package/dist/spinner.d.ts +2 -4
- package/dist/spinner.d.ts.map +1 -0
- package/dist/stock-label.cjs +14 -12
- package/dist/stock-label.cjs.map +1 -1
- package/dist/stock-label.d.ts +7 -7
- package/dist/stock-label.d.ts.map +1 -0
- package/dist/stock-label.js +14 -12
- package/dist/stock-label.js.map +1 -1
- package/dist/table.cjs.map +1 -1
- package/dist/table.d.ts +3 -4
- package/dist/table.d.ts.map +1 -0
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.d.ts +4 -5
- package/dist/tabs.d.ts.map +1 -0
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.d.ts +4 -5
- package/dist/textarea.d.ts.map +1 -0
- package/llms.txt +23 -38
- package/package.json +26 -17
- package/dist/accordion.d.cts +0 -9
- package/dist/add-to-cart-button.d.cts +0 -14
- package/dist/breadcrumb.d.cts +0 -22
- package/dist/breadcrumbs.d.cts +0 -31
- package/dist/button.d.cts +0 -27
- package/dist/card.d.cts +0 -10
- package/dist/checkbox.d.cts +0 -6
- package/dist/chunk-AE4GLYJE.cjs.map +0 -1
- package/dist/chunk-DCXYO3RB.js.map +0 -1
- package/dist/chunk-I5NVZORX.cjs.map +0 -1
- package/dist/chunk-OJ5G4BLS.js.map +0 -1
- package/dist/command.d.cts +0 -87
- package/dist/confirm-dialog.d.cts +0 -35
- package/dist/data-table.d.cts +0 -55
- package/dist/detail-panel.d.cts +0 -59
- package/dist/dialog.d.cts +0 -22
- package/dist/dropdown-menu.d.cts +0 -30
- package/dist/financing-widget.d.cts +0 -45
- package/dist/form-field.d.cts +0 -14
- package/dist/form-input.d.cts +0 -19
- package/dist/form-select.d.cts +0 -34
- package/dist/form-textarea.d.cts +0 -12
- package/dist/gtm.d.cts +0 -69
- package/dist/input.d.cts +0 -6
- package/dist/label.d.cts +0 -8
- package/dist/list-view.d.cts +0 -18
- package/dist/mdx-components.d.cts +0 -20
- package/dist/navigation-menu.d.cts +0 -15
- package/dist/pagination.d.cts +0 -50
- package/dist/payment-modal.d.cts +0 -30
- package/dist/popover.d.cts +0 -9
- package/dist/price-format.d.cts +0 -21
- package/dist/price.d.cts +0 -90
- package/dist/provider.d.cts +0 -47
- package/dist/quantity-input.d.cts +0 -33
- package/dist/radio-group.d.cts +0 -7
- package/dist/resource-tabs.d.cts +0 -33
- package/dist/select.d.cts +0 -15
- package/dist/separator.d.cts +0 -6
- package/dist/session-replay.d.cts +0 -44
- package/dist/skeleton.d.cts +0 -5
- package/dist/spinner.d.cts +0 -10
- package/dist/stock-label.d.cts +0 -47
- package/dist/table.d.cts +0 -12
- package/dist/tabs.d.cts +0 -9
- package/dist/textarea.d.cts +0 -6
package/dist/command.js
CHANGED
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/command.tsx"],"sourcesContent":["/** Styled cmdk wrapper. Includes CommandDialog for modal search. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { type DialogProps } from \"@radix-ui/react-dialog\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { LuSearch } from \"react-icons/lu\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Dialog, DialogContent, DialogTitle } from \"./dialog\";\n\nconst Command = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className,\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\ntype CommandDialogProps = DialogProps & {\n /** Accessible name for the dialog, read by screen readers (visually hidden). */\n title?: string;\n};\n\nconst CommandDialog = ({ children, title = \"Command menu\", ...props }: CommandDialogProps) => {\n return (\n <Dialog {...props}>\n <DialogContent className=\"overflow-hidden p-0\" aria-describedby={undefined}>\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst CommandInput = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n <div className=\"flex items-center border-b px-3\" cmdk-input-wrapper=\"\">\n <LuSearch className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n ref={ref}\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n </div>\n));\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n {...props}\n />\n));\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Empty>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className={cn(\"py-6 text-center text-sm\", className)}\n {...props}\n />\n));\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Group>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className,\n )}\n {...props}\n />\n));\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\",\n className,\n )}\n {...props}\n />\n));\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nconst CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n};\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n"],"mappings":";;;;;;;;;AAGA,YAAY,WAAW;
|
|
1
|
+
{"version":3,"sources":["../src/command.tsx"],"sourcesContent":["/** Styled cmdk wrapper. Includes CommandDialog for modal search. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { type DialogProps } from \"@radix-ui/react-dialog\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { LuSearch } from \"react-icons/lu\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Dialog, DialogContent, DialogTitle } from \"./dialog\";\n\nconst Command = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive\n ref={ref}\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className,\n )}\n {...props}\n />\n));\nCommand.displayName = CommandPrimitive.displayName;\n\ntype CommandDialogProps = DialogProps & {\n /** Accessible name for the dialog, read by screen readers (visually hidden). */\n title?: string;\n};\n\nconst CommandDialog = ({ children, title = \"Command menu\", ...props }: CommandDialogProps) => {\n return (\n <Dialog {...props}>\n <DialogContent className=\"overflow-hidden p-0\" aria-describedby={undefined}>\n <DialogTitle className=\"sr-only\">{title}</DialogTitle>\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n};\n\nconst CommandInput = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Input>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n <div className=\"flex items-center border-b px-3\" cmdk-input-wrapper=\"\">\n <LuSearch className=\"mr-2 h-4 w-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n ref={ref}\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n </div>\n));\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.List\n ref={ref}\n className={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n {...props}\n />\n));\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Empty>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Empty\n ref={ref}\n className={cn(\"py-6 text-center text-sm\", className)}\n {...props}\n />\n));\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Group>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Group\n ref={ref}\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className,\n )}\n {...props}\n />\n));\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Separator\n ref={ref}\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ComponentRef<typeof CommandPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n <CommandPrimitive.Item\n ref={ref}\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\",\n className,\n )}\n {...props}\n />\n));\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nconst CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\"text-muted-foreground ml-auto text-xs tracking-widest\", className)}\n {...props}\n />\n );\n};\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n"],"mappings":";;;;;;;;;AAGA,YAAY,WAAW;AACvB,OAAiC;AACjC,SAAS,WAAW,wBAAwB;AAC5C,SAAS,gBAAgB;AACzB,SAAS,UAAU;AAOjB,cAmBI,YAnBJ;AAJF,IAAM,UAAgB,iBAGpB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,QAAQ,cAAc,iBAAiB;AAOvC,IAAM,gBAAgB,CAAC,EAAE,UAAU,QAAQ,gBAAgB,GAAG,MAAM,MAA0B;AAC5F,SACE,oBAAC,UAAQ,GAAG,OACV,+BAAC,iBAAc,WAAU,uBAAsB,oBAAkB,QAC/D;AAAA,wBAAC,eAAY,WAAU,WAAW,iBAAM;AAAA,IACxC,oBAAC,WAAQ,WAAU,+WAChB,UACH;AAAA,KACF,GACF;AAEJ;AAEA,IAAM,eAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,qBAAC,SAAI,WAAU,mCAAkC,sBAAmB,IAClE;AAAA,sBAAC,YAAS,WAAU,oCAAmC;AAAA,EACvD;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAAA,GACF,CACD;AACD,aAAa,cAAc,iBAAiB,MAAM;AAElD,IAAM,cAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,iBAAiB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,mDAAmD,SAAS;AAAA,IACzE,GAAG;AAAA;AACN,CACD;AACD,YAAY,cAAc,iBAAiB,KAAK;AAEhD,IAAM,eAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,iBAAiB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,4BAA4B,SAAS;AAAA,IAClD,GAAG;AAAA;AACN,CACD;AACD,aAAa,cAAc,iBAAiB,MAAM;AAElD,IAAM,eAAqB,iBAGzB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,iBAAiB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,aAAa,cAAc,iBAAiB,MAAM;AAElD,IAAM,mBAAyB,iBAG7B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,iBAAiB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,wBAAwB,SAAS;AAAA,IAC9C,GAAG;AAAA;AACN,CACD;AACD,iBAAiB,cAAc,iBAAiB,UAAU;AAE1D,IAAM,cAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B;AAAA,EAAC,iBAAiB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,YAAY,cAAc,iBAAiB,KAAK;AAEhD,IAAM,kBAAkB,CAAC,EAAE,WAAW,GAAG,MAAM,MAA6C;AAC1F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,yDAAyD,SAAS;AAAA,MAC/E,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,gBAAgB,cAAc;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/confirm-dialog.cjs","../src/confirm-dialog.tsx"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACyCQ,+CAAA;AAhBR,SAAS,aAAA,CAAc;AAAA,EACrB,IAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA,EAAe,SAAA;AAAA,EACf,YAAA,EAAc,QAAA;AAAA,EACd,QAAA,EAAU,SAAA;AAAA,EACV,SAAA;AAAA,EACA,QAAA,EAAU;AACZ,CAAA,EAAuB;AACrB,EAAA,uBACE,6BAAA,wBAAC,EAAA,EAAO,IAAA,EAAY,YAAA,EAGlB,QAAA,kBAAA,8BAAA,+BAAC,EAAA,EAAe,GAAI,YAAA,EAAc,CAAC,EAAA,EAAI,EAAE,kBAAA,EAAoB,KAAA,EAAU,CAAA,EACrE,QAAA,EAAA;AAAA,oBAAA,8BAAA,8BAAC,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,6BAAA,6BAAC,EAAA,EAAa,QAAA,EAAA,MAAA,CAAM,CAAA;AAAA,MACnB,YAAA,mBAAe,6BAAA,mCAAC,EAAA,EAAmB,QAAA,EAAA,YAAA,CAAY;AAAA,IAAA,EAAA,CAClD,CAAA;AAAA,oBACA,8BAAA,8BAAC,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,6BAAA,wBAAC,EAAA,EAAO,OAAA,EAAQ,SAAA,EAAU,OAAA,EAAS,CAAA,EAAA,GAAM,YAAA,CAAa,KAAK,CAAA,EAAG,QAAA,EAAU,OAAA,EACrE,QAAA,EAAA,YAAA,CACH,CAAA;AAAA,sBACA,8BAAA,wBAAC,EAAA,EAAO,OAAA,EAAkB,OAAA,EAAS,SAAA,EAAW,QAAA,EAAU,OAAA,EACrD,QAAA,EAAA;AAAA,QAAA,QAAA,mBAAW,6BAAA,yBAAC,EAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,SAAA,EAAU,OAAA,CAAO,CAAA;AAAA,QAC/C;AAAA,MAAA,EAAA,CACH;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF,CAAA;AAEJ;AACA,aAAA,CAAc,YAAA,EAAc,eAAA;AD9B5B;AACE;AACF,sCAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/confirm-dialog.cjs","sourcesContent":[null,"/** Reusable confirmation dialog composing Dialog + Button. */\n\"use client\";\n\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n} from \"./dialog\";\nimport { Button } from \"./button\";\nimport { Spinner } from \"./spinner\";\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n variant?: \"default\" | \"destructive\";\n onConfirm: () => void;\n loading?: boolean;\n}\n\n/**\n * Pre-composed confirmation dialog for delete/action confirmations.\n *\n * @example\n * ```tsx\n * <ConfirmDialog\n * open={showDelete}\n * onOpenChange={setShowDelete}\n * title=\"Delete brand?\"\n * description=\"This action cannot be undone.\"\n * variant=\"destructive\"\n * onConfirm={() => deleteBrand.mutate(uid)}\n * loading={deleteBrand.isPending}\n * />\n * ```\n */\nfunction ConfirmDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n variant = \"default\",\n onConfirm,\n loading = false,\n}: ConfirmDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n {/* Without a description, opt out of aria-describedby explicitly so screen\n readers aren't pointed at a missing element (Radix requires one or the other). */}\n <DialogContent {...(description ? {} : { \"aria-describedby\": undefined })}>\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n {description && <DialogDescription>{description}</DialogDescription>}\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button variant={variant} onClick={onConfirm} disabled={loading}>\n {loading && <Spinner size=\"sm\" className=\"mr-2\" />}\n {confirmLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\nConfirmDialog.displayName = \"ConfirmDialog\";\n\nexport { ConfirmDialog };\n"]}
|
package/dist/confirm-dialog.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface ConfirmDialogProps {
|
|
1
|
+
export interface ConfirmDialogProps {
|
|
4
2
|
open: boolean;
|
|
5
3
|
onOpenChange: (open: boolean) => void;
|
|
6
4
|
title: string;
|
|
@@ -27,9 +25,9 @@ interface ConfirmDialogProps {
|
|
|
27
25
|
* />
|
|
28
26
|
* ```
|
|
29
27
|
*/
|
|
30
|
-
declare function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel, cancelLabel, variant, onConfirm, loading, }: ConfirmDialogProps):
|
|
28
|
+
declare function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel, cancelLabel, variant, onConfirm, loading, }: ConfirmDialogProps): import("react").JSX.Element;
|
|
31
29
|
declare namespace ConfirmDialog {
|
|
32
30
|
var displayName: string;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
export { ConfirmDialog };
|
|
33
|
+
//# sourceMappingURL=confirm-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../src/confirm-dialog.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;IACpC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,iBAAS,aAAa,CAAC,EACrB,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAwB,EACxB,WAAsB,EACtB,OAAmB,EACnB,SAAS,EACT,OAAe,GAChB,EAAE,kBAAkB,+BAsBpB;kBAhCQ,aAAa;;;AAmCtB,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/data-table.cjs
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
var _chunkNEY26NNFcjs = require('./chunk-NEY26NNF.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkTFP5RICBcjs = require('./chunk-TFP5RICB.cjs');
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
var _chunkQKWXJM4Qcjs = require('./chunk-QKWXJM4Q.cjs');
|
|
14
20
|
|
|
15
21
|
|
|
16
22
|
|
|
@@ -52,10 +58,8 @@ var _reacttable = require('@tanstack/react-table');
|
|
|
52
58
|
var _web = require('@simpleapps-com/augur-utils/web');
|
|
53
59
|
var _lu = require('react-icons/lu');
|
|
54
60
|
var _jsxruntime = require('react/jsx-runtime');
|
|
55
|
-
var ALIGN_CLASS = { left: "text-left", center: "text-center", right: "text-right" };
|
|
56
61
|
function getAlignCn(meta) {
|
|
57
|
-
|
|
58
|
-
return ALIGN_CLASS[align];
|
|
62
|
+
return _chunkQKWXJM4Qcjs.alignClass.call(void 0, _nullishCoalesce(_optionalChain([meta, 'optionalAccess', _ => _.align]), () => ( "left")));
|
|
59
63
|
}
|
|
60
64
|
function buildTanstackColumns(columns, selectable) {
|
|
61
65
|
const cols = [];
|
|
@@ -99,12 +103,7 @@ function buildTanstackColumns(columns, selectable) {
|
|
|
99
103
|
}
|
|
100
104
|
function exportToCsv(columns, data, filename) {
|
|
101
105
|
const headers = columns.map((c) => c.header);
|
|
102
|
-
const rows = data.map(
|
|
103
|
-
(row) => columns.map((col) => {
|
|
104
|
-
const str = String(_nullishCoalesce(row[col.key], () => ( "")));
|
|
105
|
-
return str.includes(",") || str.includes('"') || str.includes("\n") ? `"${str.replace(/"/g, '""')}"` : str;
|
|
106
|
-
})
|
|
107
|
-
);
|
|
106
|
+
const rows = data.map((row) => columns.map((col) => _chunkQKWXJM4Qcjs.csvField.call(void 0, String(_nullishCoalesce(row[col.key], () => ( ""))))));
|
|
108
107
|
const csv = [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
|
|
109
108
|
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
|
|
110
109
|
const url = URL.createObjectURL(blob);
|
|
@@ -143,7 +142,7 @@ function ColumnToggle({ table }) {
|
|
|
143
142
|
function HeaderCell({ header }) {
|
|
144
143
|
const canSort = header.column.getCanSort();
|
|
145
144
|
const sorted = header.column.getIsSorted();
|
|
146
|
-
const ariaSort = canSort
|
|
145
|
+
const ariaSort = _chunkQKWXJM4Qcjs.ariaSortOf.call(void 0, canSort, sorted === false ? "unsorted" : sorted);
|
|
147
146
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEY26NNFcjs.TableHead, { className: getAlignCn(header.column.columnDef.meta), "aria-sort": ariaSort, children: canSort ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
148
147
|
"button",
|
|
149
148
|
{
|
|
@@ -234,10 +233,11 @@ function TableBodyContent({
|
|
|
234
233
|
rows,
|
|
235
234
|
onRowClick
|
|
236
235
|
}) {
|
|
237
|
-
|
|
236
|
+
const view = _chunkQKWXJM4Qcjs.bodyViewOf.call(void 0, loading, rows.length);
|
|
237
|
+
if (view === "loading") {
|
|
238
238
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEY26NNFcjs.TableRow, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEY26NNFcjs.TableCell, { colSpan, className: "h-24 text-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk5VMEEKZ5cjs.Spinner, { size: "lg", className: "mx-auto" }) }) });
|
|
239
239
|
}
|
|
240
|
-
if (
|
|
240
|
+
if (view === "empty") {
|
|
241
241
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEY26NNFcjs.TableRow, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkNEY26NNFcjs.TableCell, { colSpan, className: "h-24 text-center", children: emptyMessage }) });
|
|
242
242
|
}
|
|
243
243
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: rows.map((row) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataRow, { row, onRowClick }, row.id)) });
|
|
@@ -270,7 +270,7 @@ function PaginationFooter({ pagination }) {
|
|
|
270
270
|
}
|
|
271
271
|
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", {}),
|
|
272
272
|
showPages && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
273
|
-
|
|
273
|
+
_chunkTFP5RICBcjs.ListPagination,
|
|
274
274
|
{
|
|
275
275
|
page: pagination.page,
|
|
276
276
|
totalPages: pagination.totalPages,
|
|
@@ -280,6 +280,16 @@ function PaginationFooter({ pagination }) {
|
|
|
280
280
|
)
|
|
281
281
|
] });
|
|
282
282
|
}
|
|
283
|
+
function changeHandler(onChange, current, setInternal) {
|
|
284
|
+
if (!onChange) return setInternal;
|
|
285
|
+
return (updater) => onChange(_reacttable.functionalUpdate.call(void 0, updater, current));
|
|
286
|
+
}
|
|
287
|
+
function clientRowModels(isManualSorting, isManualFiltering) {
|
|
288
|
+
return {
|
|
289
|
+
getSortedRowModel: isManualSorting ? void 0 : _reacttable.getSortedRowModel.call(void 0, ),
|
|
290
|
+
getFilteredRowModel: isManualFiltering ? void 0 : _reacttable.getFilteredRowModel.call(void 0, )
|
|
291
|
+
};
|
|
292
|
+
}
|
|
283
293
|
function useDataTable(opts) {
|
|
284
294
|
const isManualFiltering = opts.externalGlobalFilter !== void 0;
|
|
285
295
|
const isManualSorting = opts.externalSorting !== void 0;
|
|
@@ -290,13 +300,13 @@ function useDataTable(opts) {
|
|
|
290
300
|
const sorting = _nullishCoalesce(opts.externalSorting, () => ( internalSorting));
|
|
291
301
|
const globalFilter = _nullishCoalesce(opts.externalGlobalFilter, () => ( internalGlobalFilter));
|
|
292
302
|
const rowSelectionState = _nullishCoalesce(opts.externalRowSelection, () => ( internalRowSelection));
|
|
293
|
-
const handleSortingChange = opts.onSortingChange
|
|
294
|
-
opts.onSortingChange(_reacttable.functionalUpdate.call(void 0, updater, sorting));
|
|
295
|
-
} : setInternalSorting;
|
|
303
|
+
const handleSortingChange = changeHandler(opts.onSortingChange, sorting, setInternalSorting);
|
|
296
304
|
const handleGlobalFilterChange = _nullishCoalesce(opts.onGlobalFilterChange, () => ( setInternalGlobalFilter));
|
|
297
|
-
const handleRowSelectionChange =
|
|
298
|
-
opts.onRowSelectionChange
|
|
299
|
-
|
|
305
|
+
const handleRowSelectionChange = changeHandler(
|
|
306
|
+
opts.onRowSelectionChange,
|
|
307
|
+
rowSelectionState,
|
|
308
|
+
setInternalRowSelection
|
|
309
|
+
);
|
|
300
310
|
const tanstackColumns = React.useMemo(
|
|
301
311
|
() => buildTanstackColumns(opts.columns, opts.selectable),
|
|
302
312
|
[opts.columns, opts.selectable]
|
|
@@ -315,8 +325,7 @@ function useDataTable(opts) {
|
|
|
315
325
|
onRowSelectionChange: handleRowSelectionChange,
|
|
316
326
|
onColumnVisibilityChange: setColumnVisibility,
|
|
317
327
|
getCoreRowModel: _reacttable.getCoreRowModel.call(void 0, ),
|
|
318
|
-
|
|
319
|
-
getFilteredRowModel: isManualFiltering ? void 0 : _reacttable.getFilteredRowModel.call(void 0, ),
|
|
328
|
+
...clientRowModels(isManualSorting, isManualFiltering),
|
|
320
329
|
manualSorting: isManualSorting,
|
|
321
330
|
manualFiltering: isManualFiltering,
|
|
322
331
|
manualPagination: opts.pagination !== void 0,
|
|
@@ -326,6 +335,9 @@ function useDataTable(opts) {
|
|
|
326
335
|
const selectedRows = opts.selectable ? table.getSelectedRowModel().rows.map((r) => r.original) : [];
|
|
327
336
|
return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };
|
|
328
337
|
}
|
|
338
|
+
function toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows) {
|
|
339
|
+
return Boolean(searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0);
|
|
340
|
+
}
|
|
329
341
|
function DataTable({
|
|
330
342
|
columns,
|
|
331
343
|
data,
|
|
@@ -363,7 +375,7 @@ function DataTable({
|
|
|
363
375
|
externalRowSelection: rowSelection,
|
|
364
376
|
onRowSelectionChange
|
|
365
377
|
});
|
|
366
|
-
const showToolbar = searchable
|
|
378
|
+
const showToolbar = toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows);
|
|
367
379
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _web.cn.call(void 0, "space-y-4", className), children: [
|
|
368
380
|
showToolbar && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
369
381
|
Toolbar,
|
package/dist/data-table.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/data-table.cjs","../src/data-table.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/data-table.cjs","sourcesContent":[null,"/** Feature-complete admin data table built on TanStack Table. */\n\"use client\";\n\nimport * as React from \"react\";\nimport {\n flexRender,\n functionalUpdate,\n getCoreRowModel,\n getSortedRowModel,\n getFilteredRowModel,\n useReactTable,\n type ColumnDef as TanstackColumnDef,\n type SortingState,\n type RowSelectionState,\n type Updater,\n type VisibilityState,\n type Table as TanstackTable,\n type Header,\n type Row,\n type Cell,\n} from \"@tanstack/react-table\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from \"react-icons/lu\";\nimport { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"./table\";\nimport { Input } from \"./input\";\nimport { Spinner } from \"./spinner\";\nimport { Checkbox } from \"./checkbox\";\nimport { Button } from \"./button\";\nimport { ListPagination } from \"./pagination\";\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"./select\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ColumnDef<T> {\n key: keyof T & string;\n header: string;\n sortable?: boolean;\n render?: (row: T) => React.ReactNode;\n align?: \"left\" | \"center\" | \"right\";\n hideable?: boolean;\n}\n\nexport interface DataTablePagination {\n page: number;\n totalPages: number;\n getHref: (page: number) => string;\n onPageChange?: (page: number) => void;\n /** Current page size. Required when pageSizeOptions is set. */\n pageSize?: number;\n /** Available page size options. Renders a dropdown when provided. */\n pageSizeOptions?: number[];\n /** Called when the user selects a different page size. */\n onPageSizeChange?: (size: number) => void;\n}\n\nexport interface DataTableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n searchable?: boolean;\n searchPlaceholder?: string;\n onRowClick?: (row: T) => void;\n loading?: boolean;\n emptyMessage?: string;\n toolbar?: React.ReactNode;\n className?: string;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n globalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n sortingState?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n selectable?: boolean;\n rowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n bulkActions?: (selectedRows: T[]) => React.ReactNode;\n columnToggle?: boolean;\n exportCsv?: boolean;\n csvFilename?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst ALIGN_CLASS = { left: \"text-left\", center: \"text-center\", right: \"text-right\" } as const;\n\nfunction getAlignCn(meta: unknown): string {\n const align = (meta as { align?: string } | undefined)?.align ?? \"left\";\n return ALIGN_CLASS[align as keyof typeof ALIGN_CLASS];\n}\n\nfunction buildTanstackColumns<T>(\n columns: ColumnDef<T>[],\n selectable: boolean,\n): TanstackColumnDef<T, unknown>[] {\n const cols: TanstackColumnDef<T, unknown>[] = [];\n if (selectable) {\n cols.push({\n id: \"_select\",\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n onClick={(e) => e.stopPropagation()}\n />\n ),\n enableSorting: false,\n enableHiding: false,\n meta: { align: \"center\" },\n });\n }\n for (const col of columns) {\n cols.push({\n id: col.key,\n accessorKey: col.key,\n header: col.header,\n enableSorting: col.sortable ?? false,\n enableHiding: col.hideable !== false,\n cell: col.render\n ? (info) => col.render!(info.row.original)\n : (info) => String(info.getValue() ?? \"\"),\n meta: { align: col.align },\n });\n }\n return cols;\n}\n\nfunction exportToCsv<T>(columns: ColumnDef<T>[], data: T[], filename: string) {\n const headers = columns.map((c) => c.header);\n const rows = data.map((row) =>\n columns.map((col) => {\n const str = String(row[col.key] ?? \"\");\n return str.includes(\",\") || str.includes('\"') || str.includes(\"\\n\")\n ? `\"${str.replace(/\"/g, '\"\"')}\"`\n : str;\n }),\n );\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction SortIndicator({ direction }: { direction: false | \"asc\" | \"desc\" }) {\n if (direction === \"asc\") return <LuArrowUp className=\"h-4 w-4\" />;\n if (direction === \"desc\") return <LuArrowDown className=\"h-4 w-4\" />;\n return <LuArrowUpDown className=\"text-muted-foreground/50 h-4 w-4\" />;\n}\n\nfunction ColumnToggle<T>({ table }: { table: TanstackTable<T> }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <LuSettings2 className=\"mr-2 h-4 w-4\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {table\n .getAllColumns()\n .filter((col) => col.getCanHide())\n .map((col) => (\n <DropdownMenuCheckboxItem\n key={col.id}\n checked={col.getIsVisible()}\n onCheckedChange={(v) => col.toggleVisibility(!!v)}\n >\n {col.columnDef.header as string}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction HeaderCell<T>({ header }: { header: Header<T, unknown> }) {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n // aria-sort announces sort state to screen readers; only meaningful on\n // sortable columns. Sorting is triggered by a real <button> so it is\n // keyboard-focusable and Enter/Space-activatable (a click handler on the\n // <th> alone is mouse-only).\n const ariaSort = canSort\n ? sorted === \"asc\"\n ? \"ascending\"\n : sorted === \"desc\"\n ? \"descending\"\n : \"none\"\n : undefined;\n\n return (\n <TableHead className={getAlignCn(header.column.columnDef.meta)} aria-sort={ariaSort}>\n {canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n className=\"inline-flex cursor-pointer select-none items-center gap-1\"\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n <SortIndicator direction={sorted} />\n </button>\n ) : (\n <span className=\"inline-flex items-center gap-1\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n </span>\n )}\n </TableHead>\n );\n}\n\nfunction DataCell<T>({ cell }: { cell: Cell<T, unknown> }) {\n return (\n <TableCell className={getAlignCn(cell.column.columnDef.meta)}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n}\n\nfunction DataRow<T>({ row, onRowClick }: { row: Row<T>; onRowClick?: (r: T) => void }) {\n return (\n <TableRow\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n className={cn(onRowClick && \"cursor-pointer\")}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <DataCell key={cell.id} cell={cell} />\n ))}\n </TableRow>\n );\n}\n\nfunction ExportButton<T>({\n columns,\n data,\n csvFilename,\n}: {\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n}) {\n return (\n <Button variant=\"outline\" size=\"sm\" onClick={() => exportToCsv(columns, data, csvFilename)}>\n <LuDownload className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n );\n}\n\nfunction BulkActionsBar<T>({\n selectedRows,\n bulkActions,\n}: {\n selectedRows: T[];\n bulkActions: (rows: T[]) => React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">{selectedRows.length} selected</span>\n {bulkActions(selectedRows)}\n </div>\n );\n}\n\nfunction Toolbar<T>({\n searchable,\n searchPlaceholder,\n globalFilter,\n onGlobalFilterChange,\n selectedRows,\n bulkActions,\n toolbar,\n exportCsv,\n columns,\n data,\n csvFilename,\n columnToggle,\n table,\n}: {\n searchable: boolean;\n searchPlaceholder: string;\n globalFilter: string;\n onGlobalFilterChange: (value: string) => void;\n selectedRows: T[];\n bulkActions?: (rows: T[]) => React.ReactNode;\n toolbar?: React.ReactNode;\n exportCsv: boolean;\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n columnToggle: boolean;\n table: TanstackTable<T>;\n}) {\n const hasSelection = selectedRows.length > 0;\n return (\n <div className=\"flex items-center gap-4\">\n {searchable && (\n <Input\n placeholder={searchPlaceholder}\n value={globalFilter}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n className=\"max-w-sm\"\n />\n )}\n {hasSelection && bulkActions && (\n <BulkActionsBar selectedRows={selectedRows} bulkActions={bulkActions} />\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {toolbar}\n {exportCsv && <ExportButton columns={columns} data={data} csvFilename={csvFilename} />}\n {columnToggle && <ColumnToggle table={table} />}\n </div>\n </div>\n );\n}\n\nfunction TableBodyContent<T>({\n loading,\n colSpan,\n emptyMessage,\n rows,\n onRowClick,\n}: {\n loading: boolean;\n colSpan: number;\n emptyMessage: string;\n rows: Row<T>[];\n onRowClick?: (r: T) => void;\n}) {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n <Spinner size=\"lg\" className=\"mx-auto\" />\n </TableCell>\n </TableRow>\n );\n }\n if (rows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n {emptyMessage}\n </TableCell>\n </TableRow>\n );\n }\n return (\n <>\n {rows.map((row) => (\n <DataRow key={row.id} row={row} onRowClick={onRowClick} />\n ))}\n </>\n );\n}\n\nfunction PageSizeSelector({\n pageSize,\n options,\n onChange,\n}: {\n pageSize: number;\n options: number[];\n onChange: (size: number) => void;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Rows per page</span>\n <Select value={String(pageSize)} onValueChange={(v) => onChange(Number(v))}>\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((size) => (\n <SelectItem key={size} value={String(size)}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\nfunction PaginationFooter({ pagination }: { pagination?: DataTablePagination }) {\n if (!pagination) return null;\n const showPageSize =\n pagination.pageSizeOptions && pagination.pageSize !== undefined && pagination.onPageSizeChange;\n const showPages = pagination.totalPages > 1;\n if (!showPageSize && !showPages) return null;\n return (\n <div className=\"flex items-center justify-between\">\n {showPageSize ? (\n <PageSizeSelector\n pageSize={pagination.pageSize!}\n options={pagination.pageSizeOptions!}\n onChange={pagination.onPageSizeChange!}\n />\n ) : (\n <div />\n )}\n {showPages && (\n <ListPagination\n page={pagination.page}\n totalPages={pagination.totalPages}\n getHref={pagination.getHref}\n onPageChange={pagination.onPageChange}\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook: encapsulates all state management and TanStack Table configuration\n// ---------------------------------------------------------------------------\n\ninterface UseDataTableOptions<T> {\n columns: ColumnDef<T>[];\n data: T[];\n selectable: boolean;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n externalGlobalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n externalSorting?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n externalRowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n}\n\nfunction useDataTable<T>(opts: UseDataTableOptions<T>) {\n const isManualFiltering = opts.externalGlobalFilter !== undefined;\n const isManualSorting = opts.externalSorting !== undefined;\n\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([]);\n const [internalGlobalFilter, setInternalGlobalFilter] = React.useState(\"\");\n const [internalRowSelection, setInternalRowSelection] = React.useState<RowSelectionState>({});\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});\n\n const sorting = opts.externalSorting ?? internalSorting;\n const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;\n const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;\n\n // TanStack hands these an Updater<T> = T | ((old: T) => T). Resolve via\n // functionalUpdate so a plain value (e.g. from resetRowSelection()/setSorting(v))\n // is not called as a function — the old cast-and-call threw on plain values.\n const handleSortingChange = opts.onSortingChange\n ? (updater: Updater<SortingState>) => {\n opts.onSortingChange!(functionalUpdate(updater, sorting));\n }\n : setInternalSorting;\n\n const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;\n\n const handleRowSelectionChange = opts.onRowSelectionChange\n ? (updater: Updater<RowSelectionState>) => {\n opts.onRowSelectionChange!(functionalUpdate(updater, rowSelectionState));\n }\n : setInternalRowSelection;\n\n const tanstackColumns = React.useMemo(\n () => buildTanstackColumns(opts.columns, opts.selectable),\n [opts.columns, opts.selectable],\n );\n\n const table = useReactTable({\n data: opts.data,\n columns: tanstackColumns,\n state: {\n sorting,\n globalFilter: isManualFiltering ? undefined : globalFilter,\n rowSelection: rowSelectionState,\n columnVisibility,\n },\n onSortingChange: handleSortingChange,\n onGlobalFilterChange: isManualFiltering ? undefined : setInternalGlobalFilter,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: isManualSorting ? undefined : getSortedRowModel(),\n getFilteredRowModel: isManualFiltering ? undefined : getFilteredRowModel(),\n manualSorting: isManualSorting,\n manualFiltering: isManualFiltering,\n manualPagination: opts.pagination !== undefined,\n enableRowSelection: opts.selectable,\n getRowId: opts.getRowId ? (row) => opts.getRowId!(row) : undefined,\n });\n\n const selectedRows = opts.selectable\n ? table.getSelectedRowModel().rows.map((r) => r.original)\n : [];\n\n return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nfunction DataTable<T>({\n columns,\n data,\n searchable = false,\n searchPlaceholder = \"Search...\",\n onRowClick,\n loading = false,\n emptyMessage = \"No results.\",\n toolbar,\n className,\n getRowId,\n pagination,\n globalFilter: externalGlobalFilter,\n onGlobalFilterChange,\n sortingState,\n onSortingChange,\n selectable = false,\n rowSelection,\n onRowSelectionChange,\n bulkActions,\n columnToggle = false,\n exportCsv = false,\n csvFilename = \"export\",\n}: DataTableProps<T>) {\n const { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows } =\n useDataTable({\n columns,\n data,\n selectable,\n getRowId,\n pagination,\n externalGlobalFilter,\n onGlobalFilterChange,\n externalSorting: sortingState,\n onSortingChange,\n externalRowSelection: rowSelection,\n onRowSelectionChange,\n });\n\n const showToolbar = searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0;\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {showToolbar && (\n <Toolbar\n searchable={searchable}\n searchPlaceholder={searchPlaceholder}\n globalFilter={globalFilter}\n onGlobalFilterChange={handleGlobalFilterChange}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n toolbar={toolbar}\n exportCsv={exportCsv}\n columns={columns}\n data={data}\n csvFilename={csvFilename}\n columnToggle={columnToggle}\n table={table}\n />\n )}\n <Table>\n <TableHeader className=\"bg-background sticky top-0 z-10\">\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((h) => (\n <HeaderCell key={h.id} header={h} />\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n <TableBodyContent\n loading={loading}\n colSpan={tanstackColumns.length}\n emptyMessage={emptyMessage}\n rows={table.getRowModel().rows}\n onRowClick={onRowClick}\n />\n </TableBody>\n </Table>\n <PaginationFooter pagination={pagination} />\n </div>\n );\n}\nDataTable.displayName = \"DataTable\";\n\nexport { DataTable };\nexport type { SortingState, RowSelectionState, VisibilityState };\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/data-table.cjs","../src/data-table.tsx"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/data-table.cjs","sourcesContent":[null,"/** Feature-complete admin data table built on TanStack Table. */\n\"use client\";\n\nimport * as React from \"react\";\nimport {\n flexRender,\n functionalUpdate,\n getCoreRowModel,\n getSortedRowModel,\n getFilteredRowModel,\n useReactTable,\n type ColumnDef as TanstackColumnDef,\n type SortingState,\n type RowSelectionState,\n type Updater,\n type VisibilityState,\n type Table as TanstackTable,\n type Header,\n type Row,\n type Cell,\n} from \"@tanstack/react-table\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from \"react-icons/lu\";\nimport { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"./table\";\nimport { Input } from \"./input\";\nimport { Spinner } from \"./spinner\";\nimport { alignClass, ariaSortOf, bodyViewOf, csvField } from \"./rules\";\nimport { Checkbox } from \"./checkbox\";\nimport { Button } from \"./button\";\nimport { ListPagination } from \"./pagination\";\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"./select\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ColumnDef<T> {\n key: keyof T & string;\n header: string;\n sortable?: boolean;\n render?: (row: T) => React.ReactNode;\n align?: \"left\" | \"center\" | \"right\";\n hideable?: boolean;\n}\n\nexport interface DataTablePagination {\n page: number;\n totalPages: number;\n getHref: (page: number) => string;\n onPageChange?: (page: number) => void;\n /** Current page size. Required when pageSizeOptions is set. */\n pageSize?: number;\n /** Available page size options. Renders a dropdown when provided. */\n pageSizeOptions?: number[];\n /** Called when the user selects a different page size. */\n onPageSizeChange?: (size: number) => void;\n}\n\nexport interface DataTableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n searchable?: boolean;\n searchPlaceholder?: string;\n onRowClick?: (row: T) => void;\n loading?: boolean;\n emptyMessage?: string;\n toolbar?: React.ReactNode;\n className?: string;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n globalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n sortingState?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n selectable?: boolean;\n rowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n bulkActions?: (selectedRows: T[]) => React.ReactNode;\n columnToggle?: boolean;\n exportCsv?: boolean;\n csvFilename?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction getAlignCn(meta: unknown): string {\n return alignClass((meta as { align?: string } | undefined)?.align ?? \"left\");\n}\n\nfunction buildTanstackColumns<T>(\n columns: ColumnDef<T>[],\n selectable: boolean,\n): TanstackColumnDef<T, unknown>[] {\n const cols: TanstackColumnDef<T, unknown>[] = [];\n if (selectable) {\n cols.push({\n id: \"_select\",\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n onClick={(e) => e.stopPropagation()}\n />\n ),\n enableSorting: false,\n enableHiding: false,\n meta: { align: \"center\" },\n });\n }\n for (const col of columns) {\n cols.push({\n id: col.key,\n accessorKey: col.key,\n header: col.header,\n enableSorting: col.sortable ?? false,\n enableHiding: col.hideable !== false,\n cell: col.render\n ? (info) => col.render!(info.row.original)\n : (info) => String(info.getValue() ?? \"\"),\n meta: { align: col.align },\n });\n }\n return cols;\n}\n\nfunction exportToCsv<T>(columns: ColumnDef<T>[], data: T[], filename: string) {\n const headers = columns.map((c) => c.header);\n const rows = data.map((row) => columns.map((col) => csvField(String(row[col.key] ?? \"\"))));\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction SortIndicator({ direction }: { direction: false | \"asc\" | \"desc\" }) {\n if (direction === \"asc\") return <LuArrowUp className=\"h-4 w-4\" />;\n if (direction === \"desc\") return <LuArrowDown className=\"h-4 w-4\" />;\n return <LuArrowUpDown className=\"text-muted-foreground/50 h-4 w-4\" />;\n}\n\nfunction ColumnToggle<T>({ table }: { table: TanstackTable<T> }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <LuSettings2 className=\"mr-2 h-4 w-4\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {table\n .getAllColumns()\n .filter((col) => col.getCanHide())\n .map((col) => (\n <DropdownMenuCheckboxItem\n key={col.id}\n checked={col.getIsVisible()}\n onCheckedChange={(v) => col.toggleVisibility(!!v)}\n >\n {col.columnDef.header as string}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction HeaderCell<T>({ header }: { header: Header<T, unknown> }) {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n // aria-sort announces sort state to screen readers; only meaningful on\n // sortable columns. Sorting is triggered by a real <button> so it is\n // keyboard-focusable and Enter/Space-activatable (a click handler on the\n // <th> alone is mouse-only).\n // ariaSortOf gives only \"ascending\", \"descending\", \"none\" or undefined.\n const ariaSort = ariaSortOf(canSort, sorted === false ? \"unsorted\" : sorted) as\n React.AriaAttributes[\"aria-sort\"] | undefined;\n\n return (\n <TableHead className={getAlignCn(header.column.columnDef.meta)} aria-sort={ariaSort}>\n {canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n className=\"inline-flex cursor-pointer select-none items-center gap-1\"\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n <SortIndicator direction={sorted} />\n </button>\n ) : (\n <span className=\"inline-flex items-center gap-1\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n </span>\n )}\n </TableHead>\n );\n}\n\nfunction DataCell<T>({ cell }: { cell: Cell<T, unknown> }) {\n return (\n <TableCell className={getAlignCn(cell.column.columnDef.meta)}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n}\n\nfunction DataRow<T>({ row, onRowClick }: { row: Row<T>; onRowClick?: (r: T) => void }) {\n return (\n <TableRow\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n className={cn(onRowClick && \"cursor-pointer\")}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <DataCell key={cell.id} cell={cell} />\n ))}\n </TableRow>\n );\n}\n\nfunction ExportButton<T>({\n columns,\n data,\n csvFilename,\n}: {\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n}) {\n return (\n <Button variant=\"outline\" size=\"sm\" onClick={() => exportToCsv(columns, data, csvFilename)}>\n <LuDownload className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n );\n}\n\nfunction BulkActionsBar<T>({\n selectedRows,\n bulkActions,\n}: {\n selectedRows: T[];\n bulkActions: (rows: T[]) => React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">{selectedRows.length} selected</span>\n {bulkActions(selectedRows)}\n </div>\n );\n}\n\nfunction Toolbar<T>({\n searchable,\n searchPlaceholder,\n globalFilter,\n onGlobalFilterChange,\n selectedRows,\n bulkActions,\n toolbar,\n exportCsv,\n columns,\n data,\n csvFilename,\n columnToggle,\n table,\n}: {\n searchable: boolean;\n searchPlaceholder: string;\n globalFilter: string;\n onGlobalFilterChange: (value: string) => void;\n selectedRows: T[];\n bulkActions?: (rows: T[]) => React.ReactNode;\n toolbar?: React.ReactNode;\n exportCsv: boolean;\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n columnToggle: boolean;\n table: TanstackTable<T>;\n}) {\n const hasSelection = selectedRows.length > 0;\n return (\n <div className=\"flex items-center gap-4\">\n {searchable && (\n <Input\n placeholder={searchPlaceholder}\n value={globalFilter}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n className=\"max-w-sm\"\n />\n )}\n {hasSelection && bulkActions && (\n <BulkActionsBar selectedRows={selectedRows} bulkActions={bulkActions} />\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {toolbar}\n {exportCsv && <ExportButton columns={columns} data={data} csvFilename={csvFilename} />}\n {columnToggle && <ColumnToggle table={table} />}\n </div>\n </div>\n );\n}\n\nfunction TableBodyContent<T>({\n loading,\n colSpan,\n emptyMessage,\n rows,\n onRowClick,\n}: {\n loading: boolean;\n colSpan: number;\n emptyMessage: string;\n rows: Row<T>[];\n onRowClick?: (r: T) => void;\n}) {\n const view = bodyViewOf(loading, rows.length);\n if (view === \"loading\") {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n <Spinner size=\"lg\" className=\"mx-auto\" />\n </TableCell>\n </TableRow>\n );\n }\n if (view === \"empty\") {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n {emptyMessage}\n </TableCell>\n </TableRow>\n );\n }\n return (\n <>\n {rows.map((row) => (\n <DataRow key={row.id} row={row} onRowClick={onRowClick} />\n ))}\n </>\n );\n}\n\nfunction PageSizeSelector({\n pageSize,\n options,\n onChange,\n}: {\n pageSize: number;\n options: number[];\n onChange: (size: number) => void;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Rows per page</span>\n <Select value={String(pageSize)} onValueChange={(v) => onChange(Number(v))}>\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((size) => (\n <SelectItem key={size} value={String(size)}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\nfunction PaginationFooter({ pagination }: { pagination?: DataTablePagination }) {\n if (!pagination) return null;\n const showPageSize =\n pagination.pageSizeOptions && pagination.pageSize !== undefined && pagination.onPageSizeChange;\n const showPages = pagination.totalPages > 1;\n if (!showPageSize && !showPages) return null;\n return (\n <div className=\"flex items-center justify-between\">\n {showPageSize ? (\n <PageSizeSelector\n pageSize={pagination.pageSize!}\n options={pagination.pageSizeOptions!}\n onChange={pagination.onPageSizeChange!}\n />\n ) : (\n <div />\n )}\n {showPages && (\n <ListPagination\n page={pagination.page}\n totalPages={pagination.totalPages}\n getHref={pagination.getHref}\n onPageChange={pagination.onPageChange}\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook: encapsulates all state management and TanStack Table configuration\n// ---------------------------------------------------------------------------\n\ninterface UseDataTableOptions<T> {\n columns: ColumnDef<T>[];\n data: T[];\n selectable: boolean;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n externalGlobalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n externalSorting?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n externalRowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n}\n\n/**\n * The change handler TanStack calls: the caller's (with TanStack's Updater<S> =\n * S | ((old: S) => S) resolved against the current value via functionalUpdate, so a plain\n * value from resetRowSelection()/setSorting(v) is not called as a function), or the internal\n * state setter when the state is uncontrolled.\n */\nfunction changeHandler<S>(\n onChange: ((state: S) => void) | undefined,\n current: S,\n setInternal: React.Dispatch<React.SetStateAction<S>>,\n): (updater: Updater<S>) => void {\n if (!onChange) return setInternal;\n return (updater) => onChange(functionalUpdate(updater, current));\n}\n\n/** TanStack's client-side models, left out when the caller sorts or filters on the server. */\nfunction clientRowModels(isManualSorting: boolean, isManualFiltering: boolean) {\n return {\n getSortedRowModel: isManualSorting ? undefined : getSortedRowModel(),\n getFilteredRowModel: isManualFiltering ? undefined : getFilteredRowModel(),\n };\n}\n\nfunction useDataTable<T>(opts: UseDataTableOptions<T>) {\n const isManualFiltering = opts.externalGlobalFilter !== undefined;\n const isManualSorting = opts.externalSorting !== undefined;\n\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([]);\n const [internalGlobalFilter, setInternalGlobalFilter] = React.useState(\"\");\n const [internalRowSelection, setInternalRowSelection] = React.useState<RowSelectionState>({});\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});\n\n const sorting = opts.externalSorting ?? internalSorting;\n const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;\n const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;\n\n const handleSortingChange = changeHandler(opts.onSortingChange, sorting, setInternalSorting);\n\n const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;\n\n const handleRowSelectionChange = changeHandler(\n opts.onRowSelectionChange,\n rowSelectionState,\n setInternalRowSelection,\n );\n\n const tanstackColumns = React.useMemo(\n () => buildTanstackColumns(opts.columns, opts.selectable),\n [opts.columns, opts.selectable],\n );\n\n const table = useReactTable({\n data: opts.data,\n columns: tanstackColumns,\n state: {\n sorting,\n globalFilter: isManualFiltering ? undefined : globalFilter,\n rowSelection: rowSelectionState,\n columnVisibility,\n },\n onSortingChange: handleSortingChange,\n onGlobalFilterChange: isManualFiltering ? undefined : setInternalGlobalFilter,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n ...clientRowModels(isManualSorting, isManualFiltering),\n manualSorting: isManualSorting,\n manualFiltering: isManualFiltering,\n manualPagination: opts.pagination !== undefined,\n enableRowSelection: opts.selectable,\n getRowId: opts.getRowId ? (row) => opts.getRowId!(row) : undefined,\n });\n\n const selectedRows = opts.selectable\n ? table.getSelectedRowModel().rows.map((r) => r.original)\n : [];\n\n return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\n/** The toolbar shows when it has something to show: search, custom content, column toggle, CSV export, or a selection. */\nfunction toolbarVisible(\n searchable: boolean,\n toolbar: React.ReactNode,\n columnToggle: boolean,\n exportCsv: boolean,\n selectedRows: readonly unknown[],\n): boolean {\n return Boolean(searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0);\n}\n\nfunction DataTable<T>({\n columns,\n data,\n searchable = false,\n searchPlaceholder = \"Search...\",\n onRowClick,\n loading = false,\n emptyMessage = \"No results.\",\n toolbar,\n className,\n getRowId,\n pagination,\n globalFilter: externalGlobalFilter,\n onGlobalFilterChange,\n sortingState,\n onSortingChange,\n selectable = false,\n rowSelection,\n onRowSelectionChange,\n bulkActions,\n columnToggle = false,\n exportCsv = false,\n csvFilename = \"export\",\n}: DataTableProps<T>) {\n const { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows } =\n useDataTable({\n columns,\n data,\n selectable,\n getRowId,\n pagination,\n externalGlobalFilter,\n onGlobalFilterChange,\n externalSorting: sortingState,\n onSortingChange,\n externalRowSelection: rowSelection,\n onRowSelectionChange,\n });\n\n const showToolbar = toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {showToolbar && (\n <Toolbar\n searchable={searchable}\n searchPlaceholder={searchPlaceholder}\n globalFilter={globalFilter}\n onGlobalFilterChange={handleGlobalFilterChange}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n toolbar={toolbar}\n exportCsv={exportCsv}\n columns={columns}\n data={data}\n csvFilename={csvFilename}\n columnToggle={columnToggle}\n table={table}\n />\n )}\n <Table>\n <TableHeader className=\"bg-background sticky top-0 z-10\">\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((h) => (\n <HeaderCell key={h.id} header={h} />\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n <TableBodyContent\n loading={loading}\n colSpan={tanstackColumns.length}\n emptyMessage={emptyMessage}\n rows={table.getRowModel().rows}\n onRowClick={onRowClick}\n />\n </TableBody>\n </Table>\n <PaginationFooter pagination={pagination} />\n </div>\n );\n}\nDataTable.displayName = \"DataTable\";\n\nexport { DataTable };\nexport type { SortingState, RowSelectionState, VisibilityState };\n"]}
|
package/dist/data-table.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export { RowSelectionState, SortingState, VisibilityState } from '@tanstack/react-table';
|
|
5
|
-
|
|
6
|
-
interface ColumnDef<T> {
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type SortingState, type RowSelectionState, type VisibilityState } from "@tanstack/react-table";
|
|
3
|
+
export interface ColumnDef<T> {
|
|
7
4
|
key: keyof T & string;
|
|
8
5
|
header: string;
|
|
9
6
|
sortable?: boolean;
|
|
@@ -11,7 +8,7 @@ interface ColumnDef<T> {
|
|
|
11
8
|
align?: "left" | "center" | "right";
|
|
12
9
|
hideable?: boolean;
|
|
13
10
|
}
|
|
14
|
-
interface DataTablePagination {
|
|
11
|
+
export interface DataTablePagination {
|
|
15
12
|
page: number;
|
|
16
13
|
totalPages: number;
|
|
17
14
|
getHref: (page: number) => string;
|
|
@@ -23,7 +20,7 @@ interface DataTablePagination {
|
|
|
23
20
|
/** Called when the user selects a different page size. */
|
|
24
21
|
onPageSizeChange?: (size: number) => void;
|
|
25
22
|
}
|
|
26
|
-
interface DataTableProps<T> {
|
|
23
|
+
export interface DataTableProps<T> {
|
|
27
24
|
columns: ColumnDef<T>[];
|
|
28
25
|
data: T[];
|
|
29
26
|
searchable?: boolean;
|
|
@@ -47,9 +44,10 @@ interface DataTableProps<T> {
|
|
|
47
44
|
exportCsv?: boolean;
|
|
48
45
|
csvFilename?: string;
|
|
49
46
|
}
|
|
50
|
-
declare function DataTable<T>({ columns, data, searchable, searchPlaceholder, onRowClick, loading, emptyMessage, toolbar, className, getRowId, pagination, globalFilter: externalGlobalFilter, onGlobalFilterChange, sortingState, onSortingChange, selectable, rowSelection, onRowSelectionChange, bulkActions, columnToggle, exportCsv, csvFilename, }: DataTableProps<T>):
|
|
47
|
+
declare function DataTable<T>({ columns, data, searchable, searchPlaceholder, onRowClick, loading, emptyMessage, toolbar, className, getRowId, pagination, globalFilter: externalGlobalFilter, onGlobalFilterChange, sortingState, onSortingChange, selectable, rowSelection, onRowSelectionChange, bulkActions, columnToggle, exportCsv, csvFilename, }: DataTableProps<T>): React.JSX.Element;
|
|
51
48
|
declare namespace DataTable {
|
|
52
49
|
var displayName: string;
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
export
|
|
51
|
+
export { DataTable };
|
|
52
|
+
export type { SortingState, RowSelectionState, VisibilityState };
|
|
53
|
+
//# sourceMappingURL=data-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../src/data-table.tsx"],"names":[],"mappings":"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"}
|
package/dist/data-table.js
CHANGED
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
} from "./chunk-XIKSI7NY.js";
|
|
11
11
|
import {
|
|
12
12
|
ListPagination
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KVHOMD4T.js";
|
|
14
|
+
import {
|
|
15
|
+
alignClass,
|
|
16
|
+
ariaSortOf,
|
|
17
|
+
bodyViewOf,
|
|
18
|
+
csvField
|
|
19
|
+
} from "./chunk-IO77MGHW.js";
|
|
14
20
|
import {
|
|
15
21
|
Select,
|
|
16
22
|
SelectContent,
|
|
@@ -52,10 +58,8 @@ import {
|
|
|
52
58
|
import { cn } from "@simpleapps-com/augur-utils/web";
|
|
53
59
|
import { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from "react-icons/lu";
|
|
54
60
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
55
|
-
var ALIGN_CLASS = { left: "text-left", center: "text-center", right: "text-right" };
|
|
56
61
|
function getAlignCn(meta) {
|
|
57
|
-
|
|
58
|
-
return ALIGN_CLASS[align];
|
|
62
|
+
return alignClass(meta?.align ?? "left");
|
|
59
63
|
}
|
|
60
64
|
function buildTanstackColumns(columns, selectable) {
|
|
61
65
|
const cols = [];
|
|
@@ -99,12 +103,7 @@ function buildTanstackColumns(columns, selectable) {
|
|
|
99
103
|
}
|
|
100
104
|
function exportToCsv(columns, data, filename) {
|
|
101
105
|
const headers = columns.map((c) => c.header);
|
|
102
|
-
const rows = data.map(
|
|
103
|
-
(row) => columns.map((col) => {
|
|
104
|
-
const str = String(row[col.key] ?? "");
|
|
105
|
-
return str.includes(",") || str.includes('"') || str.includes("\n") ? `"${str.replace(/"/g, '""')}"` : str;
|
|
106
|
-
})
|
|
107
|
-
);
|
|
106
|
+
const rows = data.map((row) => columns.map((col) => csvField(String(row[col.key] ?? ""))));
|
|
108
107
|
const csv = [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
|
|
109
108
|
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
|
|
110
109
|
const url = URL.createObjectURL(blob);
|
|
@@ -143,7 +142,7 @@ function ColumnToggle({ table }) {
|
|
|
143
142
|
function HeaderCell({ header }) {
|
|
144
143
|
const canSort = header.column.getCanSort();
|
|
145
144
|
const sorted = header.column.getIsSorted();
|
|
146
|
-
const ariaSort = canSort
|
|
145
|
+
const ariaSort = ariaSortOf(canSort, sorted === false ? "unsorted" : sorted);
|
|
147
146
|
return /* @__PURE__ */ jsx(TableHead, { className: getAlignCn(header.column.columnDef.meta), "aria-sort": ariaSort, children: canSort ? /* @__PURE__ */ jsxs(
|
|
148
147
|
"button",
|
|
149
148
|
{
|
|
@@ -234,10 +233,11 @@ function TableBodyContent({
|
|
|
234
233
|
rows,
|
|
235
234
|
onRowClick
|
|
236
235
|
}) {
|
|
237
|
-
|
|
236
|
+
const view = bodyViewOf(loading, rows.length);
|
|
237
|
+
if (view === "loading") {
|
|
238
238
|
return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "h-24 text-center", children: /* @__PURE__ */ jsx(Spinner, { size: "lg", className: "mx-auto" }) }) });
|
|
239
239
|
}
|
|
240
|
-
if (
|
|
240
|
+
if (view === "empty") {
|
|
241
241
|
return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "h-24 text-center", children: emptyMessage }) });
|
|
242
242
|
}
|
|
243
243
|
return /* @__PURE__ */ jsx(Fragment, { children: rows.map((row) => /* @__PURE__ */ jsx(DataRow, { row, onRowClick }, row.id)) });
|
|
@@ -280,6 +280,16 @@ function PaginationFooter({ pagination }) {
|
|
|
280
280
|
)
|
|
281
281
|
] });
|
|
282
282
|
}
|
|
283
|
+
function changeHandler(onChange, current, setInternal) {
|
|
284
|
+
if (!onChange) return setInternal;
|
|
285
|
+
return (updater) => onChange(functionalUpdate(updater, current));
|
|
286
|
+
}
|
|
287
|
+
function clientRowModels(isManualSorting, isManualFiltering) {
|
|
288
|
+
return {
|
|
289
|
+
getSortedRowModel: isManualSorting ? void 0 : getSortedRowModel(),
|
|
290
|
+
getFilteredRowModel: isManualFiltering ? void 0 : getFilteredRowModel()
|
|
291
|
+
};
|
|
292
|
+
}
|
|
283
293
|
function useDataTable(opts) {
|
|
284
294
|
const isManualFiltering = opts.externalGlobalFilter !== void 0;
|
|
285
295
|
const isManualSorting = opts.externalSorting !== void 0;
|
|
@@ -290,13 +300,13 @@ function useDataTable(opts) {
|
|
|
290
300
|
const sorting = opts.externalSorting ?? internalSorting;
|
|
291
301
|
const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;
|
|
292
302
|
const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;
|
|
293
|
-
const handleSortingChange = opts.onSortingChange
|
|
294
|
-
opts.onSortingChange(functionalUpdate(updater, sorting));
|
|
295
|
-
} : setInternalSorting;
|
|
303
|
+
const handleSortingChange = changeHandler(opts.onSortingChange, sorting, setInternalSorting);
|
|
296
304
|
const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;
|
|
297
|
-
const handleRowSelectionChange =
|
|
298
|
-
opts.onRowSelectionChange
|
|
299
|
-
|
|
305
|
+
const handleRowSelectionChange = changeHandler(
|
|
306
|
+
opts.onRowSelectionChange,
|
|
307
|
+
rowSelectionState,
|
|
308
|
+
setInternalRowSelection
|
|
309
|
+
);
|
|
300
310
|
const tanstackColumns = React.useMemo(
|
|
301
311
|
() => buildTanstackColumns(opts.columns, opts.selectable),
|
|
302
312
|
[opts.columns, opts.selectable]
|
|
@@ -315,8 +325,7 @@ function useDataTable(opts) {
|
|
|
315
325
|
onRowSelectionChange: handleRowSelectionChange,
|
|
316
326
|
onColumnVisibilityChange: setColumnVisibility,
|
|
317
327
|
getCoreRowModel: getCoreRowModel(),
|
|
318
|
-
|
|
319
|
-
getFilteredRowModel: isManualFiltering ? void 0 : getFilteredRowModel(),
|
|
328
|
+
...clientRowModels(isManualSorting, isManualFiltering),
|
|
320
329
|
manualSorting: isManualSorting,
|
|
321
330
|
manualFiltering: isManualFiltering,
|
|
322
331
|
manualPagination: opts.pagination !== void 0,
|
|
@@ -326,6 +335,9 @@ function useDataTable(opts) {
|
|
|
326
335
|
const selectedRows = opts.selectable ? table.getSelectedRowModel().rows.map((r) => r.original) : [];
|
|
327
336
|
return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };
|
|
328
337
|
}
|
|
338
|
+
function toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows) {
|
|
339
|
+
return Boolean(searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0);
|
|
340
|
+
}
|
|
329
341
|
function DataTable({
|
|
330
342
|
columns,
|
|
331
343
|
data,
|
|
@@ -363,7 +375,7 @@ function DataTable({
|
|
|
363
375
|
externalRowSelection: rowSelection,
|
|
364
376
|
onRowSelectionChange
|
|
365
377
|
});
|
|
366
|
-
const showToolbar = searchable
|
|
378
|
+
const showToolbar = toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows);
|
|
367
379
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
368
380
|
showToolbar && /* @__PURE__ */ jsx(
|
|
369
381
|
Toolbar,
|