@dynostack/react-grid 0.2.0 → 0.3.1
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 +162 -7
- package/dist/index.cjs +463 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -3
- package/dist/index.d.ts +103 -3
- package/dist/index.js +465 -35
- package/dist/index.js.map +1 -1
- package/dist/styles.css +51 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createContext, useState, useRef, useEffect, useMemo, useLayoutEffect, useId
|
|
1
|
+
import { createContext, useContext, useState, useRef, useEffect, useMemo, useLayoutEffect, useId } from 'react';
|
|
2
2
|
import { useReactTable, getPaginationRowModel, getExpandedRowModel, getSortedRowModel, getFilteredRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
3
|
-
import { Trash2Icon, XIcon, SearchIcon, RefreshCwIcon, ColumnsIcon, DownloadIcon, FileTextIcon, FileSpreadsheetIcon, PlusIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon, ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon, PinOffIcon, PinIcon, EyeOffIcon, FilterIcon, CheckIcon, MoreHorizontalIcon, ChevronDownIcon, GripVerticalIcon, Loader2Icon, MinusIcon, CopyIcon, PencilIcon, EyeIcon, ChevronUpIcon } from 'lucide-react';
|
|
3
|
+
import { Trash2Icon, XIcon, SearchIcon, RefreshCwIcon, ColumnsIcon, DownloadIcon, FileTextIcon, FileSpreadsheetIcon, PlusIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon, ArrowDownIcon, ArrowUpIcon, ChevronsUpDownIcon, PinOffIcon, PinIcon, EyeOffIcon, FilterIcon, CheckIcon, MoreHorizontalIcon, ChevronDownIcon, GripVerticalIcon, Loader2Icon, MinusIcon, CopyIcon, PencilIcon, EyeIcon, ChevronUpIcon, LayoutGridIcon, Rows3Icon, ListIcon } from 'lucide-react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
|
-
import { Slot, Separator as Separator$1, Popover as Popover$1, Checkbox as Checkbox$1, DropdownMenu as DropdownMenu$1, Select as Select$1 } from 'radix-ui';
|
|
6
|
+
import { Slot, Separator as Separator$1, Popover as Popover$1, Checkbox as Checkbox$1, DropdownMenu as DropdownMenu$1, Select as Select$1, Dialog, AlertDialog as AlertDialog$1 } from 'radix-ui';
|
|
7
7
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
8
8
|
import { cva } from 'class-variance-authority';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
@@ -159,6 +159,10 @@ function Separator({
|
|
|
159
159
|
}
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
|
+
var PortalContainerContext = createContext(null);
|
|
163
|
+
function usePortalContainer() {
|
|
164
|
+
return useContext(PortalContainerContext);
|
|
165
|
+
}
|
|
162
166
|
function DropdownMenu({
|
|
163
167
|
...props
|
|
164
168
|
}) {
|
|
@@ -181,7 +185,8 @@ function DropdownMenuContent({
|
|
|
181
185
|
sideOffset = 4,
|
|
182
186
|
...props
|
|
183
187
|
}) {
|
|
184
|
-
|
|
188
|
+
const container = usePortalContainer();
|
|
189
|
+
return /* @__PURE__ */ jsx(DropdownMenu$1.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
|
|
185
190
|
DropdownMenu$1.Content,
|
|
186
191
|
{
|
|
187
192
|
"data-slot": "dropdown-menu-content",
|
|
@@ -259,7 +264,8 @@ function PopoverContent({
|
|
|
259
264
|
sideOffset = 6,
|
|
260
265
|
...props
|
|
261
266
|
}) {
|
|
262
|
-
|
|
267
|
+
const container = usePortalContainer();
|
|
268
|
+
return /* @__PURE__ */ jsx(Popover$1.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
|
|
263
269
|
Popover$1.Content,
|
|
264
270
|
{
|
|
265
271
|
"data-slot": "popover-content",
|
|
@@ -614,7 +620,8 @@ function SelectContent({
|
|
|
614
620
|
position = "popper",
|
|
615
621
|
...props
|
|
616
622
|
}) {
|
|
617
|
-
|
|
623
|
+
const container = usePortalContainer();
|
|
624
|
+
return /* @__PURE__ */ jsx(Select$1.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsxs(
|
|
618
625
|
Select$1.Content,
|
|
619
626
|
{
|
|
620
627
|
"data-slot": "select-content",
|
|
@@ -1043,15 +1050,17 @@ function OpSelect({
|
|
|
1043
1050
|
value,
|
|
1044
1051
|
onChange
|
|
1045
1052
|
}) {
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1053
|
+
return /* @__PURE__ */ jsxs(Select, { value, onValueChange: (v) => onChange(v), children: [
|
|
1054
|
+
/* @__PURE__ */ jsx(
|
|
1055
|
+
SelectTrigger,
|
|
1056
|
+
{
|
|
1057
|
+
size: "sm",
|
|
1058
|
+
className: "h-8 w-full justify-between text-xs",
|
|
1059
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
1060
|
+
}
|
|
1061
|
+
),
|
|
1062
|
+
/* @__PURE__ */ jsx(SelectContent, { children: ops.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.v, className: "text-xs", children: o.l }, o.v)) })
|
|
1063
|
+
] });
|
|
1055
1064
|
}
|
|
1056
1065
|
function CombineToggle({
|
|
1057
1066
|
value,
|
|
@@ -1719,14 +1728,23 @@ function DataTableRowActions({
|
|
|
1719
1728
|
const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
|
|
1720
1729
|
const triggerRef = useRef(null);
|
|
1721
1730
|
const menuRef = useRef(null);
|
|
1731
|
+
const portalContainer = usePortalContainer();
|
|
1722
1732
|
useLayoutEffect(() => {
|
|
1723
1733
|
if (!open || !triggerRef.current) return;
|
|
1724
1734
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1735
|
+
if (portalContainer) {
|
|
1736
|
+
const cRect = portalContainer.getBoundingClientRect();
|
|
1737
|
+
setMenuPosition({
|
|
1738
|
+
top: rect.bottom - cRect.top + 4,
|
|
1739
|
+
left: Math.max(8, rect.right - cRect.left - 160)
|
|
1740
|
+
});
|
|
1741
|
+
} else {
|
|
1742
|
+
setMenuPosition({
|
|
1743
|
+
top: rect.bottom + 4,
|
|
1744
|
+
left: Math.max(8, rect.right - 160)
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
}, [open, portalContainer]);
|
|
1730
1748
|
useEffect(() => {
|
|
1731
1749
|
if (!open) return;
|
|
1732
1750
|
const onPointerDown = (event) => {
|
|
@@ -1788,8 +1806,12 @@ function DataTableRowActions({
|
|
|
1788
1806
|
"div",
|
|
1789
1807
|
{
|
|
1790
1808
|
ref: menuRef,
|
|
1791
|
-
className: "
|
|
1792
|
-
style: {
|
|
1809
|
+
className: "z-[1000] w-40 rounded-md border bg-popover p-1 text-popover-foreground shadow-lg",
|
|
1810
|
+
style: {
|
|
1811
|
+
position: portalContainer ? "absolute" : "fixed",
|
|
1812
|
+
top: menuPosition.top,
|
|
1813
|
+
left: menuPosition.left
|
|
1814
|
+
},
|
|
1793
1815
|
children: [
|
|
1794
1816
|
actions.map((a) => /* @__PURE__ */ jsxs(
|
|
1795
1817
|
RowActionButton,
|
|
@@ -1827,7 +1849,7 @@ function DataTableRowActions({
|
|
|
1827
1849
|
]
|
|
1828
1850
|
}
|
|
1829
1851
|
),
|
|
1830
|
-
document.body
|
|
1852
|
+
portalContainer ?? document.body
|
|
1831
1853
|
)
|
|
1832
1854
|
] });
|
|
1833
1855
|
}
|
|
@@ -2050,6 +2072,7 @@ function splitTheme(theme) {
|
|
|
2050
2072
|
}
|
|
2051
2073
|
function buildPreset(hue, chroma = 0.03) {
|
|
2052
2074
|
const c = chroma;
|
|
2075
|
+
const destH = blendTowardRed(hue);
|
|
2053
2076
|
return {
|
|
2054
2077
|
light: {
|
|
2055
2078
|
background: `oklch(0.99 ${c * 0.2} ${hue})`,
|
|
@@ -2066,7 +2089,7 @@ function buildPreset(hue, chroma = 0.03) {
|
|
|
2066
2089
|
mutedForeground: `oklch(0.5 ${c * 1.5} ${hue})`,
|
|
2067
2090
|
accent: `oklch(0.94 ${c * 1.2} ${hue})`,
|
|
2068
2091
|
accentForeground: `oklch(0.3 ${c * 3} ${hue})`,
|
|
2069
|
-
destructive: `oklch(0.577 0.
|
|
2092
|
+
destructive: `oklch(0.577 0.22 ${destH})`,
|
|
2070
2093
|
destructiveForeground: `oklch(0.985 0 0)`,
|
|
2071
2094
|
border: `oklch(0.9 ${c * 0.8} ${hue})`,
|
|
2072
2095
|
input: `oklch(0.9 ${c * 0.8} ${hue})`,
|
|
@@ -2088,7 +2111,7 @@ function buildPreset(hue, chroma = 0.03) {
|
|
|
2088
2111
|
mutedForeground: `oklch(0.7 ${c * 0.5} ${hue})`,
|
|
2089
2112
|
accent: `oklch(0.3 ${c * 1.5} ${hue})`,
|
|
2090
2113
|
accentForeground: `oklch(0.97 ${c * 0.2} ${hue})`,
|
|
2091
|
-
destructive: `oklch(0.
|
|
2114
|
+
destructive: `oklch(0.65 0.22 ${destH})`,
|
|
2092
2115
|
destructiveForeground: `oklch(0.985 0 0)`,
|
|
2093
2116
|
border: `oklch(0.27 ${c * 0.8} ${hue})`,
|
|
2094
2117
|
input: `oklch(0.27 ${c * 0.8} ${hue})`,
|
|
@@ -2097,6 +2120,11 @@ function buildPreset(hue, chroma = 0.03) {
|
|
|
2097
2120
|
}
|
|
2098
2121
|
};
|
|
2099
2122
|
}
|
|
2123
|
+
function blendTowardRed(hue) {
|
|
2124
|
+
const red = 25;
|
|
2125
|
+
let delta = (hue - red + 540) % 360 - 180;
|
|
2126
|
+
return (red + delta * 0.3 + 360) % 360;
|
|
2127
|
+
}
|
|
2100
2128
|
function tokensToCssBlock(tokens) {
|
|
2101
2129
|
if (!tokens) return "";
|
|
2102
2130
|
const parts = [];
|
|
@@ -2166,6 +2194,332 @@ var themePresets = {
|
|
|
2166
2194
|
};
|
|
2167
2195
|
var ISOLATE_LIGHT_TOKENS = neutral.light;
|
|
2168
2196
|
var ISOLATE_DARK_TOKENS = neutral.dark;
|
|
2197
|
+
function Sheet(props) {
|
|
2198
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
|
|
2199
|
+
}
|
|
2200
|
+
function SheetOverlay({
|
|
2201
|
+
className,
|
|
2202
|
+
...props
|
|
2203
|
+
}) {
|
|
2204
|
+
return /* @__PURE__ */ jsx(
|
|
2205
|
+
Dialog.Overlay,
|
|
2206
|
+
{
|
|
2207
|
+
"data-slot": "sheet-overlay",
|
|
2208
|
+
className: cn(
|
|
2209
|
+
"fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
2210
|
+
className
|
|
2211
|
+
),
|
|
2212
|
+
...props
|
|
2213
|
+
}
|
|
2214
|
+
);
|
|
2215
|
+
}
|
|
2216
|
+
var SIDE_CLASS = {
|
|
2217
|
+
right: "right-0 top-0 h-full w-3/4 max-w-md border-l data-closed:slide-out-to-right data-open:slide-in-from-right",
|
|
2218
|
+
left: "left-0 top-0 h-full w-3/4 max-w-md border-r data-closed:slide-out-to-left data-open:slide-in-from-left",
|
|
2219
|
+
top: "left-0 top-0 w-full max-h-[80vh] border-b data-closed:slide-out-to-top data-open:slide-in-from-top",
|
|
2220
|
+
bottom: "left-0 bottom-0 w-full max-h-[80vh] border-t data-closed:slide-out-to-bottom data-open:slide-in-from-bottom"
|
|
2221
|
+
};
|
|
2222
|
+
function SheetContent({
|
|
2223
|
+
className,
|
|
2224
|
+
side = "right",
|
|
2225
|
+
children,
|
|
2226
|
+
...props
|
|
2227
|
+
}) {
|
|
2228
|
+
const container = usePortalContainer();
|
|
2229
|
+
return /* @__PURE__ */ jsxs(Dialog.Portal, { container: container ?? void 0, children: [
|
|
2230
|
+
/* @__PURE__ */ jsx(SheetOverlay, {}),
|
|
2231
|
+
/* @__PURE__ */ jsxs(
|
|
2232
|
+
Dialog.Content,
|
|
2233
|
+
{
|
|
2234
|
+
"data-slot": "sheet-content",
|
|
2235
|
+
className: cn(
|
|
2236
|
+
"fixed z-50 flex flex-col gap-4 bg-background p-6 shadow-lg outline-none transition data-open:animate-in data-closed:animate-out duration-200",
|
|
2237
|
+
SIDE_CLASS[side],
|
|
2238
|
+
className
|
|
2239
|
+
),
|
|
2240
|
+
...props,
|
|
2241
|
+
children: [
|
|
2242
|
+
children,
|
|
2243
|
+
/* @__PURE__ */ jsx(
|
|
2244
|
+
Dialog.Close,
|
|
2245
|
+
{
|
|
2246
|
+
className: "absolute top-4 right-4 rounded-md p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
|
|
2247
|
+
"aria-label": "Close",
|
|
2248
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
|
|
2249
|
+
}
|
|
2250
|
+
)
|
|
2251
|
+
]
|
|
2252
|
+
}
|
|
2253
|
+
)
|
|
2254
|
+
] });
|
|
2255
|
+
}
|
|
2256
|
+
function SheetHeader({ className, ...props }) {
|
|
2257
|
+
return /* @__PURE__ */ jsx(
|
|
2258
|
+
"div",
|
|
2259
|
+
{
|
|
2260
|
+
"data-slot": "sheet-header",
|
|
2261
|
+
className: cn("flex flex-col gap-1.5 pr-8", className),
|
|
2262
|
+
...props
|
|
2263
|
+
}
|
|
2264
|
+
);
|
|
2265
|
+
}
|
|
2266
|
+
function SheetTitle({
|
|
2267
|
+
className,
|
|
2268
|
+
...props
|
|
2269
|
+
}) {
|
|
2270
|
+
return /* @__PURE__ */ jsx(
|
|
2271
|
+
Dialog.Title,
|
|
2272
|
+
{
|
|
2273
|
+
"data-slot": "sheet-title",
|
|
2274
|
+
className: cn("text-lg font-semibold leading-none", className),
|
|
2275
|
+
...props
|
|
2276
|
+
}
|
|
2277
|
+
);
|
|
2278
|
+
}
|
|
2279
|
+
function SheetDescription({
|
|
2280
|
+
className,
|
|
2281
|
+
...props
|
|
2282
|
+
}) {
|
|
2283
|
+
return /* @__PURE__ */ jsx(
|
|
2284
|
+
Dialog.Description,
|
|
2285
|
+
{
|
|
2286
|
+
"data-slot": "sheet-description",
|
|
2287
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
2288
|
+
...props
|
|
2289
|
+
}
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
var COLS_CLASS = {
|
|
2293
|
+
compact: "grid-cols-1",
|
|
2294
|
+
relaxed: "grid-cols-1 sm:grid-cols-2",
|
|
2295
|
+
comfy: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
|
|
2296
|
+
};
|
|
2297
|
+
var DENSITY_ICON = {
|
|
2298
|
+
compact: /* @__PURE__ */ jsx(ListIcon, { className: "size-3.5" }),
|
|
2299
|
+
relaxed: /* @__PURE__ */ jsx(Rows3Icon, { className: "size-3.5" }),
|
|
2300
|
+
comfy: /* @__PURE__ */ jsx(LayoutGridIcon, { className: "size-3.5" })
|
|
2301
|
+
};
|
|
2302
|
+
function DataTableViewSheet({
|
|
2303
|
+
table,
|
|
2304
|
+
row,
|
|
2305
|
+
open,
|
|
2306
|
+
onOpenChange,
|
|
2307
|
+
config
|
|
2308
|
+
}) {
|
|
2309
|
+
const [density, setDensity] = useState(
|
|
2310
|
+
config?.defaultDensity ?? "compact"
|
|
2311
|
+
);
|
|
2312
|
+
const fields = useMemo(() => {
|
|
2313
|
+
if (!row) return [];
|
|
2314
|
+
const wanted = config?.fields;
|
|
2315
|
+
const allCols = table.getAllLeafColumns().filter((c) => {
|
|
2316
|
+
if (c.id === "__select" || c.id === "__actions" || c.id === "__expand")
|
|
2317
|
+
return false;
|
|
2318
|
+
if (wanted) return wanted.includes(c.id);
|
|
2319
|
+
return c.getIsVisible();
|
|
2320
|
+
});
|
|
2321
|
+
if (wanted) {
|
|
2322
|
+
return wanted.map((id) => allCols.find((c) => c.id === id)).filter((c) => Boolean(c));
|
|
2323
|
+
}
|
|
2324
|
+
return allCols;
|
|
2325
|
+
}, [table, row, config?.fields]);
|
|
2326
|
+
if (!row) return null;
|
|
2327
|
+
const labels = config?.labels;
|
|
2328
|
+
const emptyValue = labels?.emptyValue ?? "\u2014";
|
|
2329
|
+
const densityLabels = {
|
|
2330
|
+
compact: labels?.density?.compact ?? "Compact",
|
|
2331
|
+
relaxed: labels?.density?.relaxed ?? "Relaxed",
|
|
2332
|
+
comfy: labels?.density?.comfy ?? "Comfy"
|
|
2333
|
+
};
|
|
2334
|
+
return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(SheetContent, { side: config?.side ?? "right", children: [
|
|
2335
|
+
config?.renderHeader ? config.renderHeader(row) : /* @__PURE__ */ jsxs(SheetHeader, { children: [
|
|
2336
|
+
/* @__PURE__ */ jsx(SheetTitle, { children: labels?.title ? labels.title(row) : "Details" }),
|
|
2337
|
+
labels?.description && /* @__PURE__ */ jsx(SheetDescription, { children: labels.description(row) })
|
|
2338
|
+
] }),
|
|
2339
|
+
!config?.hideDensityTabs && /* @__PURE__ */ jsx(
|
|
2340
|
+
"div",
|
|
2341
|
+
{
|
|
2342
|
+
role: "tablist",
|
|
2343
|
+
"aria-label": "Layout density",
|
|
2344
|
+
className: "inline-flex w-fit gap-0.5 rounded-md border bg-muted/40 p-0.5 text-xs",
|
|
2345
|
+
children: ["compact", "relaxed", "comfy"].map((d) => /* @__PURE__ */ jsxs(
|
|
2346
|
+
"button",
|
|
2347
|
+
{
|
|
2348
|
+
role: "tab",
|
|
2349
|
+
"aria-selected": density === d,
|
|
2350
|
+
onClick: () => setDensity(d),
|
|
2351
|
+
className: cn(
|
|
2352
|
+
"inline-flex items-center gap-1 rounded px-2 py-1 transition-colors",
|
|
2353
|
+
density === d ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
2354
|
+
),
|
|
2355
|
+
children: [
|
|
2356
|
+
DENSITY_ICON[d],
|
|
2357
|
+
densityLabels[d]
|
|
2358
|
+
]
|
|
2359
|
+
},
|
|
2360
|
+
d
|
|
2361
|
+
))
|
|
2362
|
+
}
|
|
2363
|
+
),
|
|
2364
|
+
/* @__PURE__ */ jsx("div", { className: cn("grid gap-3 overflow-y-auto", COLS_CLASS[density]), children: fields.map((col) => {
|
|
2365
|
+
const colId = col.id;
|
|
2366
|
+
const colDef = col.columnDef;
|
|
2367
|
+
const headerLabel = colDef.meta?.label ?? (typeof colDef.header === "string" ? colDef.header : colId);
|
|
2368
|
+
const rawValue = row[colDef.accessorKey ?? colId];
|
|
2369
|
+
const rendered = config?.renderField ? config.renderField({ column: col, value: rawValue, row }) : defaultRenderValue(rawValue, emptyValue);
|
|
2370
|
+
return /* @__PURE__ */ jsxs(
|
|
2371
|
+
"div",
|
|
2372
|
+
{
|
|
2373
|
+
className: "flex flex-col gap-0.5 rounded-md border bg-card p-2.5",
|
|
2374
|
+
children: [
|
|
2375
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] uppercase tracking-wide text-muted-foreground", children: headerLabel }),
|
|
2376
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground break-words", children: rendered })
|
|
2377
|
+
]
|
|
2378
|
+
},
|
|
2379
|
+
colId
|
|
2380
|
+
);
|
|
2381
|
+
}) }),
|
|
2382
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false), children: "Close" }) })
|
|
2383
|
+
] }) });
|
|
2384
|
+
}
|
|
2385
|
+
function defaultRenderValue(value, empty) {
|
|
2386
|
+
if (value == null || value === "") return empty;
|
|
2387
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
2388
|
+
if (value instanceof Date) return value.toLocaleString();
|
|
2389
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
2390
|
+
return String(value);
|
|
2391
|
+
}
|
|
2392
|
+
function AlertDialog(props) {
|
|
2393
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Root, { "data-slot": "alert-dialog", ...props });
|
|
2394
|
+
}
|
|
2395
|
+
function AlertDialogContent({
|
|
2396
|
+
className,
|
|
2397
|
+
children,
|
|
2398
|
+
...props
|
|
2399
|
+
}) {
|
|
2400
|
+
const container = usePortalContainer();
|
|
2401
|
+
return /* @__PURE__ */ jsxs(AlertDialog$1.Portal, { container: container ?? void 0, children: [
|
|
2402
|
+
/* @__PURE__ */ jsx(
|
|
2403
|
+
AlertDialog$1.Overlay,
|
|
2404
|
+
{
|
|
2405
|
+
className: "fixed inset-0 z-50 bg-foreground/30 backdrop-blur-sm data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0"
|
|
2406
|
+
}
|
|
2407
|
+
),
|
|
2408
|
+
/* @__PURE__ */ jsx(
|
|
2409
|
+
AlertDialog$1.Content,
|
|
2410
|
+
{
|
|
2411
|
+
"data-slot": "alert-dialog-content",
|
|
2412
|
+
className: cn(
|
|
2413
|
+
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-md -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-background p-6 shadow-lg outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
2414
|
+
className
|
|
2415
|
+
),
|
|
2416
|
+
...props,
|
|
2417
|
+
children
|
|
2418
|
+
}
|
|
2419
|
+
)
|
|
2420
|
+
] });
|
|
2421
|
+
}
|
|
2422
|
+
function AlertDialogHeader({ className, ...props }) {
|
|
2423
|
+
return /* @__PURE__ */ jsx(
|
|
2424
|
+
"div",
|
|
2425
|
+
{
|
|
2426
|
+
"data-slot": "alert-dialog-header",
|
|
2427
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
2428
|
+
...props
|
|
2429
|
+
}
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
function AlertDialogFooter({ className, ...props }) {
|
|
2433
|
+
return /* @__PURE__ */ jsx(
|
|
2434
|
+
"div",
|
|
2435
|
+
{
|
|
2436
|
+
"data-slot": "alert-dialog-footer",
|
|
2437
|
+
className: cn(
|
|
2438
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
2439
|
+
className
|
|
2440
|
+
),
|
|
2441
|
+
...props
|
|
2442
|
+
}
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
function AlertDialogTitle({
|
|
2446
|
+
className,
|
|
2447
|
+
...props
|
|
2448
|
+
}) {
|
|
2449
|
+
return /* @__PURE__ */ jsx(
|
|
2450
|
+
AlertDialog$1.Title,
|
|
2451
|
+
{
|
|
2452
|
+
"data-slot": "alert-dialog-title",
|
|
2453
|
+
className: cn("text-lg font-semibold leading-none", className),
|
|
2454
|
+
...props
|
|
2455
|
+
}
|
|
2456
|
+
);
|
|
2457
|
+
}
|
|
2458
|
+
function AlertDialogDescription({
|
|
2459
|
+
className,
|
|
2460
|
+
...props
|
|
2461
|
+
}) {
|
|
2462
|
+
return /* @__PURE__ */ jsx(
|
|
2463
|
+
AlertDialog$1.Description,
|
|
2464
|
+
{
|
|
2465
|
+
"data-slot": "alert-dialog-description",
|
|
2466
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
2467
|
+
...props
|
|
2468
|
+
}
|
|
2469
|
+
);
|
|
2470
|
+
}
|
|
2471
|
+
function AlertDialogAction({
|
|
2472
|
+
className,
|
|
2473
|
+
...props
|
|
2474
|
+
}) {
|
|
2475
|
+
return /* @__PURE__ */ jsx(
|
|
2476
|
+
AlertDialog$1.Action,
|
|
2477
|
+
{
|
|
2478
|
+
className: cn(buttonVariants(), className),
|
|
2479
|
+
...props
|
|
2480
|
+
}
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
function AlertDialogCancel({
|
|
2484
|
+
className,
|
|
2485
|
+
...props
|
|
2486
|
+
}) {
|
|
2487
|
+
return /* @__PURE__ */ jsx(
|
|
2488
|
+
AlertDialog$1.Cancel,
|
|
2489
|
+
{
|
|
2490
|
+
className: cn(buttonVariants({ variant: "outline" }), className),
|
|
2491
|
+
...props
|
|
2492
|
+
}
|
|
2493
|
+
);
|
|
2494
|
+
}
|
|
2495
|
+
function DataTableConfirmDelete({
|
|
2496
|
+
open,
|
|
2497
|
+
onOpenChange,
|
|
2498
|
+
context,
|
|
2499
|
+
onConfirm,
|
|
2500
|
+
config
|
|
2501
|
+
}) {
|
|
2502
|
+
if (!context) return null;
|
|
2503
|
+
const title = config?.title ? config.title(context) : context.source === "bulk" ? `Delete ${context.rows.length} ${context.rows.length === 1 ? "row" : "rows"}?` : "Delete this row?";
|
|
2504
|
+
const description = config?.description ? config.description(context) : context.source === "bulk" ? `${context.rows.length} ${context.rows.length === 1 ? "row" : "rows"} will be permanently removed. This cannot be undone.` : "This row will be permanently removed. This cannot be undone.";
|
|
2505
|
+
return /* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
2506
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
|
|
2507
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: title }),
|
|
2508
|
+
/* @__PURE__ */ jsx(AlertDialogDescription, { children: description })
|
|
2509
|
+
] }),
|
|
2510
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
|
|
2511
|
+
/* @__PURE__ */ jsx(AlertDialogCancel, { children: config?.cancelLabel ?? "Cancel" }),
|
|
2512
|
+
/* @__PURE__ */ jsx(
|
|
2513
|
+
AlertDialogAction,
|
|
2514
|
+
{
|
|
2515
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
2516
|
+
onClick: onConfirm,
|
|
2517
|
+
children: config?.confirmLabel ?? "Delete"
|
|
2518
|
+
}
|
|
2519
|
+
)
|
|
2520
|
+
] })
|
|
2521
|
+
] }) });
|
|
2522
|
+
}
|
|
2169
2523
|
function getPinningStyles(column) {
|
|
2170
2524
|
const isPinned = column.getIsPinned();
|
|
2171
2525
|
if (!isPinned) return {};
|
|
@@ -2238,7 +2592,9 @@ function ActionsCellHost({ row }) {
|
|
|
2238
2592
|
rowActions,
|
|
2239
2593
|
customRowActions,
|
|
2240
2594
|
onRowAction,
|
|
2241
|
-
onRowSave
|
|
2595
|
+
onRowSave,
|
|
2596
|
+
onView,
|
|
2597
|
+
onRequestDelete
|
|
2242
2598
|
} = useEditingContext();
|
|
2243
2599
|
const rowId = row.id;
|
|
2244
2600
|
const isRowEdit = editingRowId === rowId;
|
|
@@ -2269,6 +2625,11 @@ function ActionsCellHost({ row }) {
|
|
|
2269
2625
|
setEditingRowId(rowId);
|
|
2270
2626
|
return;
|
|
2271
2627
|
}
|
|
2628
|
+
if (a === "view") {
|
|
2629
|
+
onView?.(row.original);
|
|
2630
|
+
} else if (a === "delete") {
|
|
2631
|
+
onRequestDelete?.(row.original);
|
|
2632
|
+
}
|
|
2272
2633
|
onRowAction?.(a, row.original);
|
|
2273
2634
|
}
|
|
2274
2635
|
}
|
|
@@ -2331,7 +2692,11 @@ function DataTable({
|
|
|
2331
2692
|
labels: labelsProp,
|
|
2332
2693
|
density = "default",
|
|
2333
2694
|
theme,
|
|
2334
|
-
isolate = false
|
|
2695
|
+
isolate = false,
|
|
2696
|
+
onView,
|
|
2697
|
+
onDelete,
|
|
2698
|
+
viewSheet,
|
|
2699
|
+
confirmDelete = true
|
|
2335
2700
|
}) {
|
|
2336
2701
|
const labels = { ...DEFAULT_LABELS, ...labelsProp };
|
|
2337
2702
|
const f = {
|
|
@@ -2361,6 +2726,40 @@ function DataTable({
|
|
|
2361
2726
|
darkCss: darkTokens ? tokensToCssBlock(darkTokens) : null
|
|
2362
2727
|
};
|
|
2363
2728
|
}, [theme, isolate]);
|
|
2729
|
+
const [gridRoot, setGridRoot] = useState(null);
|
|
2730
|
+
const [viewRow, setViewRow] = useState(null);
|
|
2731
|
+
const [confirmCtx, setConfirmCtx] = useState(null);
|
|
2732
|
+
const confirmEnabled = confirmDelete !== false;
|
|
2733
|
+
const confirmConfig = typeof confirmDelete === "object" ? confirmDelete : void 0;
|
|
2734
|
+
const viewSheetEnabled = viewSheet !== false;
|
|
2735
|
+
const viewSheetConfig = viewSheet && typeof viewSheet === "object" ? viewSheet : void 0;
|
|
2736
|
+
const handleViewRequest = (row) => {
|
|
2737
|
+
onView?.(row);
|
|
2738
|
+
if (viewSheetEnabled) setViewRow(row);
|
|
2739
|
+
};
|
|
2740
|
+
const handleDeleteRequest = (row) => {
|
|
2741
|
+
if (confirmEnabled) {
|
|
2742
|
+
setConfirmCtx({ rows: [row], source: "single" });
|
|
2743
|
+
} else {
|
|
2744
|
+
onDelete?.(row);
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
const handleBulkDeleteRequest = (rows2) => {
|
|
2748
|
+
if (confirmEnabled) {
|
|
2749
|
+
setConfirmCtx({ rows: rows2, source: "bulk" });
|
|
2750
|
+
} else {
|
|
2751
|
+
onBulkDelete?.(rows2);
|
|
2752
|
+
}
|
|
2753
|
+
};
|
|
2754
|
+
const handleConfirmDelete = () => {
|
|
2755
|
+
if (!confirmCtx) return;
|
|
2756
|
+
if (confirmCtx.source === "single") {
|
|
2757
|
+
onDelete?.(confirmCtx.rows[0]);
|
|
2758
|
+
} else {
|
|
2759
|
+
onBulkDelete?.(confirmCtx.rows);
|
|
2760
|
+
}
|
|
2761
|
+
setConfirmCtx(null);
|
|
2762
|
+
};
|
|
2364
2763
|
const [sorting, setSorting] = useState([]);
|
|
2365
2764
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
2366
2765
|
const [internalGlobalFilter, setInternalGlobalFilter] = useState("");
|
|
@@ -2719,7 +3118,9 @@ function DataTable({
|
|
|
2719
3118
|
customRowActions,
|
|
2720
3119
|
onRowAction,
|
|
2721
3120
|
onCellEdit,
|
|
2722
|
-
onRowSave
|
|
3121
|
+
onRowSave,
|
|
3122
|
+
onView: handleViewRequest,
|
|
3123
|
+
onRequestDelete: handleDeleteRequest
|
|
2723
3124
|
}),
|
|
2724
3125
|
[
|
|
2725
3126
|
editingCell,
|
|
@@ -2729,19 +3130,28 @@ function DataTable({
|
|
|
2729
3130
|
customRowActions,
|
|
2730
3131
|
onRowAction,
|
|
2731
3132
|
onCellEdit,
|
|
2732
|
-
onRowSave
|
|
3133
|
+
onRowSave,
|
|
3134
|
+
// intentional: handleViewRequest / handleDeleteRequest close over
|
|
3135
|
+
// viewSheetEnabled / confirmEnabled which are derived from props above.
|
|
3136
|
+
// They're recreated each render; the inputs here capture the prop deps.
|
|
3137
|
+
onView,
|
|
3138
|
+
onDelete,
|
|
3139
|
+
onBulkDelete,
|
|
3140
|
+
viewSheetEnabled,
|
|
3141
|
+
confirmEnabled
|
|
2733
3142
|
]
|
|
2734
3143
|
);
|
|
2735
|
-
return /* @__PURE__ */ jsx(
|
|
3144
|
+
return /* @__PURE__ */ jsx(PortalContainerContext.Provider, { value: gridRoot, children: /* @__PURE__ */ jsx(
|
|
2736
3145
|
DataTableEditingContext.Provider,
|
|
2737
3146
|
{
|
|
2738
3147
|
value: editingContextValue,
|
|
2739
3148
|
children: /* @__PURE__ */ jsxs(
|
|
2740
3149
|
"div",
|
|
2741
3150
|
{
|
|
3151
|
+
ref: setGridRoot,
|
|
2742
3152
|
"data-dyno-grid": instanceId,
|
|
2743
3153
|
className: cn(
|
|
2744
|
-
"flex flex-col rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
3154
|
+
"relative flex flex-col rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
2745
3155
|
DENSITY_CLASS[density],
|
|
2746
3156
|
className
|
|
2747
3157
|
),
|
|
@@ -2760,7 +3170,7 @@ function DataTable({
|
|
|
2760
3170
|
isFetching: effectiveIsFetching,
|
|
2761
3171
|
onRefresh: f.refresh ? effectiveOnRefresh : void 0,
|
|
2762
3172
|
onAddRow: f.addRow ? handleAddRow : void 0,
|
|
2763
|
-
onBulkDelete,
|
|
3173
|
+
onBulkDelete: onBulkDelete ? handleBulkDeleteRequest : void 0,
|
|
2764
3174
|
exportFileName,
|
|
2765
3175
|
globalFilter,
|
|
2766
3176
|
onGlobalFilterChange: (v) => {
|
|
@@ -2884,12 +3294,32 @@ function DataTable({
|
|
|
2884
3294
|
labels.refreshing
|
|
2885
3295
|
] })
|
|
2886
3296
|
] }),
|
|
2887
|
-
f.pagination && /* @__PURE__ */ jsx(DataTablePagination, { table, pageSizeOptions })
|
|
3297
|
+
f.pagination && /* @__PURE__ */ jsx(DataTablePagination, { table, pageSizeOptions }),
|
|
3298
|
+
/* @__PURE__ */ jsx(
|
|
3299
|
+
DataTableViewSheet,
|
|
3300
|
+
{
|
|
3301
|
+
table,
|
|
3302
|
+
row: viewRow,
|
|
3303
|
+
open: viewRow != null,
|
|
3304
|
+
onOpenChange: (o) => !o && setViewRow(null),
|
|
3305
|
+
config: viewSheetConfig
|
|
3306
|
+
}
|
|
3307
|
+
),
|
|
3308
|
+
/* @__PURE__ */ jsx(
|
|
3309
|
+
DataTableConfirmDelete,
|
|
3310
|
+
{
|
|
3311
|
+
open: confirmCtx != null,
|
|
3312
|
+
onOpenChange: (o) => !o && setConfirmCtx(null),
|
|
3313
|
+
context: confirmCtx,
|
|
3314
|
+
onConfirm: handleConfirmDelete,
|
|
3315
|
+
config: confirmConfig
|
|
3316
|
+
}
|
|
3317
|
+
)
|
|
2888
3318
|
]
|
|
2889
3319
|
}
|
|
2890
3320
|
)
|
|
2891
3321
|
}
|
|
2892
|
-
);
|
|
3322
|
+
) });
|
|
2893
3323
|
}
|
|
2894
3324
|
function DataTableRow({
|
|
2895
3325
|
row,
|
|
@@ -2938,6 +3368,6 @@ function renderSkeleton(cols, rows) {
|
|
|
2938
3368
|
return Array.from({ length: rows }).map((_, r) => /* @__PURE__ */ jsx("tr", { className: "border-b", children: Array.from({ length: cols }).map((__, c) => /* @__PURE__ */ jsx("td", { className: "px-2 py-2", children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }) }, c)) }, r));
|
|
2939
3369
|
}
|
|
2940
3370
|
|
|
2941
|
-
export { ColumnFilterPanel, DataTable, DataTableColumnHeader, DataTablePagination, DataTableRowActions, DataTableToolbar, EditableCell, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle };
|
|
3371
|
+
export { ColumnFilterPanel, DataTable, DataTableColumnHeader, DataTablePagination, DataTableRowActions, DataTableToolbar, EditableCell, ISOLATE_DARK_TOKENS, ISOLATE_LIGHT_TOKENS, PortalContainerContext, booleanFilterFn, buildPreset, dateFilterFn, exportToCsv, exportToExcel, isFilterActive, numberFilterFn, setFilterFn, splitTheme, textFilterFn, themePresets, themeToStyle, tokensToCssBlock, tokensToStyle, usePortalContainer };
|
|
2942
3372
|
//# sourceMappingURL=index.js.map
|
|
2943
3373
|
//# sourceMappingURL=index.js.map
|