@geomak/ui 5.9.0 → 6.0.0
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 +244 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -37
- package/dist/index.d.ts +124 -37
- package/dist/index.js +245 -142
- package/dist/index.js.map +1 -1
- package/dist/styles.css +79 -27
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -918,7 +918,8 @@ function Tooltip({
|
|
|
918
918
|
title,
|
|
919
919
|
placement = "top",
|
|
920
920
|
delayDuration = 300,
|
|
921
|
-
sideOffset = 8
|
|
921
|
+
sideOffset = 8,
|
|
922
|
+
className = ""
|
|
922
923
|
}) {
|
|
923
924
|
return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Provider, { delayDuration, children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipPrimitive__namespace.Root, { children: [
|
|
924
925
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex", children }) }),
|
|
@@ -938,8 +939,9 @@ function Tooltip({
|
|
|
938
939
|
// Out animation (always the same — just fade)
|
|
939
940
|
"data-[state=closed]:animate-tooltip-out",
|
|
940
941
|
// In animation — direction-aware
|
|
941
|
-
ANIMATION[placement]
|
|
942
|
-
|
|
942
|
+
ANIMATION[placement],
|
|
943
|
+
className
|
|
944
|
+
].filter(Boolean).join(" "),
|
|
943
945
|
children: [
|
|
944
946
|
title,
|
|
945
947
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -956,131 +958,225 @@ function Tooltip({
|
|
|
956
958
|
] }) });
|
|
957
959
|
}
|
|
958
960
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
961
|
+
var TabsContext = React8.createContext(null);
|
|
962
|
+
function useTabsContext() {
|
|
963
|
+
const ctx = React8.useContext(TabsContext);
|
|
964
|
+
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
965
|
+
return ctx;
|
|
966
|
+
}
|
|
967
|
+
var SIZE = {
|
|
968
|
+
sm: { trigger: "h-8 text-xs px-2.5", icon: "h-3.5 w-3.5", add: "h-8 w-8" },
|
|
969
|
+
md: { trigger: "h-10 text-sm px-3", icon: "h-4 w-4", add: "h-10 w-9" },
|
|
970
|
+
lg: { trigger: "h-12 text-sm px-4", icon: "h-[18px] w-[18px]", add: "h-12 w-10" }
|
|
971
|
+
};
|
|
972
|
+
var MARKER_TRANSITION = { duration: 0.26, ease: [0.16, 1, 0.3, 1] };
|
|
959
973
|
function Tabs({
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
974
|
+
value,
|
|
975
|
+
defaultValue,
|
|
976
|
+
onValueChange,
|
|
977
|
+
variant = "underline",
|
|
978
|
+
size = "md",
|
|
979
|
+
orientation = "horizontal",
|
|
980
|
+
className = "",
|
|
981
|
+
style,
|
|
982
|
+
children
|
|
966
983
|
}) {
|
|
967
|
-
const
|
|
968
|
-
React8.
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
React8.
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
}
|
|
976
|
-
const exists = tabs.find((t) => t.key === value);
|
|
977
|
-
if (!exists) {
|
|
978
|
-
setValue(tabs[tabs.length - 1].key);
|
|
979
|
-
}
|
|
980
|
-
}, [tabs, value]);
|
|
981
|
-
const handleValueChange = (newValue) => {
|
|
982
|
-
const prev = tabs.find((t) => t.key === value);
|
|
983
|
-
const next = tabs.find((t) => t.key === newValue);
|
|
984
|
-
onTabChange?.(prev, next);
|
|
985
|
-
setValue(newValue);
|
|
986
|
-
};
|
|
987
|
-
const toPreviousTab = () => {
|
|
988
|
-
const idx = tabs.findIndex((t) => t.key === value);
|
|
989
|
-
if (idx > 0) handleValueChange(tabs[idx - 1].key);
|
|
990
|
-
};
|
|
991
|
-
const toNextTab = () => {
|
|
992
|
-
const idx = tabs.findIndex((t) => t.key === value);
|
|
993
|
-
if (idx < tabs.length - 1) handleValueChange(tabs[idx + 1].key);
|
|
984
|
+
const isControlled = value !== void 0;
|
|
985
|
+
const [internal, setInternal] = React8.useState(defaultValue);
|
|
986
|
+
const current = isControlled ? value : internal;
|
|
987
|
+
const reduced = !!framerMotion.useReducedMotion();
|
|
988
|
+
const indicatorId = React8.useId();
|
|
989
|
+
const handle = (next) => {
|
|
990
|
+
if (!isControlled) setInternal(next);
|
|
991
|
+
onValueChange?.(next);
|
|
994
992
|
};
|
|
995
|
-
|
|
996
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
993
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
997
994
|
TabsPrimitive__namespace.Root,
|
|
995
|
+
{
|
|
996
|
+
value: current,
|
|
997
|
+
onValueChange: handle,
|
|
998
|
+
orientation,
|
|
999
|
+
className: [
|
|
1000
|
+
"flex min-w-0",
|
|
1001
|
+
orientation === "vertical" ? "flex-row gap-4" : "flex-col gap-3",
|
|
1002
|
+
className
|
|
1003
|
+
].filter(Boolean).join(" "),
|
|
1004
|
+
style,
|
|
1005
|
+
children
|
|
1006
|
+
}
|
|
1007
|
+
) });
|
|
1008
|
+
}
|
|
1009
|
+
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1010
|
+
const { variant, orientation, reduced } = useTabsContext();
|
|
1011
|
+
const horizontal = orientation === "horizontal";
|
|
1012
|
+
const scrollRef = React8.useRef(null);
|
|
1013
|
+
const [edges, setEdges] = React8.useState({ start: false, end: false });
|
|
1014
|
+
const scrollable = variant !== "segmented";
|
|
1015
|
+
React8.useLayoutEffect(() => {
|
|
1016
|
+
const el = scrollRef.current;
|
|
1017
|
+
if (!el || !scrollable) return;
|
|
1018
|
+
const update = () => {
|
|
1019
|
+
if (horizontal) {
|
|
1020
|
+
setEdges({
|
|
1021
|
+
start: el.scrollLeft > 1,
|
|
1022
|
+
end: el.scrollLeft + el.clientWidth < el.scrollWidth - 1
|
|
1023
|
+
});
|
|
1024
|
+
} else {
|
|
1025
|
+
setEdges({
|
|
1026
|
+
start: el.scrollTop > 1,
|
|
1027
|
+
end: el.scrollTop + el.clientHeight < el.scrollHeight - 1
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
1031
|
+
update();
|
|
1032
|
+
el.addEventListener("scroll", update, { passive: true });
|
|
1033
|
+
const ro = new ResizeObserver(update);
|
|
1034
|
+
ro.observe(el);
|
|
1035
|
+
return () => {
|
|
1036
|
+
el.removeEventListener("scroll", update);
|
|
1037
|
+
ro.disconnect();
|
|
1038
|
+
};
|
|
1039
|
+
}, [horizontal, scrollable, children]);
|
|
1040
|
+
const nudge = React8.useCallback((dir) => {
|
|
1041
|
+
const el = scrollRef.current;
|
|
1042
|
+
if (!el) return;
|
|
1043
|
+
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1044
|
+
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1045
|
+
}, [horizontal, reduced]);
|
|
1046
|
+
const maskStyle = scrollable && (edges.start || edges.end) ? (() => {
|
|
1047
|
+
const dir = horizontal ? "to right" : "to bottom";
|
|
1048
|
+
const a = edges.start ? "transparent, black 36px" : "black";
|
|
1049
|
+
const b = edges.end ? "black calc(100% - 36px), transparent" : "black";
|
|
1050
|
+
const img = `linear-gradient(${dir}, ${a}, ${b})`;
|
|
1051
|
+
return { maskImage: img, WebkitMaskImage: img };
|
|
1052
|
+
})() : {};
|
|
1053
|
+
const trackClass = (() => {
|
|
1054
|
+
if (variant === "segmented") {
|
|
1055
|
+
return horizontal ? "inline-flex items-center gap-1 rounded-lg border border-border bg-surface-raised p-1 w-fit" : "inline-flex flex-col items-stretch gap-1 rounded-lg border border-border bg-surface-raised p-1 w-fit";
|
|
1056
|
+
}
|
|
1057
|
+
const hairline = horizontal ? "border-b border-border" : "border-r border-border";
|
|
1058
|
+
const align = variant === "enclosed" && horizontal ? "items-end" : "items-stretch";
|
|
1059
|
+
return `flex ${horizontal ? "flex-row" : "flex-col"} ${align} gap-1 ${hairline}`;
|
|
1060
|
+
})();
|
|
1061
|
+
const scrollClass = scrollable ? horizontal ? "overflow-x-auto overflow-y-hidden hidden-scrollbar" : "overflow-y-auto overflow-x-hidden hidden-scrollbar" : "";
|
|
1062
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["relative flex min-w-0", horizontal ? "flex-row items-stretch" : "flex-col items-stretch", className].filter(Boolean).join(" "), children: [
|
|
1063
|
+
scrollable && edges.start && /* @__PURE__ */ jsxRuntime.jsx(Chevron, { side: "start", orientation, onClick: () => nudge(-1) }),
|
|
1064
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1065
|
+
TabsPrimitive__namespace.List,
|
|
1066
|
+
{
|
|
1067
|
+
ref: scrollRef,
|
|
1068
|
+
"aria-label": ariaLabel,
|
|
1069
|
+
className: [scrollClass, trackClass, "min-w-0 flex-1"].filter(Boolean).join(" "),
|
|
1070
|
+
style: maskStyle,
|
|
1071
|
+
children
|
|
1072
|
+
}
|
|
1073
|
+
),
|
|
1074
|
+
scrollable && edges.end && /* @__PURE__ */ jsxRuntime.jsx(Chevron, { side: "end", orientation, onClick: () => nudge(1) })
|
|
1075
|
+
] });
|
|
1076
|
+
}
|
|
1077
|
+
function Chevron({ side, orientation, onClick }) {
|
|
1078
|
+
const horizontal = orientation === "horizontal";
|
|
1079
|
+
const rotate = horizontal ? side === "start" ? "rotate-180" : "" : side === "start" ? "-rotate-90" : "rotate-90";
|
|
1080
|
+
const pos = horizontal ? side === "start" ? "left-0 top-1/2 -translate-y-1/2" : "right-0 top-1/2 -translate-y-1/2" : side === "start" ? "top-0 left-1/2 -translate-x-1/2" : "bottom-0 left-1/2 -translate-x-1/2";
|
|
1081
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1082
|
+
"button",
|
|
1083
|
+
{
|
|
1084
|
+
type: "button",
|
|
1085
|
+
"aria-label": side === "start" ? "Scroll tabs backward" : "Scroll tabs forward",
|
|
1086
|
+
onClick,
|
|
1087
|
+
className: `absolute z-20 ${pos} flex h-7 w-7 items-center justify-center rounded-full border border-border bg-surface text-foreground-secondary shadow-sm hover:text-foreground hover:bg-surface-raised transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent`,
|
|
1088
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: `h-4 w-4 ${rotate}`, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, className = "", children }) {
|
|
1093
|
+
const { value: active, variant, size, orientation, indicatorId, reduced } = useTabsContext();
|
|
1094
|
+
const isActive = active === value;
|
|
1095
|
+
const horizontal = orientation === "horizontal";
|
|
1096
|
+
const sz = SIZE[size];
|
|
1097
|
+
const base = "group/trigger relative inline-flex items-center justify-center whitespace-nowrap font-medium select-none transition-colors duration-150 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0";
|
|
1098
|
+
const variantCls = variant === "segmented" ? `rounded-md ${isActive ? "text-accent" : "text-foreground-secondary hover:text-foreground"} focus-visible:text-accent` : variant === "enclosed" ? `${horizontal ? "rounded-t-md border border-b-0 -mb-px" : "rounded-l-md border border-r-0 -mr-px"} ${isActive ? "bg-surface border-border text-foreground" : "border-transparent text-foreground-secondary hover:text-foreground hover:bg-surface-raised"} focus-visible:text-accent` : `${isActive ? "text-accent" : "text-foreground-secondary hover:text-foreground"} focus-visible:text-accent`;
|
|
1099
|
+
const trigger = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1100
|
+
TabsPrimitive__namespace.Trigger,
|
|
998
1101
|
{
|
|
999
1102
|
value,
|
|
1000
|
-
|
|
1001
|
-
className: "
|
|
1103
|
+
disabled,
|
|
1104
|
+
className: [base, sz.trigger, closeable ? "pr-8" : "", variantCls, className].filter(Boolean).join(" "),
|
|
1002
1105
|
children: [
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
{
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
),
|
|
1014
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1015
|
-
|
|
1016
|
-
{
|
|
1017
|
-
"aria-label": "Tabs",
|
|
1018
|
-
className: "flex-1 flex items-center gap-1 overflow-x-auto overflow-y-hidden rounded-lg scroll-smooth snap-x snap-mandatory hidden-scrollbar",
|
|
1019
|
-
children: tabs.map((tab) => (
|
|
1020
|
-
// Trigger + close button are SIBLINGS, not nested.
|
|
1021
|
-
// Nesting a clickable element inside <button> is invalid
|
|
1022
|
-
// HTML and breaks keyboard activation of the inner one.
|
|
1023
|
-
// The wrapper carries `group` so the close button can
|
|
1024
|
-
// react to the trigger's `data-state=active` for styling.
|
|
1025
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1026
|
-
"div",
|
|
1027
|
-
{
|
|
1028
|
-
className: "snap-start snap-always relative flex items-center flex-1 min-w-[120px] max-w-[220px] flex-shrink-0 group",
|
|
1029
|
-
children: [
|
|
1030
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1031
|
-
TabsPrimitive__namespace.Trigger,
|
|
1032
|
-
{
|
|
1033
|
-
value: tab.key,
|
|
1034
|
-
className: `w-full ${tabsClosable ? "pr-8" : "pr-3"} pl-3 py-2 rounded-3xl cursor-pointer transition-all duration-200 select-none h-10 text-left
|
|
1035
|
-
text-foreground-secondary bg-surface-raised
|
|
1036
|
-
hover:bg-surface hover:text-foreground
|
|
1037
|
-
data-[state=active]:bg-accent data-[state=active]:text-accent-foreground
|
|
1038
|
-
focus:outline-none focus-visible:ring-2 focus-visible:ring-accent`,
|
|
1039
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm block", children: tab.title })
|
|
1040
|
-
}
|
|
1041
|
-
),
|
|
1042
|
-
tabsClosable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1043
|
-
"button",
|
|
1044
|
-
{
|
|
1045
|
-
type: "button",
|
|
1046
|
-
"aria-label": `Close ${tab.title}`,
|
|
1047
|
-
onClick: (e) => {
|
|
1048
|
-
e.stopPropagation();
|
|
1049
|
-
onTabClose?.(tab.key);
|
|
1050
|
-
},
|
|
1051
|
-
className: "absolute right-1.5 top-1/2 -translate-y-1/2 rounded p-0.5 text-foreground-secondary group-data-[state=active]:text-accent-foreground hover:bg-black/10 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
1052
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1053
|
-
}
|
|
1054
|
-
)
|
|
1055
|
-
]
|
|
1056
|
-
},
|
|
1057
|
-
tab.key
|
|
1058
|
-
)
|
|
1059
|
-
))
|
|
1060
|
-
}
|
|
1061
|
-
),
|
|
1062
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1063
|
-
"button",
|
|
1064
|
-
{
|
|
1065
|
-
type: "button",
|
|
1066
|
-
onClick: toNextTab,
|
|
1067
|
-
"aria-label": "Next tab",
|
|
1068
|
-
className: "cursor-pointer rounded-lg transition-colors duration-150 hover:bg-surface-raised text-foreground-secondary hover:text-foreground flex-shrink-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
1069
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-6 w-6", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
1070
|
-
}
|
|
1071
|
-
)
|
|
1106
|
+
variant === "segmented" && isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1107
|
+
framerMotion.motion.span,
|
|
1108
|
+
{
|
|
1109
|
+
layoutId: `${indicatorId}-seg`,
|
|
1110
|
+
className: "absolute inset-0 rounded-md bg-surface shadow-sm",
|
|
1111
|
+
transition: reduced ? { duration: 0 } : MARKER_TRANSITION,
|
|
1112
|
+
"aria-hidden": "true"
|
|
1113
|
+
}
|
|
1114
|
+
),
|
|
1115
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative z-[1] inline-flex items-center gap-2 min-w-0", children: [
|
|
1116
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `flex-shrink-0 inline-flex items-center justify-center ${sz.icon}`, children: icon }),
|
|
1117
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }),
|
|
1118
|
+
badge != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-border px-1 text-[11px] font-semibold leading-none text-foreground-secondary group-data-[state=active]/trigger:bg-accent group-data-[state=active]/trigger:text-accent-foreground transition-colors", children: badge })
|
|
1072
1119
|
] }),
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1120
|
+
variant === "underline" && isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1121
|
+
framerMotion.motion.span,
|
|
1122
|
+
{
|
|
1123
|
+
layoutId: `${indicatorId}-line`,
|
|
1124
|
+
className: horizontal ? "absolute left-2 right-2 bottom-0 h-0.5 rounded-full bg-accent" : "absolute top-1.5 bottom-1.5 right-0 w-0.5 rounded-full bg-accent",
|
|
1125
|
+
transition: reduced ? { duration: 0 } : MARKER_TRANSITION,
|
|
1126
|
+
"aria-hidden": "true"
|
|
1127
|
+
}
|
|
1128
|
+
)
|
|
1080
1129
|
]
|
|
1081
1130
|
}
|
|
1082
1131
|
);
|
|
1132
|
+
if (!closeable) return trigger;
|
|
1133
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative inline-flex items-center flex-shrink-0", children: [
|
|
1134
|
+
trigger,
|
|
1135
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1136
|
+
"button",
|
|
1137
|
+
{
|
|
1138
|
+
type: "button",
|
|
1139
|
+
"aria-label": "Close tab",
|
|
1140
|
+
onClick: (e) => {
|
|
1141
|
+
e.stopPropagation();
|
|
1142
|
+
onClose?.();
|
|
1143
|
+
},
|
|
1144
|
+
className: "absolute right-1.5 top-1/2 z-[2] -translate-y-1/2 inline-flex h-5 w-5 items-center justify-center rounded text-foreground-muted hover:text-status-error hover:bg-surface-raised transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-accent",
|
|
1145
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 5L5 15M5 5l10 10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1146
|
+
}
|
|
1147
|
+
)
|
|
1148
|
+
] });
|
|
1149
|
+
}
|
|
1150
|
+
function TabsAdd({ onClick, "aria-label": ariaLabel = "Add tab", className = "" }) {
|
|
1151
|
+
const { size } = useTabsContext();
|
|
1152
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1153
|
+
"button",
|
|
1154
|
+
{
|
|
1155
|
+
type: "button",
|
|
1156
|
+
onClick,
|
|
1157
|
+
"aria-label": ariaLabel,
|
|
1158
|
+
className: `flex-shrink-0 inline-flex items-center justify-center rounded-md text-foreground-muted hover:text-foreground hover:bg-surface-raised transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent ${SIZE[size].add} ${className}`.trim(),
|
|
1159
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12h14" }) })
|
|
1160
|
+
}
|
|
1161
|
+
);
|
|
1083
1162
|
}
|
|
1163
|
+
function TabsPanel({ value, keepMounted, className = "", style, children }) {
|
|
1164
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1165
|
+
TabsPrimitive__namespace.Content,
|
|
1166
|
+
{
|
|
1167
|
+
value,
|
|
1168
|
+
forceMount: keepMounted || void 0,
|
|
1169
|
+
className: ["min-w-0 flex-1 focus:outline-none data-[state=inactive]:hidden", className].filter(Boolean).join(" "),
|
|
1170
|
+
style,
|
|
1171
|
+
children
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
Tabs.List = TabsList;
|
|
1176
|
+
Tabs.Trigger = TabsTrigger;
|
|
1177
|
+
Tabs.Panel = TabsPanel;
|
|
1178
|
+
Tabs.Add = TabsAdd;
|
|
1179
|
+
var Tabs_default = Tabs;
|
|
1084
1180
|
var isParent = (item) => Boolean(item.children && item.children.length > 0);
|
|
1085
1181
|
function TreeNodeItem({
|
|
1086
1182
|
item,
|
|
@@ -1172,9 +1268,11 @@ function Tree({
|
|
|
1172
1268
|
nodes,
|
|
1173
1269
|
onNodeClick,
|
|
1174
1270
|
defaultExpandAll = false,
|
|
1175
|
-
defaultExpandedKeys = []
|
|
1271
|
+
defaultExpandedKeys = [],
|
|
1272
|
+
className = "",
|
|
1273
|
+
style
|
|
1176
1274
|
}) {
|
|
1177
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
1275
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `p-1 w-full ${className}`.trim(), style, children: nodes.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1178
1276
|
TreeNodeItem,
|
|
1179
1277
|
{
|
|
1180
1278
|
item,
|
|
@@ -1441,7 +1539,8 @@ function LoadingSpinner({
|
|
|
1441
1539
|
inline = false,
|
|
1442
1540
|
spinnerColor,
|
|
1443
1541
|
textColor,
|
|
1444
|
-
backdropOpacity = 0.8
|
|
1542
|
+
backdropOpacity = 0.8,
|
|
1543
|
+
className = ""
|
|
1445
1544
|
}) {
|
|
1446
1545
|
const reduced = framerMotion.useReducedMotion();
|
|
1447
1546
|
const letters = prompt ? Array.from(prompt) : [];
|
|
@@ -1476,7 +1575,7 @@ function LoadingSpinner({
|
|
|
1476
1575
|
role: "status",
|
|
1477
1576
|
"aria-live": "polite",
|
|
1478
1577
|
"aria-label": prompt ?? "Loading",
|
|
1479
|
-
className:
|
|
1578
|
+
className: `flex flex-col items-center justify-center gap-3 ${className}`.trim(),
|
|
1480
1579
|
children: content
|
|
1481
1580
|
}
|
|
1482
1581
|
);
|
|
@@ -1487,7 +1586,7 @@ function LoadingSpinner({
|
|
|
1487
1586
|
role: "status",
|
|
1488
1587
|
"aria-live": "polite",
|
|
1489
1588
|
"aria-label": prompt ?? "Loading",
|
|
1490
|
-
className:
|
|
1589
|
+
className: `fixed inset-0 z-[8000000] flex flex-col items-center justify-center gap-6 bg-background backdrop-blur-sm ${className}`.trim(),
|
|
1491
1590
|
style: { opacity: backdropOpacity },
|
|
1492
1591
|
children: content
|
|
1493
1592
|
}
|
|
@@ -1596,7 +1695,8 @@ function ScalableContainer({
|
|
|
1596
1695
|
assignClassOnClick,
|
|
1597
1696
|
expandIcon,
|
|
1598
1697
|
collapseIcon,
|
|
1599
|
-
togglePosition = "top-right"
|
|
1698
|
+
togglePosition = "top-right",
|
|
1699
|
+
className = ""
|
|
1600
1700
|
}) {
|
|
1601
1701
|
const containerRef = React8.useRef(null);
|
|
1602
1702
|
const [internalScaled, setInternalScaled] = React8.useState(false);
|
|
@@ -1631,8 +1731,9 @@ function ScalableContainer({
|
|
|
1631
1731
|
// OS-window aesthetic: subtle elevation at rest, lifted shadow
|
|
1632
1732
|
// when expanded. No background colour change.
|
|
1633
1733
|
isScaled ? "shadow-2xl" : "shadow-md",
|
|
1634
|
-
"transition-shadow duration-300"
|
|
1635
|
-
|
|
1734
|
+
"transition-shadow duration-300",
|
|
1735
|
+
className
|
|
1736
|
+
].filter(Boolean).join(" "),
|
|
1636
1737
|
children: [
|
|
1637
1738
|
/* @__PURE__ */ jsxRuntime.jsx(Tooltip, { placement: "bottom", title: isScaled ? "Collapse" : "Expand", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1638
1739
|
"button",
|
|
@@ -1684,12 +1785,13 @@ function OpaqueGridCard({
|
|
|
1684
1785
|
item,
|
|
1685
1786
|
isRight = false,
|
|
1686
1787
|
buttonText = "Open Application",
|
|
1687
|
-
onOpen
|
|
1788
|
+
onOpen,
|
|
1789
|
+
className = ""
|
|
1688
1790
|
}) {
|
|
1689
1791
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1690
1792
|
"div",
|
|
1691
1793
|
{
|
|
1692
|
-
className: `flex flex-col w-[200px] h-[250px] rounded-lg items-center p-2 ${!isRight ? "opaque-carousel-card-left dark:opaque-carousel-card-dark-left" : "opaque-carousel-card-right dark:opaque-carousel-card-dark-right"}
|
|
1794
|
+
className: `flex flex-col w-[200px] h-[250px] rounded-lg items-center p-2 ${!isRight ? "opaque-carousel-card-left dark:opaque-carousel-card-dark-left" : "opaque-carousel-card-right dark:opaque-carousel-card-dark-right"} ${className}`.trim(),
|
|
1693
1795
|
children: [
|
|
1694
1796
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1695
1797
|
"div",
|
|
@@ -1731,10 +1833,10 @@ function OpaqueGridCard({
|
|
|
1731
1833
|
}
|
|
1732
1834
|
);
|
|
1733
1835
|
}
|
|
1734
|
-
function CatalogGrid({ items, buttonText, onOpen }) {
|
|
1735
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
1836
|
+
function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
1837
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 ${className}`.trim(), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(GridCard, { item, buttonText, onOpen }, item.key)) });
|
|
1736
1838
|
}
|
|
1737
|
-
function CatalogCarousel({ items, buttonText, onOpen }) {
|
|
1839
|
+
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
1738
1840
|
const [activeIndex, setActiveIndex] = React8.useState(0);
|
|
1739
1841
|
const [indexPool, setIndexPool] = React8.useState([]);
|
|
1740
1842
|
const cardRefs = React8.useRef([]);
|
|
@@ -1771,7 +1873,7 @@ function CatalogCarousel({ items, buttonText, onOpen }) {
|
|
|
1771
1873
|
}, [activeIndex, getIndexes, items.length]);
|
|
1772
1874
|
const nextApp = () => setActiveIndex((prev) => prev + 1 === items.length ? 0 : prev + 1);
|
|
1773
1875
|
const previousApp = () => setActiveIndex((prev) => prev - 1 === -1 ? items.length - 1 : prev - 1);
|
|
1774
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
1876
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex items-center justify-center w-full h-full ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-10", children: [
|
|
1775
1877
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1776
1878
|
"button",
|
|
1777
1879
|
{
|
|
@@ -1821,16 +1923,16 @@ function CatalogCarousel({ items, buttonText, onOpen }) {
|
|
|
1821
1923
|
)
|
|
1822
1924
|
] }) });
|
|
1823
1925
|
}
|
|
1824
|
-
function Catalog({ display: display2 = "grid", items = [], buttonText, onOpen }) {
|
|
1825
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className:
|
|
1926
|
+
function Catalog({ display: display2 = "grid", items = [], buttonText, onOpen, className = "" }) {
|
|
1927
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full h-full ${className}`.trim(), children: display2 === "grid" ? /* @__PURE__ */ jsxRuntime.jsx(CatalogGrid, { items, buttonText, onOpen }) : /* @__PURE__ */ jsxRuntime.jsx(CatalogCarousel, { items, buttonText, onOpen }) });
|
|
1826
1928
|
}
|
|
1827
|
-
function ContextMenu({ items, children }) {
|
|
1929
|
+
function ContextMenu({ items, children, className = "" }) {
|
|
1828
1930
|
return /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuPrimitive__namespace.Root, { children: [
|
|
1829
1931
|
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Trigger, { asChild: true, children }),
|
|
1830
1932
|
/* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1831
1933
|
ContextMenuPrimitive__namespace.Content,
|
|
1832
1934
|
{
|
|
1833
|
-
className: CONTENT_CLASSNAME,
|
|
1935
|
+
className: `${CONTENT_CLASSNAME} ${className}`.trim(),
|
|
1834
1936
|
collisionPadding: 8,
|
|
1835
1937
|
children: items.map((item) => renderItem(item))
|
|
1836
1938
|
}
|
|
@@ -3015,9 +3117,9 @@ function TableSkeletonBody({
|
|
|
3015
3117
|
i
|
|
3016
3118
|
)) });
|
|
3017
3119
|
}
|
|
3018
|
-
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode" }) {
|
|
3120
|
+
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
3019
3121
|
const id = React8.useId();
|
|
3020
|
-
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className:
|
|
3122
|
+
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3021
3123
|
SwitchPrimitive__namespace.Root,
|
|
3022
3124
|
{
|
|
3023
3125
|
id,
|
|
@@ -4639,7 +4741,8 @@ function DatePicker({
|
|
|
4639
4741
|
format = defaultFormat,
|
|
4640
4742
|
weekStartsOn = 0,
|
|
4641
4743
|
clearable = true,
|
|
4642
|
-
size = "md"
|
|
4744
|
+
size = "md",
|
|
4745
|
+
className = ""
|
|
4643
4746
|
}) {
|
|
4644
4747
|
const errorId = React8.useId();
|
|
4645
4748
|
const hasError = errorMessage != null;
|
|
@@ -4720,7 +4823,7 @@ function DatePicker({
|
|
|
4720
4823
|
}
|
|
4721
4824
|
};
|
|
4722
4825
|
const displayValue = value ? format(value) : "";
|
|
4723
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
4826
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 ${className}`.trim(), children: [
|
|
4724
4827
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`, children: [
|
|
4725
4828
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4726
4829
|
FieldLabel,
|
|
@@ -5004,7 +5107,7 @@ function TextArea({
|
|
|
5004
5107
|
}
|
|
5005
5108
|
);
|
|
5006
5109
|
}
|
|
5007
|
-
var
|
|
5110
|
+
var SIZE2 = {
|
|
5008
5111
|
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
5009
5112
|
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
5010
5113
|
lg: { h: "h-control-lg", text: "text-sm", pad: "px-4" }
|
|
@@ -5026,7 +5129,7 @@ function SegmentedControl({
|
|
|
5026
5129
|
errorMessage,
|
|
5027
5130
|
"aria-label": ariaLabel
|
|
5028
5131
|
}) {
|
|
5029
|
-
const sz =
|
|
5132
|
+
const sz = SIZE2[size];
|
|
5030
5133
|
const groupId = React8.useId();
|
|
5031
5134
|
const errorId = React8.useId();
|
|
5032
5135
|
const hasError = errorMessage != null;
|
|
@@ -6695,7 +6798,7 @@ exports.SkeletonText = SkeletonText;
|
|
|
6695
6798
|
exports.Slider = Slider;
|
|
6696
6799
|
exports.Switch = Switch;
|
|
6697
6800
|
exports.Table = Table;
|
|
6698
|
-
exports.Tabs =
|
|
6801
|
+
exports.Tabs = Tabs_default;
|
|
6699
6802
|
exports.TagsInput = TagsInput;
|
|
6700
6803
|
exports.Temporal = DatePicker;
|
|
6701
6804
|
exports.TextArea = TextArea;
|