@justanarthur/modo-ui 0.0.0-stage → 0.2.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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE.beui +21 -0
  3. package/LICENSE.fluid-functionalism +21 -0
  4. package/LICENSE.motion-primitives +21 -0
  5. package/LICENSE.sileo +21 -0
  6. package/README.md +608 -2
  7. package/dist/base.css +994 -0
  8. package/dist/blocks/sidebar-app/index.d.ts +34 -0
  9. package/dist/blocks/sidebar-app/index.js +31 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +16 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +14 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +42 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +21 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +35 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +38 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +18 -0
  24. package/dist/components/inputs/date-time/date-picker/index.d.ts +82 -0
  25. package/dist/components/inputs/date-time/date-picker/index.js +32 -0
  26. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +64 -0
  27. package/dist/components/inputs/date-time/date-range-picker/index.js +31 -0
  28. package/dist/components/inputs/date-time/duration-picker/index.d.ts +57 -0
  29. package/dist/components/inputs/date-time/duration-picker/index.js +31 -0
  30. package/dist/components/inputs/date-time/month-picker/index.d.ts +57 -0
  31. package/dist/components/inputs/date-time/month-picker/index.js +30 -0
  32. package/dist/components/inputs/date-time/time-picker/index.d.ts +59 -0
  33. package/dist/components/inputs/date-time/time-picker/index.js +31 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +19 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +16 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +25 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +20 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +25 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +34 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +14 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +14 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +28 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +99 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +23 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +21 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +22 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +36 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +29 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +37 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +44 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +26 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +19 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +24 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +21 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +17 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +26 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +13 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +511 -0
  84. package/dist/preset.d.ts +104 -0
  85. package/dist/preset.js +124 -0
  86. package/dist/primitives/code/index.d.ts +23 -0
  87. package/dist/primitives/code/index.js +11 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +11 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +25 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +19 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +19 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +12 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +21 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +17 -0
  102. package/dist/shared/components-0ke6xada.js +123 -0
  103. package/dist/shared/components-0q0sqfh4.js +146 -0
  104. package/dist/shared/components-0sn7ypjw.js +61 -0
  105. package/dist/shared/components-1j9791sn.js +345 -0
  106. package/dist/shared/components-1rfwbyyc.js +361 -0
  107. package/dist/shared/components-1v7rxytx.js +30 -0
  108. package/dist/shared/components-1xekx2hx.js +215 -0
  109. package/dist/shared/components-39jq9va1.js +86 -0
  110. package/dist/shared/components-3gae8nta.js +719 -0
  111. package/dist/shared/components-3k8xpnpq.js +1759 -0
  112. package/dist/shared/components-3ky44908.js +9 -0
  113. package/dist/shared/components-3mkepka5.js +111 -0
  114. package/dist/shared/components-3wk0w46f.js +667 -0
  115. package/dist/shared/components-4cnjmgex.js +124 -0
  116. package/dist/shared/components-59efxjd9.js +298 -0
  117. package/dist/shared/components-5xc2j8jz.js +159 -0
  118. package/dist/shared/components-62ybc7t2.js +496 -0
  119. package/dist/shared/components-66mv71kx.js +262 -0
  120. package/dist/shared/components-7ans7ce5.js +120 -0
  121. package/dist/shared/components-7btqt08d.js +270 -0
  122. package/dist/shared/components-7r3etddy.js +171 -0
  123. package/dist/shared/components-7x9kawxv.js +152 -0
  124. package/dist/shared/components-8fpr3s4p.js +292 -0
  125. package/dist/shared/components-9jvzzvt1.js +198 -0
  126. package/dist/shared/components-apdwtweq.js +484 -0
  127. package/dist/shared/components-asr5pg50.js +191 -0
  128. package/dist/shared/components-b2wyq2cq.js +232 -0
  129. package/dist/shared/components-c6s6b43g.js +15 -0
  130. package/dist/shared/components-ca2c898n.js +1828 -0
  131. package/dist/shared/components-cbxjn9p8.js +141 -0
  132. package/dist/shared/components-chacnk61.js +216 -0
  133. package/dist/shared/components-cv16mryv.js +62 -0
  134. package/dist/shared/components-ez65vtbq.js +110 -0
  135. package/dist/shared/components-ezxhrmer.js +17 -0
  136. package/dist/shared/components-gc5vtq2f.js +149 -0
  137. package/dist/shared/components-gf5s6ap9.js +42 -0
  138. package/dist/shared/components-gvr9w41t.js +193 -0
  139. package/dist/shared/components-h2dpcwgc.js +137 -0
  140. package/dist/shared/components-hawvy2qz.js +105 -0
  141. package/dist/shared/components-hqeq3w9q.js +375 -0
  142. package/dist/shared/components-jjw69c4c.js +28 -0
  143. package/dist/shared/components-jwst3vtj.js +346 -0
  144. package/dist/shared/components-kvr7f9hy.js +45 -0
  145. package/dist/shared/components-men63rwj.js +9 -0
  146. package/dist/shared/components-mhd39z7x.js +22 -0
  147. package/dist/shared/components-n7mjr357.js +26 -0
  148. package/dist/shared/components-ng72k97e.js +128 -0
  149. package/dist/shared/components-nh8tma1n.js +986 -0
  150. package/dist/shared/components-njzgqdwy.js +445 -0
  151. package/dist/shared/components-ny774h8p.js +293 -0
  152. package/dist/shared/components-q4daerx0.js +58 -0
  153. package/dist/shared/components-q5xj5c16.js +79 -0
  154. package/dist/shared/components-rr7a6ja9.js +160 -0
  155. package/dist/shared/components-s2bz1xpk.js +63 -0
  156. package/dist/shared/components-tqvarbfv.js +288 -0
  157. package/dist/shared/components-v6xp325t.js +304 -0
  158. package/dist/shared/components-v7wtz8hk.js +144 -0
  159. package/dist/shared/components-vc7vq5nz.js +32 -0
  160. package/dist/shared/components-vfbhxf5r.js +58 -0
  161. package/dist/shared/components-vynjtrk6.js +19 -0
  162. package/dist/shared/components-wvp1m52g.js +1200 -0
  163. package/dist/shared/components-yh3kwdhr.js +981 -0
  164. package/dist/shared/components-ytb2tefr.js +291 -0
  165. package/dist/shared/components-zfnmn5d4.js +220 -0
  166. package/dist/shared/components-zrkzcayz.js +141 -0
  167. package/dist/shared/components-zx6b6yby.js +42 -0
  168. package/dist/styles.css +1949 -0
  169. package/dist/tailwind.css +219 -0
  170. package/dist/tokens.css +345 -0
  171. package/package.json +103 -4
@@ -0,0 +1,198 @@
1
+ import {
2
+ useReduceMotion
3
+ } from "./components-men63rwj.js";
4
+ import {
5
+ cn2
6
+ } from "./components-ezxhrmer.js";
7
+ import {
8
+ FluidHoverHighlight2
9
+ } from "./components-kvr7f9hy.js";
10
+ import {
11
+ useShape
12
+ } from "./components-cv16mryv.js";
13
+ import {
14
+ useSize2
15
+ } from "./components-0sn7ypjw.js";
16
+ import {
17
+ useFluidHover2,
18
+ useRegisterFluidHoverItem2
19
+ } from "./components-59efxjd9.js";
20
+
21
+ // lib/date-locale.ts
22
+ import { isValid, parse } from "date-fns";
23
+ import { enUS } from "react-day-picker/locale";
24
+ var defaultLocale = enUS;
25
+ function hourCycleOf(locale) {
26
+ return new Intl.DateTimeFormat(locale.code, { hour: "numeric" }).resolvedOptions().hourCycle ?? "h23";
27
+ }
28
+ function parseWith(text, patterns, locale, reference) {
29
+ for (const pattern of patterns) {
30
+ const date = parse(text.trim(), pattern, reference, { locale });
31
+ if (isValid(date) && date.getFullYear() >= 1000)
32
+ return date;
33
+ }
34
+ return null;
35
+ }
36
+ function parseDateText(text, locale, reference = new Date) {
37
+ return parseWith(text, ["P", "PP", "PPP", "PPPP"], locale, reference);
38
+ }
39
+ function parseTimeText(text, locale, reference = new Date) {
40
+ return parseWith(text, ["p", "HH:mm", "H:mm"], locale, reference);
41
+ }
42
+ function parseMonthText(text, locale, reference = new Date) {
43
+ return parseWith(text, ["LLLL y", "LLL y", "MM/y", "M/y", "MM.y"], locale, reference);
44
+ }
45
+ function fieldLabel(locale, field) {
46
+ return new Intl.DisplayNames(locale.code, { type: "dateTimeField" }).of(field) ?? field;
47
+ }
48
+
49
+ // lib/scroll-column.tsx
50
+ import { useEffect, useRef } from "react";
51
+ import { jsx, jsxs } from "react/jsx-runtime";
52
+ function centre(list, item, behavior) {
53
+ const l = list.getBoundingClientRect();
54
+ const i = item.getBoundingClientRect();
55
+ const sx = l.width / list.offsetWidth || 1;
56
+ const sy = l.height / list.offsetHeight || 1;
57
+ list.scrollTo({
58
+ top: list.scrollTop + (i.top - l.top) / sy - (list.clientHeight - item.offsetHeight) / 2,
59
+ left: list.scrollLeft + (i.left - l.left) / sx - (list.clientWidth - item.offsetWidth) / 2,
60
+ behavior
61
+ });
62
+ }
63
+ var dividedColumns = "flex [&>*+*]:border-s [&>*]:border-border";
64
+ var STEP = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 };
65
+ function ScrollColumn({
66
+ label,
67
+ options,
68
+ value,
69
+ onValueChange,
70
+ inView,
71
+ follow = value,
72
+ orientation = "vertical",
73
+ className
74
+ }) {
75
+ const listRef = useRef(null);
76
+ const containerRef = useRef(null);
77
+ const pointerInside = useRef(false);
78
+ const centred = useRef(false);
79
+ const reduceMotion = useReduceMotion();
80
+ const horizontal = orientation === "horizontal";
81
+ const hover = useFluidHover2(containerRef, { axis: horizontal ? "x" : "y" });
82
+ const shape = useShape();
83
+ const axis = useRef(horizontal);
84
+ useEffect(() => {
85
+ const list = listRef.current;
86
+ const item = list?.querySelector(`[data-value="${follow}"]`);
87
+ if (!list || !item || pointerInside.current)
88
+ return;
89
+ const glide = centred.current && axis.current === horizontal && !reduceMotion;
90
+ centre(list, item, glide ? "smooth" : "instant");
91
+ centred.current = true;
92
+ axis.current = horizontal;
93
+ }, [follow, horizontal]);
94
+ const followed = useRef(follow);
95
+ followed.current = follow;
96
+ useEffect(() => {
97
+ const list = listRef.current;
98
+ if (!list)
99
+ return;
100
+ const observer = new ResizeObserver(() => {
101
+ const item = list.querySelector(`[data-value="${followed.current}"]`);
102
+ if (item && !pointerInside.current)
103
+ centre(list, item, "instant");
104
+ });
105
+ observer.observe(list);
106
+ return () => observer.disconnect();
107
+ }, []);
108
+ const banded = options.map((o) => inView?.(o.value) ?? false);
109
+ const tabStop = options.some((o) => o.value === value) ? value : follow ?? options[0]?.value;
110
+ const onKeyDown = (e) => {
111
+ const items = [
112
+ ...containerRef.current?.querySelectorAll('[role="option"]:not(:disabled)') ?? []
113
+ ];
114
+ const at = items.indexOf(document.activeElement);
115
+ const next = e.key === "Home" ? 0 : e.key === "End" ? items.length - 1 : STEP[e.key] ? at + (STEP[e.key] ?? 0) : undefined;
116
+ if (next === undefined)
117
+ return;
118
+ e.preventDefault();
119
+ const item = items[Math.max(0, Math.min(items.length - 1, next))];
120
+ item?.focus({ preventScroll: true });
121
+ if (item && listRef.current)
122
+ centre(listRef.current, item, reduceMotion ? "instant" : "smooth");
123
+ };
124
+ return /* @__PURE__ */ jsx("div", {
125
+ ref: listRef,
126
+ role: "listbox",
127
+ "aria-label": label,
128
+ "aria-orientation": orientation,
129
+ onKeyDown,
130
+ onPointerEnter: () => {
131
+ pointerInside.current = true;
132
+ },
133
+ onPointerLeave: () => {
134
+ pointerInside.current = false;
135
+ },
136
+ className: cn2("scrollbar-hide [--scroll-fade-size:24px]", horizontal ? "overflow-x-auto overflow-y-hidden scroll-fade-x" : "overflow-y-auto overflow-x-hidden scroll-fade", className),
137
+ children: /* @__PURE__ */ jsxs("div", {
138
+ ref: containerRef,
139
+ onMouseMove: hover.handlers.onMouseMove,
140
+ onMouseEnter: hover.handlers.onMouseEnter,
141
+ onMouseLeave: hover.handlers.onMouseLeave,
142
+ onClick: hover.handlers.onClick,
143
+ className: cn2("relative flex p-1", horizontal ? "w-max flex-row" : "flex-col"),
144
+ children: [
145
+ /* @__PURE__ */ jsx(FluidHoverHighlight2, {
146
+ hover,
147
+ className: shape.bg
148
+ }),
149
+ options.map((option, index) => /* @__PURE__ */ jsx(ScrollColumnItem, {
150
+ index,
151
+ registerItem: hover.registerItem,
152
+ option,
153
+ selected: option.value === value,
154
+ band: !banded[index] ? undefined : banded[index - 1] ? banded[index + 1] ? "middle" : "end" : banded[index + 1] ? "start" : "single",
155
+ horizontal,
156
+ tabStop: option.value === tabStop,
157
+ onSelect: () => onValueChange(option.value)
158
+ }, option.value))
159
+ ]
160
+ })
161
+ });
162
+ }
163
+ function ScrollColumnItem({
164
+ index,
165
+ registerItem,
166
+ option,
167
+ selected,
168
+ band,
169
+ horizontal,
170
+ tabStop,
171
+ onSelect
172
+ }) {
173
+ const ref = useRef(null);
174
+ useRegisterFluidHoverItem2(registerItem, index, ref);
175
+ const shape = useShape();
176
+ const sizeClasses = useSize2();
177
+ return /* @__PURE__ */ jsxs("button", {
178
+ ref,
179
+ type: "button",
180
+ role: "option",
181
+ "aria-selected": selected,
182
+ tabIndex: tabStop ? 0 : -1,
183
+ disabled: option.disabled,
184
+ "data-value": option.value,
185
+ "data-fluid-hover-index": index,
186
+ onClick: onSelect,
187
+ className: cn2("relative z-[1] flex shrink-0 items-center justify-center px-2 tabular-nums whitespace-nowrap outline-none", "transition-[color,background-color] duration-fast focus-visible:ring-1 focus-visible:ring-focus-ring", "disabled:opacity-50 disabled:pointer-events-none", sizeClasses.segmentItem, sizeClasses.text, shape.item, band && !selected && "bg-accent/20 dark:bg-accent/12", selected && "bg-active", band && band !== "single" && "rounded-none", band === "start" && (horizontal ? "rounded-s-lg" : "rounded-t-lg"), band === "end" && (horizontal ? "rounded-e-lg" : "rounded-b-lg"), selected ? "text-foreground weight-semibold" : band ? "text-foreground" : "text-muted-foreground"),
188
+ children: [
189
+ selected && /* @__PURE__ */ jsx("span", {
190
+ "aria-hidden": true,
191
+ className: "absolute start-1 top-1/2 size-1 -translate-y-1/2 rounded-full bg-current"
192
+ }),
193
+ option.label
194
+ ]
195
+ });
196
+ }
197
+
198
+ export { defaultLocale, hourCycleOf, parseDateText, parseTimeText, parseMonthText, fieldLabel, dividedColumns, ScrollColumn };
@@ -0,0 +1,484 @@
1
+ import {
2
+ cn2
3
+ } from "./components-ezxhrmer.js";
4
+ import {
5
+ FluidHoverHighlight2
6
+ } from "./components-kvr7f9hy.js";
7
+ import {
8
+ useIcon
9
+ } from "./components-zrkzcayz.js";
10
+ import {
11
+ useShape
12
+ } from "./components-cv16mryv.js";
13
+ import {
14
+ useSize2
15
+ } from "./components-0sn7ypjw.js";
16
+ import {
17
+ useFluidHover2,
18
+ useRegisterFluidHoverItem2
19
+ } from "./components-59efxjd9.js";
20
+ import {
21
+ SizeProvider2
22
+ } from "./components-jjw69c4c.js";
23
+
24
+ // components/card/index.tsx
25
+ import {
26
+ Children,
27
+ cloneElement,
28
+ createContext,
29
+ forwardRef,
30
+ isValidElement,
31
+ useContext,
32
+ useMemo,
33
+ useRef
34
+ } from "react";
35
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
36
+ var CardGroupContext = createContext(null);
37
+ var CardContext = createContext({
38
+ emphasized: false,
39
+ orientation: "card",
40
+ clickable: false,
41
+ hasImage: false
42
+ });
43
+ var CardGroup2 = forwardRef(({
44
+ orientation = "card",
45
+ columns = 1,
46
+ border = "none",
47
+ separated = false,
48
+ fluidHover = true,
49
+ className,
50
+ children,
51
+ ...props
52
+ }, ref) => {
53
+ const containerRef = useRef(null);
54
+ const shape = useShape();
55
+ const axis = columns > 1 ? "xy" : "y";
56
+ const hover = useFluidHover2(containerRef, { axis, gapClick: { maxDistance: 16 } });
57
+ const { activeIndex, handlers, registerItem } = hover;
58
+ const childArray = Children.toArray(children).filter(isValidElement);
59
+ const count = childArray.length;
60
+ const indexed = childArray.map((child, i) => cloneElement(child, { index: i }));
61
+ const selectedIndex = childArray.findIndex((child) => child.props.selected);
62
+ const outlined = border === "outlined";
63
+ const divided = !separated;
64
+ const contextValue = useMemo(() => ({
65
+ registerItem,
66
+ activeIndex,
67
+ selectedIndex,
68
+ orientation,
69
+ columns,
70
+ count,
71
+ separated,
72
+ divided,
73
+ outlined
74
+ }), [registerItem, activeIndex, selectedIndex, orientation, columns, count, separated, divided, outlined]);
75
+ return /* @__PURE__ */ jsx(CardGroupContext.Provider, {
76
+ value: contextValue,
77
+ children: /* @__PURE__ */ jsxs("div", {
78
+ ref: (node) => {
79
+ containerRef.current = node;
80
+ if (typeof ref === "function")
81
+ ref(node);
82
+ else if (ref)
83
+ ref.current = node;
84
+ },
85
+ ...props,
86
+ "data-slot": "card-group",
87
+ "data-orientation": orientation,
88
+ className: cn2("relative grid", outlined && !separated && `border border-border/60 overflow-hidden ${shape.container}`, separated ? "gap-2" : "gap-0", className),
89
+ style: {
90
+ gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))`
91
+ },
92
+ onMouseEnter: fluidHover ? handlers.onMouseEnter : undefined,
93
+ onMouseMove: fluidHover ? handlers.onMouseMove : undefined,
94
+ onMouseLeave: fluidHover ? handlers.onMouseLeave : undefined,
95
+ onClick: fluidHover ? handlers.onClick : undefined,
96
+ children: [
97
+ /* @__PURE__ */ jsx(FluidHoverHighlight2, {
98
+ hover,
99
+ hidden: !fluidHover,
100
+ className: cn2("z-0", shape.container)
101
+ }),
102
+ indexed
103
+ ]
104
+ })
105
+ });
106
+ });
107
+ CardGroup2.displayName = "CardGroup";
108
+ var Card2 = forwardRef(({
109
+ onClick,
110
+ href,
111
+ external,
112
+ label,
113
+ selected = false,
114
+ disabled = false,
115
+ dismissible = false,
116
+ dismissOnHover = true,
117
+ onDismiss,
118
+ size,
119
+ index,
120
+ className,
121
+ children,
122
+ ...props
123
+ }, ref) => {
124
+ const internalRef = useRef(null);
125
+ const shape = useShape();
126
+ const sizeClasses = useSize2(size);
127
+ const compact = sizeClasses.variant === "compact";
128
+ const group = useContext(CardGroupContext);
129
+ const XIcon = useIcon("x");
130
+ const orientation = group?.orientation ?? "card";
131
+ const columns = group?.columns ?? 1;
132
+ const count = group?.count ?? 1;
133
+ const separated = group?.separated ?? true;
134
+ const divided = group?.divided ?? false;
135
+ const outlined = group?.outlined ?? false;
136
+ const activeIndex = group?.activeIndex ?? null;
137
+ const selectedIndex = group?.selectedIndex ?? -1;
138
+ const registerItem = href || onClick ? group?.registerItem : undefined;
139
+ useRegisterFluidHoverItem2(registerItem, index, internalRef);
140
+ const col = index !== undefined ? index % columns : 0;
141
+ const hasBelow = index !== undefined && index + columns < count;
142
+ const hasRight = index !== undefined && col < columns - 1 && index + 1 < count;
143
+ const self = index ?? -1;
144
+ const touchesBelow = (i) => i === self || i === self + columns;
145
+ const touchesRight = (i) => i === self || i === self + 1;
146
+ const showBottom = divided && hasBelow && !(touchesBelow(activeIndex ?? -1) || touchesBelow(selectedIndex));
147
+ const showRight = divided && hasRight && !(touchesRight(activeIndex ?? -1) || touchesRight(selectedIndex));
148
+ const isInline = orientation === "inline";
149
+ const isCardImage = (child) => isValidElement(child) && (child.type === CardImage2 || child.type?.displayName === "CardImage");
150
+ const hasImage = Children.toArray(children).some(isCardImage);
151
+ const inlineImage = isInline && hasImage;
152
+ const clickable = !!href || !!onClick;
153
+ const emphasized = selected;
154
+ const tileShape = !group ? cn2(shape.container, "overflow-hidden") : separated && outlined ? cn2(shape.container, "overflow-hidden border border-border/60") : "";
155
+ const overlay = clickable && !disabled ? href ? /* @__PURE__ */ jsx("a", {
156
+ href,
157
+ onClick,
158
+ target: external ? "_blank" : undefined,
159
+ rel: external ? "noopener noreferrer" : undefined,
160
+ "aria-label": label,
161
+ className: "absolute inset-0 z-20 outline-none focus-visible:ring-1 focus-visible:ring-focus-ring rounded-[inherit]"
162
+ }) : /* @__PURE__ */ jsx("button", {
163
+ type: "button",
164
+ onClick,
165
+ "aria-label": label,
166
+ "aria-pressed": selected || undefined,
167
+ className: "absolute inset-0 z-20 outline-none focus-visible:ring-1 focus-visible:ring-focus-ring rounded-[inherit]"
168
+ }) : null;
169
+ const cardContext = useMemo(() => ({ emphasized, orientation, clickable, hasImage }), [emphasized, orientation, clickable, hasImage]);
170
+ let body = children;
171
+ if (inlineImage) {
172
+ const parts = Children.toArray(children);
173
+ const image = parts.find(isCardImage);
174
+ const rest = parts.filter((part) => part !== image);
175
+ body = /* @__PURE__ */ jsxs(Fragment, {
176
+ children: [
177
+ image,
178
+ /* @__PURE__ */ jsx("div", {
179
+ className: cn2("flex min-w-0 flex-1 flex-col justify-center gap-2", compact ? "py-2.5 pr-3" : "py-3.5 pr-4"),
180
+ children: rest
181
+ })
182
+ ]
183
+ });
184
+ }
185
+ const card = /* @__PURE__ */ jsx(CardContext.Provider, {
186
+ value: cardContext,
187
+ children: /* @__PURE__ */ jsxs("div", {
188
+ ref: (node) => {
189
+ internalRef.current = node;
190
+ if (typeof ref === "function")
191
+ ref(node);
192
+ else if (ref)
193
+ ref.current = node;
194
+ },
195
+ "data-slot": "card",
196
+ "data-fluid-hover-index": index,
197
+ "data-selected": selected || undefined,
198
+ "data-orientation": orientation,
199
+ "aria-disabled": disabled || undefined,
200
+ className: cn2("group/card relative z-10 min-w-0 min-h-[60px]", inlineImage ? cn2("flex flex-row items-center", compact ? "gap-2.5" : "gap-3") : isInline ? cn2("flex flex-row items-center", compact ? "gap-2.5 pl-3" : "gap-3 pl-4") : cn2("flex flex-col", compact ? "pb-3" : "pb-4"), !group && clickable && !disabled && "transition-colors duration-fast hover:bg-hover", dismissible && isInline && (dismissOnHover ? "[&:hover_[data-slot=card-header]]:pr-10 [&:focus-within_[data-slot=card-header]]:pr-10" : "[&_[data-slot=card-header]]:pr-10"), tileShape, disabled && "opacity-50 pointer-events-none", className),
201
+ ...props,
202
+ children: [
203
+ selected && /* @__PURE__ */ jsx("span", {
204
+ "aria-hidden": true,
205
+ className: cn2("absolute inset-0 -z-10 bg-active pointer-events-none", shape.container)
206
+ }),
207
+ showBottom && /* @__PURE__ */ jsx("span", {
208
+ "aria-hidden": true,
209
+ className: "absolute inset-x-0 bottom-0 h-px bg-border/60 pointer-events-none -z-10"
210
+ }),
211
+ showRight && /* @__PURE__ */ jsx("span", {
212
+ "aria-hidden": true,
213
+ className: cn2("absolute top-0 right-0 w-px bg-border/60 pointer-events-none -z-10", showBottom ? "bottom-px" : "bottom-0")
214
+ }),
215
+ overlay,
216
+ body,
217
+ dismissible && /* @__PURE__ */ jsx("button", {
218
+ type: "button",
219
+ onClick: onDismiss,
220
+ "aria-label": "Dismiss",
221
+ className: cn2("absolute right-2 top-2 z-30 flex h-7 w-7 items-center justify-center text-muted-foreground hover:text-foreground cursor-pointer outline-none transition-colors duration-fast focus-visible:ring-1 focus-visible:ring-focus-ring", hasImage ? "bg-card/70 backdrop-blur-sm hover:bg-card" : "hover:bg-hover", dismissOnHover && "pointer-events-none opacity-0 transition-opacity duration-fast group-hover/card:pointer-events-auto group-hover/card:opacity-100 group-focus-within/card:pointer-events-auto group-focus-within/card:opacity-100 focus-visible:pointer-events-auto focus-visible:opacity-100", shape.button),
222
+ children: /* @__PURE__ */ jsx(XIcon, {
223
+ size: compact ? 13 : 15,
224
+ strokeWidth: 1.5
225
+ })
226
+ })
227
+ ]
228
+ })
229
+ });
230
+ return size ? /* @__PURE__ */ jsx(SizeProvider2, {
231
+ size,
232
+ children: card
233
+ }) : card;
234
+ });
235
+ Card2.displayName = "Card";
236
+ var CardHeader2 = forwardRef(({ className, ...props }, ref) => {
237
+ const { orientation, hasImage } = useContext(CardContext);
238
+ const inlineImage = orientation === "inline" && hasImage;
239
+ const sizeClasses = useSize2();
240
+ const compact = sizeClasses.variant === "compact";
241
+ return /* @__PURE__ */ jsx("div", {
242
+ ref,
243
+ "data-slot": "card-header",
244
+ className: cn2("grid auto-rows-min items-start gap-1 has-data-[slot=card-action]:grid-cols-[1fr_auto]", inlineImage ? "min-w-0" : orientation === "inline" ? cn2("min-w-0 flex-1", compact ? "py-2.5" : "py-3.5") : compact ? "px-3 pt-3" : "px-4 pt-4", className),
245
+ ...props
246
+ });
247
+ });
248
+ CardHeader2.displayName = "CardHeader";
249
+ var CardTitle2 = forwardRef(({ className, children, ...props }, ref) => {
250
+ const { emphasized, orientation } = useContext(CardContext);
251
+ const sizeClasses = useSize2();
252
+ const compact = sizeClasses.variant === "compact";
253
+ const trim = orientation === "inline" ? "[text-box:trim-both_cap_alphabetic]" : "";
254
+ return /* @__PURE__ */ jsxs("span", {
255
+ ref,
256
+ "data-slot": "card-title",
257
+ className: cn2("inline-grid grid-cols-[minmax(0,1fr)] leading-snug", compact ? "text-subtitle-compact" : "text-subtitle", className),
258
+ ...props,
259
+ children: [
260
+ /* @__PURE__ */ jsx("span", {
261
+ className: cn2("col-start-1 row-start-1 invisible min-w-0 overflow-hidden text-ellipsis", trim, "weight-semibold"),
262
+ "aria-hidden": "true",
263
+ children
264
+ }),
265
+ /* @__PURE__ */ jsx("span", {
266
+ className: cn2("col-start-1 row-start-1 min-w-0 overflow-hidden text-ellipsis text-foreground transition-[font-variation-settings] duration-fast", trim, emphasized ? "weight-semibold" : "weight-normal"),
267
+ children
268
+ })
269
+ ]
270
+ });
271
+ });
272
+ CardTitle2.displayName = "CardTitle";
273
+ var CardDescription2 = forwardRef(({ className, ...props }, ref) => {
274
+ const sizeClasses = useSize2();
275
+ const compact = sizeClasses.variant === "compact";
276
+ return /* @__PURE__ */ jsx("p", {
277
+ ref,
278
+ "data-slot": "card-description",
279
+ className: cn2("leading-normal text-muted-foreground", compact ? "text-subtitle-compact" : "text-subtitle", className),
280
+ ...props
281
+ });
282
+ });
283
+ CardDescription2.displayName = "CardDescription";
284
+ var CardAction2 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
285
+ ref,
286
+ "data-slot": "card-action",
287
+ className: cn2("relative z-30 col-start-2 row-span-2 row-start-1 self-start justify-self-end", className),
288
+ ...props
289
+ }));
290
+ CardAction2.displayName = "CardAction";
291
+ var CardContent2 = forwardRef(({ className, ...props }, ref) => {
292
+ const { orientation } = useContext(CardContext);
293
+ const sizeClasses = useSize2();
294
+ const compact = sizeClasses.variant === "compact";
295
+ return /* @__PURE__ */ jsx("div", {
296
+ ref,
297
+ "data-slot": "card-content",
298
+ className: cn2(orientation === "inline" ? "" : compact ? "px-3 pt-2.5" : "px-4 pt-3", className),
299
+ ...props
300
+ });
301
+ });
302
+ CardContent2.displayName = "CardContent";
303
+ var CardFooter2 = forwardRef(({ className, ...props }, ref) => {
304
+ const { orientation, hasImage } = useContext(CardContext);
305
+ const inlineImage = orientation === "inline" && hasImage;
306
+ const sizeClasses = useSize2();
307
+ const compact = sizeClasses.variant === "compact";
308
+ return /* @__PURE__ */ jsx("div", {
309
+ ref,
310
+ "data-slot": "card-footer",
311
+ className: cn2("relative z-30 flex items-center gap-1", inlineImage ? "flex-wrap" : orientation === "inline" ? cn2("shrink-0 ml-auto", compact ? "pr-3" : "pr-4") : cn2("flex-wrap", compact ? "px-3 pt-2.5" : "px-4 pt-3"), className),
312
+ ...props
313
+ });
314
+ });
315
+ CardFooter2.displayName = "CardFooter";
316
+ function CardMedia2({ logo, logoAlt, icon: Icon, size = 22, className }) {
317
+ const { orientation } = useContext(CardContext);
318
+ const shape = useShape();
319
+ const sizeClasses = useSize2();
320
+ const compact = sizeClasses.variant === "compact";
321
+ const wrap = cn2(orientation === "inline" ? "" : "mb-2", className);
322
+ if (logo) {
323
+ const logos = Array.isArray(logo) ? logo : [logo];
324
+ return /* @__PURE__ */ jsx("span", {
325
+ "data-slot": "card-media",
326
+ className: cn2("inline-flex items-center gap-1.5 shrink-0", wrap),
327
+ children: logos.map((src, i) => /* @__PURE__ */ jsxs("span", {
328
+ className: "inline-flex items-center gap-1.5",
329
+ children: [
330
+ i > 0 && /* @__PURE__ */ jsx("span", {
331
+ "aria-hidden": true,
332
+ className: "w-2 h-px bg-border"
333
+ }),
334
+ /* @__PURE__ */ jsx("img", {
335
+ src,
336
+ alt: logoAlt ?? "",
337
+ width: size,
338
+ height: size,
339
+ className: cn2("object-contain", shape.bg),
340
+ style: { width: size, height: size }
341
+ })
342
+ ]
343
+ }, i))
344
+ });
345
+ }
346
+ if (Icon) {
347
+ return /* @__PURE__ */ jsx("span", {
348
+ "data-slot": "card-media",
349
+ className: cn2("inline-flex items-center justify-center shrink-0 size-8 bg-hover", shape.bg, wrap),
350
+ children: /* @__PURE__ */ jsx(Icon, {
351
+ size: compact ? 16 : 18,
352
+ strokeWidth: 1.5,
353
+ className: "text-muted-foreground"
354
+ })
355
+ });
356
+ }
357
+ return null;
358
+ }
359
+ function CardImage2({ src, alt, className }) {
360
+ const { orientation } = useContext(CardContext);
361
+ return /* @__PURE__ */ jsx("img", {
362
+ src,
363
+ alt: alt ?? "",
364
+ "data-slot": "card-image",
365
+ className: cn2("object-cover rounded-xs", orientation === "inline" ? "size-40 shrink-0" : "w-full aspect-[16/9]", className)
366
+ });
367
+ }
368
+ CardImage2.displayName = "CardImage";
369
+ var CardEyebrow2 = forwardRef(({ className, ...props }, ref) => {
370
+ const compact = useSize2().variant === "compact";
371
+ return /* @__PURE__ */ jsx("span", {
372
+ ref,
373
+ "data-slot": "card-eyebrow",
374
+ className: cn2(compact ? "text-caption-compact" : "text-caption", "uppercase tracking-wide text-muted-foreground", "weight-semibold", className),
375
+ ...props
376
+ });
377
+ });
378
+ CardEyebrow2.displayName = "CardEyebrow";
379
+ function CardFeature2({ icon: Icon, title, description }) {
380
+ const sizeClasses = useSize2();
381
+ const compact = sizeClasses.variant === "compact";
382
+ return /* @__PURE__ */ jsxs("div", {
383
+ "data-slot": "card-feature",
384
+ className: cn2("flex items-start", sizeClasses.gap),
385
+ children: [
386
+ Icon && /* @__PURE__ */ jsx(Icon, {
387
+ size: sizeClasses.icon,
388
+ strokeWidth: 1.5,
389
+ className: "mt-0.5 shrink-0 text-muted-foreground"
390
+ }),
391
+ /* @__PURE__ */ jsxs("div", {
392
+ className: "flex flex-col gap-0.5 min-w-0",
393
+ children: [
394
+ /* @__PURE__ */ jsx("span", {
395
+ className: cn2("text-foreground [text-box:trim-both_cap_alphabetic]", sizeClasses.text, "weight-medium"),
396
+ children: title
397
+ }),
398
+ description && /* @__PURE__ */ jsx("span", {
399
+ className: cn2("leading-relaxed text-muted-foreground", compact ? "text-caption-compact" : "text-caption"),
400
+ children: description
401
+ })
402
+ ]
403
+ })
404
+ ]
405
+ });
406
+ }
407
+ var CARD_BUTTON_VARIANTS = {
408
+ primary: "bg-foreground text-background hover:bg-foreground/90 active:bg-foreground/80",
409
+ secondary: "bg-accent text-foreground hover:bg-accent/80 active:bg-accent",
410
+ ghost: "text-muted-foreground hover:text-foreground hover:bg-hover active:bg-active",
411
+ link: "text-foreground underline-offset-4 hover:underline !px-0 !h-auto"
412
+ };
413
+ function CardButton2({
414
+ children,
415
+ onClick,
416
+ href,
417
+ variant = "ghost",
418
+ icon: Icon,
419
+ iconPosition,
420
+ external = false,
421
+ disabled = false
422
+ }) {
423
+ const shape = useShape();
424
+ const ArrowRight = useIcon("arrow-right");
425
+ const sizeClasses = useSize2();
426
+ const compact = sizeClasses.variant === "compact";
427
+ const position = iconPosition ?? (external ? "end" : "start");
428
+ const glyph = Icon ? /* @__PURE__ */ jsx(Icon, {
429
+ size: compact ? 12 : 14,
430
+ strokeWidth: 1.5,
431
+ className: "shrink-0 transition-[stroke-width] duration-fast group-hover/action:stroke-[2]"
432
+ }) : null;
433
+ const externalGlyph = external ? /* @__PURE__ */ jsx(ArrowRight, {
434
+ size: 13,
435
+ strokeWidth: 1.5,
436
+ className: "shrink-0 -rotate-45 transition-[stroke-width] duration-fast group-hover/action:stroke-[2]"
437
+ }) : null;
438
+ const inner = /* @__PURE__ */ jsxs(Fragment, {
439
+ children: [
440
+ position === "start" && glyph,
441
+ /* @__PURE__ */ jsx("span", {
442
+ className: "[text-box:trim-both_cap_alphabetic]",
443
+ children
444
+ }),
445
+ position === "end" && glyph,
446
+ externalGlyph
447
+ ]
448
+ });
449
+ const classes = cn2("group/action relative z-30 inline-flex items-center justify-center gap-1.5 h-7 px-2.5 cursor-pointer outline-none", compact ? "text-caption-compact" : "text-caption", "weight-medium", "transition-colors duration-fast", "focus-visible:ring-1 focus-visible:ring-focus-ring", "disabled:opacity-50 disabled:pointer-events-none", shape.button, CARD_BUTTON_VARIANTS[variant]);
450
+ if (href) {
451
+ return /* @__PURE__ */ jsx("a", {
452
+ href,
453
+ onClick,
454
+ target: external ? "_blank" : undefined,
455
+ rel: external ? "noopener noreferrer" : undefined,
456
+ className: classes,
457
+ children: inner
458
+ });
459
+ }
460
+ return /* @__PURE__ */ jsx("button", {
461
+ type: "button",
462
+ onClick,
463
+ disabled,
464
+ className: classes,
465
+ children: inner
466
+ });
467
+ }
468
+ Object.assign(Card2, {
469
+ Group: CardGroup2,
470
+ Header: CardHeader2,
471
+ Title: CardTitle2,
472
+ Description: CardDescription2,
473
+ Action: CardAction2,
474
+ Content: CardContent2,
475
+ Footer: CardFooter2,
476
+ Media: CardMedia2,
477
+ Image: CardImage2,
478
+ Eyebrow: CardEyebrow2,
479
+ Feature: CardFeature2,
480
+ Button: CardButton2
481
+ });
482
+ var card_default = Card2;
483
+
484
+ export { CardGroup2, Card2, CardHeader2, CardTitle2, CardDescription2, CardAction2, CardContent2, CardFooter2, CardMedia2, CardImage2, CardEyebrow2, CardFeature2, CardButton2, card_default };