@undevy-org/tablewright 0.4.0 → 0.5.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/AppliedStateChips.js +15 -6
- package/dist/es/components/data-table/ColumnFilterPopover.js +42 -29
- package/dist/es/components/data-table/CompoundFilterPopover.js +38 -22
- package/dist/es/components/data-table/DrawerShell.js +2 -0
- package/dist/es/components/data-table/FilterFormPanel.js +36 -18
- package/dist/es/components/data-table/FilterPopoverFooter.js +12 -4
- package/dist/es/components/data-table/TableLayout.js +10 -1
- package/dist/es/components/layout/Sidebar.js +8 -1
- package/dist/es/components/layout/SidebarAccountMenu.js +3 -2
- package/dist/es/components/layout/SidebarUser.js +2 -1
- package/dist/es/lib/collapsed-nav-link-a11y.js +6 -0
- package/dist/es/lib/decorative-avatar-alt.js +6 -0
- package/dist/es/lib/scroll-region-tab-index.js +4 -0
- package/dist/styles.css +3 -0
- package/dist/tablewright.cjs +175 -89
- package/dist/tablewright.css +3 -0
- package/dist/types/components/data-table/AppliedStateChips.d.ts +13 -1
- package/dist/types/components/data-table/ColumnFilterPopover.d.ts +22 -1
- package/dist/types/components/data-table/CompoundFilterPopover.d.ts +19 -1
- package/dist/types/components/data-table/FilterFormPanel.d.ts +17 -1
- package/dist/types/components/data-table/FilterPopoverFooter.d.ts +8 -1
- package/dist/types/components/layout/Sidebar.d.ts +1 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/lib/collapsed-nav-link-a11y.d.ts +2 -0
- package/dist/types/lib/decorative-avatar-alt.d.ts +2 -0
- package/dist/types/lib/scroll-region-tab-index.d.ts +2 -0
- package/package.json +7 -2
package/dist/tablewright.cjs
CHANGED
|
@@ -682,6 +682,7 @@ function CopyableText({
|
|
|
682
682
|
)
|
|
683
683
|
] });
|
|
684
684
|
}
|
|
685
|
+
const SCROLL_REGION_TAB_INDEX = 0;
|
|
685
686
|
function useScrollActivity(idleMs = 700) {
|
|
686
687
|
const nodeRef = React.useRef(null);
|
|
687
688
|
const [nodeVersion, setNodeVersion] = React.useState(0);
|
|
@@ -797,6 +798,7 @@ function DrawerShell({
|
|
|
797
798
|
"div",
|
|
798
799
|
{
|
|
799
800
|
ref: bodyScrollRef,
|
|
801
|
+
tabIndex: SCROLL_REGION_TAB_INDEX,
|
|
800
802
|
className: "scrollbar-auto-hide min-h-0 flex-1 overflow-y-auto px-6 py-6",
|
|
801
803
|
children
|
|
802
804
|
}
|
|
@@ -862,7 +864,15 @@ function TableLayout({ children, className }) {
|
|
|
862
864
|
}
|
|
863
865
|
function ScrollArea({ children, className }) {
|
|
864
866
|
const scrollRef = useScrollActivity();
|
|
865
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
867
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
868
|
+
"div",
|
|
869
|
+
{
|
|
870
|
+
ref: scrollRef,
|
|
871
|
+
tabIndex: SCROLL_REGION_TAB_INDEX,
|
|
872
|
+
className: cn("scrollbar-auto-hide flex-1 overflow-auto", className),
|
|
873
|
+
children
|
|
874
|
+
}
|
|
875
|
+
);
|
|
866
876
|
}
|
|
867
877
|
TableLayout.ScrollArea = ScrollArea;
|
|
868
878
|
function stickyStyle(meta, isHeader) {
|
|
@@ -1200,16 +1210,24 @@ const ViewChip = React__namespace.forwardRef(
|
|
|
1200
1210
|
}
|
|
1201
1211
|
);
|
|
1202
1212
|
ViewChip.displayName = "ViewChip";
|
|
1213
|
+
const DEFAULT_LABELS$5 = {
|
|
1214
|
+
apply: "Apply",
|
|
1215
|
+
clear: "Clear"
|
|
1216
|
+
};
|
|
1203
1217
|
function FilterPopoverFooter({
|
|
1204
1218
|
onApply,
|
|
1205
1219
|
onClear,
|
|
1206
|
-
|
|
1207
|
-
|
|
1220
|
+
labels: labelOverrides,
|
|
1221
|
+
applyLabel,
|
|
1222
|
+
clearLabel,
|
|
1208
1223
|
className
|
|
1209
1224
|
}) {
|
|
1225
|
+
const labels = { ...DEFAULT_LABELS$5, ...labelOverrides };
|
|
1226
|
+
const apply = applyLabel ?? labels.apply;
|
|
1227
|
+
const clear = clearLabel ?? labels.clear;
|
|
1210
1228
|
return /* @__PURE__ */ jsxRuntime.jsxs(ButtonFooter, { className: cn("px-3 py-2.5", className), children: [
|
|
1211
|
-
onClear && /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: onClear, children:
|
|
1212
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", size: "sm", onClick: onApply, children:
|
|
1229
|
+
onClear && /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: onClear, children: clear }),
|
|
1230
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", size: "sm", onClick: onApply, children: apply })
|
|
1213
1231
|
] });
|
|
1214
1232
|
}
|
|
1215
1233
|
function Root({
|
|
@@ -1837,6 +1855,9 @@ const AppShellContext = React.createContext(null);
|
|
|
1837
1855
|
function useAppShell() {
|
|
1838
1856
|
return React.useContext(AppShellContext);
|
|
1839
1857
|
}
|
|
1858
|
+
function collapsedNavLinkAriaLabel(showExpanded, label) {
|
|
1859
|
+
return showExpanded ? void 0 : label;
|
|
1860
|
+
}
|
|
1840
1861
|
function isItemActive(href, activeKey) {
|
|
1841
1862
|
if (href === "" || href === "/") return activeKey === "" || activeKey === "/";
|
|
1842
1863
|
return activeKey === href || activeKey.startsWith(href + "/");
|
|
@@ -1909,10 +1930,15 @@ const Sidebar = React__namespace.forwardRef(
|
|
|
1909
1930
|
),
|
|
1910
1931
|
showExpanded && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[13px]", children: item.label })
|
|
1911
1932
|
] });
|
|
1933
|
+
const collapsedLinkLabel = collapsedNavLinkAriaLabel(
|
|
1934
|
+
showExpanded,
|
|
1935
|
+
item.label
|
|
1936
|
+
);
|
|
1912
1937
|
if (renderLink) {
|
|
1913
1938
|
return /* @__PURE__ */ jsxRuntime.jsx(React__namespace.Fragment, { children: renderLink(item.href, {
|
|
1914
1939
|
className: itemClassName,
|
|
1915
|
-
children
|
|
1940
|
+
children,
|
|
1941
|
+
...collapsedLinkLabel ? { "aria-label": collapsedLinkLabel } : {}
|
|
1916
1942
|
}) }, item.key);
|
|
1917
1943
|
}
|
|
1918
1944
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1920,6 +1946,7 @@ const Sidebar = React__namespace.forwardRef(
|
|
|
1920
1946
|
{
|
|
1921
1947
|
href: item.href,
|
|
1922
1948
|
className: itemClassName,
|
|
1949
|
+
"aria-label": collapsedLinkLabel,
|
|
1923
1950
|
children
|
|
1924
1951
|
},
|
|
1925
1952
|
item.key
|
|
@@ -2080,6 +2107,9 @@ const AppShell = Object.assign(AppShellRoot, {
|
|
|
2080
2107
|
Header: AppShellHeader,
|
|
2081
2108
|
Content: AppShellContent
|
|
2082
2109
|
});
|
|
2110
|
+
function decorativeAvatarAlt(adjacentNameVisible, name) {
|
|
2111
|
+
return adjacentNameVisible ? "" : name;
|
|
2112
|
+
}
|
|
2083
2113
|
function getInitials$1(name) {
|
|
2084
2114
|
return name.split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
|
|
2085
2115
|
}
|
|
@@ -2101,7 +2131,7 @@ const SidebarUser = React__namespace.forwardRef(
|
|
|
2101
2131
|
"img",
|
|
2102
2132
|
{
|
|
2103
2133
|
src: avatarUrl,
|
|
2104
|
-
alt: name,
|
|
2134
|
+
alt: decorativeAvatarAlt(!effectiveCollapsed, name),
|
|
2105
2135
|
className: "h-8 w-8 shrink-0 rounded-full object-cover"
|
|
2106
2136
|
}
|
|
2107
2137
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[var(--bg-tertiary)] text-[11px] font-semibold text-[var(--text-secondary)]", children: getInitials$1(name) }),
|
|
@@ -2133,7 +2163,7 @@ function SidebarAccountMenu({
|
|
|
2133
2163
|
"img",
|
|
2134
2164
|
{
|
|
2135
2165
|
src: avatarUrl,
|
|
2136
|
-
alt: name,
|
|
2166
|
+
alt: decorativeAvatarAlt(!effectiveCollapsed, name),
|
|
2137
2167
|
className: "h-7 w-7 shrink-0 rounded-full object-cover"
|
|
2138
2168
|
}
|
|
2139
2169
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-[var(--bg-tertiary)] text-[11px] font-semibold text-[var(--text-secondary)]", children: getInitials(name) });
|
|
@@ -2169,7 +2199,7 @@ function SidebarAccountMenu({
|
|
|
2169
2199
|
"img",
|
|
2170
2200
|
{
|
|
2171
2201
|
src: avatarUrl,
|
|
2172
|
-
alt: name,
|
|
2202
|
+
alt: decorativeAvatarAlt(true, name),
|
|
2173
2203
|
className: "h-8 w-8 shrink-0 rounded-full object-cover"
|
|
2174
2204
|
}
|
|
2175
2205
|
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[var(--bg-tertiary)] text-[11px] font-semibold text-[var(--text-secondary)]", children: getInitials(name) }),
|
|
@@ -2366,7 +2396,7 @@ function ExpiryTimestampCell({ value, timestampMs }) {
|
|
|
2366
2396
|
relativeLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `text-[11px] ${urgencyClass[urgency]}`, children: relativeLabel })
|
|
2367
2397
|
] });
|
|
2368
2398
|
}
|
|
2369
|
-
const DEFAULT_LABELS$
|
|
2399
|
+
const DEFAULT_LABELS$4 = {
|
|
2370
2400
|
sort: "Sort",
|
|
2371
2401
|
sortByColumn: (label) => `Sort by ${label}`,
|
|
2372
2402
|
ascending: "Ascending",
|
|
@@ -2428,7 +2458,7 @@ function ColumnHeaderMenu({
|
|
|
2428
2458
|
menuWidth = "w-[200px]"
|
|
2429
2459
|
}) {
|
|
2430
2460
|
const [open, setOpen] = React.useState(false);
|
|
2431
|
-
const labels = { ...DEFAULT_LABELS$
|
|
2461
|
+
const labels = { ...DEFAULT_LABELS$4, ...labelOverrides };
|
|
2432
2462
|
const isStacked = !!primaryLabel;
|
|
2433
2463
|
const isSingleSortable = !!label && !!onSort;
|
|
2434
2464
|
const isSortable = isStacked || isSingleSortable;
|
|
@@ -2732,7 +2762,7 @@ function isFilterValueEmpty(value) {
|
|
|
2732
2762
|
if (Array.isArray(value)) return value.length === 0;
|
|
2733
2763
|
return Object.values(value).every((x) => typeof x !== "number" && isFilterValueEmpty(x));
|
|
2734
2764
|
}
|
|
2735
|
-
const DEFAULT_LABELS$
|
|
2765
|
+
const DEFAULT_LABELS$3 = {
|
|
2736
2766
|
searchPlaceholder: "Search...",
|
|
2737
2767
|
addValuePlaceholder: "Add value...",
|
|
2738
2768
|
noData: "no data",
|
|
@@ -2744,6 +2774,9 @@ const DEFAULT_LABELS$2 = {
|
|
|
2744
2774
|
chipTo: "to",
|
|
2745
2775
|
chipMin: "min",
|
|
2746
2776
|
chipMax: "max",
|
|
2777
|
+
contains: "Contains",
|
|
2778
|
+
orBadge: "OR",
|
|
2779
|
+
numberInputPlaceholder: "0",
|
|
2747
2780
|
valuesCount: (n) => `${n} values`,
|
|
2748
2781
|
selectedCount: (n) => `${n} selected`
|
|
2749
2782
|
};
|
|
@@ -2774,8 +2807,11 @@ function ColumnFilterPopover({
|
|
|
2774
2807
|
chipClassName,
|
|
2775
2808
|
stats,
|
|
2776
2809
|
requestOpen,
|
|
2777
|
-
onRequestOpenHandled
|
|
2810
|
+
onRequestOpenHandled,
|
|
2811
|
+
labels: labelOverrides,
|
|
2812
|
+
footerLabels
|
|
2778
2813
|
}) {
|
|
2814
|
+
const labels = { ...DEFAULT_LABELS$3, ...labelOverrides };
|
|
2779
2815
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
2780
2816
|
const onRequestOpenHandledRef = React.useRef(onRequestOpenHandled);
|
|
2781
2817
|
React.useEffect(() => {
|
|
@@ -2912,7 +2948,7 @@ function ColumnFilterPopover({
|
|
|
2912
2948
|
if (!textStats || textStats.type !== "text") {
|
|
2913
2949
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-wrap", children: [
|
|
2914
2950
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-[var(--text-tertiary)] whitespace-nowrap min-w-[54px]", children: label }),
|
|
2915
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children:
|
|
2951
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children: labels.noData })
|
|
2916
2952
|
] });
|
|
2917
2953
|
}
|
|
2918
2954
|
const { samples, totalUnique } = textStats;
|
|
@@ -2942,8 +2978,8 @@ function ColumnFilterPopover({
|
|
|
2942
2978
|
const filtText = filteredStats?.type === "text" ? filteredStats : null;
|
|
2943
2979
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 w-64 space-y-3", children: [
|
|
2944
2980
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children: [
|
|
2945
|
-
|
|
2946
|
-
draftTags.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] font-semibold text-[var(--tag-blue-text)] bg-[var(--tag-blue-bg)] rounded px-1 py-0.5 uppercase", children:
|
|
2981
|
+
labels.contains,
|
|
2982
|
+
draftTags.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] font-semibold text-[var(--tag-blue-text)] bg-[var(--tag-blue-bg)] rounded px-1 py-0.5 uppercase", children: labels.orBadge })
|
|
2947
2983
|
] }),
|
|
2948
2984
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1 rounded-md border border-[var(--border-subtle)] bg-[var(--bg-surface)] px-2 py-1.5 focus-within:border-[var(--border-focus)]", children: [
|
|
2949
2985
|
draftTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2970,7 +3006,7 @@ function ColumnFilterPopover({
|
|
|
2970
3006
|
{
|
|
2971
3007
|
autoFocus: true,
|
|
2972
3008
|
className: "flex-1 min-w-[60px] bg-transparent text-sm text-[var(--text-primary)] outline-none placeholder:text-[var(--text-tertiary)]",
|
|
2973
|
-
placeholder: draftTags.length === 0 ?
|
|
3009
|
+
placeholder: draftTags.length === 0 ? labels.searchPlaceholder : labels.addValuePlaceholder,
|
|
2974
3010
|
value: draftInput,
|
|
2975
3011
|
onChange: (e) => setDraftInput(e.target.value),
|
|
2976
3012
|
onKeyDown: handleTextKeyDown
|
|
@@ -2978,8 +3014,8 @@ function ColumnFilterPopover({
|
|
|
2978
3014
|
)
|
|
2979
3015
|
] }),
|
|
2980
3016
|
allText && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[var(--border-subtle)] pt-2 space-y-2", children: [
|
|
2981
|
-
renderTextRow(
|
|
2982
|
-
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderTextRow(
|
|
3017
|
+
renderTextRow(labels.statsTextAllPrefix, allText),
|
|
3018
|
+
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderTextRow(labels.statsTextFilteredPrefix, filtText) })
|
|
2983
3019
|
] })
|
|
2984
3020
|
] });
|
|
2985
3021
|
}
|
|
@@ -3018,7 +3054,7 @@ function ColumnFilterPopover({
|
|
|
3018
3054
|
if (!dateStats || dateStats.type !== "date") {
|
|
3019
3055
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-wrap", children: [
|
|
3020
3056
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-[var(--text-tertiary)] whitespace-nowrap min-w-[54px]", children: label }),
|
|
3021
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children:
|
|
3057
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children: labels.noData })
|
|
3022
3058
|
] });
|
|
3023
3059
|
}
|
|
3024
3060
|
const { min, max } = dateStats;
|
|
@@ -3046,7 +3082,7 @@ function ColumnFilterPopover({
|
|
|
3046
3082
|
className: chipCls(draftDate.from === min),
|
|
3047
3083
|
onClick: () => setDraftDate((prev) => ({ ...prev, from: min })),
|
|
3048
3084
|
children: [
|
|
3049
|
-
|
|
3085
|
+
labels.chipFrom,
|
|
3050
3086
|
" ",
|
|
3051
3087
|
formatChipDate(min)
|
|
3052
3088
|
]
|
|
@@ -3059,7 +3095,7 @@ function ColumnFilterPopover({
|
|
|
3059
3095
|
className: chipCls(draftDate.to === max),
|
|
3060
3096
|
onClick: () => setDraftDate((prev) => ({ ...prev, to: max })),
|
|
3061
3097
|
children: [
|
|
3062
|
-
|
|
3098
|
+
labels.chipTo,
|
|
3063
3099
|
" ",
|
|
3064
3100
|
formatChipDate(max)
|
|
3065
3101
|
]
|
|
@@ -3071,7 +3107,7 @@ function ColumnFilterPopover({
|
|
|
3071
3107
|
const filtDate = filteredStats?.type === "date" ? filteredStats : null;
|
|
3072
3108
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 w-64 space-y-4", children: [
|
|
3073
3109
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3074
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children:
|
|
3110
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children: labels.chipFrom }),
|
|
3075
3111
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3076
3112
|
Input,
|
|
3077
3113
|
{
|
|
@@ -3082,7 +3118,7 @@ function ColumnFilterPopover({
|
|
|
3082
3118
|
)
|
|
3083
3119
|
] }),
|
|
3084
3120
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3085
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children:
|
|
3121
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children: labels.chipTo }),
|
|
3086
3122
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3087
3123
|
Input,
|
|
3088
3124
|
{
|
|
@@ -3093,8 +3129,8 @@ function ColumnFilterPopover({
|
|
|
3093
3129
|
)
|
|
3094
3130
|
] }),
|
|
3095
3131
|
allDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[var(--border-subtle)] pt-2 space-y-2", children: [
|
|
3096
|
-
renderDateRow(
|
|
3097
|
-
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderDateRow(
|
|
3132
|
+
renderDateRow(labels.statsAllPrefix, allDate),
|
|
3133
|
+
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderDateRow(labels.statsFilteredPrefix, filtDate) })
|
|
3098
3134
|
] })
|
|
3099
3135
|
] });
|
|
3100
3136
|
}
|
|
@@ -3103,7 +3139,7 @@ function ColumnFilterPopover({
|
|
|
3103
3139
|
if (!numStats || numStats.type !== "number-range") {
|
|
3104
3140
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 flex-wrap", children: [
|
|
3105
3141
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-[var(--text-tertiary)] whitespace-nowrap min-w-[54px]", children: label }),
|
|
3106
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children:
|
|
3142
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded bg-[var(--bg-secondary)] px-1.5 py-0.5 text-[11px] text-[var(--text-tertiary)] italic", children: labels.noData })
|
|
3107
3143
|
] });
|
|
3108
3144
|
}
|
|
3109
3145
|
const { min, max } = numStats;
|
|
@@ -3134,7 +3170,7 @@ function ColumnFilterPopover({
|
|
|
3134
3170
|
className: chipCls(draftNumberFrom === String(min)),
|
|
3135
3171
|
onClick: () => setDraftNumberFrom(String(min)),
|
|
3136
3172
|
children: [
|
|
3137
|
-
|
|
3173
|
+
labels.chipMin,
|
|
3138
3174
|
" ",
|
|
3139
3175
|
min
|
|
3140
3176
|
]
|
|
@@ -3147,7 +3183,7 @@ function ColumnFilterPopover({
|
|
|
3147
3183
|
className: chipCls(draftNumberTo === String(max)),
|
|
3148
3184
|
onClick: () => setDraftNumberTo(String(max)),
|
|
3149
3185
|
children: [
|
|
3150
|
-
|
|
3186
|
+
labels.chipMax,
|
|
3151
3187
|
" ",
|
|
3152
3188
|
max
|
|
3153
3189
|
]
|
|
@@ -3159,13 +3195,13 @@ function ColumnFilterPopover({
|
|
|
3159
3195
|
const filtNum = filteredStats?.type === "number-range" ? filteredStats : null;
|
|
3160
3196
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 w-64 space-y-4", children: [
|
|
3161
3197
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3162
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children:
|
|
3198
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children: labels.chipMin }),
|
|
3163
3199
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3164
3200
|
Input,
|
|
3165
3201
|
{
|
|
3166
3202
|
type: "number",
|
|
3167
3203
|
autoFocus: true,
|
|
3168
|
-
placeholder: allNum ? String(allNum.min) :
|
|
3204
|
+
placeholder: allNum ? String(allNum.min) : labels.numberInputPlaceholder,
|
|
3169
3205
|
value: draftNumberFrom,
|
|
3170
3206
|
onChange: (e) => setDraftNumberFrom(e.target.value),
|
|
3171
3207
|
onKeyDown: (e) => {
|
|
@@ -3178,12 +3214,12 @@ function ColumnFilterPopover({
|
|
|
3178
3214
|
)
|
|
3179
3215
|
] }),
|
|
3180
3216
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
3181
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children:
|
|
3217
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-[var(--text-tertiary)] uppercase tracking-wider block", children: labels.chipMax }),
|
|
3182
3218
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3183
3219
|
Input,
|
|
3184
3220
|
{
|
|
3185
3221
|
type: "number",
|
|
3186
|
-
placeholder: allNum ? String(allNum.max) :
|
|
3222
|
+
placeholder: allNum ? String(allNum.max) : labels.numberInputPlaceholder,
|
|
3187
3223
|
value: draftNumberTo,
|
|
3188
3224
|
onChange: (e) => setDraftNumberTo(e.target.value),
|
|
3189
3225
|
onKeyDown: (e) => {
|
|
@@ -3196,8 +3232,8 @@ function ColumnFilterPopover({
|
|
|
3196
3232
|
)
|
|
3197
3233
|
] }),
|
|
3198
3234
|
allNum && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[var(--border-subtle)] pt-2 space-y-2", children: [
|
|
3199
|
-
renderNumRow(
|
|
3200
|
-
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderNumRow(
|
|
3235
|
+
renderNumRow(labels.statsAllPrefix, allNum),
|
|
3236
|
+
filteredStats !== null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderNumRow(labels.statsFilteredPrefix, filtNum) })
|
|
3201
3237
|
] })
|
|
3202
3238
|
] });
|
|
3203
3239
|
}
|
|
@@ -3214,21 +3250,21 @@ function ColumnFilterPopover({
|
|
|
3214
3250
|
}
|
|
3215
3251
|
if (value.length === 2) {
|
|
3216
3252
|
const joined = value.join(", ");
|
|
3217
|
-
return joined.length > 24 ?
|
|
3253
|
+
return joined.length > 24 ? labels.valuesCount(value.length) : joined;
|
|
3218
3254
|
}
|
|
3219
|
-
return
|
|
3255
|
+
return labels.valuesCount(value.length);
|
|
3220
3256
|
}
|
|
3221
3257
|
if (config.type === "enum" && Array.isArray(value)) {
|
|
3222
3258
|
if (value.length === 1) {
|
|
3223
3259
|
return config.options?.find((o) => o.value === value[0])?.label ?? value[0];
|
|
3224
3260
|
}
|
|
3225
|
-
return
|
|
3261
|
+
return labels.selectedCount(value.length);
|
|
3226
3262
|
}
|
|
3227
3263
|
if (config.type === "date") {
|
|
3228
3264
|
const { from, to } = getDateRange(value);
|
|
3229
3265
|
if (from && to) return `${from} — ${to}`;
|
|
3230
|
-
if (from) return `${
|
|
3231
|
-
if (to) return `${
|
|
3266
|
+
if (from) return `${labels.chipFrom} ${from}`;
|
|
3267
|
+
if (to) return `${labels.chipTo} ${to}`;
|
|
3232
3268
|
}
|
|
3233
3269
|
if (config.type === "number-range") {
|
|
3234
3270
|
const { from, to } = getNumberRange(value);
|
|
@@ -3257,20 +3293,33 @@ function ColumnFilterPopover({
|
|
|
3257
3293
|
className: "w-auto p-0 [box-shadow:var(--shadow-menu)] border-[var(--border-subtle)] flex flex-col max-h-[min(var(--radix-popover-content-available-height),520px)] overflow-hidden",
|
|
3258
3294
|
children: [
|
|
3259
3295
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overscroll-contain", children: renderContent() }),
|
|
3260
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 bg-[var(--bg-surface)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3296
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 bg-[var(--bg-surface)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3297
|
+
FilterPopoverFooter,
|
|
3298
|
+
{
|
|
3299
|
+
onApply: handleApply,
|
|
3300
|
+
onClear: handleClear,
|
|
3301
|
+
labels: footerLabels
|
|
3302
|
+
}
|
|
3303
|
+
) })
|
|
3261
3304
|
]
|
|
3262
3305
|
}
|
|
3263
3306
|
)
|
|
3264
3307
|
] });
|
|
3265
3308
|
}
|
|
3266
|
-
const DEFAULT_LABELS$
|
|
3309
|
+
const DEFAULT_LABELS$2 = {
|
|
3267
3310
|
searchPlaceholder: "Search...",
|
|
3268
3311
|
addPlaceholder: "Add...",
|
|
3269
3312
|
contains: "Contains",
|
|
3313
|
+
orBadge: "OR",
|
|
3270
3314
|
chipMin: "min",
|
|
3271
3315
|
chipMax: "max",
|
|
3272
3316
|
statsAllPrefix: "All:",
|
|
3273
|
-
statsFilteredPrefix: "Filt:"
|
|
3317
|
+
statsFilteredPrefix: "Filt:",
|
|
3318
|
+
numberInputPlaceholder: "0",
|
|
3319
|
+
resetSectionTitle: (subLabel) => `Reset ${subLabel}`,
|
|
3320
|
+
filtersCount: (n) => `${n} filters`,
|
|
3321
|
+
subValuesCount: (n) => `${n} values`,
|
|
3322
|
+
subSelectedCount: (n) => `${n} selected`
|
|
3274
3323
|
};
|
|
3275
3324
|
function initDraft(sub, compound) {
|
|
3276
3325
|
const val = compound[sub.key];
|
|
@@ -3305,7 +3354,7 @@ function draftToValue(draft) {
|
|
|
3305
3354
|
const all = trimmed.length > 0 && !draft.tags.includes(trimmed) ? [...draft.tags, trimmed] : [...draft.tags];
|
|
3306
3355
|
return all.length > 0 ? all : void 0;
|
|
3307
3356
|
}
|
|
3308
|
-
function formatSubDisplay(sub, val) {
|
|
3357
|
+
function formatSubDisplay(sub, val, labels) {
|
|
3309
3358
|
if (isFilterValueEmpty(val)) return null;
|
|
3310
3359
|
if (sub.type === "number-range") {
|
|
3311
3360
|
const { from, to } = getNumberRange(val);
|
|
@@ -3319,14 +3368,14 @@ function formatSubDisplay(sub, val) {
|
|
|
3319
3368
|
const label = sub.options?.find((o) => o.value === val[0])?.label ?? val[0];
|
|
3320
3369
|
return `${sub.label}: ${label}`;
|
|
3321
3370
|
}
|
|
3322
|
-
return `${sub.label}: ${val.length}
|
|
3371
|
+
return `${sub.label}: ${labels.subSelectedCount(val.length)}`;
|
|
3323
3372
|
}
|
|
3324
3373
|
if (Array.isArray(val) && val.length > 0) {
|
|
3325
3374
|
if (val.length === 1) {
|
|
3326
3375
|
const display = val[0].length > 15 ? `${val[0].slice(0, 15)}…` : val[0];
|
|
3327
3376
|
return `${sub.label}: ${display}`;
|
|
3328
3377
|
}
|
|
3329
|
-
return `${sub.label}: ${val.length}
|
|
3378
|
+
return `${sub.label}: ${labels.subValuesCount(val.length)}`;
|
|
3330
3379
|
}
|
|
3331
3380
|
return null;
|
|
3332
3381
|
}
|
|
@@ -3339,8 +3388,11 @@ function CompoundFilterPopover({
|
|
|
3339
3388
|
chipClassName,
|
|
3340
3389
|
columnFilterStats,
|
|
3341
3390
|
requestOpen,
|
|
3342
|
-
onRequestOpenHandled
|
|
3391
|
+
onRequestOpenHandled,
|
|
3392
|
+
labels: labelOverrides,
|
|
3393
|
+
footerLabels
|
|
3343
3394
|
}) {
|
|
3395
|
+
const labels = { ...DEFAULT_LABELS$2, ...labelOverrides };
|
|
3344
3396
|
const subFilters = config.subFilters ?? [];
|
|
3345
3397
|
const compound = getCompoundValue(filter.value);
|
|
3346
3398
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
@@ -3416,12 +3468,12 @@ function CompoundFilterPopover({
|
|
|
3416
3468
|
if (isFilterValueEmpty(compound)) return void 0;
|
|
3417
3469
|
const parts = [];
|
|
3418
3470
|
for (const sub of subFilters) {
|
|
3419
|
-
const display = formatSubDisplay(sub, compound[sub.key]);
|
|
3471
|
+
const display = formatSubDisplay(sub, compound[sub.key], labels);
|
|
3420
3472
|
if (display) parts.push(display);
|
|
3421
3473
|
}
|
|
3422
3474
|
if (parts.length === 0) return void 0;
|
|
3423
3475
|
const joined = parts.join(" & ");
|
|
3424
|
-
return joined.length > 30 ?
|
|
3476
|
+
return joined.length > 30 ? labels.filtersCount(parts.length) : joined;
|
|
3425
3477
|
};
|
|
3426
3478
|
const updateDraft = (key, updater) => {
|
|
3427
3479
|
setDrafts((prev) => ({ ...prev, [key]: updater(prev[key]) }));
|
|
@@ -3444,7 +3496,7 @@ function CompoundFilterPopover({
|
|
|
3444
3496
|
className: chipCls(draft.from === String(min)),
|
|
3445
3497
|
onClick: () => updateDraft(sub.key, (d) => ({ ...d, from: String(min) })),
|
|
3446
3498
|
children: [
|
|
3447
|
-
|
|
3499
|
+
labels.chipMin,
|
|
3448
3500
|
" ",
|
|
3449
3501
|
min.toLocaleString()
|
|
3450
3502
|
]
|
|
@@ -3457,7 +3509,7 @@ function CompoundFilterPopover({
|
|
|
3457
3509
|
className: chipCls(draft.to === String(max)),
|
|
3458
3510
|
onClick: () => updateDraft(sub.key, (d) => ({ ...d, to: String(max) })),
|
|
3459
3511
|
children: [
|
|
3460
|
-
|
|
3512
|
+
labels.chipMax,
|
|
3461
3513
|
" ",
|
|
3462
3514
|
max.toLocaleString()
|
|
3463
3515
|
]
|
|
@@ -3468,13 +3520,13 @@ function CompoundFilterPopover({
|
|
|
3468
3520
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3469
3521
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
3470
3522
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-1", children: [
|
|
3471
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--text-tertiary)] block", children:
|
|
3523
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--text-tertiary)] block", children: labels.chipMin }),
|
|
3472
3524
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3473
3525
|
Input,
|
|
3474
3526
|
{
|
|
3475
3527
|
type: "number",
|
|
3476
3528
|
autoFocus: subFilters.indexOf(sub) === 0,
|
|
3477
|
-
placeholder: allNum ? String(allNum.min) :
|
|
3529
|
+
placeholder: allNum ? String(allNum.min) : labels.numberInputPlaceholder,
|
|
3478
3530
|
value: draft.from,
|
|
3479
3531
|
onChange: (e) => updateDraft(sub.key, (prev) => ({
|
|
3480
3532
|
...prev,
|
|
@@ -3490,12 +3542,12 @@ function CompoundFilterPopover({
|
|
|
3490
3542
|
)
|
|
3491
3543
|
] }),
|
|
3492
3544
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-1", children: [
|
|
3493
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--text-tertiary)] block", children:
|
|
3545
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--text-tertiary)] block", children: labels.chipMax }),
|
|
3494
3546
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3495
3547
|
Input,
|
|
3496
3548
|
{
|
|
3497
3549
|
type: "number",
|
|
3498
|
-
placeholder: allNum ? String(allNum.max) :
|
|
3550
|
+
placeholder: allNum ? String(allNum.max) : labels.numberInputPlaceholder,
|
|
3499
3551
|
value: draft.to,
|
|
3500
3552
|
onChange: (e) => updateDraft(sub.key, (prev) => ({
|
|
3501
3553
|
...prev,
|
|
@@ -3512,8 +3564,8 @@ function CompoundFilterPopover({
|
|
|
3512
3564
|
] })
|
|
3513
3565
|
] }),
|
|
3514
3566
|
allNum && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[var(--border-subtle)] mt-3 pt-2 space-y-2", children: [
|
|
3515
|
-
renderNumRow(
|
|
3516
|
-
filtNum && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderNumRow(
|
|
3567
|
+
renderNumRow(labels.statsAllPrefix, allNum),
|
|
3568
|
+
filtNum && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderNumRow(labels.statsFilteredPrefix, filtNum) })
|
|
3517
3569
|
] })
|
|
3518
3570
|
] });
|
|
3519
3571
|
};
|
|
@@ -3610,8 +3662,8 @@ function CompoundFilterPopover({
|
|
|
3610
3662
|
};
|
|
3611
3663
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3612
3664
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--text-tertiary)] block mb-2", children: [
|
|
3613
|
-
|
|
3614
|
-
draft.tags.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] font-semibold text-[var(--tag-blue-text)] bg-[var(--tag-blue-bg)] rounded px-1 py-0.5 uppercase", children:
|
|
3665
|
+
labels.contains,
|
|
3666
|
+
draft.tags.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[10px] font-semibold text-[var(--tag-blue-text)] bg-[var(--tag-blue-bg)] rounded px-1 py-0.5 uppercase", children: labels.orBadge })
|
|
3615
3667
|
] }),
|
|
3616
3668
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1 rounded-md border border-[var(--border-subtle)] bg-[var(--bg-surface)] px-2 py-1.5 focus-within:border-[var(--border-focus)]", children: [
|
|
3617
3669
|
draft.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -3641,7 +3693,7 @@ function CompoundFilterPopover({
|
|
|
3641
3693
|
{
|
|
3642
3694
|
autoFocus: subFilters.indexOf(sub) === 0,
|
|
3643
3695
|
className: "flex-1 min-w-[50px] bg-transparent text-sm text-[var(--text-primary)] outline-none placeholder:text-[var(--text-tertiary)]",
|
|
3644
|
-
placeholder: draft.tags.length === 0 ?
|
|
3696
|
+
placeholder: draft.tags.length === 0 ? labels.searchPlaceholder : labels.addPlaceholder,
|
|
3645
3697
|
value: draft.input,
|
|
3646
3698
|
onChange: (e) => updateDraft(sub.key, (prev) => ({ ...prev, input: e.target.value })),
|
|
3647
3699
|
onKeyDown: handleTextKeyDown
|
|
@@ -3649,8 +3701,8 @@ function CompoundFilterPopover({
|
|
|
3649
3701
|
)
|
|
3650
3702
|
] }),
|
|
3651
3703
|
allText && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-[var(--border-subtle)] mt-3 pt-2 space-y-2", children: [
|
|
3652
|
-
renderTextRow(
|
|
3653
|
-
filtText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderTextRow(
|
|
3704
|
+
renderTextRow(labels.statsAllPrefix, allText),
|
|
3705
|
+
filtText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-[var(--border-subtle)] pt-1.5", children: renderTextRow(labels.statsFilteredPrefix, filtText) })
|
|
3654
3706
|
] })
|
|
3655
3707
|
] });
|
|
3656
3708
|
};
|
|
@@ -3732,7 +3784,7 @@ function CompoundFilterPopover({
|
|
|
3732
3784
|
type: "button",
|
|
3733
3785
|
className: "text-[11px] text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] transition-colors",
|
|
3734
3786
|
onClick: () => handleResetSection(sub.key),
|
|
3735
|
-
title:
|
|
3787
|
+
title: labels.resetSectionTitle(sub.label),
|
|
3736
3788
|
children: "✕"
|
|
3737
3789
|
}
|
|
3738
3790
|
)
|
|
@@ -3744,13 +3796,20 @@ function CompoundFilterPopover({
|
|
|
3744
3796
|
},
|
|
3745
3797
|
sub.key
|
|
3746
3798
|
)) }),
|
|
3747
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 bg-[var(--bg-surface)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3799
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 bg-[var(--bg-surface)]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3800
|
+
FilterPopoverFooter,
|
|
3801
|
+
{
|
|
3802
|
+
onApply: handleApply,
|
|
3803
|
+
onClear: handleClearAll,
|
|
3804
|
+
labels: footerLabels
|
|
3805
|
+
}
|
|
3806
|
+
) })
|
|
3748
3807
|
]
|
|
3749
3808
|
}
|
|
3750
3809
|
)
|
|
3751
3810
|
] });
|
|
3752
3811
|
}
|
|
3753
|
-
const DEFAULT_LABELS = {
|
|
3812
|
+
const DEFAULT_LABELS$1 = {
|
|
3754
3813
|
clearAll: "Clear all",
|
|
3755
3814
|
columns: "Columns",
|
|
3756
3815
|
hiddenCount: (n) => `${n} hidden`
|
|
@@ -3772,8 +3831,13 @@ function AppliedStateChips({
|
|
|
3772
3831
|
onClearAll,
|
|
3773
3832
|
columnFilterStats,
|
|
3774
3833
|
requestOpenFilterId,
|
|
3775
|
-
onRequestOpenHandled
|
|
3834
|
+
onRequestOpenHandled,
|
|
3835
|
+
labels: labelOverrides,
|
|
3836
|
+
columnFilterLabels,
|
|
3837
|
+
compoundFilterLabels,
|
|
3838
|
+
filterPopoverFooterLabels
|
|
3776
3839
|
}) {
|
|
3840
|
+
const labels = { ...DEFAULT_LABELS$1, ...labelOverrides };
|
|
3777
3841
|
const hasFilters = filters.length > 0;
|
|
3778
3842
|
const hasSort = currentSort !== null;
|
|
3779
3843
|
const hasHiddenColumns = hiddenColumnsCount > 0;
|
|
@@ -3784,13 +3848,13 @@ function AppliedStateChips({
|
|
|
3784
3848
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 pb-3", children: [
|
|
3785
3849
|
/* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "secondary", onClick: onClearAll, className: "shrink-0", children: [
|
|
3786
3850
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 14 }),
|
|
3787
|
-
|
|
3851
|
+
labels.clearAll
|
|
3788
3852
|
] }),
|
|
3789
3853
|
hasHiddenColumns && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3790
3854
|
FilterChip,
|
|
3791
3855
|
{
|
|
3792
|
-
label:
|
|
3793
|
-
value:
|
|
3856
|
+
label: labels.columns,
|
|
3857
|
+
value: labels.hiddenCount(hiddenColumnsCount),
|
|
3794
3858
|
onRemove: onResetColumns,
|
|
3795
3859
|
onClick: onOpenColumnsMenu,
|
|
3796
3860
|
className: "cursor-pointer"
|
|
@@ -3813,7 +3877,9 @@ function AppliedStateChips({
|
|
|
3813
3877
|
chipClassName: isEmpty ? "border-dashed" : void 0,
|
|
3814
3878
|
columnFilterStats,
|
|
3815
3879
|
requestOpen: filter.columnId === requestOpenFilterId,
|
|
3816
|
-
onRequestOpenHandled
|
|
3880
|
+
onRequestOpenHandled,
|
|
3881
|
+
labels: compoundFilterLabels,
|
|
3882
|
+
footerLabels: filterPopoverFooterLabels
|
|
3817
3883
|
},
|
|
3818
3884
|
filter.columnId
|
|
3819
3885
|
);
|
|
@@ -3829,7 +3895,9 @@ function AppliedStateChips({
|
|
|
3829
3895
|
chipClassName: isEmpty ? "border-dashed" : void 0,
|
|
3830
3896
|
stats: columnFilterStats?.[filter.columnId],
|
|
3831
3897
|
requestOpen: filter.columnId === requestOpenFilterId,
|
|
3832
|
-
onRequestOpenHandled
|
|
3898
|
+
onRequestOpenHandled,
|
|
3899
|
+
labels: columnFilterLabels,
|
|
3900
|
+
footerLabels: filterPopoverFooterLabels
|
|
3833
3901
|
},
|
|
3834
3902
|
filter.columnId
|
|
3835
3903
|
);
|
|
@@ -3864,6 +3932,21 @@ function hasActiveManagedFilters(filters, managedFieldIds) {
|
|
|
3864
3932
|
const managed = new Set(managedFieldIds);
|
|
3865
3933
|
return filters.some((f) => managed.has(f.columnId) && !isFilterValueEmpty(f.value));
|
|
3866
3934
|
}
|
|
3935
|
+
const DEFAULT_LABELS = {
|
|
3936
|
+
closeFiltersAriaLabel: "Close filters",
|
|
3937
|
+
closeFiltersTitle: "Close filters",
|
|
3938
|
+
apply: "Apply",
|
|
3939
|
+
clear: "Clear",
|
|
3940
|
+
anyPlaceholder: "Any",
|
|
3941
|
+
rangeFromPlaceholder: "From",
|
|
3942
|
+
rangeToPlaceholder: "To",
|
|
3943
|
+
fieldRangeFromAriaLabel: (fieldLabel) => `${fieldLabel} — from`,
|
|
3944
|
+
fieldRangeToAriaLabel: (fieldLabel) => `${fieldLabel} — to`,
|
|
3945
|
+
compoundSubRangeFromAriaLabel: (subLabel) => `${subLabel} — from`,
|
|
3946
|
+
compoundSubRangeToAriaLabel: (subLabel) => `${subLabel} — to`,
|
|
3947
|
+
compoundSubRangeFromPlaceholder: (subLabel) => `${subLabel} from`,
|
|
3948
|
+
compoundSubRangeToPlaceholder: (subLabel) => `${subLabel} to`
|
|
3949
|
+
};
|
|
3867
3950
|
function deriveInitialState(fields, filters) {
|
|
3868
3951
|
const byId = new Map(filters.map((f) => [f.columnId, f.value]));
|
|
3869
3952
|
const next = {};
|
|
@@ -3880,8 +3963,10 @@ function FilterFormPanel({
|
|
|
3880
3963
|
className,
|
|
3881
3964
|
id,
|
|
3882
3965
|
onClose,
|
|
3883
|
-
hiddenSubFilterKeys
|
|
3966
|
+
hiddenSubFilterKeys,
|
|
3967
|
+
labels: labelOverrides
|
|
3884
3968
|
}) {
|
|
3969
|
+
const labels = { ...DEFAULT_LABELS, ...labelOverrides };
|
|
3885
3970
|
const hiddenSubSet = React.useMemo(() => new Set(hiddenSubFilterKeys ?? []), [hiddenSubFilterKeys]);
|
|
3886
3971
|
const renderableFields = React.useMemo(
|
|
3887
3972
|
() => fields.filter((id2) => {
|
|
@@ -3956,8 +4041,8 @@ function FilterFormPanel({
|
|
|
3956
4041
|
type: "button",
|
|
3957
4042
|
variant: "ghost",
|
|
3958
4043
|
size: "icon",
|
|
3959
|
-
"aria-label":
|
|
3960
|
-
title:
|
|
4044
|
+
"aria-label": labels.closeFiltersAriaLabel,
|
|
4045
|
+
title: labels.closeFiltersTitle,
|
|
3961
4046
|
onClick: onClose,
|
|
3962
4047
|
className: "h-7 w-7",
|
|
3963
4048
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
@@ -3974,7 +4059,8 @@ function FilterFormPanel({
|
|
|
3974
4059
|
value: state[fieldId],
|
|
3975
4060
|
onChange: (v) => setField(fieldId, v),
|
|
3976
4061
|
fieldId,
|
|
3977
|
-
hiddenSubSet
|
|
4062
|
+
hiddenSubSet,
|
|
4063
|
+
labels
|
|
3978
4064
|
},
|
|
3979
4065
|
fieldId
|
|
3980
4066
|
);
|
|
@@ -3988,16 +4074,16 @@ function FilterFormPanel({
|
|
|
3988
4074
|
size: "sm",
|
|
3989
4075
|
onClick: handleClear,
|
|
3990
4076
|
disabled: isClearDisabled,
|
|
3991
|
-
children:
|
|
4077
|
+
children: labels.clear
|
|
3992
4078
|
}
|
|
3993
4079
|
),
|
|
3994
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", size: "sm", children:
|
|
4080
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", size: "sm", children: labels.apply })
|
|
3995
4081
|
] }) })
|
|
3996
4082
|
]
|
|
3997
4083
|
}
|
|
3998
4084
|
);
|
|
3999
4085
|
}
|
|
4000
|
-
function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
4086
|
+
function Field({ config, value, onChange, fieldId, hiddenSubSet, labels }) {
|
|
4001
4087
|
if (config.type === "text") {
|
|
4002
4088
|
const text = Array.isArray(value) ? value[0] ?? "" : "";
|
|
4003
4089
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex min-w-0 flex-col gap-1.5", children: [
|
|
@@ -4026,7 +4112,7 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4026
4112
|
value: selected || null,
|
|
4027
4113
|
onChange: (v) => onChange(v ? [v] : void 0),
|
|
4028
4114
|
options: config.options ?? [],
|
|
4029
|
-
placeholder:
|
|
4115
|
+
placeholder: labels.anyPlaceholder,
|
|
4030
4116
|
triggerAriaLabel: config.label,
|
|
4031
4117
|
triggerClassName: "h-9 min-w-0"
|
|
4032
4118
|
}
|
|
@@ -4047,7 +4133,7 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4047
4133
|
Input,
|
|
4048
4134
|
{
|
|
4049
4135
|
type: "date",
|
|
4050
|
-
"aria-label":
|
|
4136
|
+
"aria-label": labels.fieldRangeFromAriaLabel(config.label),
|
|
4051
4137
|
value: range.from ?? "",
|
|
4052
4138
|
onChange: update("from"),
|
|
4053
4139
|
className: "h-9 min-w-0 flex-1"
|
|
@@ -4057,7 +4143,7 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4057
4143
|
Input,
|
|
4058
4144
|
{
|
|
4059
4145
|
type: "date",
|
|
4060
|
-
"aria-label":
|
|
4146
|
+
"aria-label": labels.fieldRangeToAriaLabel(config.label),
|
|
4061
4147
|
value: range.to ?? "",
|
|
4062
4148
|
onChange: update("to"),
|
|
4063
4149
|
className: "h-9 min-w-0 flex-1"
|
|
@@ -4081,10 +4167,10 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4081
4167
|
Input,
|
|
4082
4168
|
{
|
|
4083
4169
|
type: "number",
|
|
4084
|
-
"aria-label":
|
|
4170
|
+
"aria-label": labels.fieldRangeFromAriaLabel(config.label),
|
|
4085
4171
|
value: range.from ?? "",
|
|
4086
4172
|
onChange: update("from"),
|
|
4087
|
-
placeholder:
|
|
4173
|
+
placeholder: labels.rangeFromPlaceholder,
|
|
4088
4174
|
className: "h-9 min-w-0 flex-1"
|
|
4089
4175
|
}
|
|
4090
4176
|
),
|
|
@@ -4092,10 +4178,10 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4092
4178
|
Input,
|
|
4093
4179
|
{
|
|
4094
4180
|
type: "number",
|
|
4095
|
-
"aria-label":
|
|
4181
|
+
"aria-label": labels.fieldRangeToAriaLabel(config.label),
|
|
4096
4182
|
value: range.to ?? "",
|
|
4097
4183
|
onChange: update("to"),
|
|
4098
|
-
placeholder:
|
|
4184
|
+
placeholder: labels.rangeToPlaceholder,
|
|
4099
4185
|
className: "h-9 min-w-0 flex-1"
|
|
4100
4186
|
}
|
|
4101
4187
|
)
|
|
@@ -4175,10 +4261,10 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4175
4261
|
Input,
|
|
4176
4262
|
{
|
|
4177
4263
|
type: "number",
|
|
4178
|
-
"aria-label":
|
|
4264
|
+
"aria-label": labels.compoundSubRangeFromAriaLabel(sub.label),
|
|
4179
4265
|
value: range.from ?? "",
|
|
4180
4266
|
onChange: updateRange("from"),
|
|
4181
|
-
placeholder:
|
|
4267
|
+
placeholder: labels.compoundSubRangeFromPlaceholder(sub.label),
|
|
4182
4268
|
className: "h-9 min-w-0 flex-1"
|
|
4183
4269
|
}
|
|
4184
4270
|
),
|
|
@@ -4186,10 +4272,10 @@ function Field({ config, value, onChange, fieldId, hiddenSubSet }) {
|
|
|
4186
4272
|
Input,
|
|
4187
4273
|
{
|
|
4188
4274
|
type: "number",
|
|
4189
|
-
"aria-label":
|
|
4275
|
+
"aria-label": labels.compoundSubRangeToAriaLabel(sub.label),
|
|
4190
4276
|
value: range.to ?? "",
|
|
4191
4277
|
onChange: updateRange("to"),
|
|
4192
|
-
placeholder:
|
|
4278
|
+
placeholder: labels.compoundSubRangeToPlaceholder(sub.label),
|
|
4193
4279
|
className: "h-9 min-w-0 flex-1"
|
|
4194
4280
|
}
|
|
4195
4281
|
)
|