@eifi1/ui-kit 0.7.0 → 0.8.0
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/README.md +32 -17
- package/dist/chart.d.ts +3 -2
- package/dist/components/alert-banner.d.ts +59 -10
- package/dist/components/alert-banner.js +114 -8
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +5 -0
- package/dist/components/button-group.d.ts +26 -0
- package/dist/components/button-group.js +49 -0
- package/dist/components/button-group.js.map +1 -0
- package/dist/components/calculator.d.ts +5 -0
- package/dist/components/chart-zoom.d.ts +63 -14
- package/dist/components/chart-zoom.js +82 -16
- package/dist/components/chart-zoom.js.map +1 -1
- package/dist/components/chip.d.ts +67 -2
- package/dist/components/chip.js +73 -8
- package/dist/components/chip.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +120 -0
- package/dist/components/confirm-dialog.js +96 -0
- package/dist/components/confirm-dialog.js.map +1 -0
- package/dist/components/copy-button.d.ts +62 -0
- package/dist/components/copy-button.js +95 -0
- package/dist/components/copy-button.js.map +1 -0
- package/dist/components/data-table-filter-popover.d.ts +1 -1
- package/dist/components/data-table-filters.d.ts +1 -1
- package/dist/components/data-table-pagination.d.ts +5 -1
- package/dist/components/data-table-pagination.js +71 -58
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-sort.d.ts +28 -5
- package/dist/components/data-table-sort.js +11 -7
- package/dist/components/data-table-sort.js.map +1 -1
- package/dist/components/data-table.d.ts +1 -1
- package/dist/components/data-table.js +544 -423
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +51 -5
- package/dist/components/date-picker.js +152 -40
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/description-list.d.ts +60 -0
- package/dist/components/description-list.js +112 -0
- package/dist/components/description-list.js.map +1 -0
- package/dist/components/disclosure.d.ts +37 -2
- package/dist/components/disclosure.js +14 -5
- package/dist/components/disclosure.js.map +1 -1
- package/dist/components/facing-pair.d.ts +2 -0
- package/dist/components/file-button.d.ts +19 -1
- package/dist/components/file-button.js +8 -1
- package/dist/components/file-button.js.map +1 -1
- package/dist/components/file-dropzone.d.ts +56 -9
- package/dist/components/file-dropzone.js +100 -70
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/floating-panel.d.ts +107 -0
- package/dist/components/floating-panel.js +206 -0
- package/dist/components/floating-panel.js.map +1 -0
- package/dist/components/full-bleed-dialog.d.ts +12 -1
- package/dist/components/full-bleed-dialog.js +26 -5
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/modal.d.ts +6 -2
- package/dist/components/modal.js +2 -1
- package/dist/components/modal.js.map +1 -1
- package/dist/components/number-field.d.ts +5 -0
- package/dist/components/number-input.d.ts +5 -0
- package/dist/components/numpad-sheet.d.ts +5 -0
- package/dist/components/progress-bar.d.ts +54 -0
- package/dist/components/progress-bar.js +94 -0
- package/dist/components/progress-bar.js.map +1 -0
- package/dist/components/scroll-area.d.ts +53 -0
- package/dist/components/scroll-area.js +86 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/separator.d.ts +23 -0
- package/dist/components/separator.js +24 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/series-chart-ticks.d.ts +34 -1
- package/dist/components/series-chart-ticks.js +83 -1
- package/dist/components/series-chart-ticks.js.map +1 -1
- package/dist/components/series-chart.d.ts +314 -19
- package/dist/components/series-chart.js +510 -120
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/settings-fields.d.ts +2 -0
- package/dist/components/skeleton.d.ts +36 -0
- package/dist/components/skeleton.js +35 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/stat-tile.d.ts +60 -6
- package/dist/components/stat-tile.js +60 -26
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/table.d.ts +83 -0
- package/dist/components/table.js +166 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/time-input.d.ts +2 -0
- package/dist/components/toggle-legend.d.ts +3 -2
- package/dist/components/toggle-legend.js +1 -1
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/tooltip.d.ts +10 -4
- package/dist/components/tooltip.js +23 -6
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/tree-view.d.ts +129 -0
- package/dist/components/tree-view.js +376 -0
- package/dist/components/tree-view.js.map +1 -0
- package/dist/components/treemap.d.ts +9 -2
- package/dist/components/treemap.js +2 -1
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/ui.d.ts +92 -14
- package/dist/components/ui.js +112 -30
- package/dist/components/ui.js.map +1 -1
- package/dist/components/use-table-state.d.ts +1 -1
- package/dist/{data-table-filters-noy0Abvi.d.ts → data-table-filters-CF1PXqjQ.d.ts} +73 -3
- package/dist/data-table.d.ts +2 -2
- package/dist/data-table.js.map +1 -1
- package/dist/hooks/use-copy-to-clipboard.d.ts +28 -0
- package/dist/hooks/use-copy-to-clipboard.js +81 -0
- package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
- package/dist/hooks/use-debounce.d.ts +43 -0
- package/dist/hooks/use-debounce.js +56 -0
- package/dist/hooks/use-debounce.js.map +1 -0
- package/dist/hooks/use-file-drop.d.ts +72 -0
- package/dist/hooks/use-file-drop.js +57 -0
- package/dist/hooks/use-file-drop.js.map +1 -0
- package/dist/i18n/defaults.d.ts +5 -0
- package/dist/i18n/defaults.js +7 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +17 -0
- package/dist/i18n/kit-labels.js +6 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/de-CH-informal.d.ts +43 -0
- package/dist/i18n/locales/de-CH-informal.js +8 -0
- package/dist/i18n/locales/de-CH-informal.js.map +1 -0
- package/dist/i18n/locales/de-CH.d.ts +5 -0
- package/dist/i18n/locales/de-CH.js +1 -14
- package/dist/i18n/locales/de-CH.js.map +1 -1
- package/dist/i18n/locales/de-informal.d.ts +64 -0
- package/dist/i18n/locales/de-informal.js +37 -0
- package/dist/i18n/locales/de-informal.js.map +1 -0
- package/dist/i18n/locales/de.d.ts +5 -0
- package/dist/i18n/locales/de.js +25 -0
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +5 -0
- package/dist/i18n/locales/es.js +25 -0
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +5 -0
- package/dist/i18n/locales/fr.js +25 -0
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +5 -0
- package/dist/i18n/locales/hu.js +25 -0
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +5 -0
- package/dist/i18n/locales/it.js +25 -0
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +5 -0
- package/dist/i18n/locales/zh.js +25 -0
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/swiss.d.ts +13 -0
- package/dist/i18n/swiss.js +19 -0
- package/dist/i18n/swiss.js.map +1 -0
- package/dist/index.d.ts +26 -11
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/dates.d.ts +37 -1
- package/dist/lib/dates.js +19 -0
- package/dist/lib/dates.js.map +1 -1
- package/dist/rhf/form.d.ts +2 -0
- package/dist/rhf.d.ts +2 -0
- package/dist/search/command-palette.d.ts +15 -1
- package/dist/search/command-palette.js +10 -2
- package/dist/search/command-palette.js.map +1 -1
- package/dist/shell/app-shell.js +2 -2
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +35 -2
- package/dist/wizard/stepper-nav.js +54 -22
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +107 -5
- package/dist/wizard/types.js +2 -1
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.js +141 -21
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/wizard-summary.d.ts +10 -2
- package/dist/wizard/wizard-summary.js +3 -1
- package/dist/wizard/wizard-summary.js.map +1 -1
- package/dist/wizard.d.ts +4 -1
- package/dist/wizard.js.map +1 -1
- package/package.json +1 -1
- package/src/components/alert-banner.tsx +211 -20
- package/src/components/button-group.tsx +75 -0
- package/src/components/chart-zoom.tsx +158 -20
- package/src/components/chip.tsx +160 -9
- package/src/components/confirm-dialog.tsx +242 -0
- package/src/components/copy-button.tsx +158 -0
- package/src/components/data-table-pagination.tsx +19 -6
- package/src/components/data-table-sort.ts +49 -10
- package/src/components/data-table.tsx +293 -24
- package/src/components/date-picker.tsx +262 -57
- package/src/components/description-list.tsx +174 -0
- package/src/components/disclosure.tsx +58 -5
- package/src/components/file-button.tsx +22 -2
- package/src/components/file-dropzone.tsx +198 -100
- package/src/components/floating-panel.tsx +341 -0
- package/src/components/full-bleed-dialog.tsx +48 -5
- package/src/components/modal.tsx +9 -2
- package/src/components/progress-bar.tsx +163 -0
- package/src/components/scroll-area.tsx +129 -0
- package/src/components/separator.tsx +37 -0
- package/src/components/series-chart-ticks.ts +135 -0
- package/src/components/series-chart.tsx +934 -67
- package/src/components/skeleton.tsx +65 -0
- package/src/components/stat-tile.tsx +160 -27
- package/src/components/table.tsx +263 -0
- package/src/components/toggle-legend.tsx +4 -3
- package/src/components/tooltip.tsx +40 -12
- package/src/components/tree-view.tsx +589 -0
- package/src/components/treemap.tsx +10 -2
- package/src/components/ui.tsx +268 -42
- package/src/data-table.ts +2 -0
- package/src/hooks/use-copy-to-clipboard.ts +122 -0
- package/src/hooks/use-debounce.ts +105 -0
- package/src/hooks/use-file-drop.ts +123 -0
- package/src/i18n/defaults.ts +6 -0
- package/src/i18n/kit-labels.tsx +19 -0
- package/src/i18n/locales/de-CH-informal.ts +10 -0
- package/src/i18n/locales/de-CH.ts +1 -16
- package/src/i18n/locales/de-informal.ts +61 -0
- package/src/i18n/locales/de.ts +25 -0
- package/src/i18n/locales/es.ts +25 -0
- package/src/i18n/locales/fr.ts +25 -0
- package/src/i18n/locales/hu.ts +25 -0
- package/src/i18n/locales/it.ts +25 -0
- package/src/i18n/locales/zh.ts +25 -0
- package/src/i18n/swiss.ts +25 -0
- package/src/index.ts +29 -0
- package/src/lib/dates.ts +48 -0
- package/src/search/command-palette.tsx +29 -3
- package/src/shell/app-shell.tsx +2 -2
- package/src/wizard/stepper-nav.tsx +102 -28
- package/src/wizard/types.ts +106 -4
- package/src/wizard/use-wizard.ts +211 -31
- package/src/wizard/wizard-summary.tsx +24 -12
- package/src/wizard.ts +3 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes } from 'react';
|
|
3
|
+
import { ButtonVariant, IconButtonSize } from './ui.js';
|
|
4
|
+
import { TooltipSide } from './tooltip.js';
|
|
5
|
+
import '../hooks/use-anchored-rect.js';
|
|
6
|
+
|
|
7
|
+
/** The words a copy button says. The visible three are short on purpose (they
|
|
8
|
+
* replace the button's own text in the `label` variant); the two announcements
|
|
9
|
+
* are the sentences a screen reader hears, since the button's focus never moves. */
|
|
10
|
+
interface CopyButtonLabels {
|
|
11
|
+
copy: string;
|
|
12
|
+
copied: string;
|
|
13
|
+
failed: string;
|
|
14
|
+
copiedAnnouncement: string;
|
|
15
|
+
failedAnnouncement: string;
|
|
16
|
+
}
|
|
17
|
+
declare const DEFAULT_COPY_BUTTON_LABELS: CopyButtonLabels;
|
|
18
|
+
interface CopyButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "onClick"> {
|
|
19
|
+
/** What to copy. A function is read at click time — for a value that is expensive
|
|
20
|
+
* to build (a CSV of the table) or that changes under the button. */
|
|
21
|
+
text: string | (() => string);
|
|
22
|
+
/** `icon` (default): a square icon button whose tooltip states the result.
|
|
23
|
+
* `label`: a text button whose words change to the result. */
|
|
24
|
+
variant?: "icon" | "label";
|
|
25
|
+
/** The idle accessible name — and, in the `label` variant, the visible text:
|
|
26
|
+
* "Copy IBAN" says WHAT is copied, which a row of three copy icons needs. Default
|
|
27
|
+
* `copyButton.copy`. */
|
|
28
|
+
label?: string;
|
|
29
|
+
/** The button's own look. Default: `ghost` for the icon, `secondary` for the label. */
|
|
30
|
+
buttonVariant?: ButtonVariant;
|
|
31
|
+
/** Icon variant only. */
|
|
32
|
+
size?: IconButtonSize;
|
|
33
|
+
/** Icon variant only: where the result tooltip opens. */
|
|
34
|
+
tooltipSide?: TooltipSide;
|
|
35
|
+
/** Pass through to the tooltip — needed inside a scroll container (see Tooltip). */
|
|
36
|
+
tooltipPortal?: boolean;
|
|
37
|
+
/** ms until the button returns to idle. Default 2000. */
|
|
38
|
+
resetAfter?: number;
|
|
39
|
+
/** Called with the real outcome once the copy settles. */
|
|
40
|
+
onCopied?: (ok: boolean) => void;
|
|
41
|
+
labels?: Partial<CopyButtonLabels>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A button that copies a value and tells the truth about whether it did.
|
|
45
|
+
*
|
|
46
|
+
* keksdose asked for it after two of its own copy buttons said "Copied" on a build
|
|
47
|
+
* where the copy had failed (no Clipboard API over plain http). This one takes its
|
|
48
|
+
* state from {@link useCopyToClipboard}, which reads the result, and has a `failed`
|
|
49
|
+
* state that looks and sounds different from success.
|
|
50
|
+
*
|
|
51
|
+
* The result is spoken through {@link useAnnounce}: activating the button moves no
|
|
52
|
+
* focus, so without a live region a screen-reader user hears nothing at all. A
|
|
53
|
+
* failure goes through an ASSERTIVE region and a success through a polite one — the
|
|
54
|
+
* failure is the news that changes what they do next.
|
|
55
|
+
*
|
|
56
|
+
* The icon variant keeps the SAME accessible name in every state. A button renaming
|
|
57
|
+
* itself under the focus is announced inconsistently across readers; the live region
|
|
58
|
+
* is the channel that is actually heard.
|
|
59
|
+
*/
|
|
60
|
+
declare function CopyButton({ text, variant, label, buttonVariant, size, tooltipSide, tooltipPortal, resetAfter, onCopied, labels, className, disabled, ...rest }: CopyButtonProps): react.JSX.Element;
|
|
61
|
+
|
|
62
|
+
export { CopyButton, type CopyButtonLabels, type CopyButtonProps, DEFAULT_COPY_BUTTON_LABELS };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Check, Copy, X } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { useKitLabels } from "../i18n/kit-labels.js";
|
|
6
|
+
import { useAnnounce } from "../hooks/use-announce.js";
|
|
7
|
+
import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard.js";
|
|
8
|
+
import { Button, IconButton } from "./ui.js";
|
|
9
|
+
import { Tooltip } from "./tooltip.js";
|
|
10
|
+
const DEFAULT_COPY_BUTTON_LABELS = {
|
|
11
|
+
copy: "Copy",
|
|
12
|
+
copied: "Copied",
|
|
13
|
+
failed: "Couldn\u2019t copy",
|
|
14
|
+
copiedAnnouncement: "Copied to clipboard",
|
|
15
|
+
failedAnnouncement: "Couldn\u2019t copy to the clipboard"
|
|
16
|
+
};
|
|
17
|
+
const ICONS = { idle: Copy, copied: Check, failed: X };
|
|
18
|
+
function CopyButton({
|
|
19
|
+
text,
|
|
20
|
+
variant = "icon",
|
|
21
|
+
label,
|
|
22
|
+
buttonVariant,
|
|
23
|
+
size = "sm",
|
|
24
|
+
tooltipSide = "top",
|
|
25
|
+
tooltipPortal = false,
|
|
26
|
+
resetAfter = 2e3,
|
|
27
|
+
onCopied,
|
|
28
|
+
labels,
|
|
29
|
+
className,
|
|
30
|
+
disabled,
|
|
31
|
+
...rest
|
|
32
|
+
}) {
|
|
33
|
+
const words = useKitLabels("copyButton", DEFAULT_COPY_BUTTON_LABELS, labels);
|
|
34
|
+
const { state, copy } = useCopyToClipboard({ resetAfter });
|
|
35
|
+
const polite = useAnnounce();
|
|
36
|
+
const assertive = useAnnounce({ politeness: "assertive" });
|
|
37
|
+
const idleText = label ?? words.copy;
|
|
38
|
+
const stateText = state === "copied" ? words.copied : state === "failed" ? words.failed : idleText;
|
|
39
|
+
const Icon = ICONS[state];
|
|
40
|
+
const iconTone = state === "copied" ? "text-[var(--success)]" : state === "failed" ? "text-[var(--danger)]" : void 0;
|
|
41
|
+
const onClick = async () => {
|
|
42
|
+
const ok = await copy(typeof text === "function" ? text() : text);
|
|
43
|
+
if (ok) polite.announce(words.copiedAnnouncement);
|
|
44
|
+
else assertive.announce(words.failedAnnouncement);
|
|
45
|
+
onCopied?.(ok);
|
|
46
|
+
};
|
|
47
|
+
const regions = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48
|
+
/* @__PURE__ */ jsx("span", { ...polite.regionProps }),
|
|
49
|
+
/* @__PURE__ */ jsx("span", { ...assertive.regionProps })
|
|
50
|
+
] });
|
|
51
|
+
if (variant === "label") {
|
|
52
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
53
|
+
/* @__PURE__ */ jsxs(
|
|
54
|
+
Button,
|
|
55
|
+
{
|
|
56
|
+
type: "button",
|
|
57
|
+
...rest,
|
|
58
|
+
disabled,
|
|
59
|
+
variant: buttonVariant ?? "secondary",
|
|
60
|
+
"data-state": state,
|
|
61
|
+
onClick,
|
|
62
|
+
className,
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: cn("size-4 shrink-0", iconTone) }),
|
|
65
|
+
stateText
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
regions
|
|
70
|
+
] });
|
|
71
|
+
}
|
|
72
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73
|
+
/* @__PURE__ */ jsx(Tooltip, { label: stateText, side: tooltipSide, portal: tooltipPortal, children: /* @__PURE__ */ jsx(
|
|
74
|
+
IconButton,
|
|
75
|
+
{
|
|
76
|
+
type: "button",
|
|
77
|
+
...rest,
|
|
78
|
+
disabled,
|
|
79
|
+
"aria-label": idleText,
|
|
80
|
+
variant: buttonVariant ?? "ghost",
|
|
81
|
+
size,
|
|
82
|
+
"data-state": state,
|
|
83
|
+
onClick,
|
|
84
|
+
className: cn(iconTone, className),
|
|
85
|
+
children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": true })
|
|
86
|
+
}
|
|
87
|
+
) }),
|
|
88
|
+
regions
|
|
89
|
+
] });
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
CopyButton,
|
|
93
|
+
DEFAULT_COPY_BUTTON_LABELS
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=copy-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/copy-button.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\nimport { Check, Copy, X } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { useKitLabels } from \"../i18n/kit-labels\";\nimport { useAnnounce } from \"../hooks/use-announce\";\nimport { useCopyToClipboard } from \"../hooks/use-copy-to-clipboard\";\nimport type { CopyState } from \"../hooks/use-copy-to-clipboard\";\nimport { Button, IconButton } from \"./ui\";\nimport type { ButtonVariant, IconButtonSize } from \"./ui\";\nimport { Tooltip } from \"./tooltip\";\nimport type { TooltipSide } from \"./tooltip\";\n\n/** The words a copy button says. The visible three are short on purpose (they\n * replace the button's own text in the `label` variant); the two announcements\n * are the sentences a screen reader hears, since the button's focus never moves. */\nexport interface CopyButtonLabels {\n copy: string;\n copied: string;\n failed: string;\n copiedAnnouncement: string;\n failedAnnouncement: string;\n}\n\nexport const DEFAULT_COPY_BUTTON_LABELS: CopyButtonLabels = {\n copy: \"Copy\",\n copied: \"Copied\",\n failed: \"Couldn’t copy\",\n copiedAnnouncement: \"Copied to clipboard\",\n failedAnnouncement: \"Couldn’t copy to the clipboard\",\n};\n\nexport interface CopyButtonProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\" | \"onClick\"> {\n /** What to copy. A function is read at click time — for a value that is expensive\n * to build (a CSV of the table) or that changes under the button. */\n text: string | (() => string);\n /** `icon` (default): a square icon button whose tooltip states the result.\n * `label`: a text button whose words change to the result. */\n variant?: \"icon\" | \"label\";\n /** The idle accessible name — and, in the `label` variant, the visible text:\n * \"Copy IBAN\" says WHAT is copied, which a row of three copy icons needs. Default\n * `copyButton.copy`. */\n label?: string;\n /** The button's own look. Default: `ghost` for the icon, `secondary` for the label. */\n buttonVariant?: ButtonVariant;\n /** Icon variant only. */\n size?: IconButtonSize;\n /** Icon variant only: where the result tooltip opens. */\n tooltipSide?: TooltipSide;\n /** Pass through to the tooltip — needed inside a scroll container (see Tooltip). */\n tooltipPortal?: boolean;\n /** ms until the button returns to idle. Default 2000. */\n resetAfter?: number;\n /** Called with the real outcome once the copy settles. */\n onCopied?: (ok: boolean) => void;\n labels?: Partial<CopyButtonLabels>;\n}\n\nconst ICONS: Record<CopyState, typeof Copy> = { idle: Copy, copied: Check, failed: X };\n\n/**\n * A button that copies a value and tells the truth about whether it did.\n *\n * keksdose asked for it after two of its own copy buttons said \"Copied\" on a build\n * where the copy had failed (no Clipboard API over plain http). This one takes its\n * state from {@link useCopyToClipboard}, which reads the result, and has a `failed`\n * state that looks and sounds different from success.\n *\n * The result is spoken through {@link useAnnounce}: activating the button moves no\n * focus, so without a live region a screen-reader user hears nothing at all. A\n * failure goes through an ASSERTIVE region and a success through a polite one — the\n * failure is the news that changes what they do next.\n *\n * The icon variant keeps the SAME accessible name in every state. A button renaming\n * itself under the focus is announced inconsistently across readers; the live region\n * is the channel that is actually heard.\n */\nexport function CopyButton({\n text,\n variant = \"icon\",\n label,\n buttonVariant,\n size = \"sm\",\n tooltipSide = \"top\",\n tooltipPortal = false,\n resetAfter = 2000,\n onCopied,\n labels,\n className,\n disabled,\n ...rest\n}: CopyButtonProps) {\n const words = useKitLabels(\"copyButton\", DEFAULT_COPY_BUTTON_LABELS, labels);\n const { state, copy } = useCopyToClipboard({ resetAfter });\n const polite = useAnnounce();\n const assertive = useAnnounce({ politeness: \"assertive\" });\n\n const idleText = label ?? words.copy;\n const stateText = state === \"copied\" ? words.copied : state === \"failed\" ? words.failed : idleText;\n const Icon = ICONS[state];\n const iconTone =\n state === \"copied\" ? \"text-[var(--success)]\" : state === \"failed\" ? \"text-[var(--danger)]\" : undefined;\n\n const onClick = async () => {\n const ok = await copy(typeof text === \"function\" ? text() : text);\n if (ok) polite.announce(words.copiedAnnouncement);\n else assertive.announce(words.failedAnnouncement);\n onCopied?.(ok);\n };\n\n const regions = (\n <>\n <span {...polite.regionProps} />\n <span {...assertive.regionProps} />\n </>\n );\n\n if (variant === \"label\") {\n return (\n <>\n <Button\n type=\"button\"\n {...rest}\n disabled={disabled}\n variant={buttonVariant ?? \"secondary\"}\n data-state={state}\n onClick={onClick}\n className={className}\n >\n <Icon aria-hidden className={cn(\"size-4 shrink-0\", iconTone)} />\n {stateText}\n </Button>\n {regions}\n </>\n );\n }\n\n return (\n <>\n <Tooltip label={stateText} side={tooltipSide} portal={tooltipPortal}>\n <IconButton\n type=\"button\"\n {...rest}\n disabled={disabled}\n aria-label={idleText}\n variant={buttonVariant ?? \"ghost\"}\n size={size}\n data-state={state}\n onClick={onClick}\n className={cn(iconTone, className)}\n >\n <Icon aria-hidden />\n </IconButton>\n </Tooltip>\n {regions}\n </>\n );\n}\n"],"mappings":";AA+GI,mBACE,KADF;AA9GJ,SAAS,OAAO,MAAM,SAAS;AAC/B,SAAS,UAAU;AACnB,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AAEnC,SAAS,QAAQ,kBAAkB;AAEnC,SAAS,eAAe;AAcjB,MAAM,6BAA+C;AAAA,EAC1D,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,oBAAoB;AAAA,EACpB,oBAAoB;AACtB;AA6BA,MAAM,QAAwC,EAAE,MAAM,MAAM,QAAQ,OAAO,QAAQ,EAAE;AAmB9E,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,QAAQ,aAAa,cAAc,4BAA4B,MAAM;AAC3E,QAAM,EAAE,OAAO,KAAK,IAAI,mBAAmB,EAAE,WAAW,CAAC;AACzD,QAAM,SAAS,YAAY;AAC3B,QAAM,YAAY,YAAY,EAAE,YAAY,YAAY,CAAC;AAEzD,QAAM,WAAW,SAAS,MAAM;AAChC,QAAM,YAAY,UAAU,WAAW,MAAM,SAAS,UAAU,WAAW,MAAM,SAAS;AAC1F,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,WACJ,UAAU,WAAW,0BAA0B,UAAU,WAAW,yBAAyB;AAE/F,QAAM,UAAU,YAAY;AAC1B,UAAM,KAAK,MAAM,KAAK,OAAO,SAAS,aAAa,KAAK,IAAI,IAAI;AAChE,QAAI,GAAI,QAAO,SAAS,MAAM,kBAAkB;AAAA,QAC3C,WAAU,SAAS,MAAM,kBAAkB;AAChD,eAAW,EAAE;AAAA,EACf;AAEA,QAAM,UACJ,iCACE;AAAA,wBAAC,UAAM,GAAG,OAAO,aAAa;AAAA,IAC9B,oBAAC,UAAM,GAAG,UAAU,aAAa;AAAA,KACnC;AAGF,MAAI,YAAY,SAAS;AACvB,WACE,iCACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACJ,GAAG;AAAA,UACJ;AAAA,UACA,SAAS,iBAAiB;AAAA,UAC1B,cAAY;AAAA,UACZ;AAAA,UACA;AAAA,UAEA;AAAA,gCAAC,QAAK,eAAW,MAAC,WAAW,GAAG,mBAAmB,QAAQ,GAAG;AAAA,YAC7D;AAAA;AAAA;AAAA,MACH;AAAA,MACC;AAAA,OACH;AAAA,EAEJ;AAEA,SACE,iCACE;AAAA,wBAAC,WAAQ,OAAO,WAAW,MAAM,aAAa,QAAQ,eACpD;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACJ,GAAG;AAAA,QACJ;AAAA,QACA,cAAY;AAAA,QACZ,SAAS,iBAAiB;AAAA,QAC1B;AAAA,QACA,cAAY;AAAA,QACZ;AAAA,QACA,WAAW,GAAG,UAAU,SAAS;AAAA,QAEjC,8BAAC,QAAK,eAAW,MAAC;AAAA;AAAA,IACpB,GACF;AAAA,IACC;AAAA,KACH;AAEJ;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { b as DataTableColumn, e as FilterValue } from '../data-table-filters-CF1PXqjQ.js';
|
|
3
3
|
import { DataTableLabels } from './data-table-labels.js';
|
|
4
4
|
import './data-table-sort.js';
|
|
5
5
|
import './swipeable-row.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as ColumnFilter,
|
|
1
|
+
export { C as ColumnFilter, e as FilterValue, f as decodeFilterValue, g as decodeFilterValueOfType, h as defaultFilterState, i as encodeFilterValue, j as isFilterActive, r as resolveFilter, k as rowMatches } from '../data-table-filters-CF1PXqjQ.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
import './data-table-sort.js';
|
|
4
4
|
import './swipeable-row.js';
|
|
@@ -15,9 +15,13 @@ interface PaginationProps {
|
|
|
15
15
|
labels?: Partial<DataTableLabels>;
|
|
16
16
|
/** For the page numbers and page-size options; falls back to the provider's. */
|
|
17
17
|
locale?: string;
|
|
18
|
+
/** `"compact"` for a pager under a compact {@link DataTable} (lenkbank's in-card
|
|
19
|
+
* tables): a slimmer footer and page buttons, so the pager is not the tallest row
|
|
20
|
+
* of a table that was made compact on purpose. */
|
|
21
|
+
density?: "comfortable" | "compact";
|
|
18
22
|
}
|
|
19
23
|
/** Footer for {@link DataTable}: range summary, page-size select, and a
|
|
20
24
|
* windowed page-number strip (first/last + ±2 around the current page). */
|
|
21
|
-
declare function Pagination({ page, totalPages, pageSize, total, onPage, onPageSize, labels: labelsProp, locale: localeProp, }: PaginationProps): react.JSX.Element;
|
|
25
|
+
declare function Pagination({ page, totalPages, pageSize, total, onPage, onPageSize, labels: labelsProp, locale: localeProp, density, }: PaginationProps): react.JSX.Element;
|
|
22
26
|
|
|
23
27
|
export { PAGE_SIZE_OPTIONS, Pagination };
|
|
@@ -14,8 +14,10 @@ function Pagination({
|
|
|
14
14
|
onPage,
|
|
15
15
|
onPageSize,
|
|
16
16
|
labels: labelsProp,
|
|
17
|
-
locale: localeProp
|
|
17
|
+
locale: localeProp,
|
|
18
|
+
density = "comfortable"
|
|
18
19
|
}) {
|
|
20
|
+
const compact = density === "compact";
|
|
19
21
|
const labels = useKitLabels("dataTable", DEFAULT_DATA_TABLE_LABELS, labelsProp);
|
|
20
22
|
const locale = useKitLocale(localeProp);
|
|
21
23
|
const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
@@ -33,64 +35,75 @@ function Pagination({
|
|
|
33
35
|
if (idx > 0 && p - visible[idx - 1] > 1) items.push("ellipsis");
|
|
34
36
|
items.push(p);
|
|
35
37
|
});
|
|
36
|
-
return /* @__PURE__ */ jsxs(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
onChange: (e) => onPageSize(e.target.value === "all" ? Infinity : Number(e.target.value)),
|
|
44
|
-
className: "rounded border border-[var(--border)] bg-[var(--bg-surface)] px-1 py-0.5 text-xs",
|
|
45
|
-
"aria-label": labels.pageSize,
|
|
46
|
-
children: [
|
|
47
|
-
PAGE_SIZE_OPTIONS.map((n) => /* @__PURE__ */ jsx("option", { value: n, children: num.format(n) }, n)),
|
|
48
|
-
/* @__PURE__ */ jsx("option", { value: "all", children: labels.pageSizeAll })
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
] }),
|
|
53
|
-
pageSize !== Infinity && totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
54
|
-
/* @__PURE__ */ jsx(
|
|
55
|
-
"button",
|
|
56
|
-
{
|
|
57
|
-
type: "button",
|
|
58
|
-
onClick: () => onPage(Math.max(0, page - 1)),
|
|
59
|
-
disabled: page === 0,
|
|
60
|
-
className: "rounded p-1 hover:bg-[var(--bg-hover)] disabled:opacity-40",
|
|
61
|
-
"aria-label": labels.prevPage,
|
|
62
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4 rtl:-scale-x-100" })
|
|
63
|
-
}
|
|
38
|
+
return /* @__PURE__ */ jsxs(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
"data-density": density,
|
|
42
|
+
className: cn(
|
|
43
|
+
"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--border)] text-xs text-[var(--text-secondary)]",
|
|
44
|
+
compact ? "px-2 py-1" : "px-3 py-2"
|
|
64
45
|
),
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
48
|
+
/* @__PURE__ */ jsx("span", { children: pageSize === Infinity ? labels.rowCount(total) : labels.pageRange(page * pageSize + 1, Math.min(total, (page + 1) * pageSize), total) }),
|
|
49
|
+
onPageSize && /* @__PURE__ */ jsxs(
|
|
50
|
+
"select",
|
|
51
|
+
{
|
|
52
|
+
value: pageSize === Infinity ? "all" : pageSize,
|
|
53
|
+
onChange: (e) => onPageSize(e.target.value === "all" ? Infinity : Number(e.target.value)),
|
|
54
|
+
className: "rounded border border-[var(--border)] bg-[var(--bg-surface)] px-1 py-0.5 text-xs",
|
|
55
|
+
"aria-label": labels.pageSize,
|
|
56
|
+
children: [
|
|
57
|
+
PAGE_SIZE_OPTIONS.map((n) => /* @__PURE__ */ jsx("option", { value: n, children: num.format(n) }, n)),
|
|
58
|
+
/* @__PURE__ */ jsx("option", { value: "all", children: labels.pageSizeAll })
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
] }),
|
|
63
|
+
pageSize !== Infinity && totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"button",
|
|
66
|
+
{
|
|
67
|
+
type: "button",
|
|
68
|
+
onClick: () => onPage(Math.max(0, page - 1)),
|
|
69
|
+
disabled: page === 0,
|
|
70
|
+
className: cn("rounded hover:bg-[var(--bg-hover)] disabled:opacity-40", compact ? "p-0.5" : "p-1"),
|
|
71
|
+
"aria-label": labels.prevPage,
|
|
72
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: cn("rtl:-scale-x-100", compact ? "size-3.5" : "size-4") })
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
items.map(
|
|
76
|
+
(it, i) => it === "ellipsis" ? /* @__PURE__ */ jsx("span", { className: "px-1 text-[var(--text-placeholder)]", children: "\u2026" }, `e${i}`) : /* @__PURE__ */ jsx(
|
|
77
|
+
"button",
|
|
78
|
+
{
|
|
79
|
+
type: "button",
|
|
80
|
+
onClick: () => onPage(it),
|
|
81
|
+
"aria-current": it === page ? "page" : void 0,
|
|
82
|
+
className: cn(
|
|
83
|
+
"rounded",
|
|
84
|
+
compact ? "min-w-6 px-1.5 py-0" : "min-w-7 px-2 py-0.5",
|
|
85
|
+
it === page ? "bg-[var(--bg-inverse)] text-[var(--text-inverse)]" : "hover:bg-[var(--bg-hover)]"
|
|
86
|
+
),
|
|
87
|
+
children: num.format(it + 1)
|
|
88
|
+
},
|
|
89
|
+
it
|
|
90
|
+
)
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"button",
|
|
94
|
+
{
|
|
95
|
+
type: "button",
|
|
96
|
+
onClick: () => onPage(Math.min(totalPages - 1, page + 1)),
|
|
97
|
+
disabled: page >= totalPages - 1,
|
|
98
|
+
className: cn("rounded hover:bg-[var(--bg-hover)] disabled:opacity-40", compact ? "p-0.5" : "p-1"),
|
|
99
|
+
"aria-label": labels.nextPage,
|
|
100
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn("rtl:-scale-x-100", compact ? "size-3.5" : "size-4") })
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
] })
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
);
|
|
94
107
|
}
|
|
95
108
|
export {
|
|
96
109
|
PAGE_SIZE_OPTIONS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table-pagination.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { DEFAULT_DATA_TABLE_LABELS, type DataTableLabels } from \"./data-table-labels\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\n\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200] as const;\n\ninterface PaginationProps {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n onPage: (p: number) => void;\n /** Omit when the page size is not the user's to change (a server that fixes it):\n * the select is then not rendered at all, rather than rendered and inert. */\n onPageSize?: (n: number) => void;\n /** Over `dataTable` from `<UiKitProvider labels>`, over the English defaults. */\n labels?: Partial<DataTableLabels>;\n /** For the page numbers and page-size options; falls back to the provider's. */\n locale?: string;\n}\n\n/** Footer for {@link DataTable}: range summary, page-size select, and a\n * windowed page-number strip (first/last + ±2 around the current page). */\nexport function Pagination({\n page,\n totalPages,\n pageSize,\n total,\n onPage,\n onPageSize,\n labels: labelsProp,\n locale: localeProp,\n}: PaginationProps) {\n // prop > provider > English, like every other kit component. This defaulted straight\n // to the English object, so a standalone pager under a translated provider still\n // said \"Rows per page\" — only the pager INSIDE a DataTable was translated, because\n // the table resolved the provider's labels and handed them down.\n const labels = useKitLabels(\"dataTable\", DEFAULT_DATA_TABLE_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n // The bare numbers on the strip and in the select are text too: `String(n)` is\n // always ASCII digits, which is wrong for a locale that writes its own. The range\n // summary is not formatted here — `pageRange` / `rowCount` take NUMBERS so the\n // translation can format them itself, alongside the words around them.\n const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const visible = useMemo(() => {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i);\n const set = new Set<number>([0, totalPages - 1, page]);\n for (let d = 1; d <= 2; d++) {\n if (page - d >= 0) set.add(page - d);\n if (page + d <= totalPages - 1) set.add(page + d);\n }\n return Array.from(set).sort((a, b) => a - b);\n }, [page, totalPages]);\n\n const items: (number | \"ellipsis\")[] = [];\n visible.forEach((p, idx) => {\n if (idx > 0 && p - visible[idx - 1] > 1) items.push(\"ellipsis\");\n items.push(p);\n });\n\n return (\n <div
|
|
1
|
+
{"version":3,"sources":["../../src/components/data-table-pagination.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { DEFAULT_DATA_TABLE_LABELS, type DataTableLabels } from \"./data-table-labels\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\n\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200] as const;\n\ninterface PaginationProps {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n onPage: (p: number) => void;\n /** Omit when the page size is not the user's to change (a server that fixes it):\n * the select is then not rendered at all, rather than rendered and inert. */\n onPageSize?: (n: number) => void;\n /** Over `dataTable` from `<UiKitProvider labels>`, over the English defaults. */\n labels?: Partial<DataTableLabels>;\n /** For the page numbers and page-size options; falls back to the provider's. */\n locale?: string;\n /** `\"compact\"` for a pager under a compact {@link DataTable} (lenkbank's in-card\n * tables): a slimmer footer and page buttons, so the pager is not the tallest row\n * of a table that was made compact on purpose. */\n density?: \"comfortable\" | \"compact\";\n}\n\n/** Footer for {@link DataTable}: range summary, page-size select, and a\n * windowed page-number strip (first/last + ±2 around the current page). */\nexport function Pagination({\n page,\n totalPages,\n pageSize,\n total,\n onPage,\n onPageSize,\n labels: labelsProp,\n locale: localeProp,\n density = \"comfortable\",\n}: PaginationProps) {\n const compact = density === \"compact\";\n // prop > provider > English, like every other kit component. This defaulted straight\n // to the English object, so a standalone pager under a translated provider still\n // said \"Rows per page\" — only the pager INSIDE a DataTable was translated, because\n // the table resolved the provider's labels and handed them down.\n const labels = useKitLabels(\"dataTable\", DEFAULT_DATA_TABLE_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n // The bare numbers on the strip and in the select are text too: `String(n)` is\n // always ASCII digits, which is wrong for a locale that writes its own. The range\n // summary is not formatted here — `pageRange` / `rowCount` take NUMBERS so the\n // translation can format them itself, alongside the words around them.\n const num = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const visible = useMemo(() => {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i);\n const set = new Set<number>([0, totalPages - 1, page]);\n for (let d = 1; d <= 2; d++) {\n if (page - d >= 0) set.add(page - d);\n if (page + d <= totalPages - 1) set.add(page + d);\n }\n return Array.from(set).sort((a, b) => a - b);\n }, [page, totalPages]);\n\n const items: (number | \"ellipsis\")[] = [];\n visible.forEach((p, idx) => {\n if (idx > 0 && p - visible[idx - 1] > 1) items.push(\"ellipsis\");\n items.push(p);\n });\n\n return (\n <div\n data-density={density}\n className={cn(\n \"flex flex-wrap items-center justify-between gap-2 border-t border-[var(--border)] text-xs text-[var(--text-secondary)]\",\n compact ? \"px-2 py-1\" : \"px-3 py-2\",\n )}\n >\n <div className=\"flex items-center gap-2\">\n <span>\n {pageSize === Infinity\n ? labels.rowCount(total)\n : labels.pageRange(page * pageSize + 1, Math.min(total, (page + 1) * pageSize), total)}\n </span>\n {onPageSize && (\n <select\n value={pageSize === Infinity ? \"all\" : pageSize}\n onChange={(e) =>\n onPageSize(e.target.value === \"all\" ? Infinity : Number(e.target.value))\n }\n className=\"rounded border border-[var(--border)] bg-[var(--bg-surface)] px-1 py-0.5 text-xs\"\n aria-label={labels.pageSize}\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>\n {num.format(n)}\n </option>\n ))}\n <option value=\"all\">{labels.pageSizeAll}</option>\n </select>\n )}\n </div>\n {pageSize !== Infinity && totalPages > 1 && (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => onPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.prevPage}\n >\n {/* \"Previous\" points back along the line — left in LTR, right in RTL. */}\n <ChevronLeft className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n {items.map((it, i) =>\n it === \"ellipsis\" ? (\n <span key={`e${i}`} className=\"px-1 text-[var(--text-placeholder)]\">\n …\n </span>\n ) : (\n <button\n key={it}\n type=\"button\"\n onClick={() => onPage(it)}\n // Which page you are on is carried only by a background colour\n // otherwise, and the strip is a row of bare numbers with nothing\n // else to tell them apart.\n aria-current={it === page ? \"page\" : undefined}\n className={cn(\n \"rounded\",\n compact ? \"min-w-6 px-1.5 py-0\" : \"min-w-7 px-2 py-0.5\",\n it === page\n ? \"bg-[var(--bg-inverse)] text-[var(--text-inverse)]\"\n : \"hover:bg-[var(--bg-hover)]\",\n )}\n >\n {num.format(it + 1)}\n </button>\n ),\n )}\n <button\n type=\"button\"\n onClick={() => onPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className={cn(\"rounded hover:bg-[var(--bg-hover)] disabled:opacity-40\", compact ? \"p-0.5\" : \"p-1\")}\n aria-label={labels.nextPage}\n >\n <ChevronRight className={cn(\"rtl:-scale-x-100\", compact ? \"size-3.5\" : \"size-4\")} />\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";AA6EQ,cAME,YANF;AA7ER,SAAS,eAAe;AACxB,SAAS,aAAa,oBAAoB;AAC1C,SAAS,UAAU;AACnB,SAAS,iCAAuD;AAChE,SAAS,cAAc,oBAAoB;AAEpC,MAAM,oBAAoB,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;AAuB/C,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AACZ,GAAoB;AAClB,QAAM,UAAU,YAAY;AAK5B,QAAM,SAAS,aAAa,aAAa,2BAA2B,UAAU;AAC9E,QAAM,SAAS,aAAa,UAAU;AAKtC,QAAM,MAAM,QAAQ,MAAM,IAAI,KAAK,aAAa,MAAM,GAAG,CAAC,MAAM,CAAC;AACjE,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,cAAc,EAAG,QAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,CAAC,GAAG,MAAM,CAAC;AAC1E,UAAM,MAAM,oBAAI,IAAY,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC;AACrD,aAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,UAAI,OAAO,KAAK,EAAG,KAAI,IAAI,OAAO,CAAC;AACnC,UAAI,OAAO,KAAK,aAAa,EAAG,KAAI,IAAI,OAAO,CAAC;AAAA,IAClD;AACA,WAAO,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,EAC7C,GAAG,CAAC,MAAM,UAAU,CAAC;AAErB,QAAM,QAAiC,CAAC;AACxC,UAAQ,QAAQ,CAAC,GAAG,QAAQ;AAC1B,QAAI,MAAM,KAAK,IAAI,QAAQ,MAAM,CAAC,IAAI,EAAG,OAAM,KAAK,UAAU;AAC9D,UAAM,KAAK,CAAC;AAAA,EACd,CAAC;AAED,SACE;AAAA,IAAC;AAAA;AAAA,MACC,gBAAc;AAAA,MACd,WAAW;AAAA,QACT;AAAA,QACA,UAAU,cAAc;AAAA,MAC1B;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAU,2BACb;AAAA,8BAAC,UACE,uBAAa,WACV,OAAO,SAAS,KAAK,IACrB,OAAO,UAAU,OAAO,WAAW,GAAG,KAAK,IAAI,QAAQ,OAAO,KAAK,QAAQ,GAAG,KAAK,GACzF;AAAA,UACC,cACC;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,aAAa,WAAW,QAAQ;AAAA,cACvC,UAAU,CAAC,MACT,WAAW,EAAE,OAAO,UAAU,QAAQ,WAAW,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,cAEzE,WAAU;AAAA,cACV,cAAY,OAAO;AAAA,cAElB;AAAA,kCAAkB,IAAI,CAAC,MACtB,oBAAC,YAAe,OAAO,GACpB,cAAI,OAAO,CAAC,KADF,CAEb,CACD;AAAA,gBACD,oBAAC,YAAO,OAAM,OAAO,iBAAO,aAAY;AAAA;AAAA;AAAA,UAC1C;AAAA,WAEJ;AAAA,QACC,aAAa,YAAY,aAAa,KACrC,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,cAC3C,UAAU,SAAS;AAAA,cACnB,WAAW,GAAG,0DAA0D,UAAU,UAAU,KAAK;AAAA,cACjG,cAAY,OAAO;AAAA,cAGnB,8BAAC,eAAY,WAAW,GAAG,oBAAoB,UAAU,aAAa,QAAQ,GAAG;AAAA;AAAA,UACnF;AAAA,UACC,MAAM;AAAA,YAAI,CAAC,IAAI,MACd,OAAO,aACL,oBAAC,UAAmB,WAAU,uCAAsC,sBAAzD,IAAI,CAAC,EAEhB,IAEA;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,SAAS,MAAM,OAAO,EAAE;AAAA,gBAIxB,gBAAc,OAAO,OAAO,SAAS;AAAA,gBACrC,WAAW;AAAA,kBACT;AAAA,kBACA,UAAU,wBAAwB;AAAA,kBAClC,OAAO,OACH,sDACA;AAAA,gBACN;AAAA,gBAEC,cAAI,OAAO,KAAK,CAAC;AAAA;AAAA,cAfb;AAAA,YAgBP;AAAA,UAEJ;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,OAAO,KAAK,IAAI,aAAa,GAAG,OAAO,CAAC,CAAC;AAAA,cACxD,UAAU,QAAQ,aAAa;AAAA,cAC/B,WAAW,GAAG,0DAA0D,UAAU,UAAU,KAAK;AAAA,cACjG,cAAY,OAAO;AAAA,cAEnB,8BAAC,gBAAa,WAAW,GAAG,oBAAoB,UAAU,aAAa,QAAQ,GAAG;AAAA;AAAA,UACpF;AAAA,WACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
|
|
@@ -14,10 +14,33 @@ declare function normalizeSorts(raw: unknown): SortState[];
|
|
|
14
14
|
declare function encodeSorts(sorts: SortState[]): string | null;
|
|
15
15
|
/** Decode a `sort` URL param, dropping unknown and duplicated keys. */
|
|
16
16
|
declare function decodeSorts(raw: string | null, validKeys: ReadonlySet<string>): SortState[];
|
|
17
|
+
/**
|
|
18
|
+
* How a header click steps through the directions (see {@link nextSorts}).
|
|
19
|
+
*
|
|
20
|
+
* * `"tri"` — first direction → the other → unsorted. The default, and the only cycle
|
|
21
|
+
* before 0.8.0.
|
|
22
|
+
* * `"toggle"` — first direction ⇄ the other, never unsorted: a report table that is
|
|
23
|
+
* ALWAYS ranked by something (keksdose's aggregated tables) must not have a third
|
|
24
|
+
* click that silently drops the ranking. Clicking another column still replaces
|
|
25
|
+
* the sort, so the table can always be re-ranked; a shift-click criterion flips in
|
|
26
|
+
* place and stays for the same reason.
|
|
27
|
+
*/
|
|
28
|
+
type SortCycle = "tri" | "toggle";
|
|
29
|
+
/** Per-click options for {@link nextSorts}; every field is optional and the
|
|
30
|
+
* defaults reproduce the pre-0.8.0 cycle exactly. */
|
|
31
|
+
interface SortStepOptions {
|
|
32
|
+
/** The direction a column starts in on its first click. `"desc"` for money and
|
|
33
|
+
* count columns, where the interesting rows are the large ones. Default `"asc"`. */
|
|
34
|
+
firstDir?: SortDir;
|
|
35
|
+
/** Default `"tri"`. */
|
|
36
|
+
cycle?: SortCycle;
|
|
37
|
+
}
|
|
17
38
|
/** Header-click semantics. Plain click: make `key` the only sort — cycling
|
|
18
|
-
*
|
|
19
|
-
* (`additive`): append `key` as the next-priority
|
|
20
|
-
* entry
|
|
21
|
-
|
|
39
|
+
* first → other → none (`"tri"`) or first ⇄ other (`"toggle"`) when it already is
|
|
40
|
+
* the sole criterion. Shift-click (`additive`): append `key` as the next-priority
|
|
41
|
+
* sort, or step an existing entry in place (first → other → removed under `"tri"`,
|
|
42
|
+
* a plain flip under `"toggle"`). `firstDir` defaults to `"asc"`, `cycle` to
|
|
43
|
+
* `"tri"` — the cycle every table had before the options existed. */
|
|
44
|
+
declare function nextSorts(prev: SortState[], key: string, additive: boolean, options?: SortStepOptions): SortState[];
|
|
22
45
|
|
|
23
|
-
export { type SortDir, type SortState, decodeSorts, encodeSorts, nextSorts, normalizeSorts };
|
|
46
|
+
export { type SortCycle, type SortDir, type SortState, type SortStepOptions, decodeSorts, encodeSorts, nextSorts, normalizeSorts };
|
|
@@ -33,18 +33,22 @@ function decodeSorts(raw, validKeys) {
|
|
|
33
33
|
}
|
|
34
34
|
return out;
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
const flip = (d) => d === "asc" ? "desc" : "asc";
|
|
37
|
+
function nextSorts(prev, key, additive, options = {}) {
|
|
38
|
+
const first = options.firstDir ?? "asc";
|
|
39
|
+
const toggle = options.cycle === "toggle";
|
|
37
40
|
const idx = prev.findIndex((s) => s.key === key);
|
|
41
|
+
const step = (dir2) => dir2 === first ? flip(first) : toggle ? first : null;
|
|
38
42
|
if (!additive) {
|
|
39
43
|
if (prev.length === 1 && idx === 0) {
|
|
40
|
-
|
|
44
|
+
const dir2 = step(prev[0].dir);
|
|
45
|
+
return dir2 ? [{ key, dir: dir2 }] : [];
|
|
41
46
|
}
|
|
42
|
-
return [{ key, dir:
|
|
43
|
-
}
|
|
44
|
-
if (idx === -1) return [...prev, { key, dir: "asc" }];
|
|
45
|
-
if (prev[idx].dir === "asc") {
|
|
46
|
-
return prev.map((s, i) => i === idx ? { key, dir: "desc" } : s);
|
|
47
|
+
return [{ key, dir: first }];
|
|
47
48
|
}
|
|
49
|
+
if (idx === -1) return [...prev, { key, dir: first }];
|
|
50
|
+
const dir = step(prev[idx].dir);
|
|
51
|
+
if (dir) return prev.map((s, i) => i === idx ? { key, dir } : s);
|
|
48
52
|
return prev.filter((_, i) => i !== idx);
|
|
49
53
|
}
|
|
50
54
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/data-table-sort.ts"],"sourcesContent":["/** Multi-column sort state for DataTable: ordered by priority (index 0 is the\n * primary sort). Encoded as `sort=date.desc,amount` in URLs and the server's\n * transactions `sort` param — the pre-multi-sort single-value format\n * (`sort=date.desc`) decodes as a one-element list. */\n\nexport type SortDir = \"asc\" | \"desc\";\nexport interface SortState {\n key: string;\n dir: SortDir;\n}\n\n/** Coerce any persisted/URL-derived shape into a `SortState[]`. The\n * pre-multi-sort localStorage format stored one `{key, dir}` object (or\n * null); arrays pass through with junk entries dropped. */\nexport function normalizeSorts(raw: unknown): SortState[] {\n const one = (v: unknown): SortState | null => {\n if (!v || typeof v !== \"object\") return null;\n const { key, dir } = v as { key?: unknown; dir?: unknown };\n if (typeof key !== \"string\" || !key) return null;\n return { key, dir: dir === \"desc\" ? \"desc\" : \"asc\" };\n };\n if (Array.isArray(raw)) {\n const out: SortState[] = [];\n for (const entry of raw) {\n const s = one(entry);\n if (s && !out.some((e) => e.key === s.key)) out.push(s);\n }\n return out;\n }\n const single = one(raw);\n return single ? [single] : [];\n}\n\nexport function encodeSorts(sorts: SortState[]): string | null {\n if (!sorts.length) return null;\n return sorts.map((s) => (s.dir === \"desc\" ? `${s.key}.desc` : s.key)).join(\",\");\n}\n\n/** Decode a `sort` URL param, dropping unknown and duplicated keys. */\nexport function decodeSorts(raw: string | null, validKeys: ReadonlySet<string>): SortState[] {\n if (!raw) return [];\n const out: SortState[] = [];\n for (const part of raw.split(\",\")) {\n const desc = part.endsWith(\".desc\");\n const asc = part.endsWith(\".asc\");\n const key = desc ? part.slice(0, -\".desc\".length) : asc ? part.slice(0, -\".asc\".length) : part;\n if (!validKeys.has(key) || out.some((s) => s.key === key)) continue;\n out.push({ key, dir: desc ? \"desc\" : \"asc\" });\n }\n return out;\n}\n\n/** Header-click semantics. Plain click: make `key` the only sort — cycling\n *
|
|
1
|
+
{"version":3,"sources":["../../src/components/data-table-sort.ts"],"sourcesContent":["/** Multi-column sort state for DataTable: ordered by priority (index 0 is the\n * primary sort). Encoded as `sort=date.desc,amount` in URLs and the server's\n * transactions `sort` param — the pre-multi-sort single-value format\n * (`sort=date.desc`) decodes as a one-element list. */\n\nexport type SortDir = \"asc\" | \"desc\";\nexport interface SortState {\n key: string;\n dir: SortDir;\n}\n\n/** Coerce any persisted/URL-derived shape into a `SortState[]`. The\n * pre-multi-sort localStorage format stored one `{key, dir}` object (or\n * null); arrays pass through with junk entries dropped. */\nexport function normalizeSorts(raw: unknown): SortState[] {\n const one = (v: unknown): SortState | null => {\n if (!v || typeof v !== \"object\") return null;\n const { key, dir } = v as { key?: unknown; dir?: unknown };\n if (typeof key !== \"string\" || !key) return null;\n return { key, dir: dir === \"desc\" ? \"desc\" : \"asc\" };\n };\n if (Array.isArray(raw)) {\n const out: SortState[] = [];\n for (const entry of raw) {\n const s = one(entry);\n if (s && !out.some((e) => e.key === s.key)) out.push(s);\n }\n return out;\n }\n const single = one(raw);\n return single ? [single] : [];\n}\n\nexport function encodeSorts(sorts: SortState[]): string | null {\n if (!sorts.length) return null;\n return sorts.map((s) => (s.dir === \"desc\" ? `${s.key}.desc` : s.key)).join(\",\");\n}\n\n/** Decode a `sort` URL param, dropping unknown and duplicated keys. */\nexport function decodeSorts(raw: string | null, validKeys: ReadonlySet<string>): SortState[] {\n if (!raw) return [];\n const out: SortState[] = [];\n for (const part of raw.split(\",\")) {\n const desc = part.endsWith(\".desc\");\n const asc = part.endsWith(\".asc\");\n const key = desc ? part.slice(0, -\".desc\".length) : asc ? part.slice(0, -\".asc\".length) : part;\n if (!validKeys.has(key) || out.some((s) => s.key === key)) continue;\n out.push({ key, dir: desc ? \"desc\" : \"asc\" });\n }\n return out;\n}\n\n/**\n * How a header click steps through the directions (see {@link nextSorts}).\n *\n * * `\"tri\"` — first direction → the other → unsorted. The default, and the only cycle\n * before 0.8.0.\n * * `\"toggle\"` — first direction ⇄ the other, never unsorted: a report table that is\n * ALWAYS ranked by something (keksdose's aggregated tables) must not have a third\n * click that silently drops the ranking. Clicking another column still replaces\n * the sort, so the table can always be re-ranked; a shift-click criterion flips in\n * place and stays for the same reason.\n */\nexport type SortCycle = \"tri\" | \"toggle\";\n\n/** Per-click options for {@link nextSorts}; every field is optional and the\n * defaults reproduce the pre-0.8.0 cycle exactly. */\nexport interface SortStepOptions {\n /** The direction a column starts in on its first click. `\"desc\"` for money and\n * count columns, where the interesting rows are the large ones. Default `\"asc\"`. */\n firstDir?: SortDir;\n /** Default `\"tri\"`. */\n cycle?: SortCycle;\n}\n\nconst flip = (d: SortDir): SortDir => (d === \"asc\" ? \"desc\" : \"asc\");\n\n/** Header-click semantics. Plain click: make `key` the only sort — cycling\n * first → other → none (`\"tri\"`) or first ⇄ other (`\"toggle\"`) when it already is\n * the sole criterion. Shift-click (`additive`): append `key` as the next-priority\n * sort, or step an existing entry in place (first → other → removed under `\"tri\"`,\n * a plain flip under `\"toggle\"`). `firstDir` defaults to `\"asc\"`, `cycle` to\n * `\"tri\"` — the cycle every table had before the options existed. */\nexport function nextSorts(\n prev: SortState[],\n key: string,\n additive: boolean,\n options: SortStepOptions = {},\n): SortState[] {\n const first = options.firstDir ?? \"asc\";\n const toggle = options.cycle === \"toggle\";\n const idx = prev.findIndex((s) => s.key === key);\n // One step from `dir`: the second direction after the first, then either back to\n // the first (toggle) or off (null). Judged against THIS column's first direction,\n // so a desc-first column goes desc → asc → none rather than skipping a step.\n const step = (dir: SortDir): SortDir | null =>\n dir === first ? flip(first) : toggle ? first : null;\n if (!additive) {\n if (prev.length === 1 && idx === 0) {\n const dir = step(prev[0].dir);\n return dir ? [{ key, dir }] : [];\n }\n return [{ key, dir: first }];\n }\n if (idx === -1) return [...prev, { key, dir: first }];\n const dir = step(prev[idx].dir);\n if (dir) return prev.map((s, i) => (i === idx ? { key, dir } : s));\n return prev.filter((_, i) => i !== idx);\n}\n"],"mappings":";AAcO,SAAS,eAAe,KAA2B;AACxD,QAAM,MAAM,CAAC,MAAiC;AAC5C,QAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,UAAM,EAAE,KAAK,IAAI,IAAI;AACrB,QAAI,OAAO,QAAQ,YAAY,CAAC,IAAK,QAAO;AAC5C,WAAO,EAAE,KAAK,KAAK,QAAQ,SAAS,SAAS,MAAM;AAAA,EACrD;AACA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,UAAM,MAAmB,CAAC;AAC1B,eAAW,SAAS,KAAK;AACvB,YAAM,IAAI,IAAI,KAAK;AACnB,UAAI,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAG,KAAI,KAAK,CAAC;AAAA,IACxD;AACA,WAAO;AAAA,EACT;AACA,QAAM,SAAS,IAAI,GAAG;AACtB,SAAO,SAAS,CAAC,MAAM,IAAI,CAAC;AAC9B;AAEO,SAAS,YAAY,OAAmC;AAC7D,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,SAAO,MAAM,IAAI,CAAC,MAAO,EAAE,QAAQ,SAAS,GAAG,EAAE,GAAG,UAAU,EAAE,GAAI,EAAE,KAAK,GAAG;AAChF;AAGO,SAAS,YAAY,KAAoB,WAA6C;AAC3F,MAAI,CAAC,IAAK,QAAO,CAAC;AAClB,QAAM,MAAmB,CAAC;AAC1B,aAAW,QAAQ,IAAI,MAAM,GAAG,GAAG;AACjC,UAAM,OAAO,KAAK,SAAS,OAAO;AAClC,UAAM,MAAM,KAAK,SAAS,MAAM;AAChC,UAAM,MAAM,OAAO,KAAK,MAAM,GAAG,CAAC,QAAQ,MAAM,IAAI,MAAM,KAAK,MAAM,GAAG,CAAC,OAAO,MAAM,IAAI;AAC1F,QAAI,CAAC,UAAU,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,EAAG;AAC3D,QAAI,KAAK,EAAE,KAAK,KAAK,OAAO,SAAS,MAAM,CAAC;AAAA,EAC9C;AACA,SAAO;AACT;AAyBA,MAAM,OAAO,CAAC,MAAyB,MAAM,QAAQ,SAAS;AAQvD,SAAS,UACd,MACA,KACA,UACA,UAA2B,CAAC,GACf;AACb,QAAM,QAAQ,QAAQ,YAAY;AAClC,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG;AAI/C,QAAM,OAAO,CAACA,SACZA,SAAQ,QAAQ,KAAK,KAAK,IAAI,SAAS,QAAQ;AACjD,MAAI,CAAC,UAAU;AACb,QAAI,KAAK,WAAW,KAAK,QAAQ,GAAG;AAClC,YAAMA,OAAM,KAAK,KAAK,CAAC,EAAE,GAAG;AAC5B,aAAOA,OAAM,CAAC,EAAE,KAAK,KAAAA,KAAI,CAAC,IAAI,CAAC;AAAA,IACjC;AACA,WAAO,CAAC,EAAE,KAAK,KAAK,MAAM,CAAC;AAAA,EAC7B;AACA,MAAI,QAAQ,GAAI,QAAO,CAAC,GAAG,MAAM,EAAE,KAAK,KAAK,MAAM,CAAC;AACpD,QAAM,MAAM,KAAK,KAAK,GAAG,EAAE,GAAG;AAC9B,MAAI,IAAK,QAAO,KAAK,IAAI,CAAC,GAAG,MAAO,MAAM,MAAM,EAAE,KAAK,IAAI,IAAI,CAAE;AACjE,SAAO,KAAK,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG;AACxC;","names":["dir"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import 'react';
|
|
2
|
-
export { D as DataTable, a as
|
|
2
|
+
export { D as DataTable, a as DataTableChrome, b as DataTableColumn, c as DataTableDensity, d as DataTableProps, F as FilterState, M as MobileSwipeActions, S as ServerPagination } from '../data-table-filters-CF1PXqjQ.js';
|
|
3
3
|
export { SortState } from './data-table-sort.js';
|
|
4
4
|
import './swipeable-row.js';
|
|
5
5
|
import './data-table-labels.js';
|