@dimaan/ui 0.0.20 → 0.0.22
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/index.cjs +479 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +367 -244
- package/dist/index.d.ts +367 -244
- package/dist/index.js +471 -195
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -756,7 +756,6 @@ function SidebarNavItem({
|
|
|
756
756
|
}
|
|
757
757
|
);
|
|
758
758
|
}
|
|
759
|
-
console.log("AppShell");
|
|
760
759
|
function isGroup(entry) {
|
|
761
760
|
return "items" in entry && Array.isArray(entry.items);
|
|
762
761
|
}
|
|
@@ -1376,15 +1375,20 @@ var detailPageBaseClass = "flex w-full flex-col gap-6";
|
|
|
1376
1375
|
var detailPageBodyClass = "flex flex-col gap-6";
|
|
1377
1376
|
var detailPageSkeletonRowClass = "h-5 w-full animate-pulse rounded-md bg-muted";
|
|
1378
1377
|
var detailPageEmptyClass = "rounded-md border border-border bg-card";
|
|
1379
|
-
var
|
|
1378
|
+
var DEFAULT_LABELS_LTR = {
|
|
1379
|
+
back: "Back",
|
|
1380
1380
|
notFoundTitle: "Not found",
|
|
1381
1381
|
notFoundDescription: "The record you\u2019re looking for does not exist or has been removed."
|
|
1382
1382
|
};
|
|
1383
|
+
var DEFAULT_LABELS_RTL = {
|
|
1384
|
+
back: "\u0631\u062C\u0648\u0639",
|
|
1385
|
+
notFoundTitle: "\u063A\u064A\u0631 \u0645\u0648\u062C\u0648\u062F",
|
|
1386
|
+
notFoundDescription: "\u0627\u0644\u0633\u062C\u0644 \u0627\u0644\u0630\u064A \u062A\u0628\u062D\u062B \u0639\u0646\u0647 \u063A\u064A\u0631 \u0645\u0648\u062C\u0648\u062F \u0623\u0648 \u062A\u0645 \u062D\u0630\u0641\u0647."
|
|
1387
|
+
};
|
|
1383
1388
|
var DEFAULT_SKELETON_ROW_COUNT = 6;
|
|
1384
1389
|
function DetailPage({
|
|
1385
1390
|
title,
|
|
1386
1391
|
description,
|
|
1387
|
-
back,
|
|
1388
1392
|
actions,
|
|
1389
1393
|
bordered = true,
|
|
1390
1394
|
isLoading = false,
|
|
@@ -1396,7 +1400,10 @@ function DetailPage({
|
|
|
1396
1400
|
className,
|
|
1397
1401
|
bodyClassName
|
|
1398
1402
|
}) {
|
|
1399
|
-
const
|
|
1403
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1404
|
+
const dir = useDirection();
|
|
1405
|
+
const defaults = dir === "rtl" ? DEFAULT_LABELS_RTL : DEFAULT_LABELS_LTR;
|
|
1406
|
+
const labels = { ...defaults, ...labelsProp };
|
|
1400
1407
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1401
1408
|
"div",
|
|
1402
1409
|
{
|
|
@@ -1410,7 +1417,7 @@ function DetailPage({
|
|
|
1410
1417
|
{
|
|
1411
1418
|
title,
|
|
1412
1419
|
description,
|
|
1413
|
-
back,
|
|
1420
|
+
back: { label: labels.back, onClick: () => navigate(-1) },
|
|
1414
1421
|
actions,
|
|
1415
1422
|
bordered
|
|
1416
1423
|
}
|
|
@@ -1724,13 +1731,13 @@ var formPageBodyClass = "flex-1";
|
|
|
1724
1731
|
var formPageActionsBarClass = "sticky bottom-0 -mx-6 -mb-6 mt-6 flex items-center justify-end gap-2 border-t border-border bg-background/95 px-6 py-3 backdrop-blur supports-[backdrop-filter]:bg-background/80";
|
|
1725
1732
|
var formPageSkeletonRowClass = "h-10 w-full animate-pulse rounded-md bg-muted";
|
|
1726
1733
|
var DEFAULT_SKELETON_ROW_COUNT2 = 6;
|
|
1727
|
-
var
|
|
1734
|
+
var DEFAULT_LABELS_LTR2 = {
|
|
1728
1735
|
back: "Back",
|
|
1729
1736
|
cancel: "Cancel",
|
|
1730
1737
|
save: "Save",
|
|
1731
1738
|
saving: "Saving\u2026"
|
|
1732
1739
|
};
|
|
1733
|
-
var
|
|
1740
|
+
var DEFAULT_LABELS_RTL2 = {
|
|
1734
1741
|
back: "\u0631\u062C\u0648\u0639",
|
|
1735
1742
|
cancel: "\u0625\u0644\u063A\u0627\u0621",
|
|
1736
1743
|
save: "\u062D\u0641\u0638",
|
|
@@ -1757,7 +1764,7 @@ function FormPage({
|
|
|
1757
1764
|
const dir = useDirection();
|
|
1758
1765
|
const formContext = reactHookForm.useFormContext();
|
|
1759
1766
|
const submitting = isSubmitting ?? formContext?.formState?.isSubmitting ?? false;
|
|
1760
|
-
const defaults = dir === "rtl" ?
|
|
1767
|
+
const defaults = dir === "rtl" ? DEFAULT_LABELS_RTL2 : DEFAULT_LABELS_LTR2;
|
|
1761
1768
|
const labels = { ...defaults, ...labelsProp };
|
|
1762
1769
|
const goBack = () => navigate(-1);
|
|
1763
1770
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-page", className: cn(formPageBaseClass, className), children: [
|
|
@@ -1925,132 +1932,6 @@ function LanguageSwitcher({
|
|
|
1925
1932
|
}
|
|
1926
1933
|
);
|
|
1927
1934
|
}
|
|
1928
|
-
|
|
1929
|
-
// src/components/select/selectVariants.ts
|
|
1930
|
-
var selectVariantClass = {
|
|
1931
|
-
default: "border border-input bg-background hover:border-ring",
|
|
1932
|
-
filled: "border border-transparent bg-muted hover:bg-muted/80",
|
|
1933
|
-
ghost: "border border-transparent bg-transparent hover:bg-accent"
|
|
1934
|
-
};
|
|
1935
|
-
var selectSizeClass = {
|
|
1936
|
-
sm: "h-8 rounded-md ps-2.5 pe-8 text-sm",
|
|
1937
|
-
md: "h-9 rounded-md ps-3 pe-9 text-sm",
|
|
1938
|
-
lg: "h-11 rounded-md ps-4 pe-10 text-base"
|
|
1939
|
-
};
|
|
1940
|
-
var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-2 focus:ring-ring/40 focus:ring-offset-1 focus:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
|
|
1941
|
-
var selectContentClass = "z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
1942
|
-
var selectViewportClass = "p-1";
|
|
1943
|
-
var selectItemClass = "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
1944
|
-
var selectItemIndicatorClass = "absolute start-2 inline-flex h-3.5 w-3.5 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5";
|
|
1945
|
-
var selectGroupLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground";
|
|
1946
|
-
var selectSeparatorClass = "-mx-1 my-1 h-px bg-border";
|
|
1947
|
-
function isGroupedOptions(options) {
|
|
1948
|
-
const first = options[0];
|
|
1949
|
-
return first !== void 0 && "options" in first;
|
|
1950
|
-
}
|
|
1951
|
-
var Select = react.forwardRef(function Select2({
|
|
1952
|
-
variant = "default",
|
|
1953
|
-
selectSize = "md",
|
|
1954
|
-
options,
|
|
1955
|
-
placeholder,
|
|
1956
|
-
value,
|
|
1957
|
-
defaultValue,
|
|
1958
|
-
onValueChange,
|
|
1959
|
-
onChange,
|
|
1960
|
-
onBlur,
|
|
1961
|
-
name,
|
|
1962
|
-
disabled,
|
|
1963
|
-
required,
|
|
1964
|
-
id,
|
|
1965
|
-
className,
|
|
1966
|
-
"aria-invalid": ariaInvalid,
|
|
1967
|
-
"aria-describedby": ariaDescribedBy,
|
|
1968
|
-
"aria-label": ariaLabel,
|
|
1969
|
-
children
|
|
1970
|
-
}, ref) {
|
|
1971
|
-
const generatedId = react.useId();
|
|
1972
|
-
const triggerId = id ?? generatedId;
|
|
1973
|
-
const handleValueChange = react.useCallback(
|
|
1974
|
-
(next) => {
|
|
1975
|
-
onValueChange?.(next);
|
|
1976
|
-
if (onChange) {
|
|
1977
|
-
const synthetic = {
|
|
1978
|
-
target: { value: next, name },
|
|
1979
|
-
currentTarget: { value: next, name },
|
|
1980
|
-
type: "change"
|
|
1981
|
-
};
|
|
1982
|
-
onChange(synthetic);
|
|
1983
|
-
}
|
|
1984
|
-
},
|
|
1985
|
-
[onValueChange, onChange, name]
|
|
1986
|
-
);
|
|
1987
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1988
|
-
RadixSelect__namespace.Root,
|
|
1989
|
-
{
|
|
1990
|
-
value,
|
|
1991
|
-
defaultValue,
|
|
1992
|
-
onValueChange: handleValueChange,
|
|
1993
|
-
disabled,
|
|
1994
|
-
required,
|
|
1995
|
-
name,
|
|
1996
|
-
children: [
|
|
1997
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1998
|
-
RadixSelect__namespace.Trigger,
|
|
1999
|
-
{
|
|
2000
|
-
ref,
|
|
2001
|
-
id: triggerId,
|
|
2002
|
-
"aria-label": ariaLabel,
|
|
2003
|
-
"aria-invalid": ariaInvalid,
|
|
2004
|
-
"aria-describedby": ariaDescribedBy,
|
|
2005
|
-
onBlur,
|
|
2006
|
-
"data-slot": "select-trigger",
|
|
2007
|
-
className: cn(
|
|
2008
|
-
selectBaseClass,
|
|
2009
|
-
selectVariantClass[variant],
|
|
2010
|
-
selectSizeClass[selectSize],
|
|
2011
|
-
className
|
|
2012
|
-
),
|
|
2013
|
-
children: [
|
|
2014
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Value, { placeholder }),
|
|
2015
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "pointer-events-none absolute end-3 top-1/2 size-4 shrink-0 -translate-y-1/2 text-muted-foreground" }) })
|
|
2016
|
-
]
|
|
2017
|
-
}
|
|
2018
|
-
),
|
|
2019
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2020
|
-
RadixSelect__namespace.Content,
|
|
2021
|
-
{
|
|
2022
|
-
position: "popper",
|
|
2023
|
-
sideOffset: 4,
|
|
2024
|
-
"data-slot": "select-content",
|
|
2025
|
-
className: selectContentClass,
|
|
2026
|
-
children: [
|
|
2027
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ScrollUpButton, { className: "flex h-6 cursor-default items-center justify-center bg-popover text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "size-4" }) }),
|
|
2028
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Viewport, { className: selectViewportClass, children: children ?? (options ? renderOptions(options) : null) }),
|
|
2029
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ScrollDownButton, { className: "flex h-6 cursor-default items-center justify-center bg-popover text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" }) })
|
|
2030
|
-
]
|
|
2031
|
-
}
|
|
2032
|
-
) })
|
|
2033
|
-
]
|
|
2034
|
-
}
|
|
2035
|
-
);
|
|
2036
|
-
});
|
|
2037
|
-
function renderOptions(options) {
|
|
2038
|
-
if (isGroupedOptions(options)) {
|
|
2039
|
-
const lastIndex = options.length - 1;
|
|
2040
|
-
return options.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(RadixSelect__namespace.Group, { children: [
|
|
2041
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Label, { className: selectGroupLabelClass, children: group.label }),
|
|
2042
|
-
group.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value)),
|
|
2043
|
-
idx < lastIndex && /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Separator, { className: selectSeparatorClass })
|
|
2044
|
-
] }, group.label));
|
|
2045
|
-
}
|
|
2046
|
-
return options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value));
|
|
2047
|
-
}
|
|
2048
|
-
var SelectItem = react.forwardRef(function SelectItem2({ className, children, ...props }, ref) {
|
|
2049
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RadixSelect__namespace.Item, { ref, className: cn(selectItemClass, className), ...props, children: [
|
|
2050
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemIndicator, { className: selectItemIndicatorClass, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, {}) }),
|
|
2051
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemText, { children })
|
|
2052
|
-
] });
|
|
2053
|
-
});
|
|
2054
1935
|
var EN_LABELS = {
|
|
2055
1936
|
rowsPerPage: "Rows per page",
|
|
2056
1937
|
pageRangeOf: "of",
|
|
@@ -2174,17 +2055,17 @@ var tableSizeClass = {
|
|
|
2174
2055
|
sm: {
|
|
2175
2056
|
row: "",
|
|
2176
2057
|
cell: "px-3 py-1.5 text-xs",
|
|
2177
|
-
head: "px-3 py-2 text-xs font-medium"
|
|
2058
|
+
head: "whitespace-nowrap px-3 py-2 text-xs font-medium"
|
|
2178
2059
|
},
|
|
2179
2060
|
md: {
|
|
2180
2061
|
row: "",
|
|
2181
2062
|
cell: "px-4 py-2.5 text-sm",
|
|
2182
|
-
head: "px-4 py-2.5 text-xs font-medium uppercase tracking-wide"
|
|
2063
|
+
head: "whitespace-nowrap px-4 py-2.5 text-xs font-medium uppercase tracking-wide"
|
|
2183
2064
|
},
|
|
2184
2065
|
lg: {
|
|
2185
2066
|
row: "",
|
|
2186
2067
|
cell: "px-5 py-3.5 text-sm",
|
|
2187
|
-
head: "px-5 py-3 text-sm font-medium"
|
|
2068
|
+
head: "whitespace-nowrap px-5 py-3 text-sm font-medium"
|
|
2188
2069
|
}
|
|
2189
2070
|
};
|
|
2190
2071
|
var tableBaseClass = "w-full caption-bottom border-collapse";
|
|
@@ -2502,20 +2383,446 @@ function SortIndicator({ active, direction }) {
|
|
|
2502
2383
|
if (!active) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { "aria-hidden": "true", className });
|
|
2503
2384
|
return direction === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { "aria-hidden": "true", className }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": "true", className });
|
|
2504
2385
|
}
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2386
|
+
|
|
2387
|
+
// src/components/select/selectVariants.ts
|
|
2388
|
+
var selectVariantClass = {
|
|
2389
|
+
default: "border border-input bg-background hover:border-ring",
|
|
2390
|
+
filled: "border border-transparent bg-muted hover:bg-muted/80",
|
|
2391
|
+
ghost: "border border-transparent bg-transparent hover:bg-accent"
|
|
2392
|
+
};
|
|
2393
|
+
var selectSizeClass = {
|
|
2394
|
+
sm: "h-8 rounded-md ps-2.5 pe-8 text-sm",
|
|
2395
|
+
md: "h-9 rounded-md ps-3 pe-9 text-sm",
|
|
2396
|
+
lg: "h-11 rounded-md ps-4 pe-10 text-base"
|
|
2397
|
+
};
|
|
2398
|
+
var selectBaseClass = "group/select relative inline-flex w-full items-center text-foreground outline-none transition-[background-color,border-color,box-shadow] focus:ring-2 focus:ring-ring/40 focus:ring-offset-1 focus:ring-offset-background aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:ring-destructive/40 disabled:pointer-events-none disabled:opacity-50 cursor-pointer data-[placeholder]:text-muted-foreground";
|
|
2399
|
+
var selectContentClass = "z-50 max-h-(--radix-select-content-available-height) min-w-(--radix-select-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
2400
|
+
var selectViewportClass = "p-1";
|
|
2401
|
+
var selectItemClass = "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 ps-8 pe-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
2402
|
+
var selectItemIndicatorClass = "absolute start-2 inline-flex h-3.5 w-3.5 items-center justify-center [&_svg]:h-3.5 [&_svg]:w-3.5";
|
|
2403
|
+
var selectGroupLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground";
|
|
2404
|
+
var selectSeparatorClass = "-mx-1 my-1 h-px bg-border";
|
|
2405
|
+
|
|
2406
|
+
// src/components/multi-select/multiSelectVariants.ts
|
|
2407
|
+
var multiSelectTriggerSizeClass = {
|
|
2408
|
+
sm: "min-h-8 rounded-md ps-2.5 pe-8 py-1 text-sm",
|
|
2409
|
+
md: "min-h-9 rounded-md ps-3 pe-9 py-1 text-sm",
|
|
2410
|
+
lg: "min-h-11 rounded-md ps-4 pe-10 py-1.5 text-base"
|
|
2411
|
+
};
|
|
2412
|
+
var multiSelectValueRowClass = "flex min-w-0 flex-1 flex-wrap items-center gap-1";
|
|
2413
|
+
var multiSelectChipClass = "max-w-full gap-1 pe-1";
|
|
2414
|
+
var multiSelectChipRemoveClass = "inline-flex size-3.5 shrink-0 items-center justify-center rounded-sm hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40";
|
|
2415
|
+
var multiSelectContentClass = "z-50 w-(--radix-popover-trigger-width) overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
2416
|
+
var multiSelectSearchRowClass = "border-b border-border p-1";
|
|
2417
|
+
var multiSelectListClass = "max-h-60 overflow-y-auto overflow-x-hidden p-1";
|
|
2418
|
+
var multiSelectOptionClass = "flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground has-[:focus-visible]:bg-accent has-[:disabled]:pointer-events-none has-[:disabled]:opacity-50";
|
|
2419
|
+
var multiSelectEmptyClass = "px-2 py-6 text-center text-sm text-muted-foreground";
|
|
2420
|
+
var DEFAULT_LABELS_LTR3 = {
|
|
2421
|
+
search: "Search\u2026",
|
|
2422
|
+
empty: "No results"
|
|
2423
|
+
};
|
|
2424
|
+
var DEFAULT_LABELS_RTL3 = {
|
|
2425
|
+
search: "\u0628\u062D\u062B\u2026",
|
|
2426
|
+
empty: "\u0644\u0627 \u0646\u062A\u0627\u0626\u062C"
|
|
2427
|
+
};
|
|
2428
|
+
function toArray(value) {
|
|
2429
|
+
return Array.isArray(value) ? value : [];
|
|
2430
|
+
}
|
|
2431
|
+
var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
2432
|
+
variant = "default",
|
|
2433
|
+
selectSize = "md",
|
|
2434
|
+
options,
|
|
2435
|
+
placeholder,
|
|
2436
|
+
value,
|
|
2437
|
+
defaultValue,
|
|
2438
|
+
onValueChange,
|
|
2439
|
+
onChange,
|
|
2440
|
+
onBlur,
|
|
2441
|
+
searchable = true,
|
|
2442
|
+
maxTagCount,
|
|
2443
|
+
labels: labelsProp,
|
|
2444
|
+
name,
|
|
2445
|
+
disabled = false,
|
|
2446
|
+
required,
|
|
2447
|
+
id,
|
|
2448
|
+
className,
|
|
2449
|
+
contentClassName,
|
|
2450
|
+
"aria-invalid": ariaInvalid,
|
|
2451
|
+
"aria-describedby": ariaDescribedBy,
|
|
2452
|
+
"aria-label": ariaLabel
|
|
2453
|
+
}, ref) {
|
|
2454
|
+
const dir = useDirection();
|
|
2455
|
+
const labels = { ...dir === "rtl" ? DEFAULT_LABELS_RTL3 : DEFAULT_LABELS_LTR3, ...labelsProp };
|
|
2456
|
+
const generatedId = react.useId();
|
|
2457
|
+
const triggerId = id ?? generatedId;
|
|
2458
|
+
const isControlled = value !== void 0;
|
|
2459
|
+
const [internal, setInternal] = react.useState(() => toArray(defaultValue));
|
|
2460
|
+
const selected = isControlled ? toArray(value) : internal;
|
|
2461
|
+
const [open, setOpen] = react.useState(false);
|
|
2462
|
+
const [query, setQuery] = react.useState("");
|
|
2463
|
+
const labelByValue = react.useMemo(() => new Map(options.map((o) => [o.value, o.label])), [options]);
|
|
2464
|
+
const filtered = react.useMemo(() => {
|
|
2465
|
+
const q = query.trim().toLowerCase();
|
|
2466
|
+
if (!searchable || q === "") return options;
|
|
2467
|
+
return options.filter((o) => o.label.toLowerCase().includes(q));
|
|
2468
|
+
}, [options, query, searchable]);
|
|
2469
|
+
const emit = (next) => {
|
|
2470
|
+
if (!isControlled) setInternal(next);
|
|
2471
|
+
onValueChange?.(next);
|
|
2472
|
+
onChange?.(next);
|
|
2473
|
+
};
|
|
2474
|
+
const toggle = (optionValue) => {
|
|
2475
|
+
emit(
|
|
2476
|
+
selected.includes(optionValue) ? selected.filter((v) => v !== optionValue) : [...selected, optionValue]
|
|
2477
|
+
);
|
|
2478
|
+
};
|
|
2479
|
+
const remove = (optionValue) => emit(selected.filter((v) => v !== optionValue));
|
|
2480
|
+
const openOnKeys = (event) => {
|
|
2481
|
+
if (disabled) return;
|
|
2482
|
+
if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
|
|
2483
|
+
event.preventDefault();
|
|
2484
|
+
setOpen(true);
|
|
2485
|
+
}
|
|
2486
|
+
};
|
|
2487
|
+
const shownValues = maxTagCount !== void 0 ? selected.slice(0, maxTagCount) : selected;
|
|
2488
|
+
const overflowCount = selected.length - shownValues.length;
|
|
2489
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RadixPopover__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
2490
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixPopover__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2491
|
+
"div",
|
|
2492
|
+
{
|
|
2493
|
+
ref,
|
|
2494
|
+
id: triggerId,
|
|
2495
|
+
role: "button",
|
|
2496
|
+
tabIndex: disabled ? -1 : 0,
|
|
2497
|
+
"aria-haspopup": "listbox",
|
|
2498
|
+
"aria-expanded": open,
|
|
2499
|
+
"aria-disabled": disabled || void 0,
|
|
2500
|
+
"aria-label": ariaLabel,
|
|
2501
|
+
"aria-invalid": ariaInvalid,
|
|
2502
|
+
"aria-describedby": ariaDescribedBy,
|
|
2503
|
+
"data-slot": "multi-select-trigger",
|
|
2504
|
+
"data-state": open ? "open" : "closed",
|
|
2505
|
+
"data-placeholder": selected.length === 0 ? "" : void 0,
|
|
2506
|
+
onClick: () => !disabled && setOpen(true),
|
|
2507
|
+
onKeyDown: openOnKeys,
|
|
2508
|
+
onBlur,
|
|
2509
|
+
className: cn(
|
|
2510
|
+
selectBaseClass,
|
|
2511
|
+
selectVariantClass[variant],
|
|
2512
|
+
multiSelectTriggerSizeClass[selectSize],
|
|
2513
|
+
className
|
|
2514
|
+
),
|
|
2515
|
+
children: [
|
|
2516
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: multiSelectValueRowClass, children: selected.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2517
|
+
shownValues.map((v) => /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "default", size: "sm", className: multiSelectChipClass, children: [
|
|
2518
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: labelByValue.get(v) ?? v }),
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2520
|
+
"button",
|
|
2521
|
+
{
|
|
2522
|
+
type: "button",
|
|
2523
|
+
tabIndex: -1,
|
|
2524
|
+
"aria-label": `Remove ${labelByValue.get(v) ?? v}`,
|
|
2525
|
+
"data-slot": "multi-select-chip-remove",
|
|
2526
|
+
className: multiSelectChipRemoveClass,
|
|
2527
|
+
onClick: (event) => {
|
|
2528
|
+
event.stopPropagation();
|
|
2529
|
+
if (!disabled) remove(v);
|
|
2530
|
+
},
|
|
2531
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true", className: "size-3" })
|
|
2532
|
+
}
|
|
2533
|
+
)
|
|
2534
|
+
] }, v)),
|
|
2535
|
+
overflowCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", children: `+${overflowCount}` }) : null
|
|
2536
|
+
] }) }),
|
|
2537
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "pointer-events-none absolute end-3 top-1/2 size-4 shrink-0 -translate-y-1/2 text-muted-foreground" }),
|
|
2538
|
+
name ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2539
|
+
"input",
|
|
2540
|
+
{
|
|
2541
|
+
type: "hidden",
|
|
2542
|
+
name,
|
|
2543
|
+
value: selected.join(","),
|
|
2544
|
+
required,
|
|
2545
|
+
readOnly: true
|
|
2546
|
+
}
|
|
2547
|
+
) : null
|
|
2548
|
+
]
|
|
2549
|
+
}
|
|
2550
|
+
) }),
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixPopover__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2552
|
+
RadixPopover__namespace.Content,
|
|
2553
|
+
{
|
|
2554
|
+
align: "start",
|
|
2555
|
+
sideOffset: 4,
|
|
2556
|
+
"data-slot": "multi-select-content",
|
|
2557
|
+
className: cn(multiSelectContentClass, contentClassName),
|
|
2558
|
+
onOpenAutoFocus: (event) => {
|
|
2559
|
+
if (!searchable) event.preventDefault();
|
|
2560
|
+
},
|
|
2561
|
+
children: [
|
|
2562
|
+
searchable ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: multiSelectSearchRowClass, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2563
|
+
Input,
|
|
2564
|
+
{
|
|
2565
|
+
type: "search",
|
|
2566
|
+
inputSize: "sm",
|
|
2567
|
+
value: query,
|
|
2568
|
+
onChange: (e) => setQuery(e.target.value),
|
|
2569
|
+
placeholder: labels.search,
|
|
2570
|
+
"aria-label": labels.search,
|
|
2571
|
+
leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4" })
|
|
2572
|
+
}
|
|
2573
|
+
) }) : null,
|
|
2574
|
+
filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: multiSelectEmptyClass, children: labels.empty }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: multiSelectListClass, children: filtered.map((option) => {
|
|
2575
|
+
const isSelected = selected.includes(option.value);
|
|
2576
|
+
const optionId = `${triggerId}-opt-${option.value}`;
|
|
2577
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2578
|
+
"label",
|
|
2579
|
+
{
|
|
2580
|
+
htmlFor: optionId,
|
|
2581
|
+
"data-slot": "multi-select-option",
|
|
2582
|
+
"data-selected": isSelected ? "true" : void 0,
|
|
2583
|
+
className: multiSelectOptionClass,
|
|
2584
|
+
children: [
|
|
2585
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2586
|
+
Checkbox,
|
|
2587
|
+
{
|
|
2588
|
+
id: optionId,
|
|
2589
|
+
size: "sm",
|
|
2590
|
+
checked: isSelected,
|
|
2591
|
+
disabled: option.disabled,
|
|
2592
|
+
onCheckedChange: () => toggle(option.value)
|
|
2593
|
+
}
|
|
2594
|
+
),
|
|
2595
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: option.label })
|
|
2596
|
+
]
|
|
2597
|
+
},
|
|
2598
|
+
option.value
|
|
2599
|
+
);
|
|
2600
|
+
}) })
|
|
2601
|
+
]
|
|
2602
|
+
}
|
|
2603
|
+
) })
|
|
2604
|
+
] });
|
|
2605
|
+
});
|
|
2606
|
+
function isGroupedOptions(options) {
|
|
2607
|
+
const first = options[0];
|
|
2608
|
+
return first !== void 0 && "options" in first;
|
|
2609
|
+
}
|
|
2610
|
+
var Select = react.forwardRef(function Select2({
|
|
2611
|
+
variant = "default",
|
|
2612
|
+
selectSize = "md",
|
|
2613
|
+
options,
|
|
2614
|
+
placeholder,
|
|
2615
|
+
value,
|
|
2616
|
+
defaultValue,
|
|
2617
|
+
onValueChange,
|
|
2618
|
+
onChange,
|
|
2619
|
+
onBlur,
|
|
2620
|
+
name,
|
|
2621
|
+
disabled,
|
|
2622
|
+
required,
|
|
2623
|
+
id,
|
|
2624
|
+
className,
|
|
2625
|
+
"aria-invalid": ariaInvalid,
|
|
2626
|
+
"aria-describedby": ariaDescribedBy,
|
|
2627
|
+
"aria-label": ariaLabel,
|
|
2628
|
+
children
|
|
2629
|
+
}, ref) {
|
|
2630
|
+
const generatedId = react.useId();
|
|
2631
|
+
const triggerId = id ?? generatedId;
|
|
2632
|
+
const handleValueChange = react.useCallback(
|
|
2633
|
+
(next) => {
|
|
2634
|
+
onValueChange?.(next);
|
|
2635
|
+
if (onChange) {
|
|
2636
|
+
const synthetic = {
|
|
2637
|
+
target: { value: next, name },
|
|
2638
|
+
currentTarget: { value: next, name },
|
|
2639
|
+
type: "change"
|
|
2640
|
+
};
|
|
2641
|
+
onChange(synthetic);
|
|
2642
|
+
}
|
|
2643
|
+
},
|
|
2644
|
+
[onValueChange, onChange, name]
|
|
2645
|
+
);
|
|
2646
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2647
|
+
RadixSelect__namespace.Root,
|
|
2648
|
+
{
|
|
2649
|
+
value,
|
|
2650
|
+
defaultValue,
|
|
2651
|
+
onValueChange: handleValueChange,
|
|
2652
|
+
disabled,
|
|
2653
|
+
required,
|
|
2654
|
+
name,
|
|
2655
|
+
children: [
|
|
2656
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2657
|
+
RadixSelect__namespace.Trigger,
|
|
2658
|
+
{
|
|
2659
|
+
ref,
|
|
2660
|
+
id: triggerId,
|
|
2661
|
+
"aria-label": ariaLabel,
|
|
2662
|
+
"aria-invalid": ariaInvalid,
|
|
2663
|
+
"aria-describedby": ariaDescribedBy,
|
|
2664
|
+
onBlur,
|
|
2665
|
+
"data-slot": "select-trigger",
|
|
2666
|
+
className: cn(
|
|
2667
|
+
selectBaseClass,
|
|
2668
|
+
selectVariantClass[variant],
|
|
2669
|
+
selectSizeClass[selectSize],
|
|
2670
|
+
className
|
|
2671
|
+
),
|
|
2672
|
+
children: [
|
|
2673
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Value, { placeholder }),
|
|
2674
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "pointer-events-none absolute end-3 top-1/2 size-4 shrink-0 -translate-y-1/2 text-muted-foreground" }) })
|
|
2675
|
+
]
|
|
2676
|
+
}
|
|
2677
|
+
),
|
|
2678
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2679
|
+
RadixSelect__namespace.Content,
|
|
2680
|
+
{
|
|
2681
|
+
position: "popper",
|
|
2682
|
+
sideOffset: 4,
|
|
2683
|
+
"data-slot": "select-content",
|
|
2684
|
+
className: selectContentClass,
|
|
2685
|
+
children: [
|
|
2686
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ScrollUpButton, { className: "flex h-6 cursor-default items-center justify-center bg-popover text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "size-4" }) }),
|
|
2687
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Viewport, { className: selectViewportClass, children: children ?? (options ? renderOptions(options) : null) }),
|
|
2688
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ScrollDownButton, { className: "flex h-6 cursor-default items-center justify-center bg-popover text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-4" }) })
|
|
2689
|
+
]
|
|
2690
|
+
}
|
|
2691
|
+
) })
|
|
2692
|
+
]
|
|
2693
|
+
}
|
|
2694
|
+
);
|
|
2695
|
+
});
|
|
2696
|
+
function renderOptions(options) {
|
|
2697
|
+
if (isGroupedOptions(options)) {
|
|
2698
|
+
const lastIndex = options.length - 1;
|
|
2699
|
+
return options.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(RadixSelect__namespace.Group, { children: [
|
|
2700
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Label, { className: selectGroupLabelClass, children: group.label }),
|
|
2701
|
+
group.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value)),
|
|
2702
|
+
idx < lastIndex && /* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Separator, { className: selectSeparatorClass })
|
|
2703
|
+
] }, group.label));
|
|
2704
|
+
}
|
|
2705
|
+
return options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value));
|
|
2706
|
+
}
|
|
2707
|
+
var SelectItem = react.forwardRef(function SelectItem2({ className, children, ...props }, ref) {
|
|
2708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RadixSelect__namespace.Item, { ref, className: cn(selectItemClass, className), ...props, children: [
|
|
2709
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemIndicator, { className: selectItemIndicatorClass, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, {}) }),
|
|
2710
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemText, { children })
|
|
2711
|
+
] });
|
|
2712
|
+
});
|
|
2713
|
+
|
|
2714
|
+
// src/components/list-page/listPageFilters.ts
|
|
2715
|
+
var FILTER_SPAN_CLASS = {
|
|
2716
|
+
narrow: "",
|
|
2717
|
+
default: "",
|
|
2718
|
+
wide: "sm:col-span-2"
|
|
2719
|
+
};
|
|
2720
|
+
function filterDefaultValue(filter) {
|
|
2721
|
+
return filter.type === "select" ? filter.options[0]?.value ?? "" : "";
|
|
2722
|
+
}
|
|
2723
|
+
function hasActiveFilters(filters, values) {
|
|
2724
|
+
for (const filter of filters ?? []) {
|
|
2725
|
+
const current = values?.[filter.key];
|
|
2726
|
+
if (current === void 0) continue;
|
|
2727
|
+
const value = filter.type === "text" ? current.trim() : current;
|
|
2728
|
+
if (value !== filterDefaultValue(filter)) return true;
|
|
2729
|
+
}
|
|
2730
|
+
return false;
|
|
2731
|
+
}
|
|
2732
|
+
function ListPageFilterBar({
|
|
2733
|
+
filters,
|
|
2734
|
+
values,
|
|
2735
|
+
onChange,
|
|
2736
|
+
disabled = false,
|
|
2737
|
+
labels
|
|
2738
|
+
}) {
|
|
2739
|
+
const active = hasActiveFilters(filters, values);
|
|
2740
|
+
const reset = () => {
|
|
2741
|
+
for (const filter of filters ?? []) {
|
|
2742
|
+
onChange?.(filter.key, filterDefaultValue(filter));
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className: "space-y-3", children: [
|
|
2746
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3", children: filters?.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2747
|
+
FilterControl,
|
|
2748
|
+
{
|
|
2749
|
+
filter,
|
|
2750
|
+
value: values?.[filter.key],
|
|
2751
|
+
onChange,
|
|
2752
|
+
disabled
|
|
2753
|
+
},
|
|
2754
|
+
filter.key
|
|
2755
|
+
)) }),
|
|
2756
|
+
active && !disabled ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", onClick: reset, children: [
|
|
2757
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "size-4" }),
|
|
2758
|
+
labels.reset
|
|
2759
|
+
] }) }) : null
|
|
2760
|
+
] });
|
|
2761
|
+
}
|
|
2762
|
+
function FilterControl({ filter, value, onChange, disabled }) {
|
|
2763
|
+
const spanClass = FILTER_SPAN_CLASS[filter.width ?? "default"];
|
|
2764
|
+
const ariaLabel = typeof filter.label === "string" ? filter.label : filter.key;
|
|
2765
|
+
switch (filter.type) {
|
|
2766
|
+
case "select":
|
|
2767
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2768
|
+
Select,
|
|
2769
|
+
{
|
|
2770
|
+
"aria-label": ariaLabel,
|
|
2771
|
+
value: value ?? filterDefaultValue(filter),
|
|
2772
|
+
onValueChange: (v) => onChange?.(filter.key, v),
|
|
2773
|
+
options: filter.options,
|
|
2774
|
+
className: spanClass,
|
|
2775
|
+
disabled
|
|
2776
|
+
}
|
|
2777
|
+
);
|
|
2778
|
+
case "text":
|
|
2779
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2780
|
+
Input,
|
|
2781
|
+
{
|
|
2782
|
+
type: "search",
|
|
2783
|
+
"aria-label": ariaLabel,
|
|
2784
|
+
placeholder: filter.placeholder,
|
|
2785
|
+
value: value ?? "",
|
|
2786
|
+
onChange: (e) => onChange?.(filter.key, e.target.value),
|
|
2787
|
+
leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "size-4" }),
|
|
2788
|
+
wrapperClassName: spanClass,
|
|
2789
|
+
disabled
|
|
2790
|
+
}
|
|
2791
|
+
);
|
|
2792
|
+
case "date":
|
|
2793
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2794
|
+
DatePicker,
|
|
2795
|
+
{
|
|
2796
|
+
"aria-label": ariaLabel,
|
|
2797
|
+
placeholder: filter.placeholder,
|
|
2798
|
+
value: value ?? "",
|
|
2799
|
+
onValueChange: (v) => onChange?.(filter.key, v),
|
|
2800
|
+
className: spanClass,
|
|
2801
|
+
disabled
|
|
2802
|
+
}
|
|
2803
|
+
);
|
|
2804
|
+
case "multiselect":
|
|
2805
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2806
|
+
MultiSelect,
|
|
2807
|
+
{
|
|
2808
|
+
"aria-label": ariaLabel,
|
|
2809
|
+
placeholder: filter.placeholder,
|
|
2810
|
+
options: filter.options,
|
|
2811
|
+
value: value ? value.split(",").filter(Boolean) : [],
|
|
2812
|
+
onValueChange: (values) => onChange?.(filter.key, values.join(",")),
|
|
2813
|
+
className: spanClass,
|
|
2814
|
+
disabled
|
|
2815
|
+
}
|
|
2816
|
+
);
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
var DEFAULT_LABELS = {
|
|
2508
2820
|
reset: "Reset filters",
|
|
2509
2821
|
emptyTitle: "No results",
|
|
2510
2822
|
emptyDescription: "Try clearing the search or adjusting the filters.",
|
|
2511
2823
|
noDataTitle: "No data yet",
|
|
2512
2824
|
noDataDescription: "Nothing has been added here so far."
|
|
2513
2825
|
};
|
|
2514
|
-
var FILTER_WIDTH_CLASS = {
|
|
2515
|
-
narrow: "w-32",
|
|
2516
|
-
default: "w-44",
|
|
2517
|
-
wide: "w-56"
|
|
2518
|
-
};
|
|
2519
2826
|
function ListPage({
|
|
2520
2827
|
title,
|
|
2521
2828
|
description,
|
|
@@ -2526,8 +2833,6 @@ function ListPage({
|
|
|
2526
2833
|
getRowId,
|
|
2527
2834
|
isLoading = false,
|
|
2528
2835
|
loadingRowCount,
|
|
2529
|
-
searchValue,
|
|
2530
|
-
onSearchChange,
|
|
2531
2836
|
filters,
|
|
2532
2837
|
filterValues,
|
|
2533
2838
|
onFilterChange,
|
|
@@ -2542,59 +2847,30 @@ function ListPage({
|
|
|
2542
2847
|
labels: labelsProp,
|
|
2543
2848
|
className
|
|
2544
2849
|
}) {
|
|
2545
|
-
const labels = { ...
|
|
2546
|
-
const
|
|
2547
|
-
const
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
const current = filterValues?.[f.key];
|
|
2552
|
-
const def = f.options[0]?.value ?? "";
|
|
2553
|
-
if (current !== void 0 && current !== def) return true;
|
|
2554
|
-
}
|
|
2555
|
-
return false;
|
|
2556
|
-
}, [searchValue, filters, filterValues]);
|
|
2850
|
+
const labels = { ...DEFAULT_LABELS, ...labelsProp };
|
|
2851
|
+
const showFilterBar = Boolean(filters?.length);
|
|
2852
|
+
const hasActiveQuery = react.useMemo(
|
|
2853
|
+
() => hasActiveFilters(filters, filterValues),
|
|
2854
|
+
[filters, filterValues]
|
|
2855
|
+
);
|
|
2557
2856
|
const reset = () => {
|
|
2558
|
-
onSearchChange?.("");
|
|
2559
2857
|
for (const f of filters ?? []) {
|
|
2560
|
-
|
|
2561
|
-
onFilterChange?.(f.key, def);
|
|
2858
|
+
onFilterChange?.(f.key, filterDefaultValue(f));
|
|
2562
2859
|
}
|
|
2563
2860
|
};
|
|
2564
2861
|
const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveQuery ? "no-data" : data.length === 0 && hasActiveQuery ? "no-results" : "rows";
|
|
2565
2862
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
|
|
2566
2863
|
/* @__PURE__ */ jsxRuntime.jsx(PageHeader, { title, description, bordered, actions }),
|
|
2567
|
-
showFilterBar ? /* @__PURE__ */ jsxRuntime.
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
wrapperClassName: "sm:max-w-xs",
|
|
2578
|
-
disabled: isLoading
|
|
2579
|
-
}
|
|
2580
|
-
) : null,
|
|
2581
|
-
filters?.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2582
|
-
Select,
|
|
2583
|
-
{
|
|
2584
|
-
"aria-label": typeof f.label === "string" ? f.label : f.key,
|
|
2585
|
-
value: filterValues?.[f.key] ?? f.options[0]?.value ?? "",
|
|
2586
|
-
onValueChange: (v) => onFilterChange?.(f.key, v),
|
|
2587
|
-
options: f.options,
|
|
2588
|
-
className: FILTER_WIDTH_CLASS[f.width ?? "default"],
|
|
2589
|
-
disabled: isLoading
|
|
2590
|
-
},
|
|
2591
|
-
f.key
|
|
2592
|
-
)),
|
|
2593
|
-
hasActiveQuery && !isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", onClick: reset, children: [
|
|
2594
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, {}),
|
|
2595
|
-
labels.reset
|
|
2596
|
-
] }) : null
|
|
2597
|
-
] }) : null,
|
|
2864
|
+
showFilterBar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2865
|
+
ListPageFilterBar,
|
|
2866
|
+
{
|
|
2867
|
+
filters,
|
|
2868
|
+
values: filterValues,
|
|
2869
|
+
onChange: onFilterChange,
|
|
2870
|
+
disabled: isLoading,
|
|
2871
|
+
labels: { reset: labels.reset }
|
|
2872
|
+
}
|
|
2873
|
+
) : null,
|
|
2598
2874
|
tableMode === "loading" || tableMode === "rows" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2599
2875
|
Table,
|
|
2600
2876
|
{
|
|
@@ -3071,6 +3347,7 @@ exports.HeaderTitle = HeaderTitle;
|
|
|
3071
3347
|
exports.Input = Input;
|
|
3072
3348
|
exports.LanguageSwitcher = LanguageSwitcher;
|
|
3073
3349
|
exports.ListPage = ListPage;
|
|
3350
|
+
exports.MultiSelect = MultiSelect;
|
|
3074
3351
|
exports.PageHeader = PageHeader;
|
|
3075
3352
|
exports.RadioGroup = RadioGroup;
|
|
3076
3353
|
exports.RadioGroupItem = RadioGroupItem;
|
|
@@ -3150,6 +3427,15 @@ exports.formPageSkeletonRowClass = formPageSkeletonRowClass;
|
|
|
3150
3427
|
exports.inputBaseClass = inputBaseClass;
|
|
3151
3428
|
exports.inputSizeClass = inputSizeClass;
|
|
3152
3429
|
exports.inputVariantClass = inputVariantClass;
|
|
3430
|
+
exports.multiSelectChipClass = multiSelectChipClass;
|
|
3431
|
+
exports.multiSelectChipRemoveClass = multiSelectChipRemoveClass;
|
|
3432
|
+
exports.multiSelectContentClass = multiSelectContentClass;
|
|
3433
|
+
exports.multiSelectEmptyClass = multiSelectEmptyClass;
|
|
3434
|
+
exports.multiSelectListClass = multiSelectListClass;
|
|
3435
|
+
exports.multiSelectOptionClass = multiSelectOptionClass;
|
|
3436
|
+
exports.multiSelectSearchRowClass = multiSelectSearchRowClass;
|
|
3437
|
+
exports.multiSelectTriggerSizeClass = multiSelectTriggerSizeClass;
|
|
3438
|
+
exports.multiSelectValueRowClass = multiSelectValueRowClass;
|
|
3153
3439
|
exports.pageHeaderActionsClass = pageHeaderActionsClass;
|
|
3154
3440
|
exports.pageHeaderBackClass = pageHeaderBackClass;
|
|
3155
3441
|
exports.pageHeaderBackIconClass = pageHeaderBackIconClass;
|