@dimaan/ui 0.0.26 → 0.0.28
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 +102 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +103 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -602,6 +602,7 @@ function SidebarHeader({ className, children, ...props }) {
|
|
|
602
602
|
function SidebarNav({ className, children, ...props }) {
|
|
603
603
|
return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: cn("flex flex-1 flex-col gap-1 overflow-y-auto p-2", className), ...props, children });
|
|
604
604
|
}
|
|
605
|
+
var SidebarNavGroupContext = react.createContext(null);
|
|
605
606
|
function SidebarNavGroup({
|
|
606
607
|
icon,
|
|
607
608
|
label,
|
|
@@ -627,19 +628,39 @@ function SidebarNavGroup({
|
|
|
627
628
|
},
|
|
628
629
|
[isControlled, onOpenChange]
|
|
629
630
|
);
|
|
631
|
+
const [activeChildIds, setActiveChildIds] = react.useState(() => /* @__PURE__ */ new Set());
|
|
632
|
+
const reportActive = react.useCallback((id, isItemActive) => {
|
|
633
|
+
setActiveChildIds((prev) => {
|
|
634
|
+
if (isItemActive === prev.has(id)) return prev;
|
|
635
|
+
const next = new Set(prev);
|
|
636
|
+
if (isItemActive) next.add(id);
|
|
637
|
+
else next.delete(id);
|
|
638
|
+
return next;
|
|
639
|
+
});
|
|
640
|
+
}, []);
|
|
641
|
+
const contextValue = react.useMemo(() => ({ reportActive }), [reportActive]);
|
|
642
|
+
const hasActiveChild = activeChildIds.size > 0;
|
|
643
|
+
const isActive = active || hasActiveChild;
|
|
644
|
+
const prevHasActiveChild = react.useRef(false);
|
|
645
|
+
react.useEffect(() => {
|
|
646
|
+
if (hasActiveChild && !prevHasActiveChild.current && !collapsed) {
|
|
647
|
+
setOpen(true);
|
|
648
|
+
}
|
|
649
|
+
prevHasActiveChild.current = hasActiveChild;
|
|
650
|
+
}, [hasActiveChild, collapsed, setOpen]);
|
|
630
651
|
react.useEffect(() => {
|
|
631
652
|
if (collapsed && open) setOpen(false);
|
|
632
653
|
}, [collapsed, open, setOpen]);
|
|
633
654
|
const titleAttr = collapsed && typeof label === "string" ? label : props.title ?? void 0;
|
|
634
655
|
const showChildren = !collapsed;
|
|
635
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
656
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-col", children: [
|
|
636
657
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
637
658
|
"button",
|
|
638
659
|
{
|
|
639
660
|
type: "button",
|
|
640
661
|
"aria-expanded": showChildren ? open : void 0,
|
|
641
662
|
"aria-controls": showChildren ? submenuId : void 0,
|
|
642
|
-
"data-active":
|
|
663
|
+
"data-active": isActive ? "true" : void 0,
|
|
643
664
|
title: titleAttr,
|
|
644
665
|
onClick: (e) => {
|
|
645
666
|
if (showChildren) setOpen(!open);
|
|
@@ -649,12 +670,19 @@ function SidebarNavGroup({
|
|
|
649
670
|
"group relative flex h-9 w-full items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
|
|
650
671
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
651
672
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
652
|
-
|
|
673
|
+
isActive && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
653
674
|
collapsed && "justify-center px-0",
|
|
654
675
|
className
|
|
655
676
|
),
|
|
656
677
|
...props,
|
|
657
678
|
children: [
|
|
679
|
+
isActive ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
680
|
+
"span",
|
|
681
|
+
{
|
|
682
|
+
"aria-hidden": "true",
|
|
683
|
+
className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
|
|
684
|
+
}
|
|
685
|
+
) : null,
|
|
658
686
|
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex h-5 w-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
659
687
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
660
688
|
"span",
|
|
@@ -680,7 +708,7 @@ function SidebarNavGroup({
|
|
|
680
708
|
"grid transition-[grid-template-rows] duration-200 ease-out",
|
|
681
709
|
showChildren && open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
|
|
682
710
|
),
|
|
683
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5 ps-7 pt-1", children }) })
|
|
711
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5 ps-7 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarNavGroupContext.Provider, { value: contextValue, children }) }) })
|
|
684
712
|
}
|
|
685
713
|
)
|
|
686
714
|
] });
|
|
@@ -710,13 +738,20 @@ function SidebarNavItem({
|
|
|
710
738
|
...props
|
|
711
739
|
}) {
|
|
712
740
|
const { collapsed } = useDashboardLayout();
|
|
713
|
-
const location = reactRouterDom.useLocation();
|
|
714
741
|
const resolved = reactRouterDom.useResolvedPath(to);
|
|
715
|
-
const
|
|
742
|
+
const group = react.useContext(SidebarNavGroupContext);
|
|
743
|
+
const itemId = react.useId();
|
|
744
|
+
const routeMatch = reactRouterDom.useMatch({ path: resolved.pathname, end: end ?? false });
|
|
745
|
+
const isActive = forcedActive || routeMatch != null;
|
|
746
|
+
react.useEffect(() => {
|
|
747
|
+
if (!group) return;
|
|
748
|
+
group.reportActive(itemId, isActive);
|
|
749
|
+
return () => group.reportActive(itemId, false);
|
|
750
|
+
}, [group, itemId, isActive]);
|
|
716
751
|
const labelContent = label ?? children;
|
|
717
752
|
const titleAttr = collapsed && typeof labelContent === "string" ? labelContent : props.title;
|
|
718
753
|
const getClassName = (active) => cn(
|
|
719
|
-
"group relative flex h-9 items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
|
|
754
|
+
"group relative flex h-9 shrink-0 items-center gap-3 rounded-md px-3 text-sm font-medium outline-none transition-colors",
|
|
720
755
|
"text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
721
756
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-sidebar",
|
|
722
757
|
active && "bg-sidebar-accent text-sidebar-accent-foreground",
|
|
@@ -724,6 +759,13 @@ function SidebarNavItem({
|
|
|
724
759
|
className
|
|
725
760
|
);
|
|
726
761
|
const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
762
|
+
isActive ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
763
|
+
"span",
|
|
764
|
+
{
|
|
765
|
+
"aria-hidden": "true",
|
|
766
|
+
className: "absolute inset-y-1.5 start-0 w-1 rounded-full bg-primary"
|
|
767
|
+
}
|
|
768
|
+
) : null,
|
|
727
769
|
icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex h-5 w-5 shrink-0 items-center justify-center", children: icon }) : null,
|
|
728
770
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
729
771
|
"span",
|
|
@@ -2621,6 +2663,7 @@ var selectItemClass = "relative flex w-full cursor-pointer select-none items-cen
|
|
|
2621
2663
|
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";
|
|
2622
2664
|
var selectGroupLabelClass = "px-2 py-1.5 text-xs font-semibold text-muted-foreground";
|
|
2623
2665
|
var selectSeparatorClass = "-mx-1 my-1 h-px bg-border";
|
|
2666
|
+
var selectStatusClass = "flex items-center justify-center gap-2 px-2 py-6 text-center text-sm text-muted-foreground";
|
|
2624
2667
|
|
|
2625
2668
|
// src/components/multi-select/multiSelectVariants.ts
|
|
2626
2669
|
var multiSelectTriggerSizeClass = {
|
|
@@ -2638,11 +2681,13 @@ var multiSelectOptionClass = "flex w-full cursor-pointer select-none items-cente
|
|
|
2638
2681
|
var multiSelectEmptyClass = "px-2 py-6 text-center text-sm text-muted-foreground";
|
|
2639
2682
|
var DEFAULT_LABELS_LTR4 = {
|
|
2640
2683
|
search: "Search\u2026",
|
|
2641
|
-
empty: "No results"
|
|
2684
|
+
empty: "No results",
|
|
2685
|
+
loading: "Loading\u2026"
|
|
2642
2686
|
};
|
|
2643
2687
|
var DEFAULT_LABELS_RTL4 = {
|
|
2644
2688
|
search: "\u0628\u062D\u062B\u2026",
|
|
2645
|
-
empty: "\u0644\u0627 \u0646\u062A\u0627\u0626\u062C"
|
|
2689
|
+
empty: "\u0644\u0627 \u0646\u062A\u0627\u0626\u062C",
|
|
2690
|
+
loading: "\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644\u2026"
|
|
2646
2691
|
};
|
|
2647
2692
|
function toArray(value) {
|
|
2648
2693
|
return Array.isArray(value) ? value : [];
|
|
@@ -2652,6 +2697,7 @@ var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
|
2652
2697
|
selectSize = "md",
|
|
2653
2698
|
options,
|
|
2654
2699
|
placeholder,
|
|
2700
|
+
loading = false,
|
|
2655
2701
|
value,
|
|
2656
2702
|
defaultValue,
|
|
2657
2703
|
onValueChange,
|
|
@@ -2732,7 +2778,10 @@ var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
|
2732
2778
|
className
|
|
2733
2779
|
),
|
|
2734
2780
|
children: [
|
|
2735
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: multiSelectValueRowClass, children:
|
|
2781
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: multiSelectValueRowClass, children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
2782
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "size-4 shrink-0 animate-spin" }),
|
|
2783
|
+
labels.loading
|
|
2784
|
+
] }) : selected.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2736
2785
|
shownValues.map((v) => /* @__PURE__ */ jsxRuntime.jsxs(Badge, { variant: "default", size: "sm", className: multiSelectChipClass, children: [
|
|
2737
2786
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: labelByValue.get(v) ?? v }),
|
|
2738
2787
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2767,7 +2816,7 @@ var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
|
2767
2816
|
]
|
|
2768
2817
|
}
|
|
2769
2818
|
) }),
|
|
2770
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixPopover__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.
|
|
2819
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixPopover__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2771
2820
|
RadixPopover__namespace.Content,
|
|
2772
2821
|
{
|
|
2773
2822
|
align: "start",
|
|
@@ -2777,7 +2826,10 @@ var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
|
2777
2826
|
onOpenAutoFocus: (event) => {
|
|
2778
2827
|
if (!searchable) event.preventDefault();
|
|
2779
2828
|
},
|
|
2780
|
-
children: [
|
|
2829
|
+
children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: multiSelectEmptyClass, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
|
|
2830
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "size-4 shrink-0 animate-spin" }),
|
|
2831
|
+
labels.loading
|
|
2832
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2781
2833
|
searchable ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: multiSelectSearchRowClass, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2782
2834
|
Input,
|
|
2783
2835
|
{
|
|
@@ -2817,7 +2869,7 @@ var MultiSelect = react.forwardRef(function MultiSelect2({
|
|
|
2817
2869
|
option.value
|
|
2818
2870
|
);
|
|
2819
2871
|
}) })
|
|
2820
|
-
]
|
|
2872
|
+
] })
|
|
2821
2873
|
}
|
|
2822
2874
|
) })
|
|
2823
2875
|
] });
|
|
@@ -2831,6 +2883,9 @@ var Select = react.forwardRef(function Select2({
|
|
|
2831
2883
|
selectSize = "md",
|
|
2832
2884
|
options,
|
|
2833
2885
|
placeholder,
|
|
2886
|
+
loading = false,
|
|
2887
|
+
loadingText = "Loading\u2026",
|
|
2888
|
+
emptyText = "No options",
|
|
2834
2889
|
value,
|
|
2835
2890
|
defaultValue,
|
|
2836
2891
|
onValueChange,
|
|
@@ -2889,7 +2944,7 @@ var Select = react.forwardRef(function Select2({
|
|
|
2889
2944
|
className
|
|
2890
2945
|
),
|
|
2891
2946
|
children: [
|
|
2892
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Value, { placeholder }),
|
|
2947
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Value, { placeholder, children: loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-2 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(SelectLoading, { text: loadingText }) }) : void 0 }),
|
|
2893
2948
|
/* @__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" }) })
|
|
2894
2949
|
]
|
|
2895
2950
|
}
|
|
@@ -2903,7 +2958,7 @@ var Select = react.forwardRef(function Select2({
|
|
|
2903
2958
|
className: selectContentClass,
|
|
2904
2959
|
children: [
|
|
2905
2960
|
/* @__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" }) }),
|
|
2906
|
-
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Viewport, { className: selectViewportClass, children: children ?? (
|
|
2961
|
+
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.Viewport, { className: selectViewportClass, children: children ?? renderViewportContent({ loading, options, loadingText, emptyText }) }),
|
|
2907
2962
|
/* @__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" }) })
|
|
2908
2963
|
]
|
|
2909
2964
|
}
|
|
@@ -2912,6 +2967,26 @@ var Select = react.forwardRef(function Select2({
|
|
|
2912
2967
|
}
|
|
2913
2968
|
);
|
|
2914
2969
|
});
|
|
2970
|
+
function SelectLoading({ text }) {
|
|
2971
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2972
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { "aria-hidden": "true", className: "size-4 shrink-0 animate-spin" }),
|
|
2973
|
+
text
|
|
2974
|
+
] });
|
|
2975
|
+
}
|
|
2976
|
+
function renderViewportContent({
|
|
2977
|
+
loading,
|
|
2978
|
+
options,
|
|
2979
|
+
loadingText,
|
|
2980
|
+
emptyText
|
|
2981
|
+
}) {
|
|
2982
|
+
if (loading) {
|
|
2983
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: selectStatusClass, role: "presentation", children: /* @__PURE__ */ jsxRuntime.jsx(SelectLoading, { text: loadingText }) });
|
|
2984
|
+
}
|
|
2985
|
+
if (!options || options.length === 0) {
|
|
2986
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: selectStatusClass, role: "presentation", children: emptyText });
|
|
2987
|
+
}
|
|
2988
|
+
return renderOptions(options);
|
|
2989
|
+
}
|
|
2915
2990
|
function renderOptions(options) {
|
|
2916
2991
|
if (isGroupedOptions(options)) {
|
|
2917
2992
|
const lastIndex = options.length - 1;
|
|
@@ -2952,6 +3027,7 @@ function DebouncedFilterInput({
|
|
|
2952
3027
|
value,
|
|
2953
3028
|
onChange,
|
|
2954
3029
|
debounceMs,
|
|
3030
|
+
id,
|
|
2955
3031
|
ariaLabel,
|
|
2956
3032
|
placeholder,
|
|
2957
3033
|
wrapperClassName,
|
|
@@ -2989,6 +3065,7 @@ function DebouncedFilterInput({
|
|
|
2989
3065
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2990
3066
|
Input,
|
|
2991
3067
|
{
|
|
3068
|
+
id,
|
|
2992
3069
|
type: "search",
|
|
2993
3070
|
"aria-label": ariaLabel,
|
|
2994
3071
|
placeholder,
|
|
@@ -3073,6 +3150,16 @@ function ListPageFilterBar({
|
|
|
3073
3150
|
}
|
|
3074
3151
|
function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
3075
3152
|
const spanClass = FILTER_SPAN_CLASS[filter.width ?? "default"];
|
|
3153
|
+
const label = filter.label ?? filter.key;
|
|
3154
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { label, className: spanClass, children: renderFilterControl({ filter, value, onChange, disabled, mode }) });
|
|
3155
|
+
}
|
|
3156
|
+
function renderFilterControl({
|
|
3157
|
+
filter,
|
|
3158
|
+
value,
|
|
3159
|
+
onChange,
|
|
3160
|
+
disabled,
|
|
3161
|
+
mode
|
|
3162
|
+
}) {
|
|
3076
3163
|
const ariaLabel = typeof filter.label === "string" ? filter.label : filter.key;
|
|
3077
3164
|
switch (filter.type) {
|
|
3078
3165
|
case "select":
|
|
@@ -3083,7 +3170,6 @@ function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
|
3083
3170
|
value: value ?? filterDefaultValue(filter),
|
|
3084
3171
|
onValueChange: (v) => onChange?.(filter.key, v),
|
|
3085
3172
|
options: filter.options,
|
|
3086
|
-
className: spanClass,
|
|
3087
3173
|
disabled
|
|
3088
3174
|
}
|
|
3089
3175
|
);
|
|
@@ -3096,7 +3182,6 @@ function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
|
3096
3182
|
debounceMs: mode === "live" ? filter.debounceMs ?? DEFAULT_TEXT_DEBOUNCE_MS : 0,
|
|
3097
3183
|
ariaLabel,
|
|
3098
3184
|
placeholder: filter.placeholder,
|
|
3099
|
-
wrapperClassName: spanClass,
|
|
3100
3185
|
disabled
|
|
3101
3186
|
}
|
|
3102
3187
|
);
|
|
@@ -3108,7 +3193,6 @@ function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
|
3108
3193
|
placeholder: filter.placeholder,
|
|
3109
3194
|
value: value ?? "",
|
|
3110
3195
|
onValueChange: (v) => onChange?.(filter.key, v),
|
|
3111
|
-
className: spanClass,
|
|
3112
3196
|
disabled
|
|
3113
3197
|
}
|
|
3114
3198
|
);
|
|
@@ -3121,7 +3205,6 @@ function FilterControl({ filter, value, onChange, disabled, mode }) {
|
|
|
3121
3205
|
options: filter.options,
|
|
3122
3206
|
value: value ? value.split(",").filter(Boolean) : [],
|
|
3123
3207
|
onValueChange: (values) => onChange?.(filter.key, values.join(",")),
|
|
3124
|
-
className: spanClass,
|
|
3125
3208
|
disabled
|
|
3126
3209
|
}
|
|
3127
3210
|
);
|