@undevy-org/tablewright 0.5.2 → 0.6.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/dist/es/components/data-table/ColumnFilterPopover.js +2 -2
- package/dist/es/components/data-table/CompoundFilterPopover.js +2 -2
- package/dist/es/components/data-table/FilterChipPopoverTrigger.js +50 -0
- package/dist/es/components/data-table/RowActionsMenu.js +3 -2
- package/dist/es/components/data-table/TableFooter.js +37 -18
- package/dist/es/components/ui/popover.js +38 -3
- package/dist/styles.css +6 -0
- package/dist/tablewright.cjs +122 -25
- package/dist/tablewright.css +6 -0
- package/dist/types/components/data-table/FilterChipPopoverTrigger.d.ts +5 -0
- package/dist/types/components/data-table/RowActionsMenu.d.ts +3 -1
- package/dist/types/components/ui/popover.d.ts +2 -2
- package/dist/types/components/ui/select.d.ts +5 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { useState, useRef, useEffect } from "react";
|
|
|
3
3
|
import { Input } from "../ui/input.js";
|
|
4
4
|
import { Checkbox } from "../ui/checkbox.js";
|
|
5
5
|
import { Popover, PopoverTrigger, PopoverContent } from "../ui/popover.js";
|
|
6
|
-
import {
|
|
6
|
+
import { FilterChipPopoverTrigger } from "./FilterChipPopoverTrigger.js";
|
|
7
7
|
import { FilterPopoverFooter } from "./FilterPopoverFooter.js";
|
|
8
8
|
import { getStringArray, getNumberRange, getDateRange, isFilterValueEmpty } from "./filter-values.js";
|
|
9
9
|
const DEFAULT_LABELS = {
|
|
@@ -520,7 +520,7 @@ function ColumnFilterPopover({
|
|
|
520
520
|
};
|
|
521
521
|
return /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
522
522
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
523
|
-
|
|
523
|
+
FilterChipPopoverTrigger,
|
|
524
524
|
{
|
|
525
525
|
label: config.label,
|
|
526
526
|
value: getDisplayValue(),
|
|
@@ -3,7 +3,7 @@ import { useState, useRef, useEffect } from "react";
|
|
|
3
3
|
import { Input } from "../ui/input.js";
|
|
4
4
|
import { Checkbox } from "../ui/checkbox.js";
|
|
5
5
|
import { Popover, PopoverTrigger, PopoverContent } from "../ui/popover.js";
|
|
6
|
-
import {
|
|
6
|
+
import { FilterChipPopoverTrigger } from "./FilterChipPopoverTrigger.js";
|
|
7
7
|
import { FilterPopoverFooter } from "./FilterPopoverFooter.js";
|
|
8
8
|
import { getCompoundValue, isFilterValueEmpty, getNumberRange, getStringArray } from "./filter-values.js";
|
|
9
9
|
const DEFAULT_LABELS = {
|
|
@@ -452,7 +452,7 @@ function CompoundFilterPopover({
|
|
|
452
452
|
};
|
|
453
453
|
return /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
454
454
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
455
|
-
|
|
455
|
+
FilterChipPopoverTrigger,
|
|
456
456
|
{
|
|
457
457
|
label: config.label,
|
|
458
458
|
value: getDisplayValue(),
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { X } from "lucide-react";
|
|
4
|
+
import { cn } from "../../lib/utils.js";
|
|
5
|
+
const FilterChipPopoverTrigger = React.forwardRef(({ label, value, onRemove, active, children, className, ...triggerRest }, ref) => /* @__PURE__ */ jsxs(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
className: cn(
|
|
9
|
+
"flex h-[var(--size-control-md)] items-center rounded-md border border-[var(--border-subtle)] text-[13px] transition-colors",
|
|
10
|
+
active ? "bg-[var(--bg-secondary)]" : "bg-[var(--bg-surface)]",
|
|
11
|
+
className
|
|
12
|
+
),
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"button",
|
|
16
|
+
{
|
|
17
|
+
ref,
|
|
18
|
+
type: "button",
|
|
19
|
+
...triggerRest,
|
|
20
|
+
className: "flex h-full flex-1 cursor-pointer items-center border-0 bg-transparent p-0 pl-2.5 pr-1.5 text-left text-[13px] font-normal text-inherit",
|
|
21
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-primary)]", children: label }),
|
|
23
|
+
value && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
24
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-tertiary)]", children: ":" }),
|
|
25
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-primary)] font-medium", children: value })
|
|
26
|
+
] }),
|
|
27
|
+
children
|
|
28
|
+
] })
|
|
29
|
+
}
|
|
30
|
+
),
|
|
31
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-full items-center pr-1.5", children: /* @__PURE__ */ jsx(
|
|
32
|
+
"button",
|
|
33
|
+
{
|
|
34
|
+
type: "button",
|
|
35
|
+
onClick: (e) => {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
onRemove();
|
|
38
|
+
},
|
|
39
|
+
className: "flex h-5 w-5 items-center justify-center rounded-sm text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--border-focus)]",
|
|
40
|
+
"aria-label": `Remove ${label} filter`,
|
|
41
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
42
|
+
}
|
|
43
|
+
) })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
));
|
|
47
|
+
FilterChipPopoverTrigger.displayName = "FilterChipPopoverTrigger";
|
|
48
|
+
export {
|
|
49
|
+
FilterChipPopoverTrigger
|
|
50
|
+
};
|
|
@@ -8,7 +8,8 @@ function RowActionsMenu({
|
|
|
8
8
|
sections,
|
|
9
9
|
align = "end",
|
|
10
10
|
triggerClassName,
|
|
11
|
-
contentClassName
|
|
11
|
+
contentClassName,
|
|
12
|
+
triggerAriaLabel = "Row actions"
|
|
12
13
|
}) {
|
|
13
14
|
const resolvedSections = sections && sections.length > 0 ? sections : actions.length > 0 ? [{ label: "", actions }] : [];
|
|
14
15
|
const isGrouped = resolvedSections.some((section) => section.label);
|
|
@@ -18,7 +19,7 @@ function RowActionsMenu({
|
|
|
18
19
|
{
|
|
19
20
|
variant: "ghost",
|
|
20
21
|
size: "icon",
|
|
21
|
-
"aria-label":
|
|
22
|
+
"aria-label": triggerAriaLabel,
|
|
22
23
|
className: cn(
|
|
23
24
|
"h-7 w-7 rounded-sm p-0 opacity-0 transition-opacity group-hover:opacity-100 data-[state=open]:opacity-100",
|
|
24
25
|
triggerClassName
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from "react";
|
|
2
3
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
3
4
|
import { Button } from "../ui/button.js";
|
|
4
5
|
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "../ui/select.js";
|
|
@@ -62,26 +63,44 @@ function TableFooter(props) {
|
|
|
62
63
|
renderPagination(props)
|
|
63
64
|
] });
|
|
64
65
|
}
|
|
66
|
+
function RowsPerPagePagination(props) {
|
|
67
|
+
const rowsPerPageLabelId = useId();
|
|
68
|
+
const rowsPerPageOptions = props.rowsPerPageOptions ?? defaultRowsPerPageOptions;
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 lg:justify-end", children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"span",
|
|
73
|
+
{
|
|
74
|
+
id: rowsPerPageLabelId,
|
|
75
|
+
className: "text-[12px] text-[var(--text-secondary)]",
|
|
76
|
+
children: "Rows per page"
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ jsxs(
|
|
80
|
+
Select,
|
|
81
|
+
{
|
|
82
|
+
value: String(props.rowsPerPage),
|
|
83
|
+
onValueChange: (value) => props.onRowsPerPageChange(Number(value)),
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
SelectTrigger,
|
|
87
|
+
{
|
|
88
|
+
"aria-labelledby": rowsPerPageLabelId,
|
|
89
|
+
className: "h-[var(--size-control-sm)] w-[var(--size-select-compact)]",
|
|
90
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
/* @__PURE__ */ jsx(SelectContent, { children: rowsPerPageOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: String(option), children: option }, option)) })
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
] }),
|
|
98
|
+
renderNumericPager(props)
|
|
99
|
+
] });
|
|
100
|
+
}
|
|
65
101
|
function renderPagination(props) {
|
|
66
102
|
if (props.paginationVariant === "perPage") {
|
|
67
|
-
|
|
68
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 lg:justify-end", children: [
|
|
69
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
70
|
-
/* @__PURE__ */ jsx("span", { className: "text-[12px] text-[var(--text-secondary)]", children: "Rows per page" }),
|
|
71
|
-
/* @__PURE__ */ jsxs(
|
|
72
|
-
Select,
|
|
73
|
-
{
|
|
74
|
-
value: String(props.rowsPerPage),
|
|
75
|
-
onValueChange: (value) => props.onRowsPerPageChange(Number(value)),
|
|
76
|
-
children: [
|
|
77
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-[var(--size-control-sm)] w-[var(--size-select-compact)]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
78
|
-
/* @__PURE__ */ jsx(SelectContent, { children: rowsPerPageOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: String(option), children: option }, option)) })
|
|
79
|
-
]
|
|
80
|
-
}
|
|
81
|
-
)
|
|
82
|
-
] }),
|
|
83
|
-
renderNumericPager(props)
|
|
84
|
-
] });
|
|
103
|
+
return /* @__PURE__ */ jsx(RowsPerPagePagination, { ...props });
|
|
85
104
|
}
|
|
86
105
|
if (props.paginationVariant !== "pages") {
|
|
87
106
|
return null;
|
|
@@ -4,23 +4,58 @@ import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
5
5
|
import { STYLE_SCOPE } from "../../lib/style-scope.js";
|
|
6
6
|
import { usePortalContainer } from "../../context/portal-container-context.js";
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const PopoverContext = React.createContext(null);
|
|
8
|
+
function usePopoverContext() {
|
|
9
|
+
const context = React.useContext(PopoverContext);
|
|
10
|
+
if (!context) {
|
|
11
|
+
throw new Error("Popover components must be used within Popover");
|
|
12
|
+
}
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
function Popover(props) {
|
|
16
|
+
const triggerId = React.useId();
|
|
17
|
+
const [triggerMounted, setTriggerMounted] = React.useState(false);
|
|
18
|
+
const setTriggerMountedStable = React.useCallback((mounted) => {
|
|
19
|
+
setTriggerMounted(mounted);
|
|
20
|
+
}, []);
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
PopoverContext.Provider,
|
|
23
|
+
{
|
|
24
|
+
value: { triggerId, triggerMounted, setTriggerMounted: setTriggerMountedStable },
|
|
25
|
+
children: /* @__PURE__ */ jsx(PopoverPrimitive.Root, { ...props })
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
const PopoverTrigger = React.forwardRef(({ id, ...props }, ref) => {
|
|
30
|
+
const { triggerId, setTriggerMounted } = usePopoverContext();
|
|
31
|
+
const resolvedId = id ?? triggerId;
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
setTriggerMounted(true);
|
|
34
|
+
return () => setTriggerMounted(false);
|
|
35
|
+
}, [setTriggerMounted]);
|
|
36
|
+
return /* @__PURE__ */ jsx(PopoverPrimitive.Trigger, { ref, id: resolvedId, ...props });
|
|
37
|
+
});
|
|
38
|
+
PopoverTrigger.displayName = PopoverPrimitive.Trigger.displayName;
|
|
9
39
|
const PopoverAnchor = PopoverPrimitive.Anchor;
|
|
10
40
|
const PopoverContent = React.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
|
|
11
41
|
const container = usePortalContainer();
|
|
42
|
+
const { triggerId, triggerMounted } = usePopoverContext();
|
|
43
|
+
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest } = props;
|
|
44
|
+
const resolvedAriaLabelledBy = ariaLabel !== void 0 && ariaLabelledBy === void 0 ? void 0 : ariaLabelledBy ?? (triggerMounted ? triggerId : void 0);
|
|
12
45
|
return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
|
|
13
46
|
PopoverPrimitive.Content,
|
|
14
47
|
{
|
|
15
48
|
ref,
|
|
16
49
|
align,
|
|
17
50
|
sideOffset,
|
|
51
|
+
"aria-label": ariaLabel,
|
|
52
|
+
"aria-labelledby": resolvedAriaLabelledBy,
|
|
18
53
|
className: cn(
|
|
19
54
|
STYLE_SCOPE,
|
|
20
55
|
"z-50 w-72 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-surface)] p-4 text-[var(--text-primary)] outline-none [box-shadow:var(--shadow-menu)]",
|
|
21
56
|
className
|
|
22
57
|
),
|
|
23
|
-
...
|
|
58
|
+
...rest
|
|
24
59
|
}
|
|
25
60
|
) });
|
|
26
61
|
});
|
package/dist/styles.css
CHANGED
|
@@ -942,6 +942,9 @@
|
|
|
942
942
|
.border {
|
|
943
943
|
border-width: 1px
|
|
944
944
|
}
|
|
945
|
+
.border-0 {
|
|
946
|
+
border-width: 0px
|
|
947
|
+
}
|
|
945
948
|
.border-b {
|
|
946
949
|
border-bottom-width: 1px
|
|
947
950
|
}
|
|
@@ -1346,6 +1349,9 @@
|
|
|
1346
1349
|
.text-\[var\(--text-utility\)\] {
|
|
1347
1350
|
color: var(--text-utility)
|
|
1348
1351
|
}
|
|
1352
|
+
.text-inherit {
|
|
1353
|
+
color: inherit
|
|
1354
|
+
}
|
|
1349
1355
|
.text-red-600 {
|
|
1350
1356
|
--tw-text-opacity: 1;
|
|
1351
1357
|
color: rgb(220 38 38 / var(--tw-text-opacity, 1))
|
package/dist/tablewright.cjs
CHANGED
|
@@ -253,23 +253,58 @@ const Input = React__namespace.forwardRef(
|
|
|
253
253
|
}
|
|
254
254
|
);
|
|
255
255
|
Input.displayName = "Input";
|
|
256
|
-
const
|
|
257
|
-
|
|
256
|
+
const PopoverContext = React__namespace.createContext(null);
|
|
257
|
+
function usePopoverContext() {
|
|
258
|
+
const context = React__namespace.useContext(PopoverContext);
|
|
259
|
+
if (!context) {
|
|
260
|
+
throw new Error("Popover components must be used within Popover");
|
|
261
|
+
}
|
|
262
|
+
return context;
|
|
263
|
+
}
|
|
264
|
+
function Popover(props) {
|
|
265
|
+
const triggerId = React__namespace.useId();
|
|
266
|
+
const [triggerMounted, setTriggerMounted] = React__namespace.useState(false);
|
|
267
|
+
const setTriggerMountedStable = React__namespace.useCallback((mounted) => {
|
|
268
|
+
setTriggerMounted(mounted);
|
|
269
|
+
}, []);
|
|
270
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
271
|
+
PopoverContext.Provider,
|
|
272
|
+
{
|
|
273
|
+
value: { triggerId, triggerMounted, setTriggerMounted: setTriggerMountedStable },
|
|
274
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Root, { ...props })
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const PopoverTrigger = React__namespace.forwardRef(({ id, ...props }, ref) => {
|
|
279
|
+
const { triggerId, setTriggerMounted } = usePopoverContext();
|
|
280
|
+
const resolvedId = id ?? triggerId;
|
|
281
|
+
React__namespace.useEffect(() => {
|
|
282
|
+
setTriggerMounted(true);
|
|
283
|
+
return () => setTriggerMounted(false);
|
|
284
|
+
}, [setTriggerMounted]);
|
|
285
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Trigger, { ref, id: resolvedId, ...props });
|
|
286
|
+
});
|
|
287
|
+
PopoverTrigger.displayName = PopoverPrimitive__namespace.Trigger.displayName;
|
|
258
288
|
const PopoverAnchor = PopoverPrimitive__namespace.Anchor;
|
|
259
289
|
const PopoverContent = React__namespace.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
|
|
260
290
|
const container = usePortalContainer();
|
|
291
|
+
const { triggerId, triggerMounted } = usePopoverContext();
|
|
292
|
+
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest } = props;
|
|
293
|
+
const resolvedAriaLabelledBy = ariaLabel !== void 0 && ariaLabelledBy === void 0 ? void 0 : ariaLabelledBy ?? (triggerMounted ? triggerId : void 0);
|
|
261
294
|
return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { container, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
262
295
|
PopoverPrimitive__namespace.Content,
|
|
263
296
|
{
|
|
264
297
|
ref,
|
|
265
298
|
align,
|
|
266
299
|
sideOffset,
|
|
300
|
+
"aria-label": ariaLabel,
|
|
301
|
+
"aria-labelledby": resolvedAriaLabelledBy,
|
|
267
302
|
className: cn(
|
|
268
303
|
STYLE_SCOPE,
|
|
269
304
|
"z-50 w-72 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-surface)] p-4 text-[var(--text-primary)] outline-none [box-shadow:var(--shadow-menu)]",
|
|
270
305
|
className
|
|
271
306
|
),
|
|
272
|
-
...
|
|
307
|
+
...rest
|
|
273
308
|
}
|
|
274
309
|
) });
|
|
275
310
|
});
|
|
@@ -1360,7 +1395,8 @@ function RowActionsMenu({
|
|
|
1360
1395
|
sections,
|
|
1361
1396
|
align = "end",
|
|
1362
1397
|
triggerClassName,
|
|
1363
|
-
contentClassName
|
|
1398
|
+
contentClassName,
|
|
1399
|
+
triggerAriaLabel = "Row actions"
|
|
1364
1400
|
}) {
|
|
1365
1401
|
const resolvedSections = sections && sections.length > 0 ? sections : actions.length > 0 ? [{ label: "", actions }] : [];
|
|
1366
1402
|
const isGrouped = resolvedSections.some((section) => section.label);
|
|
@@ -1370,7 +1406,7 @@ function RowActionsMenu({
|
|
|
1370
1406
|
{
|
|
1371
1407
|
variant: "ghost",
|
|
1372
1408
|
size: "icon",
|
|
1373
|
-
"aria-label":
|
|
1409
|
+
"aria-label": triggerAriaLabel,
|
|
1374
1410
|
className: cn(
|
|
1375
1411
|
"h-7 w-7 rounded-sm p-0 opacity-0 transition-opacity group-hover:opacity-100 data-[state=open]:opacity-100",
|
|
1376
1412
|
triggerClassName
|
|
@@ -1673,26 +1709,44 @@ function TableFooter(props) {
|
|
|
1673
1709
|
renderPagination(props)
|
|
1674
1710
|
] });
|
|
1675
1711
|
}
|
|
1712
|
+
function RowsPerPagePagination(props) {
|
|
1713
|
+
const rowsPerPageLabelId = React.useId();
|
|
1714
|
+
const rowsPerPageOptions = props.rowsPerPageOptions ?? defaultRowsPerPageOptions;
|
|
1715
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 lg:justify-end", children: [
|
|
1716
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1717
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1718
|
+
"span",
|
|
1719
|
+
{
|
|
1720
|
+
id: rowsPerPageLabelId,
|
|
1721
|
+
className: "text-[12px] text-[var(--text-secondary)]",
|
|
1722
|
+
children: "Rows per page"
|
|
1723
|
+
}
|
|
1724
|
+
),
|
|
1725
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1726
|
+
Select,
|
|
1727
|
+
{
|
|
1728
|
+
value: String(props.rowsPerPage),
|
|
1729
|
+
onValueChange: (value) => props.onRowsPerPageChange(Number(value)),
|
|
1730
|
+
children: [
|
|
1731
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1732
|
+
SelectTrigger,
|
|
1733
|
+
{
|
|
1734
|
+
"aria-labelledby": rowsPerPageLabelId,
|
|
1735
|
+
className: "h-[var(--size-control-sm)] w-[var(--size-select-compact)]",
|
|
1736
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {})
|
|
1737
|
+
}
|
|
1738
|
+
),
|
|
1739
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: rowsPerPageOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(option), children: option }, option)) })
|
|
1740
|
+
]
|
|
1741
|
+
}
|
|
1742
|
+
)
|
|
1743
|
+
] }),
|
|
1744
|
+
renderNumericPager(props)
|
|
1745
|
+
] });
|
|
1746
|
+
}
|
|
1676
1747
|
function renderPagination(props) {
|
|
1677
1748
|
if (props.paginationVariant === "perPage") {
|
|
1678
|
-
|
|
1679
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 lg:justify-end", children: [
|
|
1680
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1681
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] text-[var(--text-secondary)]", children: "Rows per page" }),
|
|
1682
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1683
|
-
Select,
|
|
1684
|
-
{
|
|
1685
|
-
value: String(props.rowsPerPage),
|
|
1686
|
-
onValueChange: (value) => props.onRowsPerPageChange(Number(value)),
|
|
1687
|
-
children: [
|
|
1688
|
-
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-[var(--size-control-sm)] w-[var(--size-select-compact)]", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
|
|
1689
|
-
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: rowsPerPageOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: String(option), children: option }, option)) })
|
|
1690
|
-
]
|
|
1691
|
-
}
|
|
1692
|
-
)
|
|
1693
|
-
] }),
|
|
1694
|
-
renderNumericPager(props)
|
|
1695
|
-
] });
|
|
1749
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RowsPerPagePagination, { ...props });
|
|
1696
1750
|
}
|
|
1697
1751
|
if (props.paginationVariant !== "pages") {
|
|
1698
1752
|
return null;
|
|
@@ -2722,6 +2776,49 @@ function GroupedColumnToggle({
|
|
|
2722
2776
|
}
|
|
2723
2777
|
);
|
|
2724
2778
|
}
|
|
2779
|
+
const FilterChipPopoverTrigger = React__namespace.forwardRef(({ label, value, onRemove, active, children, className, ...triggerRest }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2780
|
+
"div",
|
|
2781
|
+
{
|
|
2782
|
+
className: cn(
|
|
2783
|
+
"flex h-[var(--size-control-md)] items-center rounded-md border border-[var(--border-subtle)] text-[13px] transition-colors",
|
|
2784
|
+
active ? "bg-[var(--bg-secondary)]" : "bg-[var(--bg-surface)]",
|
|
2785
|
+
className
|
|
2786
|
+
),
|
|
2787
|
+
children: [
|
|
2788
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2789
|
+
"button",
|
|
2790
|
+
{
|
|
2791
|
+
ref,
|
|
2792
|
+
type: "button",
|
|
2793
|
+
...triggerRest,
|
|
2794
|
+
className: "flex h-full flex-1 cursor-pointer items-center border-0 bg-transparent p-0 pl-2.5 pr-1.5 text-left text-[13px] font-normal text-inherit",
|
|
2795
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
2796
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[var(--text-primary)]", children: label }),
|
|
2797
|
+
value && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2798
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[var(--text-tertiary)]", children: ":" }),
|
|
2799
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[var(--text-primary)] font-medium", children: value })
|
|
2800
|
+
] }),
|
|
2801
|
+
children
|
|
2802
|
+
] })
|
|
2803
|
+
}
|
|
2804
|
+
),
|
|
2805
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center pr-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2806
|
+
"button",
|
|
2807
|
+
{
|
|
2808
|
+
type: "button",
|
|
2809
|
+
onClick: (e) => {
|
|
2810
|
+
e.stopPropagation();
|
|
2811
|
+
onRemove();
|
|
2812
|
+
},
|
|
2813
|
+
className: "flex h-5 w-5 items-center justify-center rounded-sm text-[var(--text-tertiary)] hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--border-focus)]",
|
|
2814
|
+
"aria-label": `Remove ${label} filter`,
|
|
2815
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
|
|
2816
|
+
}
|
|
2817
|
+
) })
|
|
2818
|
+
]
|
|
2819
|
+
}
|
|
2820
|
+
));
|
|
2821
|
+
FilterChipPopoverTrigger.displayName = "FilterChipPopoverTrigger";
|
|
2725
2822
|
function isObjectValue(value) {
|
|
2726
2823
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2727
2824
|
}
|
|
@@ -3265,7 +3362,7 @@ function ColumnFilterPopover({
|
|
|
3265
3362
|
};
|
|
3266
3363
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
3267
3364
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3268
|
-
|
|
3365
|
+
FilterChipPopoverTrigger,
|
|
3269
3366
|
{
|
|
3270
3367
|
label: config.label,
|
|
3271
3368
|
value: getDisplayValue(),
|
|
@@ -3741,7 +3838,7 @@ function CompoundFilterPopover({
|
|
|
3741
3838
|
};
|
|
3742
3839
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
3743
3840
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3744
|
-
|
|
3841
|
+
FilterChipPopoverTrigger,
|
|
3745
3842
|
{
|
|
3746
3843
|
label: config.label,
|
|
3747
3844
|
value: getDisplayValue(),
|
package/dist/tablewright.css
CHANGED
|
@@ -790,6 +790,9 @@
|
|
|
790
790
|
.border {
|
|
791
791
|
border-width: 1px
|
|
792
792
|
}
|
|
793
|
+
.border-0 {
|
|
794
|
+
border-width: 0px
|
|
795
|
+
}
|
|
793
796
|
.border-b {
|
|
794
797
|
border-bottom-width: 1px
|
|
795
798
|
}
|
|
@@ -1194,6 +1197,9 @@
|
|
|
1194
1197
|
.text-\[var\(--text-utility\)\] {
|
|
1195
1198
|
color: var(--text-utility)
|
|
1196
1199
|
}
|
|
1200
|
+
.text-inherit {
|
|
1201
|
+
color: inherit
|
|
1202
|
+
}
|
|
1197
1203
|
.text-red-600 {
|
|
1198
1204
|
--tw-text-opacity: 1;
|
|
1199
1205
|
color: rgb(220 38 38 / var(--tw-text-opacity, 1))
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { FilterChipProps } from "./FilterChip.js";
|
|
3
|
+
export type FilterChipPopoverTriggerProps = Omit<FilterChipProps, keyof React.HTMLAttributes<HTMLDivElement>> & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
4
|
+
/** Filter chip shell whose label area is a real button for PopoverTrigger asChild. */
|
|
5
|
+
export declare const FilterChipPopoverTrigger: React.ForwardRefExoticComponent<Omit<FilterChipProps, keyof React.HTMLAttributes<HTMLDivElement>> & React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -5,6 +5,8 @@ interface RowActionsMenuProps {
|
|
|
5
5
|
align?: "start" | "center" | "end";
|
|
6
6
|
triggerClassName?: string;
|
|
7
7
|
contentClassName?: string;
|
|
8
|
+
/** Accessible name for the icon trigger (e.g. "Actions for TX-123"). */
|
|
9
|
+
triggerAriaLabel?: string;
|
|
8
10
|
}
|
|
9
|
-
export declare function RowActionsMenu({ actions, sections, align, triggerClassName, contentClassName, }: RowActionsMenuProps): import("react").JSX.Element;
|
|
11
|
+
export declare function RowActionsMenu({ actions, sections, align, triggerClassName, contentClassName, triggerAriaLabel, }: RowActionsMenuProps): import("react").JSX.Element;
|
|
10
12
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3
|
-
declare
|
|
4
|
-
declare const PopoverTrigger: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
3
|
+
declare function Popover(props: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
declare const PopoverTrigger: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
5
|
declare const PopoverAnchor: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & React.RefAttributes<HTMLDivElement>>;
|
|
6
6
|
declare const PopoverContent: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
7
7
|
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
3
|
declare const Select: React.FC<SelectPrimitive.SelectProps>;
|
|
4
|
+
/**
|
|
5
|
+
* Select field control. Give the trigger an accessible name with `aria-label`, `aria-labelledby`,
|
|
6
|
+
* or a `<label htmlFor>` that points at the trigger's `id` — the trigger shows the selected value,
|
|
7
|
+
* not the field name.
|
|
8
|
+
*/
|
|
4
9
|
declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
10
|
declare const SelectContent: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
11
|
declare const SelectItem: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undevy-org/tablewright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "React data-table and application-shell components: filters, drawers, row controls, sortable and resizable columns, built on Radix UI and TanStack Table.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|