@kala-ui/react 0.0.1-beta.7 → 0.0.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/dist/components/accordion/accordion-skeleton.js +1 -1
- package/dist/components/accordion/accordion.js +2 -1
- package/dist/components/action-icon/action-icon.d.ts +12 -0
- package/dist/components/action-icon/action-icon.js +35 -0
- package/dist/components/action-icon/action-icon.stories.d.ts +9 -0
- package/dist/components/action-icon/action-icon.stories.js +42 -0
- package/dist/components/action-icon/index.d.ts +1 -0
- package/dist/components/action-icon/index.js +1 -0
- package/dist/components/alert/alert-skeleton.js +4 -3
- package/dist/components/alert/alert.d.ts +2 -2
- package/dist/components/alert/alert.js +8 -6
- package/dist/components/alert/alert.stories.js +13 -9
- package/dist/components/alert/index.d.ts +1 -1
- package/dist/components/alert-dialog/alert-dialog.js +8 -5
- package/dist/components/app-shell/app-shell.d.ts +58 -0
- package/dist/components/app-shell/app-shell.js +111 -0
- package/dist/components/app-shell/app-shell.stories.d.ts +8 -0
- package/dist/components/app-shell/app-shell.stories.js +35 -0
- package/dist/components/app-shell/index.d.ts +1 -0
- package/dist/components/app-shell/index.js +1 -0
- package/dist/components/avatar/avatar.d.ts +2 -2
- package/dist/components/avatar/avatar.stories.js +1 -1
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/badge/badge.js +1 -1
- package/dist/components/badge/badge.stories.js +1 -1
- package/dist/components/banner/banner-skeleton.js +1 -1
- package/dist/components/banner/banner.d.ts +1 -1
- package/dist/components/banner/banner.stories.js +1 -1
- package/dist/components/box/box.d.ts +8 -0
- package/dist/components/box/box.js +10 -0
- package/dist/components/box/box.stories.d.ts +8 -0
- package/dist/components/box/box.stories.js +32 -0
- package/dist/components/box/index.d.ts +1 -0
- package/dist/components/box/index.js +1 -0
- package/dist/components/breadcrumbs/breadcrumbs-skeleton.js +1 -1
- package/dist/components/breadcrumbs/breadcrumbs.stories.js +1 -1
- package/dist/components/burger/burger.d.ts +8 -0
- package/dist/components/burger/burger.js +21 -0
- package/dist/components/burger/burger.stories.d.ts +8 -0
- package/dist/components/burger/burger.stories.js +31 -0
- package/dist/components/burger/index.d.ts +1 -0
- package/dist/components/burger/index.js +1 -0
- package/dist/components/button/button.d.ts +2 -2
- package/dist/components/button/button.stories.js +10 -7
- package/dist/components/button-group/button-group.stories.js +1 -1
- package/dist/components/calendar/calendar-skeleton.js +1 -1
- package/dist/components/calendar/calendar.d.ts +1 -1
- package/dist/components/calendar/calendar.js +1 -1
- package/dist/components/calendar/calendar.types.d.ts +3 -3
- package/dist/components/card/card-skeleton.js +2 -2
- package/dist/components/card/card.js +17 -14
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/center/center.d.ts +7 -0
- package/dist/components/center/center.js +10 -0
- package/dist/components/center/center.stories.d.ts +7 -0
- package/dist/components/center/center.stories.js +25 -0
- package/dist/components/center/index.d.ts +1 -0
- package/dist/components/center/index.js +1 -0
- package/dist/components/charts/area-chart.js +1 -1
- package/dist/components/charts/bar-chart.js +1 -1
- package/dist/components/charts/donut-chart.js +1 -1
- package/dist/components/charts/index.d.ts +2 -2
- package/dist/components/charts/index.js +2 -2
- package/dist/components/charts/line-chart.js +1 -1
- package/dist/components/charts/radial-bar-chart.js +1 -1
- package/dist/components/charts/theme-utils.d.ts +1 -1
- package/dist/components/charts/use-theme-aware-chart.d.ts +1 -1
- package/dist/components/charts/use-theme-aware-chart.js +2 -1
- package/dist/components/checkbox/checkbox.js +1 -1
- package/dist/components/checkbox/checkbox.stories.js +12 -8
- package/dist/components/close-button/close-button.d.ts +7 -0
- package/dist/components/close-button/close-button.js +9 -0
- package/dist/components/close-button/close-button.stories.d.ts +7 -0
- package/dist/components/close-button/close-button.stories.js +18 -0
- package/dist/components/close-button/index.d.ts +1 -0
- package/dist/components/close-button/index.js +1 -0
- package/dist/components/code/code.d.ts +8 -0
- package/dist/components/code/code.js +14 -0
- package/dist/components/code/code.stories.d.ts +8 -0
- package/dist/components/code/code.stories.js +31 -0
- package/dist/components/code/index.d.ts +1 -0
- package/dist/components/code/index.js +1 -0
- package/dist/components/collapse/collapse.d.ts +17 -0
- package/dist/components/collapse/collapse.js +34 -0
- package/dist/components/collapse/index.d.ts +1 -0
- package/dist/components/collapse/index.js +1 -0
- package/dist/components/color-input/color-input.d.ts +28 -0
- package/dist/components/color-input/color-input.js +35 -0
- package/dist/components/color-input/color-input.stories.d.ts +10 -0
- package/dist/components/color-input/color-input.stories.js +41 -0
- package/dist/components/color-input/index.d.ts +1 -0
- package/dist/components/color-input/index.js +1 -0
- package/dist/components/combobox/combobox-skeleton.js +1 -1
- package/dist/components/combobox/combobox.d.ts +1 -1
- package/dist/components/combobox/combobox.js +17 -8
- package/dist/components/combobox/combobox.stories.js +1 -1
- package/dist/components/command/command.d.ts +2 -2
- package/dist/components/command/command.stories.js +14 -19
- package/dist/components/container/container.d.ts +1 -1
- package/dist/components/container/index.d.ts +1 -1
- package/dist/components/container/index.js +1 -1
- package/dist/components/data-table/column-header-filter.js +11 -6
- package/dist/components/data-table/data-table-skeleton.js +5 -15
- package/dist/components/data-table/data-table.js +18 -15
- package/dist/components/data-table/data-table.stories.js +3 -5
- package/dist/components/date-picker/date-picker.d.ts +1 -1
- package/dist/components/date-picker/date-picker.js +3 -3
- package/dist/components/date-picker/date-picker.types.d.ts +1 -1
- package/dist/components/dialog/dialog-skeleton.js +1 -1
- package/dist/components/dialog/dialog.js +6 -4
- package/dist/components/dialog/dialog.stories.js +2 -2
- package/dist/components/dnd/dnd.d.ts +4 -5
- package/dist/components/dnd/dnd.js +5 -5
- package/dist/components/dnd/dnd.stories.js +48 -40
- package/dist/components/drawer/drawer.stories.js +2 -2
- package/dist/components/empty-state/empty-state-skeleton.js +2 -3
- package/dist/components/empty-state/empty-state.d.ts +1 -1
- package/dist/components/field/field-skeleton.js +1 -1
- package/dist/components/field/field.stories.js +1 -1
- package/dist/components/file-upload/file-upload-skeleton.js +1 -1
- package/dist/components/flex/flex.d.ts +7 -5
- package/dist/components/flex/flex.js +2 -2
- package/dist/components/flex/index.d.ts +1 -1
- package/dist/components/flex/index.js +1 -1
- package/dist/components/grid/grid.d.ts +24 -0
- package/dist/components/grid/grid.js +136 -0
- package/dist/components/grid/grid.stories.d.ts +8 -0
- package/dist/components/grid/grid.stories.js +31 -0
- package/dist/components/grid/index.d.ts +1 -0
- package/dist/components/grid/index.js +1 -0
- package/dist/components/group/group.d.ts +2 -2
- package/dist/components/group/group.js +1 -1
- package/dist/components/group/index.d.ts +1 -1
- package/dist/components/group/index.js +1 -1
- package/dist/components/header/header-skeleton.js +1 -1
- package/dist/components/header/header.d.ts +3 -3
- package/dist/components/header/header.js +17 -31
- package/dist/components/header/index.d.ts +1 -1
- package/dist/components/heading/heading.d.ts +4 -2
- package/dist/components/heading/heading.js +3 -7
- package/dist/components/heading/index.d.ts +1 -1
- package/dist/components/heading/index.js +1 -1
- package/dist/components/indicator/index.d.ts +1 -0
- package/dist/components/indicator/index.js +1 -0
- package/dist/components/indicator/indicator.d.ts +30 -0
- package/dist/components/indicator/indicator.js +89 -0
- package/dist/components/indicator/indicator.stories.d.ts +10 -0
- package/dist/components/indicator/indicator.stories.js +75 -0
- package/dist/components/input/input.js +1 -1
- package/dist/components/input/input.stories.js +1 -1
- package/dist/components/input-group/input-group.stories.js +1 -1
- package/dist/components/kbd/index.d.ts +1 -0
- package/dist/components/kbd/index.js +1 -0
- package/dist/components/kbd/kbd.d.ts +6 -0
- package/dist/components/kbd/kbd.js +13 -0
- package/dist/components/kbd/kbd.stories.d.ts +9 -0
- package/dist/components/kbd/kbd.stories.js +28 -0
- package/dist/components/label/label.stories.js +1 -1
- package/dist/components/list/list-skeleton.js +2 -2
- package/dist/components/list/list.js +1 -1
- package/dist/components/list/list.stories.js +1 -1
- package/dist/components/list/list.types.d.ts +2 -2
- package/dist/components/loading-overlay/index.d.ts +1 -0
- package/dist/components/loading-overlay/index.js +1 -0
- package/dist/components/loading-overlay/loading-overlay.d.ts +19 -0
- package/dist/components/loading-overlay/loading-overlay.js +19 -0
- package/dist/components/loading-overlay/loading-overlay.stories.d.ts +8 -0
- package/dist/components/loading-overlay/loading-overlay.stories.js +46 -0
- package/dist/components/metric-card/metric-card-skeleton.js +2 -2
- package/dist/components/metric-card/metric-card.js +1 -1
- package/dist/components/multi-select/multi-select-skeleton.js +1 -1
- package/dist/components/multi-select/multi-select.stories.js +1 -1
- package/dist/components/nav-link/index.d.ts +1 -0
- package/dist/components/nav-link/index.js +1 -0
- package/dist/components/nav-link/nav-link.d.ts +26 -0
- package/dist/components/nav-link/nav-link.js +26 -0
- package/dist/components/nav-link/nav-link.stories.d.ts +9 -0
- package/dist/components/nav-link/nav-link.stories.js +37 -0
- package/dist/components/navigation/navigation-skeleton.js +1 -1
- package/dist/components/number-input/index.d.ts +1 -0
- package/dist/components/number-input/index.js +1 -0
- package/dist/components/number-input/number-input.d.ts +40 -0
- package/dist/components/number-input/number-input.js +69 -0
- package/dist/components/number-input/number-input.stories.d.ts +11 -0
- package/dist/components/number-input/number-input.stories.js +54 -0
- package/dist/components/overlay/index.d.ts +1 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/overlay/overlay.d.ts +22 -0
- package/dist/components/overlay/overlay.js +45 -0
- package/dist/components/overlay/overlay.stories.d.ts +9 -0
- package/dist/components/overlay/overlay.stories.js +47 -0
- package/dist/components/page-transition/page-transition.stories.js +1 -1
- package/dist/components/pagination/index.d.ts +1 -1
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/pagination/pagination-skeleton.js +1 -1
- package/dist/components/pagination/pagination.d.ts +44 -28
- package/dist/components/pagination/pagination.js +53 -79
- package/dist/components/pagination/pagination.stories.d.ts +1 -0
- package/dist/components/pagination/pagination.stories.js +31 -5
- package/dist/components/paper/index.d.ts +1 -0
- package/dist/components/paper/index.js +1 -0
- package/dist/components/paper/paper.d.ts +12 -0
- package/dist/components/paper/paper.js +39 -0
- package/dist/components/paper/paper.stories.d.ts +7 -0
- package/dist/components/paper/paper.stories.js +30 -0
- package/dist/components/password-strength-indicator/password-strength-indicator.stories.js +1 -1
- package/dist/components/popover/popover-skeleton.js +1 -1
- package/dist/components/popover/popover.stories.js +2 -2
- package/dist/components/progress/index.d.ts +1 -1
- package/dist/components/progress/progress.d.ts +1 -1
- package/dist/components/progress/progress.stories.js +1 -1
- package/dist/components/radio-group/radio-group-skeleton.js +1 -1
- package/dist/components/radio-group/radio-group.stories.js +1 -1
- package/dist/components/resizable/resizable.stories.js +8 -8
- package/dist/components/ring-progress/index.d.ts +1 -0
- package/dist/components/ring-progress/index.js +1 -0
- package/dist/components/ring-progress/ring-progress.d.ts +24 -0
- package/dist/components/ring-progress/ring-progress.js +20 -0
- package/dist/components/ring-progress/ring-progress.stories.d.ts +9 -0
- package/dist/components/ring-progress/ring-progress.stories.js +46 -0
- package/dist/components/scroll-area/scroll-area.stories.js +26 -26
- package/dist/components/segmented-control/index.d.ts +1 -0
- package/dist/components/segmented-control/index.js +1 -0
- package/dist/components/segmented-control/segmented-control.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control.js +46 -0
- package/dist/components/segmented-control/segmented-control.stories.d.ts +10 -0
- package/dist/components/segmented-control/segmented-control.stories.js +53 -0
- package/dist/components/select/select.js +1 -1
- package/dist/components/select/select.stories.js +1 -1
- package/dist/components/separator/separator.stories.js +1 -1
- package/dist/components/session-card/session-card-skeleton.js +2 -2
- package/dist/components/session-card/session-card.js +1 -1
- package/dist/components/sidebar/sidebar-skeleton.js +2 -2
- package/dist/components/skeleton/index.d.ts +3 -3
- package/dist/components/skeleton/index.js +1 -1
- package/dist/components/skeleton/skeleton.types.d.ts +0 -249
- package/dist/components/slider/index.d.ts +1 -1
- package/dist/components/slider/slider.js +1 -1
- package/dist/components/slider/slider.stories.js +1 -1
- package/dist/components/social-login-button/social-login-button.js +6 -6
- package/dist/components/sparkline-chart/sparkline-chart.js +6 -3
- package/dist/components/sparkline-chart/sparkline-chart.stories.js +1 -1
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/spoiler/index.d.ts +1 -0
- package/dist/components/spoiler/index.js +1 -0
- package/dist/components/spoiler/spoiler.d.ts +14 -0
- package/dist/components/spoiler/spoiler.js +20 -0
- package/dist/components/spoiler/spoiler.stories.d.ts +8 -0
- package/dist/components/spoiler/spoiler.stories.js +35 -0
- package/dist/components/stack/index.d.ts +1 -1
- package/dist/components/stack/index.js +1 -1
- package/dist/components/stack/stack.d.ts +2 -2
- package/dist/components/stack/stack.js +1 -1
- package/dist/components/steps/steps-skeleton.js +1 -1
- package/dist/components/steps/steps.js +7 -5
- package/dist/components/steps/steps.stories.js +6 -2
- package/dist/components/switch/index.d.ts +1 -1
- package/dist/components/switch/switch.js +1 -1
- package/dist/components/switch/switch.stories.js +1 -1
- package/dist/components/table/table-skeleton.js +2 -2
- package/dist/components/table/table.js +4 -3
- package/dist/components/table/table.stories.js +10 -7
- package/dist/components/tabs/tabs-skeleton.js +1 -1
- package/dist/components/tabs/tabs.d.ts +3 -3
- package/dist/components/tabs/tabs.js +1 -1
- package/dist/components/tabs/tabs.stories.js +5 -5
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/text/index.js +1 -1
- package/dist/components/text/text.d.ts +7 -5
- package/dist/components/text/text.js +2 -2
- package/dist/components/text/text.stories.js +34 -3
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/textarea/textarea.stories.js +1 -1
- package/dist/components/timeline/index.d.ts +1 -0
- package/dist/components/timeline/index.js +1 -0
- package/dist/components/timeline/timeline.d.ts +35 -0
- package/dist/components/timeline/timeline.js +36 -0
- package/dist/components/timeline/timeline.stories.d.ts +7 -0
- package/dist/components/timeline/timeline.stories.js +21 -0
- package/dist/components/toast/toast.js +6 -6
- package/dist/components/toggle/toggle.stories.js +1 -1
- package/dist/components/tooltip/tooltip.stories.js +1 -1
- package/dist/components/user-menu-dropdown/user-menu-dropdown.js +1 -1
- package/dist/config/tailwind-base.d.ts +10 -0
- package/dist/config/tailwind-base.js +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +25 -10
- package/dist/lib/animations.js +94 -94
- package/dist/primitives/command/Command.js +2 -1
- package/dist/styles/globals.css +415 -82
- package/package.json +101 -24
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useDisclosure, useHotkeys } from "@kala-ui/react-hooks";
|
|
2
3
|
import { Calculator, Calendar, CreditCard, Settings, Smile, User, } from "lucide-react";
|
|
3
|
-
import {
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Box } from "../box";
|
|
6
|
+
import { Stack } from "../stack";
|
|
7
|
+
import { Text } from "../text";
|
|
4
8
|
import { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, } from "./command";
|
|
5
9
|
const meta = {
|
|
6
10
|
title: "Components/Command",
|
|
@@ -17,34 +21,25 @@ const meta = {
|
|
|
17
21
|
};
|
|
18
22
|
export default meta;
|
|
19
23
|
export const Default = {
|
|
20
|
-
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Type a command or search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Suggestions", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx("span",
|
|
24
|
+
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Type a command or search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Suggestions", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calendar" })] }), _jsxs(CommandItem, { children: [_jsx(Smile, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Search Emoji" })] }), _jsxs(CommandItem, { children: [_jsx(Calculator, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calculator" })] })] }), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: "Settings", children: [_jsxs(CommandItem, { children: [_jsx(User, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Profile" }), _jsx(CommandShortcut, { children: "\u2318P" })] }), _jsxs(CommandItem, { children: [_jsx(CreditCard, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Billing" }), _jsx(CommandShortcut, { children: "\u2318B" })] }), _jsxs(CommandItem, { children: [_jsx(Settings, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Settings" }), _jsx(CommandShortcut, { children: "\u2318S" })] })] })] })] })),
|
|
21
25
|
};
|
|
22
26
|
export const WithDialog = {
|
|
23
27
|
render: () => {
|
|
24
|
-
const [open, setOpen] =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
28
|
-
e.preventDefault();
|
|
29
|
-
setOpen((open) => !open);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
document.addEventListener("keydown", down);
|
|
33
|
-
return () => document.removeEventListener("keydown", down);
|
|
34
|
-
}, []);
|
|
35
|
-
return (_jsxs(_Fragment, { children: [_jsxs("p", { className: "text-sm text-muted-foreground mb-4", children: ["Press", " ", _jsxs("kbd", { className: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100", children: [_jsx("span", { className: "text-xs", children: "\u2318" }), "K"] })] }), _jsx("button", { type: "button", onClick: () => setOpen(true), className: "rounded-md border px-4 py-2 text-sm hover:bg-accent", children: "Open Command Menu" }), _jsxs(CommandDialog, { open: open, onOpenChange: setOpen, children: [_jsx(CommandInput, { placeholder: "Type a command or search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Suggestions", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Calendar" })] }), _jsxs(CommandItem, { children: [_jsx(Smile, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Search Emoji" })] }), _jsxs(CommandItem, { children: [_jsx(Calculator, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Calculator" })] })] }), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: "Settings", children: [_jsxs(CommandItem, { children: [_jsx(User, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Profile" }), _jsx(CommandShortcut, { children: "\u2318P" })] }), _jsxs(CommandItem, { children: [_jsx(CreditCard, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Billing" }), _jsx(CommandShortcut, { children: "\u2318B" })] }), _jsxs(CommandItem, { children: [_jsx(Settings, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Settings" }), _jsx(CommandShortcut, { children: "\u2318S" })] })] })] })] })] }));
|
|
28
|
+
const [open, { toggle, set: setOpen }] = useDisclosure(false);
|
|
29
|
+
useHotkeys([["mod+K", toggle, { preventDefault: true }]]);
|
|
30
|
+
return (_jsxs(Stack, { gap: 2, children: [_jsxs(Text, { size: "sm", className: "text-muted-foreground", children: ["Press", " ", _jsxs("kbd", { className: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100", children: [_jsx(Text, { as: "span", className: "text-xs", children: "\u2318" }), "K"] })] }), _jsxs(CommandDialog, { open: open, onOpenChange: setOpen, children: [_jsx(CommandInput, { placeholder: "Type a command or search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Suggestions", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calendar" })] }), _jsxs(CommandItem, { children: [_jsx(Smile, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Search Emoji" })] }), _jsxs(CommandItem, { children: [_jsx(Calculator, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calculator" })] })] }), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: "Settings", children: [_jsxs(CommandItem, { children: [_jsx(User, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Profile" }), _jsx(CommandShortcut, { children: "\u2318P" })] }), _jsxs(CommandItem, { children: [_jsx(CreditCard, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Billing" }), _jsx(CommandShortcut, { children: "\u2318B" })] }), _jsxs(CommandItem, { children: [_jsx(Settings, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Settings" }), _jsx(CommandShortcut, { children: "\u2318S" })] })] })] })] })] }));
|
|
36
31
|
},
|
|
37
32
|
};
|
|
38
33
|
export const WithSearch = {
|
|
39
34
|
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search for fruits..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No fruits found." }), _jsxs(CommandGroup, { heading: "Fruits", children: [_jsx(CommandItem, { value: "apple", children: "\uD83C\uDF4E Apple" }), _jsx(CommandItem, { value: "banana", children: "\uD83C\uDF4C Banana" }), _jsx(CommandItem, { value: "cherry", children: "\uD83C\uDF52 Cherry" }), _jsx(CommandItem, { value: "grape", children: "\uD83C\uDF47 Grape" }), _jsx(CommandItem, { value: "orange", children: "\uD83C\uDF4A Orange" }), _jsx(CommandItem, { value: "strawberry", children: "\uD83C\uDF53 Strawberry" }), _jsx(CommandItem, { value: "watermelon", children: "\uD83C\uDF49 Watermelon" })] })] })] })),
|
|
40
35
|
};
|
|
41
36
|
export const MultipleGroups = {
|
|
42
|
-
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Files", children: [_jsx(CommandItem, { children: _jsx("span",
|
|
37
|
+
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Files", children: [_jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Document.pdf" }) }), _jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Presentation.pptx" }) }), _jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Spreadsheet.xlsx" }) })] }), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: "Folders", children: [_jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Downloads" }) }), _jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Documents" }) }), _jsx(CommandItem, { children: _jsx(Text, { as: "span", children: "Pictures" }) })] }), _jsx(CommandSeparator, {}), _jsxs(CommandGroup, { heading: "Actions", children: [_jsxs(CommandItem, { children: [_jsx(Text, { as: "span", children: "New File" }), _jsx(CommandShortcut, { children: "\u2318N" })] }), _jsxs(CommandItem, { children: [_jsx(Text, { as: "span", children: "New Folder" }), _jsx(CommandShortcut, { children: "\u21E7\u2318N" })] })] })] })] })),
|
|
43
38
|
};
|
|
44
39
|
export const WithOnSelect = {
|
|
45
40
|
render: () => {
|
|
46
41
|
const [value, setValue] = useState("");
|
|
47
|
-
return (_jsxs(
|
|
42
|
+
return (_jsxs(Box, { children: [_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Select an option..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No results found." }), _jsxs(CommandGroup, { heading: "Options", children: [_jsx(CommandItem, { value: "option1", onSelect: () => setValue("option1"), children: "Option 1" }), _jsx(CommandItem, { value: "option2", onSelect: () => setValue("option2"), children: "Option 2" }), _jsx(CommandItem, { value: "option3", onSelect: () => setValue("option3"), children: "Option 3" })] })] })] }), value && (_jsxs(Text, { className: "mt-4 text-sm text-muted-foreground", children: ["Selected: ", value] }))] }));
|
|
48
43
|
},
|
|
49
44
|
};
|
|
50
45
|
export const DisabledItems = {
|
|
@@ -54,10 +49,10 @@ export const Loading = {
|
|
|
54
49
|
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Searching..." }), _jsx(CommandList, { children: _jsx(CommandEmpty, { children: "Loading..." }) })] })),
|
|
55
50
|
};
|
|
56
51
|
export const EmptyState = {
|
|
57
|
-
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search..." }), _jsx(CommandList, { children: _jsx(CommandEmpty, { children: _jsxs(
|
|
52
|
+
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search..." }), _jsx(CommandList, { children: _jsx(CommandEmpty, { children: _jsxs(Box, { className: "py-6 text-center", children: [_jsx(Text, { className: "text-sm text-muted-foreground", children: "No results found." }), _jsx(Text, { className: "mt-2 text-xs text-muted-foreground", children: "Try searching for something else." })] }) }) })] })),
|
|
58
53
|
};
|
|
59
54
|
export const WithIcons = {
|
|
60
|
-
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search apps..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No apps found." }), _jsxs(CommandGroup, { heading: "Applications", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx("span",
|
|
55
|
+
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search apps..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No apps found." }), _jsxs(CommandGroup, { heading: "Applications", children: [_jsxs(CommandItem, { children: [_jsx(Calendar, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calendar" }), _jsx(CommandShortcut, { children: "\u23181" })] }), _jsxs(CommandItem, { children: [_jsx(Calculator, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Calculator" }), _jsx(CommandShortcut, { children: "\u23182" })] }), _jsxs(CommandItem, { children: [_jsx(Settings, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Settings" }), _jsx(CommandShortcut, { children: "\u23183" })] }), _jsxs(CommandItem, { children: [_jsx(User, { className: "mr-2 h-4 w-4" }), _jsx(Text, { as: "span", children: "Profile" }), _jsx(CommandShortcut, { children: "\u23184" })] })] })] })] })),
|
|
61
56
|
};
|
|
62
57
|
export const LongList = {
|
|
63
58
|
render: () => (_jsxs(Command, { className: "rounded-lg border shadow-md", children: [_jsx(CommandInput, { placeholder: "Search countries..." }), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No country found." }), _jsx(CommandGroup, { heading: "Countries", children: [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type VariantProps } from "class-variance-authority";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
declare const containerVariants: (props?: ({
|
|
4
|
-
size?: "sm" | "md" | "lg" | "xl" | "
|
|
4
|
+
size?: "sm" | "md" | "lg" | "xl" | "2xl" | "full" | null | undefined;
|
|
5
5
|
centered?: boolean | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export interface ContainerProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof containerVariants> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./container";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./container";
|
|
@@ -5,16 +5,21 @@
|
|
|
5
5
|
"use client";
|
|
6
6
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Filter, X } from "lucide-react";
|
|
8
|
-
import
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { useDisclosure } from "@kala-ui/react-hooks";
|
|
9
10
|
import { Badge } from "../badge";
|
|
10
11
|
import { Button } from "../button";
|
|
11
12
|
import { Checkbox } from "../checkbox";
|
|
13
|
+
import { Flex } from "../flex";
|
|
14
|
+
import { Heading } from "../heading";
|
|
12
15
|
import { Input } from "../input";
|
|
13
16
|
import { Label } from "../label";
|
|
14
17
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
18
|
+
import { Stack } from "../stack";
|
|
19
|
+
import { Text } from "../text";
|
|
15
20
|
export function ColumnHeaderFilter({ column, activeFilters, onFilterChange, onFilterRemove, }) {
|
|
16
|
-
const [open, setOpen] =
|
|
17
|
-
const [textValue, setTextValue] = useState("");
|
|
21
|
+
const [open, { set: setOpen }] = useDisclosure(false);
|
|
22
|
+
const [textValue, setTextValue] = React.useState("");
|
|
18
23
|
const activeFilter = activeFilters.find((f) => f.key === column.key);
|
|
19
24
|
const filterValue = activeFilter?.value;
|
|
20
25
|
// For multi-select, track selected values
|
|
@@ -58,10 +63,10 @@ export function ColumnHeaderFilter({ column, activeFilters, onFilterChange, onFi
|
|
|
58
63
|
onFilterRemove(column.key);
|
|
59
64
|
setTextValue("");
|
|
60
65
|
};
|
|
61
|
-
return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0 hover:bg-muted relative", "aria-label": `Filter by ${column.label}`, children: [_jsx(Filter, { className: `h-4 w-4 ${hasActiveFilter ? "text-primary" : "text-muted-foreground"}` }), hasActiveFilter ? (_jsx(Badge, { variant: "default", className: "absolute -top-1 -right-1 h-4 w-4 p-0 flex items-center justify-center text-[10px]
|
|
66
|
+
return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0 hover:bg-muted relative", "aria-label": `Filter by ${column.label}`, children: [_jsx(Filter, { className: `h-4 w-4 ${hasActiveFilter ? "text-primary" : "text-muted-foreground"}` }), hasActiveFilter ? (_jsx(Badge, { variant: "default", className: "absolute -top-1 -right-1 h-4 w-4 p-0 flex items-center justify-center text-[10px]", children: _jsx(Text, { size: "xs", weight: "bold", className: "text-primary-foreground", children: column.type === "text" ? "1" : activeCount }) })) : null] }) }), _jsx(PopoverContent, { className: "w-64 p-3", align: "start", children: _jsxs(Stack, { gap: 3, children: [_jsxs(Flex, { align: "center", justify: "between", children: [_jsxs(Heading, { size: "h6", weight: "medium", className: "text-sm", children: ["Filter by ", column.label] }), hasActiveFilter ? (_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleClear, className: "h-7 px-2 text-xs text-muted-foreground", children: [_jsx(X, { className: "h-3 w-3 mr-1" }), "Clear"] })) : null] }), column.type === "select" && column.options ? (_jsx(Stack, { gap: 2, className: "max-h-[300px] overflow-y-auto", children: column.options.map((option) => {
|
|
62
67
|
const isChecked = selectedValues.includes(option.value);
|
|
63
|
-
return (_jsxs(
|
|
64
|
-
}) })) : (_jsxs(
|
|
68
|
+
return (_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Checkbox, { id: `${String(column.key)}-${option.value}`, checked: isChecked, onCheckedChange: (checked) => handleCheckboxChange(option.value, checked === true) }), _jsx(Label, { htmlFor: `${String(column.key)}-${option.value}`, className: "text-sm font-normal cursor-pointer flex-1 text-foreground", children: option.label })] }, option.value));
|
|
69
|
+
}) })) : (_jsxs(Stack, { gap: 2, children: [_jsx(Input, { type: "text", placeholder: column.placeholder || `Filter by ${column.label}`, value: textValue, onChange: (e) => setTextValue(e.target.value), onKeyDown: (e) => {
|
|
65
70
|
if (e.key === "Enter") {
|
|
66
71
|
handleTextApply();
|
|
67
72
|
}
|
|
@@ -10,32 +10,22 @@ import { Button } from "../button";
|
|
|
10
10
|
import { Checkbox } from "../checkbox";
|
|
11
11
|
import { FieldLabel } from "../field";
|
|
12
12
|
import { Input } from "../input";
|
|
13
|
-
import { Skeleton } from "../skeleton";
|
|
14
13
|
import { Select, SelectTrigger, SelectValue } from "../select";
|
|
14
|
+
import { Skeleton } from "../skeleton";
|
|
15
15
|
import { TableBody, TableCell, TableHead, TableHeader, TableRow, } from "../table";
|
|
16
16
|
export function DataTableSkeleton({ rows = 5, columns, showSearch = false, showFilters = false, filterCount = 3, showPagination = false, showSelection = false, showBulkActions = false, stickyHeader = true, stickyFooter = false, }) {
|
|
17
|
-
return (_jsxs("div", { className: "flex flex-col", children: [showSearch && (_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-4 shrink-0", children: [_jsx("div", { className: "flex-1 max-w-sm", children: _jsx(Input, { type: "search", placeholder: "Search...", disabled: true, className: "opacity-50" }) }), showBulkActions && (_jsxs("div", { className: "flex items-center gap-2 flex-wrap min-h-[36px]", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "0 selected" }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: "Edit" }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: "Delete" })] }))] })), showFilters && (_jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-4 shrink-0", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "Active filters:" }), Array.from({ length: filterCount }).map((_, i) => (_jsxs(Badge, { variant: "secondary", className: "gap-1.5 pl-2 pr-1 py-1 bg-primary/10 text-primary border-primary/20", children: [_jsx("span", { className: "text-xs font-medium", children: "Filter: Value" }), _jsx(Button, { variant: "ghost", size: "sm", disabled: true, className: "h-4 w-4 p-0 hover:bg-primary/20 rounded-sm", children: _jsx(Skeleton, { className: "h-3 w-3" }) })] }, `filter-${i}`))), _jsx(Button, { variant: "ghost", size: "sm", disabled: true, className: "h-7 px-2 text-xs text-muted-foreground hover:text-foreground", children: "Clear all" })] })), _jsx("div", { className: cn("border relative overflow-hidden theme-card", showPagination ? "rounded-t-lg border-b-0" : "rounded-lg", stickyFooter ? "flex-1 min-h-0" : ""), children: _jsx("div", { className: cn("overflow-auto relative", showPagination ? "rounded-t-lg" : "rounded-lg", stickyFooter
|
|
18
|
-
? "flex-1 min-h-0 max-h-[70vh]"
|
|
19
|
-
: "max-h-[600px]"), children: _jsxs("table", { className: "w-full border-separate border-spacing-0 caption-bottom text-sm", children: [_jsx(TableHeader, { className: cn(stickyHeader &&
|
|
20
|
-
"sticky top-0 z-1 bg-muted/95 backdrop-blur-sm", "[&_tr]:border-0"), children: _jsxs(TableRow, { className: "border-0", children: [showSelection && (_jsx(TableHead, { className: cn("w-12 rounded-tl-lg", stickyHeader
|
|
17
|
+
return (_jsxs("div", { className: "flex flex-col", children: [showSearch && (_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-4 shrink-0", children: [_jsx("div", { className: "flex-1 max-w-sm", children: _jsx(Input, { type: "search", placeholder: "Search...", disabled: true, className: "opacity-50" }) }), showBulkActions && (_jsxs("div", { className: "flex items-center gap-2 flex-wrap min-h-[36px]", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "0 selected" }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: "Edit" }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: "Delete" })] }))] })), showFilters && (_jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-4 shrink-0", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: "Active filters:" }), Array.from({ length: filterCount }).map((_, i) => (_jsxs(Badge, { variant: "secondary", className: "gap-1.5 pl-2 pr-1 py-1 bg-primary/10 text-primary border-primary/20", children: [_jsx("span", { className: "text-xs font-medium", children: "Filter: Value" }), _jsx(Button, { variant: "ghost", size: "sm", disabled: true, className: "h-4 w-4 p-0 hover:bg-primary/20 rounded-sm", children: _jsx(Skeleton, { className: "h-3 w-3" }) })] }, `filter-${i}`))), _jsx(Button, { variant: "ghost", size: "sm", disabled: true, className: "h-7 px-2 text-xs text-muted-foreground hover:text-foreground", children: "Clear all" })] })), _jsx("div", { className: cn("border relative overflow-hidden theme-card", showPagination ? "rounded-t-lg border-b-0" : "rounded-lg", stickyFooter ? "flex-1 min-h-0" : ""), children: _jsx("div", { className: cn("overflow-auto relative", showPagination ? "rounded-t-lg" : "rounded-lg", stickyFooter ? "flex-1 min-h-0 max-h-[70vh]" : "max-h-[600px]"), children: _jsxs("table", { className: "w-full border-separate border-spacing-0 caption-bottom text-sm", children: [_jsx(TableHeader, { className: cn(stickyHeader && "sticky top-0 z-1 bg-muted/95 backdrop-blur-sm", "[&_tr]:border-0"), children: _jsxs(TableRow, { className: "border-0", children: [showSelection && (_jsx(TableHead, { className: cn("w-12 rounded-tl-lg", stickyHeader
|
|
21
18
|
? "border-b border-border-strong/50"
|
|
22
19
|
: "border-b"), children: _jsx(Checkbox, { disabled: true }) })), columns.map((column, index) => {
|
|
23
20
|
const isFirst = !showSelection && index === 0;
|
|
24
21
|
const isLast = index === columns.length - 1;
|
|
25
22
|
return (_jsx(TableHead, { style: { width: column.width }, className: cn(column.align === "center" && "text-center", column.align === "right" && "text-right", column.hideOnMobile && "hidden md:table-cell", stickyHeader
|
|
26
23
|
? "border-b border-border-strong/50"
|
|
27
|
-
: "border-b", isFirst && "rounded-tl-lg", isLast && "rounded-tr-lg"), children: _jsx("div", { className: cn("flex items-center gap-1", column.align === "center" &&
|
|
28
|
-
"justify-center", column.align === "right" &&
|
|
29
|
-
"justify-end"), children: column.enableFiltering ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-4 flex-1" }), _jsx(Skeleton, { className: "h-4 w-4" })] })) : (_jsx(Skeleton, { className: "h-4 w-24" })) }) }, column.id));
|
|
24
|
+
: "border-b", isFirst && "rounded-tl-lg", isLast && "rounded-tr-lg"), children: _jsx("div", { className: cn("flex items-center gap-1", column.align === "center" && "justify-center", column.align === "right" && "justify-end"), children: column.enableFiltering ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "h-4 flex-1" }), _jsx(Skeleton, { className: "h-4 w-4" })] })) : (_jsx(Skeleton, { className: "h-4 w-24" })) }) }, column.id));
|
|
30
25
|
})] }) }), _jsx(TableBody, { children: Array.from({ length: rows }).map((_, rowIndex) => {
|
|
31
26
|
const isLastRow = rowIndex === rows - 1;
|
|
32
27
|
return (_jsxs(TableRow, { className: cn("border-0"), children: [showSelection && (_jsx(TableCell, { children: _jsx(Checkbox, { disabled: true, "aria-label": `Select row ${rowIndex + 1}` }) })), columns.map((column) => {
|
|
33
|
-
return (_jsx(TableCell, { className: cn(column.align ===
|
|
34
|
-
"center" &&
|
|
35
|
-
"text-center", column.align === "right" &&
|
|
36
|
-
"text-right", column.hideOnMobile &&
|
|
37
|
-
"hidden md:table-cell", !isLastRow && "border-b"), children: _jsx(Skeleton, { className: "h-4 w-32" }) }, column.id));
|
|
28
|
+
return (_jsx(TableCell, { className: cn(column.align === "center" && "text-center", column.align === "right" && "text-right", column.hideOnMobile && "hidden md:table-cell", !isLastRow && "border-b"), children: _jsx(Skeleton, { className: "h-4 w-32" }) }, column.id));
|
|
38
29
|
})] }, rowIndex));
|
|
39
|
-
}) })] }) }) }), showPagination && (_jsxs("div", { className: cn("flex flex-col sm:flex-row items-center justify-between gap-4 bg-background px-4 py-3 rounded-b-lg theme-card border-x border-b", stickyFooter &&
|
|
40
|
-
"sticky bottom-0 z-1 shadow-xl bg-background"), children: [_jsx("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: _jsx(Skeleton, { className: "h-4 w-48" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FieldLabel, { htmlFor: "page-size", className: "text-sm text-muted-foreground mb-0", children: "Rows per page:" }), _jsx(Select, { disabled: true, children: _jsx(SelectTrigger, { className: "w-20 h-9 text-foreground opacity-50", children: _jsx(SelectValue, {}) }) })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: _jsx(Skeleton, { className: "h-4 w-4" }) }), _jsx("span", { className: "text-sm text-muted-foreground px-2", children: _jsx(Skeleton, { className: "h-4 w-16 inline-block" }) }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: _jsx(Skeleton, { className: "h-4 w-4" }) })] })] })] }))] }));
|
|
30
|
+
}) })] }) }) }), showPagination && (_jsxs("div", { className: cn("flex flex-col sm:flex-row items-center justify-between gap-4 bg-background px-4 py-3 rounded-b-lg theme-card border-x border-b", stickyFooter && "sticky bottom-0 z-1 shadow-xl bg-background"), children: [_jsx("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: _jsx(Skeleton, { className: "h-4 w-48" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FieldLabel, { htmlFor: "page-size", className: "text-sm text-muted-foreground mb-0", children: "Rows per page:" }), _jsx(Select, { disabled: true, children: _jsx(SelectTrigger, { className: "w-20 h-9 text-foreground opacity-50", children: _jsx(SelectValue, {}) }) })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: _jsx(Skeleton, { className: "h-4 w-4" }) }), _jsx("span", { className: "text-sm text-muted-foreground px-2", children: _jsx(Skeleton, { className: "h-4 w-16 inline-block" }) }), _jsx(Button, { variant: "outline", size: "sm", disabled: true, className: "opacity-50", children: _jsx(Skeleton, { className: "h-4 w-4" }) })] })] })] }))] }));
|
|
41
31
|
}
|
|
@@ -17,17 +17,21 @@
|
|
|
17
17
|
*/
|
|
18
18
|
"use client";
|
|
19
19
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
|
+
import { useDisclosure } from "@kala-ui/react-hooks";
|
|
20
21
|
import { ArrowDown, ArrowUp, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Search, X, } from "lucide-react";
|
|
21
22
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
22
23
|
import { cn } from "../../lib/utils";
|
|
23
24
|
import { Badge } from "../badge";
|
|
25
|
+
import { Box } from "../box";
|
|
24
26
|
import { Button } from "../button";
|
|
25
27
|
import { Checkbox } from "../checkbox";
|
|
26
28
|
import { EmptyState } from "../empty-state";
|
|
27
|
-
import {
|
|
29
|
+
import { Flex } from "../flex";
|
|
28
30
|
import { Input } from "../input";
|
|
29
31
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../select";
|
|
32
|
+
import { Stack } from "../stack";
|
|
30
33
|
import { TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow, } from "../table";
|
|
34
|
+
import { Text } from "../text";
|
|
31
35
|
import { ColumnHeaderFilter } from "./column-header-filter";
|
|
32
36
|
import { DataTableSkeleton } from "./data-table-skeleton";
|
|
33
37
|
import { useTableState } from "./useTableState";
|
|
@@ -80,14 +84,14 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
80
84
|
const [selectedIds, setSelectedIds] = useState(selection?.selectedIds ?? new Set());
|
|
81
85
|
// Scroll container ref for scroll-to-top/bottom buttons
|
|
82
86
|
const scrollContainerRef = useRef(null);
|
|
83
|
-
const [showScrollButtons, setShowScrollButtons] =
|
|
87
|
+
const [showScrollButtons, { set: setShowScrollButtons }] = useDisclosure(false);
|
|
84
88
|
// Handle scroll event to show/hide scroll buttons
|
|
85
89
|
const handleScroll = useCallback(() => {
|
|
86
90
|
if (scrollContainerRef.current) {
|
|
87
91
|
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
88
92
|
setShowScrollButtons(scrollHeight > clientHeight && scrollTop > 100);
|
|
89
93
|
}
|
|
90
|
-
}, []);
|
|
94
|
+
}, [setShowScrollButtons]);
|
|
91
95
|
// Scroll to top/bottom functions
|
|
92
96
|
const scrollToTop = useCallback(() => {
|
|
93
97
|
scrollContainerRef.current?.scrollTo({ top: 0, behavior: "smooth" });
|
|
@@ -197,13 +201,13 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
197
201
|
// Hide search if no data and not searching (unless forceShow is true)
|
|
198
202
|
if (data.length === 0 && !searchQuery && !forceShow)
|
|
199
203
|
return null;
|
|
200
|
-
return (_jsx(
|
|
204
|
+
return (_jsx(Box, { className: "flex-1 max-w-sm", children: _jsx(Input, { type: "search", placeholder: searchConfig.placeholder, value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), prefixIcon: _jsx(Search, { className: "h-4 w-4" }), suffixIcon: searchQuery ? (_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSearchQuery(""), className: "p-1 text-muted-foreground hover:text-foreground h-auto", "aria-label": "Clear search", children: _jsx(X, { className: "h-4 w-4" }) })) : null, "aria-label": searchConfig.ariaLabel }) }));
|
|
201
205
|
};
|
|
202
206
|
// Render loading state
|
|
203
207
|
if (isLoading) {
|
|
204
208
|
// Use custom skeleton if provided
|
|
205
209
|
if (skeleton) {
|
|
206
|
-
return _jsx(
|
|
210
|
+
return _jsx(Stack, { gap: 4, className: className, children: skeleton });
|
|
207
211
|
}
|
|
208
212
|
// Use skeletonConfig if provided, otherwise fall back to legacy loadingConfig
|
|
209
213
|
const showSearch = !!searchConfig;
|
|
@@ -212,7 +216,7 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
212
216
|
const showSelection = !!selection?.enabled;
|
|
213
217
|
const showBulkActions = !!bulkActions;
|
|
214
218
|
const skeletonRows = skeletonConfig?.rows ?? loadingConfig?.rows ?? 5;
|
|
215
|
-
return (_jsx(
|
|
219
|
+
return (_jsx(Stack, { gap: 4, className: className, children: _jsx(DataTableSkeleton, { rows: skeletonRows, columns: columns, showSearch: showSearch, showFilters: showFilters, showPagination: showPagination, showSelection: showSelection, showBulkActions: showBulkActions, stickyHeader: stickyHeader, stickyFooter: stickyFooter }) }));
|
|
216
220
|
}
|
|
217
221
|
// Render empty state
|
|
218
222
|
if (displayData.length === 0) {
|
|
@@ -223,16 +227,16 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
223
227
|
: "There is no data to display at the moment.",
|
|
224
228
|
};
|
|
225
229
|
const emptyConfig = { ...defaultEmptyState, ...emptyState };
|
|
226
|
-
return (_jsxs(
|
|
230
|
+
return (_jsxs(Stack, { gap: 4, className: className, children: [renderSearchInput(), _jsx(EmptyState, { title: emptyConfig.title, description: emptyConfig.description, ...(emptyConfig.icon && { icon: emptyConfig.icon }), ...(emptyConfig.action && { action: emptyConfig.action }) })] }));
|
|
227
231
|
}
|
|
228
|
-
return (_jsxs(
|
|
232
|
+
return (_jsxs(Stack, { className: cn(stickyFooter ? "h-full min-h-0" : "", className), "aria-label": ariaLabel, role: ariaLabel ? "region" : undefined, children: [(searchConfig || bulkActions) && (_jsxs(Flex, { align: "center", justify: "between", gap: 4, className: cn("mb-4 flex-wrap", stickyFooter && "shrink-0"), children: [renderSearchInput(), bulkActions && (_jsxs(Flex, { align: "center", gap: 2, className: "flex-wrap min-h-[36px]", children: [_jsxs(Text, { size: "sm", className: "text-muted-foreground", children: [selectedIds.size, " selected"] }), bulkActions.map((action) => (_jsxs(Button, { variant: action.variant ?? "outline", size: "sm", onClick: () => action.onClick(selectedRows), disabled: selectedIds.size === 0 || action.disabled, className: cn(selectedIds.size === 0 && "opacity-50 cursor-not-allowed"), children: [action.icon, action.label] }, action.id)))] }))] })), filterableColumns && filterConfigs.length > 0 && (_jsxs(Flex, { align: "center", gap: 2, className: cn("mb-4 flex-wrap", stickyFooter && "shrink-0"), children: [_jsx(Text, { size: "sm", className: "text-muted-foreground", children: "Active filters:" }), filterConfigs.map((filter) => {
|
|
229
233
|
const column = filterableColumns.find((fc) => fc.key === filter.key);
|
|
230
234
|
if (!column)
|
|
231
235
|
return null;
|
|
232
236
|
const filterValueArray = Array.isArray(filter.value)
|
|
233
237
|
? filter.value
|
|
234
238
|
: [filter.value];
|
|
235
|
-
return filterValueArray.map((value, idx) => (_jsxs(Badge, { variant: "secondary", className: "gap-1.5 pl-2 pr-1 py-1 bg-primary/10 text-primary border-primary/20", children: [_jsxs(
|
|
239
|
+
return filterValueArray.map((value, idx) => (_jsxs(Badge, { variant: "secondary", className: "gap-1.5 pl-2 pr-1 py-1 bg-primary/10 text-primary border-primary/20", children: [_jsxs(Text, { size: "xs", weight: "medium", children: [column.label, ": ", String(value)] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
236
240
|
if (filterValueArray.length === 1) {
|
|
237
241
|
removeFilter(filter.key);
|
|
238
242
|
}
|
|
@@ -245,7 +249,7 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
245
249
|
});
|
|
246
250
|
}
|
|
247
251
|
}, className: "h-4 w-4 p-0 hover:bg-primary/20 rounded-sm", "aria-label": `Remove ${column.label} filter: ${String(value)}`, children: _jsx(X, { className: "h-3 w-3" }) })] }, `${String(filter.key)}-${value}-${idx}`)));
|
|
248
|
-
}), _jsx(Button, { variant: "ghost", size: "sm", onClick: clearFilters, className: "h-7 px-2 text-xs text-muted-foreground hover:text-foreground", children: "Clear all" })] })), _jsxs(
|
|
252
|
+
}), _jsx(Button, { variant: "ghost", size: "sm", onClick: clearFilters, className: "h-7 px-2 text-xs text-muted-foreground hover:text-foreground", children: "Clear all" })] })), _jsxs(Box, { className: cn("border relative overflow-hidden theme-card", stickyFooter && paginationConfig ? "flex-1 min-h-0" : "", bordered && "border-2", paginationConfig ? "rounded-t-lg border-b-0" : "rounded-lg"), children: [_jsx(Box, { ref: scrollContainerRef, onScroll: handleScroll, className: cn("overflow-auto relative", paginationConfig ? "rounded-t-lg" : "rounded-lg", stickyFooter ? "flex-1 min-h-0 max-h-[70vh]" : "max-h-[600px]"), children: _jsxs("table", { className: "w-full border-separate border-spacing-0 caption-bottom text-sm", children: [caption && _jsx("caption", { className: "sr-only", children: caption }), _jsx(TableHeader, { className: cn(stickyHeader && "sticky top-0 z-1 bg-muted/95 backdrop-blur-sm", "[&_tr]:border-0"), children: _jsxs(TableRow, { className: "border-0", children: [selection?.enabled && (_jsx(TableHead, { className: cn("w-12 rounded-tl-lg", stickyHeader
|
|
249
253
|
? "border-b border-border-strong/50"
|
|
250
254
|
: "border-b"), children: _jsx(Checkbox, { checked: isAllSelected
|
|
251
255
|
? true
|
|
@@ -266,9 +270,9 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
266
270
|
? sortDirection === "asc"
|
|
267
271
|
? "ascending"
|
|
268
272
|
: "descending"
|
|
269
|
-
: "none", children: _jsxs(
|
|
273
|
+
: "none", children: _jsxs(Flex, { align: "center", gap: 1, className: cn(column.align === "center" && "justify-center", column.align === "right" && "justify-end"), children: [canSort && column.accessorKey ? (_jsxs(Button, { variant: "ghost", size: "sm", onClick: () => toggleSort(column.accessorKey), className: "-ml-3 h-8 data-[state=open]:bg-accent hover:bg-accent font-semibold text-foreground hover:text-accent-foreground", "aria-label": column.ariaLabel
|
|
270
274
|
? `Sort by ${column.ariaLabel}`
|
|
271
|
-
: `Sort by ${column.header}`, children: [column.header, isSorted ? (sortDirection === "asc" ? (_jsx(ChevronUp, { className: "ml-2 h-4 w-4", "aria-hidden": "true" })) : (_jsx(ChevronDown, { className: "ml-2 h-4 w-4", "aria-hidden": "true" }))) : (_jsx(ChevronDown, { className: "ml-2 h-4 w-4 opacity-0 group-hover:opacity-40", "aria-hidden": "true" }))] })) : (_jsx(
|
|
275
|
+
: `Sort by ${column.header}`, children: [column.header, isSorted ? (sortDirection === "asc" ? (_jsx(ChevronUp, { className: "ml-2 h-4 w-4", "aria-hidden": "true" })) : (_jsx(ChevronDown, { className: "ml-2 h-4 w-4", "aria-hidden": "true" }))) : (_jsx(ChevronDown, { className: "ml-2 h-4 w-4 opacity-0 group-hover:opacity-40", "aria-hidden": "true" }))] })) : (_jsx(Text, { weight: "semibold", className: "text-muted-foreground", children: column.header })), filterColumn && (_jsx(ColumnHeaderFilter, { column: filterColumn, activeFilters: filterConfigs, onFilterChange: setFilter, onFilterRemove: removeFilter }))] }) }, column.id));
|
|
272
276
|
})] }) }), _jsx(TableBody, { children: displayData.map((row, rowIndex) => {
|
|
273
277
|
const isSelectable = !selection?.isRowSelectable || selection.isRowSelectable(row);
|
|
274
278
|
const rowId = selection?.getRowId(row);
|
|
@@ -300,11 +304,10 @@ export function DataTable({ data, columns, searchable, pagination, defaultSort,
|
|
|
300
304
|
? true
|
|
301
305
|
: isSomeSelected
|
|
302
306
|
? "indeterminate"
|
|
303
|
-
: false, onCheckedChange: handleSelectAll, "aria-label": "Select all rows (bottom)" }) })), columns.map((column) => (_jsx(TableHead, { className: cn(column.className, column.align === "center" && "text-center", column.align === "right" && "text-right", stickyFooter && ""), children: _jsx(
|
|
307
|
+
: false, onCheckedChange: handleSelectAll, "aria-label": "Select all rows (bottom)" }) })), columns.map((column) => (_jsx(TableHead, { className: cn(column.className, column.align === "center" && "text-center", column.align === "right" && "text-right", stickyFooter && ""), children: _jsx(Flex, { align: "center", gap: 2, className: cn(column.align === "center" && "justify-center", column.align === "right" && "justify-end"), children: column.enableSorting !== false ? (_jsxs(Button, { variant: "ghost", size: "sm", className: "h-auto p-0 -ml-2 justify-start font-medium hover:bg-transparent", onClick: () => toggleSort(column.accessorKey ||
|
|
304
308
|
column.id), "aria-label": `Sort by ${column.header}`, children: [column.header, sortConfig?.key ===
|
|
305
309
|
(column.accessorKey || column.id) &&
|
|
306
|
-
(sortConfig.direction === "asc" ? (_jsx(ArrowUp, { className: "ml-2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" })) : (_jsx(ArrowDown, { className: "ml-2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" })))] })) : (_jsx(
|
|
307
|
-
"sticky bottom-0 z-1 shadow-xl bg-background"), children: [_jsx("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: _jsxs("span", { children: ["Showing ", (currentPage - 1) * currentPageSize + 1, " to", " ", Math.min(currentPage * currentPageSize, paginationConfig.total), " ", "of ", paginationConfig.total, " results"] }) }), _jsxs("div", { className: "flex items-center gap-2", children: [paginationConfig.pageSizeOptions && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FieldLabel, { htmlFor: "page-size", className: "text-sm text-muted-foreground mb-0", children: "Rows per page:" }), _jsxs(Select, { value: String(currentPageSize), onValueChange: (value) => setPageSize(Number(value)), children: [_jsx(SelectTrigger, { className: "w-20 h-9 text-foreground", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: paginationConfig.pageSizeOptions.map((size) => (_jsx(SelectItem, { value: String(size), children: size }, size))) })] })] })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: previousPage, disabled: !hasPreviousPage, "aria-label": "Go to previous page", children: _jsx(ChevronLeft, { className: "h-4 w-4", "aria-hidden": "true" }) }), _jsxs("span", { className: "text-sm text-muted-foreground px-2", children: ["Page ", currentPage, " of ", totalPages] }), _jsx(Button, { variant: "outline", size: "sm", onClick: nextPage, disabled: !hasNextPage, "aria-label": "Go to next page", children: _jsx(ChevronRight, { className: "h-4 w-4", "aria-hidden": "true" }) })] })] })] }))] }));
|
|
310
|
+
(sortConfig.direction === "asc" ? (_jsx(ArrowUp, { className: "ml-2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" })) : (_jsx(ArrowDown, { className: "ml-2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" })))] })) : (_jsx(Text, { weight: "medium", children: column.header })) }) }, column.id)))] }) })), footer && (_jsx(TableFooter, { className: cn("border-t", !!paginationConfig && "border-b"), children: _jsx(TableRow, { className: "border-0", children: _jsx(TableCell, { colSpan: columns.length + (selection?.enabled ? 1 : 0), className: "p-4", children: footer }) }) }))] }) }), showScrollButtons && (_jsxs(Flex, { gap: 2, className: "absolute bottom-4 right-4 z-10", children: [_jsx(Button, { variant: "secondary", size: "icon", onClick: scrollToTop, className: "rounded-full shadow-lg h-9 w-9 bg-background/80 backdrop-blur-sm border-border-strong/20", "aria-label": "Scroll to top", children: _jsx(ArrowUp, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "secondary", size: "icon", onClick: scrollToBottom, className: "rounded-full shadow-lg h-9 w-9 bg-background/80 backdrop-blur-sm border-border-strong/20", "aria-label": "Scroll to bottom", children: _jsx(ArrowDown, { className: "h-4 w-4" }) })] }))] }), paginationConfig && (_jsxs(Flex, { align: "center", justify: "between", className: cn("px-4 py-3 border rounded-b-lg bg-muted/30", stickyFooter && "shrink-0"), children: [_jsxs(Flex, { align: "center", gap: 4, children: [_jsxs(Text, { size: "sm", className: "text-muted-foreground whitespace-nowrap", children: ["Showing", " ", _jsx(Text, { as: "span", weight: "medium", className: "text-foreground inline", children: Math.min((paginationConfig.page - 1) * paginationConfig.pageSize + 1, paginationConfig.total) }), " ", "to", " ", _jsx(Text, { as: "span", weight: "medium", className: "text-foreground inline", children: Math.min(paginationConfig.page * paginationConfig.pageSize, paginationConfig.total) }), " ", "of", " ", _jsx(Text, { as: "span", weight: "medium", className: "text-foreground inline", children: paginationConfig.total }), " ", "results"] }), paginationConfig.pageSizeOptions && (_jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Text, { size: "sm", className: "text-muted-foreground whitespace-nowrap", children: "Rows per page" }), _jsxs(Select, { value: String(paginationConfig.pageSize), onValueChange: (value) => setPageSize(Number(value)), children: [_jsx(SelectTrigger, { className: "h-8 w-[70px]", children: _jsx(SelectValue, { placeholder: String(paginationConfig.pageSize) }) }), _jsx(SelectContent, { side: "top", children: paginationConfig.pageSizeOptions.map((option) => (_jsx(SelectItem, { value: String(option), children: option }, option))) })] })] }))] }), _jsxs(Flex, { align: "center", gap: 2, children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: previousPage, disabled: !hasPreviousPage, className: "h-8 w-8 p-0", children: [_jsx(ChevronLeft, { className: "h-4 w-4" }), _jsx(Box, { as: "span", className: "sr-only", children: "Previous page" })] }), _jsx(Flex, { align: "center", gap: 1, children: _jsxs(Text, { size: "sm", weight: "medium", children: ["Page ", paginationConfig.page, " of ", totalPages] }) }), _jsxs(Button, { variant: "outline", size: "sm", onClick: nextPage, disabled: !hasNextPage, className: "h-8 w-8 p-0", children: [_jsx(ChevronRight, { className: "h-4 w-4" }), _jsx(Box, { as: "span", className: "sr-only", children: "Next page" })] })] })] }))] }));
|
|
308
311
|
}
|
|
309
312
|
// Export skeleton for direct use
|
|
310
313
|
export { DataTableSkeleton } from "./data-table-skeleton";
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* DataTable Storybook Stories
|
|
4
|
-
* Essential examples demonstrating DataTable features
|
|
5
|
-
*/
|
|
6
2
|
import React from "react";
|
|
7
3
|
import { Badge } from "../badge";
|
|
8
4
|
import { Button } from "../button";
|
|
@@ -705,7 +701,9 @@ export const ServerSideDataFetching = {
|
|
|
705
701
|
React.useEffect(() => {
|
|
706
702
|
fetchData();
|
|
707
703
|
}, [fetchData]);
|
|
708
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "p-4 bg-blue-50 dark:bg-blue-950 rounded-lg border border-blue-200 dark:border-blue-800", children: [_jsx("h3", { className: "font-semibold text-blue-900 dark:text-blue-100 mb-2", children: "Server-Side Mode" }), _jsx("p", { className: "text-sm text-blue-700 dark:text-blue-300 mb-2", children: "The table calls your callbacks when pagination, sorting, filtering, or search changes. You can then fetch fresh data from your API." }), _jsxs("div", { className: "text-xs text-blue-600 dark:text-blue-400 space-y-1", children: [_jsxs("div", { children: ["Current Page: ", currentPage] }), _jsxs("div", { children: ["Page Size: ", pageSize] }), _jsxs("div", { children: ["Total Records: ", totalRecords] }), _jsxs("div", { children: ["Sort:
|
|
704
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "p-4 bg-blue-50 dark:bg-blue-950 rounded-lg border border-blue-200 dark:border-blue-800", children: [_jsx("h3", { className: "font-semibold text-blue-900 dark:text-blue-100 mb-2", children: "Server-Side Mode" }), _jsx("p", { className: "text-sm text-blue-700 dark:text-blue-300 mb-2", children: "The table calls your callbacks when pagination, sorting, filtering, or search changes. You can then fetch fresh data from your API." }), _jsxs("div", { className: "text-xs text-blue-600 dark:text-blue-400 space-y-1", children: [_jsxs("div", { children: ["Current Page: ", currentPage] }), _jsxs("div", { children: ["Page Size: ", pageSize] }), _jsxs("div", { children: ["Total Records: ", totalRecords] }), _jsxs("div", { children: ["Sort:", " ", sortConfig
|
|
705
|
+
? `${String(sortConfig.key)} (${sortConfig.direction})`
|
|
706
|
+
: "None"] }), _jsxs("div", { children: ["Search: ", searchQuery || "None"] })] })] }), _jsx(DataTable, { data: users, columns: userColumns, isLoading: isLoading, pagination: {
|
|
709
707
|
page: currentPage,
|
|
710
708
|
pageSize: pageSize,
|
|
711
709
|
total: totalRecords,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DateRange } from "react-day-picker";
|
|
2
|
-
import { Calendar } from "../calendar
|
|
2
|
+
import { Calendar } from "../calendar";
|
|
3
3
|
export interface DatePickerProps extends Omit<React.ComponentProps<typeof Calendar>, "mode" | "selected" | "onSelect" | "className" | "required" | "disabled"> {
|
|
4
4
|
date?: Date;
|
|
5
5
|
onDateChange?: (date: Date | undefined) => void;
|
|
@@ -3,10 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { format } from "date-fns";
|
|
4
4
|
import { CalendarIcon } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Button } from "../button
|
|
7
|
-
import { Calendar } from "../calendar
|
|
6
|
+
import { Button } from "../button";
|
|
7
|
+
import { Calendar } from "../calendar";
|
|
8
8
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
9
|
-
import { Skeleton } from "../skeleton
|
|
9
|
+
import { Skeleton } from "../skeleton";
|
|
10
10
|
export function DatePicker({ date, onDateChange, placeholder = "Pick a date", disabled, buttonDisabled = false, className, buttonClassName, formatStr = "PPP", isLoading = false, ...props }) {
|
|
11
11
|
if (isLoading) {
|
|
12
12
|
return (_jsx(Skeleton, { className: cn("h-10 w-[280px] rounded-md", buttonClassName) }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DateRange } from "react-day-picker";
|
|
2
|
-
import type { Calendar } from "../calendar
|
|
2
|
+
import type { Calendar } from "../calendar";
|
|
3
3
|
export interface DatePickerProps extends Omit<React.ComponentProps<typeof Calendar>, "mode" | "selected" | "onSelect" | "className" | "required" | "disabled"> {
|
|
4
4
|
date?: Date;
|
|
5
5
|
onDateChange?: (date: Date | undefined) => void;
|
|
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
* Supports header, body, and footer sections.
|
|
7
7
|
*/
|
|
8
8
|
import { cn } from "../../lib/utils";
|
|
9
|
-
import { Skeleton } from "../skeleton
|
|
9
|
+
import { Skeleton } from "../skeleton";
|
|
10
10
|
/**
|
|
11
11
|
* Dialog skeleton component
|
|
12
12
|
*
|
|
@@ -3,6 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
+
import { Box } from "../box";
|
|
7
|
+
import { Text } from "../text";
|
|
6
8
|
function Dialog({ ...props }) {
|
|
7
9
|
return _jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
8
10
|
}
|
|
@@ -25,13 +27,13 @@ function DialogContent({ className, children, showCloseButton = true, size = "de
|
|
|
25
27
|
lg: "w-[90vw] max-w-2xl",
|
|
26
28
|
xl: "w-[90vw] max-w-4xl",
|
|
27
29
|
};
|
|
28
|
-
return (_jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { "data-slot": "dialog-content", className: cn("bg-card text-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-30 flex flex-col max-h-[90vh] translate-x-[-50%] translate-y-[-50%] rounded-lg border duration-200 theme-card", sizeClasses[size], className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", className: cn("absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none p-1 hover:bg-accent", "focus-ring"), children: [_jsx(X, { className: "size-5", "aria-hidden": "true" }), _jsx("span",
|
|
30
|
+
return (_jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { "data-slot": "dialog-content", className: cn("bg-card text-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-30 flex flex-col max-h-[90vh] translate-x-[-50%] translate-y-[-50%] rounded-lg border duration-200 theme-card", sizeClasses[size], className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", className: cn("absolute top-4 right-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none p-1 hover:bg-accent", "focus-ring"), children: [_jsx(X, { className: "size-5", "aria-hidden": "true" }), _jsx(Text, { as: "span", className: "sr-only", children: "Close" })] }))] })] }));
|
|
29
31
|
}
|
|
30
32
|
function DialogHeader({ className, ...props }) {
|
|
31
|
-
return (_jsx(
|
|
33
|
+
return (_jsx(Box, { "data-slot": "dialog-header", className: cn("flex flex-col gap-1.5 px-6 py-4 border-b", className), ...props }));
|
|
32
34
|
}
|
|
33
35
|
function DialogFooter({ className, ...props }) {
|
|
34
|
-
return (_jsx(
|
|
36
|
+
return (_jsx(Box, { "data-slot": "dialog-footer", className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end px-6 py-4 border-t bg-muted/50 rounded-b-lg", className), ...props }));
|
|
35
37
|
}
|
|
36
38
|
function DialogTitle({ className, translationKey, ...props }) {
|
|
37
39
|
return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("text-lg font-semibold leading-none tracking-tight text-foreground", className), ...props }));
|
|
@@ -40,6 +42,6 @@ function DialogDescription({ className, descriptionKey, ...props }) {
|
|
|
40
42
|
return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("text-sm leading-relaxed text-muted-foreground", className), ...props }));
|
|
41
43
|
}
|
|
42
44
|
function DialogBody({ className, ...props }) {
|
|
43
|
-
return (_jsx(
|
|
45
|
+
return (_jsx(Box, { "data-slot": "dialog-body", className: cn("flex-1 overflow-y-auto px-6 py-4 min-h-0", className), ...props }));
|
|
44
46
|
}
|
|
45
47
|
export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogBody, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from "../button";
|
|
3
3
|
import { Input } from "../input";
|
|
4
4
|
import { Label } from "../label";
|
|
5
|
-
import { Skeleton } from "../skeleton
|
|
5
|
+
import { Skeleton } from "../skeleton";
|
|
6
6
|
import { Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "./dialog";
|
|
7
7
|
const meta = {
|
|
8
8
|
title: "Overlay/Dialog",
|
|
@@ -30,7 +30,7 @@ export const ScrollingContent = {
|
|
|
30
30
|
render: () => (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Long Content" }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Terms of Service" }), _jsx(DialogDescription, { children: "Please read our terms of service carefully." })] }), _jsx(DialogBody, { children: Array.from({ length: 20 }).map(() => (_jsx("p", { className: "mb-4", children: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris." }, crypto.randomUUID()))) }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", children: "Decline" }), _jsx(Button, { children: "Accept" })] })] })] })),
|
|
31
31
|
};
|
|
32
32
|
export const LoadingSkeleton = {
|
|
33
|
-
render: () =>
|
|
33
|
+
render: () => _jsx(Skeleton, { className: "h-10 w-32 rounded-md" }),
|
|
34
34
|
parameters: {
|
|
35
35
|
docs: {
|
|
36
36
|
description: {
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* DnD Component - Drag and Drop primitives for @dnd-kit
|
|
3
3
|
* Provides consistent wrappers with animations, sortable support, and drag overlays
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import type { Modifier } from "@dnd-kit/core";
|
|
5
|
+
import type { Active, Collision, CollisionDetection, DndContextProps as DndKitContextProps, DragEndEvent, DraggableAttributes, DraggableSyntheticListeners, DragOverEvent, DragStartEvent, Modifier, Over, PointerActivationConstraint, UniqueIdentifier } from "@dnd-kit/core";
|
|
6
|
+
import { KeyboardSensor, PointerSensor, TouchSensor, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
|
|
7
|
+
import { type SortingStrategy, sortableKeyboardCoordinates, useSortable } from "@dnd-kit/sortable";
|
|
9
8
|
import type { Transform } from "@dnd-kit/utilities";
|
|
10
9
|
import * as React from "react";
|
|
11
10
|
type SyntheticListenerMap = DraggableSyntheticListeners;
|
|
@@ -37,7 +36,7 @@ export interface UseDragDropSensorsOptions {
|
|
|
37
36
|
keyboardCoordinateGetter?: typeof sortableKeyboardCoordinates;
|
|
38
37
|
}
|
|
39
38
|
declare function createDragDropSensors(options?: UseDragDropSensorsOptions): import("@dnd-kit/core").SensorDescriptor<import("@dnd-kit/core").SensorOptions>[];
|
|
40
|
-
export interface DragDropContextProps extends Omit<DndKitContextProps,
|
|
39
|
+
export interface DragDropContextProps extends Omit<DndKitContextProps, "sensors"> {
|
|
41
40
|
children: React.ReactNode;
|
|
42
41
|
sensors?: ReturnType<typeof createDragDropSensors>;
|
|
43
42
|
useSensors?: UseDragDropSensorsOptions;
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
"use client";
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
-
import { DndContext as DndKitContext,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { closestCenter, closestCorners, DndContext as DndKitContext, DragOverlay, KeyboardSensor, PointerSensor, pointerWithin, rectIntersection, TouchSensor, useDraggable, useDroppable, useSensor, useSensors, } from "@dnd-kit/core";
|
|
8
|
+
import { restrictToFirstScrollableAncestor, restrictToHorizontalAxis, restrictToParentElement, restrictToVerticalAxis, restrictToWindowEdges, } from "@dnd-kit/modifiers";
|
|
9
|
+
import { horizontalListSortingStrategy, rectSortingStrategy, rectSwappingStrategy, SortableContext as SortableContextKit, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from "@dnd-kit/sortable";
|
|
10
10
|
import { CSS } from "@dnd-kit/utilities";
|
|
11
11
|
import * as React from "react";
|
|
12
12
|
import { cn } from "../../lib/utils";
|
|
@@ -39,7 +39,7 @@ export const sortingStrategies = {
|
|
|
39
39
|
rectSwapping: rectSwappingStrategy,
|
|
40
40
|
};
|
|
41
41
|
function createDragDropSensors(options = {}) {
|
|
42
|
-
const { activationConstraint, keyboardCoordinateGetter = sortableKeyboardCoordinates } = options;
|
|
42
|
+
const { activationConstraint, keyboardCoordinateGetter = sortableKeyboardCoordinates, } = options;
|
|
43
43
|
const sensors = useSensors(useSensor(PointerSensor, {
|
|
44
44
|
activationConstraint,
|
|
45
45
|
}), useSensor(TouchSensor, {
|
|
@@ -99,7 +99,7 @@ const Draggable = React.forwardRef(({ children, className, id, disabled = false,
|
|
|
99
99
|
});
|
|
100
100
|
Draggable.displayName = "Draggable";
|
|
101
101
|
const SortableContext = React.forwardRef(({ children, items, strategy = verticalListSortingStrategy }, _ref) => {
|
|
102
|
-
const itemIds = React.useMemo(() => items.map((item) =>
|
|
102
|
+
const itemIds = React.useMemo(() => items.map((item) => typeof item === "object" && "id" in item ? item.id : item), [items]);
|
|
103
103
|
return (_jsx(SortableContextKit, { items: itemIds, strategy: strategy, children: children }));
|
|
104
104
|
});
|
|
105
105
|
SortableContext.displayName = "SortableContext";
|