@lindle/linoardo 1.0.2 → 1.0.4

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.js CHANGED
@@ -1,5 +1,6 @@
1
+ import * as React6 from 'react';
1
2
  import { twMerge } from 'tailwind-merge';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
4
 
4
5
  // src/Containment/Button/index.tsx
5
6
 
@@ -10,48 +11,56 @@ var iconBaseClasses = {
10
11
 
11
12
  // src/Containment/Button/states.button.ts
12
13
  var base = "btn-base focus-visible:outline-none focus-visible:ring-2 rounded-md transition-colors duration-200 font-medium disabled:opacity-50 disabled:cursor-not-allowed";
14
+ var blackAndWhiteVariantClass = "bg-white hover:bg-black hover:text-white text-black border border-black focus-visible:ring-black/40 focus-visible:ring-offset-white";
13
15
  var paletteVariantClasses = {
14
16
  primary: {
15
17
  solid: "bg-primary text-white hover:bg-primary/90 focus-visible:ring-primary",
16
18
  outline: "border border-primary text-primary bg-white hover:bg-primary hover:text-white focus-visible:ring-primary",
17
19
  ghost: "text-primary bg-primary/10 hover:bg-primary/20 focus-visible:ring-primary/40",
18
- text: "bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/30 underline-offset-2"
20
+ text: "bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/30 underline-offset-2",
21
+ bw: blackAndWhiteVariantClass
19
22
  },
20
23
  neutral: {
21
24
  solid: "bg-gray-600 text-white hover:bg-gray-700 focus-visible:ring-gray-500",
22
25
  outline: "border border-gray-400 text-gray-700 bg-white hover:bg-gray-700 hover:text-white focus-visible:ring-gray-400",
23
26
  ghost: "text-gray-700 bg-gray-100 hover:bg-gray-200 focus-visible:ring-gray-300",
24
- text: "bg-transparent text-gray-700 hover:bg-gray-100 focus-visible:ring-gray-200 underline-offset-2"
27
+ text: "bg-transparent text-gray-700 hover:bg-gray-100 focus-visible:ring-gray-200 underline-offset-2",
28
+ bw: blackAndWhiteVariantClass
25
29
  },
26
30
  info: {
27
31
  solid: "bg-sky-500 text-white hover:bg-sky-600 focus-visible:ring-sky-400",
28
32
  outline: "border border-sky-500 text-sky-600 bg-white hover:bg-sky-500 hover:text-white focus-visible:ring-sky-400",
29
33
  ghost: "text-sky-600 bg-sky-100 hover:bg-sky-200 focus-visible:ring-sky-300",
30
- text: "bg-transparent text-sky-600 hover:bg-sky-100 focus-visible:ring-sky-200 underline-offset-2"
34
+ text: "bg-transparent text-sky-600 hover:bg-sky-100 focus-visible:ring-sky-200 underline-offset-2",
35
+ bw: blackAndWhiteVariantClass
31
36
  },
32
37
  success: {
33
38
  solid: "bg-emerald-500 text-white hover:bg-emerald-600 focus-visible:ring-emerald-400",
34
39
  outline: "border border-emerald-500 text-emerald-600 bg-white hover:bg-emerald-500 hover:text-white focus-visible:ring-emerald-400",
35
40
  ghost: "text-emerald-600 bg-emerald-100 hover:bg-emerald-200 focus-visible:ring-emerald-300",
36
- text: "bg-transparent text-emerald-600 hover:bg-emerald-100 focus-visible:ring-emerald-200 underline-offset-2"
41
+ text: "bg-transparent text-emerald-600 hover:bg-emerald-100 focus-visible:ring-emerald-200 underline-offset-2",
42
+ bw: blackAndWhiteVariantClass
37
43
  },
38
44
  warning: {
39
45
  solid: "bg-amber-500 text-white hover:bg-amber-600 focus-visible:ring-amber-400",
40
46
  outline: "border border-amber-500 text-amber-600 bg-white hover:bg-amber-500 hover:text-white focus-visible:ring-amber-400",
41
47
  ghost: "text-amber-600 bg-amber-100 hover:bg-amber-200 focus-visible:ring-amber-300",
42
- text: "bg-transparent text-amber-600 hover:bg-amber-100 focus-visible:ring-amber-200 underline-offset-2"
48
+ text: "bg-transparent text-amber-600 hover:bg-amber-100 focus-visible:ring-amber-200 underline-offset-2",
49
+ bw: blackAndWhiteVariantClass
43
50
  },
44
51
  danger: {
45
52
  solid: "bg-red-500 text-white hover:bg-red-600 focus-visible:ring-red-400",
46
53
  outline: "border border-red-500 text-red-600 bg-white hover:bg-red-500 hover:text-white focus-visible:ring-red-400",
47
54
  ghost: "text-red-600 bg-red-100 hover:bg-red-200 focus-visible:ring-red-300",
48
- text: "bg-transparent text-red-600 hover:bg-red-100 focus-visible:ring-red-200 underline-offset-2"
55
+ text: "bg-transparent text-red-600 hover:bg-red-100 focus-visible:ring-red-200 underline-offset-2",
56
+ bw: blackAndWhiteVariantClass
49
57
  },
50
58
  surface: {
51
59
  solid: "bg-white text-gray-900 border border-gray-200 hover:bg-gray-50 focus-visible:ring-gray-200",
52
60
  outline: "border border-gray-300 text-gray-900 bg-white hover:bg-gray-100 focus-visible:ring-gray-200",
53
61
  ghost: "text-gray-900 bg-gray-100 hover:bg-gray-200 focus-visible:ring-gray-200",
54
- text: "bg-transparent text-gray-900 hover:bg-gray-100 focus-visible:ring-gray-200 underline-offset-2"
62
+ text: "bg-transparent text-gray-900 hover:bg-gray-100 focus-visible:ring-gray-200 underline-offset-2",
63
+ bw: blackAndWhiteVariantClass
55
64
  }
56
65
  };
57
66
  var resolveVariantClass = (variant, palette) => {
@@ -90,51 +99,813 @@ var sizeClasses = {
90
99
  large: "px-6 py-3 text-lg",
91
100
  "x-large": "px-7 py-3.5 text-xl"
92
101
  };
93
- var Button = ({
94
- variant = "solid",
95
- color = "primary",
96
- size = "medium",
97
- block = false,
98
- loading = false,
99
- icon,
100
- className,
101
- children,
102
- disabled,
103
- onClick,
104
- ...rest
105
- }) => {
106
- const variantClass = resolveVariantClass(variant, color);
107
- const sizeClass = sizeClasses[size] ?? sizeClasses.medium;
108
- const blockClass = block ? "w-full" : null;
109
- const isDisabled = disabled || loading;
110
- const cursor = onClick && !isDisabled ? "cursor-pointer" : "cursor-default";
111
- const resolvedIconClass = resolveIconClassName(icon);
112
- const shouldRenderIcon = Boolean(resolvedIconClass && !loading);
113
- const hasDecorators = (loading || shouldRenderIcon) && Boolean(children);
114
- const gapClass = hasDecorators ? "gap-2" : void 0;
115
- const loadingIconClass = loading ? twMerge("mdi mdi-loading mdi-spin", "leading-none") : void 0;
116
- const iconClassName = shouldRenderIcon ? twMerge("leading-none", resolvedIconClass) : void 0;
102
+ var Button = React6.forwardRef(
103
+ ({
104
+ variant = "solid",
105
+ color = "primary",
106
+ size = "medium",
107
+ block = false,
108
+ loading = false,
109
+ loadingText,
110
+ icon,
111
+ className,
112
+ children,
113
+ disabled,
114
+ onClick,
115
+ ...rest
116
+ }, ref) => {
117
+ const variantClass = resolveVariantClass(variant, color);
118
+ const sizeClass = sizeClasses[size] ?? sizeClasses.medium;
119
+ const blockClass = block ? "w-full" : null;
120
+ const isDisabled = disabled || loading;
121
+ const cursor = onClick && !isDisabled ? "cursor-pointer" : "cursor-default";
122
+ const resolvedIconClass = resolveIconClassName(icon);
123
+ const shouldRenderIcon = Boolean(resolvedIconClass && !loading);
124
+ const isLoadingTextProvided = loadingText !== void 0 && loadingText !== null;
125
+ const content = loading && isLoadingTextProvided ? loadingText : children;
126
+ const hasDecorators = (loading || shouldRenderIcon) && Boolean(content);
127
+ const gapClass = hasDecorators ? "gap-2" : void 0;
128
+ const loadingIconClass = loading ? twMerge("mdi mdi-loading mdi-spin", "leading-none") : void 0;
129
+ const iconClassName = shouldRenderIcon ? twMerge("leading-none", resolvedIconClass) : void 0;
130
+ return /* @__PURE__ */ jsxs(
131
+ "button",
132
+ {
133
+ ...rest,
134
+ ref,
135
+ onClick,
136
+ disabled: isDisabled,
137
+ className: twMerge(base, cursor, variantClass, sizeClass, blockClass, gapClass, className),
138
+ "data-loading": loading || void 0,
139
+ "aria-busy": loading || void 0,
140
+ children: [
141
+ loading && /* @__PURE__ */ jsx("i", { className: loadingIconClass, "aria-hidden": true }),
142
+ iconClassName && /* @__PURE__ */ jsx("i", { className: iconClassName, "aria-hidden": true }),
143
+ content
144
+ ]
145
+ }
146
+ );
147
+ }
148
+ );
149
+ Button.displayName = "Button";
150
+ var Button_default = Button;
151
+
152
+ // src/Containment/Chip/states.chip.ts
153
+ var chipBaseClasses = "inline-flex items-center gap-1.5 border font-medium leading-tight transition-all duration-200 select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2";
154
+ var chipSizeClasses = {
155
+ small: "text-xs px-3 py-1 min-h-[1.5rem]",
156
+ medium: "text-sm px-4 py-1.5 min-h-[2rem]",
157
+ large: "text-base px-5 py-2 min-h-[2.5rem]"
158
+ };
159
+ var closeButtonClasses = "ml-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-transparent text-current/70 transition-colors duration-200 hover:bg-current/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-current/30 focus-visible:ring-offset-2";
160
+ var blackAndWhiteChipVariantClass = "bg-white text-black border border-black hover:bg-white focus-visible:ring-black/40 focus-visible:ring-offset-white";
161
+ var paletteVariantClasses2 = {
162
+ primary: {
163
+ solid: "bg-primary text-white border border-primary hover:bg-primary/90",
164
+ outline: "bg-transparent text-primary border border-primary hover:bg-primary/10",
165
+ ghost: "bg-primary/15 text-primary border border-transparent hover:bg-primary/25",
166
+ text: "bg-transparent text-primary border border-transparent hover:text-primary/80",
167
+ bw: blackAndWhiteChipVariantClass
168
+ },
169
+ neutral: {
170
+ solid: "bg-gray-900 text-white border border-gray-900 hover:bg-gray-800",
171
+ outline: "bg-transparent text-gray-900 border border-gray-500 hover:bg-gray-100",
172
+ ghost: "bg-gray-100 text-gray-900 border border-transparent hover:bg-gray-200",
173
+ text: "bg-transparent text-gray-900 border border-transparent hover:text-gray-700",
174
+ bw: blackAndWhiteChipVariantClass
175
+ },
176
+ info: {
177
+ solid: "bg-sky-500 text-white border border-sky-500 hover:bg-sky-600",
178
+ outline: "bg-transparent text-sky-600 border border-sky-500 hover:bg-sky-50",
179
+ ghost: "bg-sky-100 text-sky-700 border border-transparent hover:bg-sky-200",
180
+ text: "bg-transparent text-sky-600 border border-transparent hover:text-sky-700",
181
+ bw: blackAndWhiteChipVariantClass
182
+ },
183
+ success: {
184
+ solid: "bg-emerald-500 text-white border border-emerald-500 hover:bg-emerald-600",
185
+ outline: "bg-transparent text-emerald-600 border border-emerald-500 hover:bg-emerald-50",
186
+ ghost: "bg-emerald-100 text-emerald-700 border border-transparent hover:bg-emerald-200",
187
+ text: "bg-transparent text-emerald-600 border border-transparent hover:text-emerald-700",
188
+ bw: blackAndWhiteChipVariantClass
189
+ },
190
+ warning: {
191
+ solid: "bg-amber-500 text-white border border-amber-500 hover:bg-amber-600",
192
+ outline: "bg-transparent text-amber-700 border border-amber-500 hover:bg-amber-50",
193
+ ghost: "bg-amber-100 text-amber-800 border border-transparent hover:bg-amber-200",
194
+ text: "bg-transparent text-amber-700 border border-transparent hover:text-amber-800",
195
+ bw: blackAndWhiteChipVariantClass
196
+ },
197
+ danger: {
198
+ solid: "bg-red-500 text-white border border-red-500 hover:bg-red-600",
199
+ outline: "bg-transparent text-red-600 border border-red-500 hover:bg-red-50",
200
+ ghost: "bg-red-100 text-red-700 border border-transparent hover:bg-red-200",
201
+ text: "bg-transparent text-red-600 border border-transparent hover:text-red-700",
202
+ bw: blackAndWhiteChipVariantClass
203
+ },
204
+ surface: {
205
+ solid: "bg-white text-gray-900 border border-gray-200 hover:bg-gray-50",
206
+ outline: "bg-transparent text-gray-900 border border-gray-300 hover:bg-gray-50",
207
+ ghost: "bg-gray-100 text-gray-900 border border-transparent hover:bg-gray-200",
208
+ text: "bg-transparent text-gray-900 border border-transparent hover:text-gray-600",
209
+ bw: blackAndWhiteChipVariantClass
210
+ }
211
+ };
212
+ var resolveVariantClass2 = (variant, palette) => {
213
+ const variants = paletteVariantClasses2[palette] ?? paletteVariantClasses2.primary;
214
+ return variants[variant] ?? variants.solid;
215
+ };
216
+ var resolveIconClassName2 = (icon) => {
217
+ if (!icon) {
218
+ return void 0;
219
+ }
220
+ if (typeof icon === "string") {
221
+ const trimmed = icon.trim();
222
+ if (!trimmed) {
223
+ return void 0;
224
+ }
225
+ if (trimmed.includes(" ")) {
226
+ return trimmed;
227
+ }
228
+ const normalized2 = trimmed.startsWith("mdi-") ? trimmed : `mdi-${trimmed}`;
229
+ return ["mdi", normalized2].join(" ");
230
+ }
231
+ const [library, providedName] = icon;
232
+ const normalizedLibrary = library.trim();
233
+ const baseClasses = iconBaseClasses[normalizedLibrary] ?? [normalizedLibrary];
234
+ const iconName = providedName.trim();
235
+ if (!iconName) {
236
+ return baseClasses.join(" ");
237
+ }
238
+ const normalized = iconName.startsWith("mdi-") ? iconName : `mdi-${iconName}`;
239
+ return Array.from(/* @__PURE__ */ new Set([...baseClasses, normalized])).join(" ");
240
+ };
241
+ var Chip = React6.forwardRef(
242
+ ({
243
+ variant = "solid",
244
+ color = "primary",
245
+ size = "medium",
246
+ pill = true,
247
+ selected = false,
248
+ closable = false,
249
+ closeIcon = "mdi-close",
250
+ onClose,
251
+ filter = false,
252
+ filterIcon = "mdi-check-bold",
253
+ prependIcon,
254
+ appendIcon,
255
+ disabled = false,
256
+ className,
257
+ children,
258
+ ...rest
259
+ }, ref) => {
260
+ const { onClick, onKeyDown, role, tabIndex, ...nativeProps } = rest;
261
+ const interactive = typeof onClick === "function";
262
+ const variantClass = resolveVariantClass2(variant, color);
263
+ const sizeClass = chipSizeClasses[size] ?? chipSizeClasses.medium;
264
+ const pillClass = pill ? "rounded-full" : "rounded-lg";
265
+ const cursorClass = disabled ? "pointer-events-none opacity-50" : interactive ? "cursor-pointer" : "cursor-default";
266
+ const selectedClass = selected ? "ring-2 ring-current/50 ring-offset-2 ring-offset-white" : void 0;
267
+ const resolvedRole = disabled ? role : role ?? (interactive ? "button" : void 0);
268
+ const resolvedTabIndex = disabled ? -1 : tabIndex ?? (interactive ? 0 : void 0);
269
+ const prependIconClassName = resolveIconClassName2(prependIcon);
270
+ const appendIconClassName = resolveIconClassName2(appendIcon);
271
+ const closeIconClassName = resolveIconClassName2(closeIcon);
272
+ const filterIconClassName = filter && selected ? resolveIconClassName2(filterIcon) : void 0;
273
+ const handleClick = React6.useCallback(
274
+ (event) => {
275
+ if (disabled) {
276
+ event.preventDefault();
277
+ event.stopPropagation();
278
+ return;
279
+ }
280
+ onClick?.(event);
281
+ },
282
+ [disabled, onClick]
283
+ );
284
+ const handleKeyDown = React6.useCallback(
285
+ (event) => {
286
+ onKeyDown?.(event);
287
+ if (event.defaultPrevented || disabled || !interactive) {
288
+ return;
289
+ }
290
+ if (event.key === "Enter" || event.key === " ") {
291
+ event.preventDefault();
292
+ event.currentTarget.click();
293
+ }
294
+ },
295
+ [disabled, interactive, onKeyDown]
296
+ );
297
+ const handleCloseClick = React6.useCallback(
298
+ (event) => {
299
+ event.stopPropagation();
300
+ if (disabled) {
301
+ event.preventDefault();
302
+ return;
303
+ }
304
+ onClose?.(event);
305
+ },
306
+ [disabled, onClose]
307
+ );
308
+ const handleCloseKeyDown = React6.useCallback((event) => {
309
+ if (event.key === " " || event.key === "Enter") {
310
+ event.stopPropagation();
311
+ }
312
+ }, []);
313
+ const renderableChildren = typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx("span", { className: "truncate", children }) : children;
314
+ const filterAdornment = filter ? /* @__PURE__ */ jsx(
315
+ "span",
316
+ {
317
+ className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-full border border-current/30 text-[0.55rem]",
318
+ "aria-hidden": true,
319
+ children: filterIconClassName ? /* @__PURE__ */ jsx("i", { className: filterIconClassName, "aria-hidden": true }) : null
320
+ }
321
+ ) : null;
322
+ return /* @__PURE__ */ jsxs(
323
+ "span",
324
+ {
325
+ ...nativeProps,
326
+ ref,
327
+ role: resolvedRole,
328
+ tabIndex: resolvedTabIndex,
329
+ "aria-disabled": disabled || void 0,
330
+ "aria-pressed": filter ? selected : void 0,
331
+ "data-selected": selected || void 0,
332
+ className: twMerge(chipBaseClasses, sizeClass, pillClass, variantClass, cursorClass, selectedClass, className),
333
+ onClick: interactive ? handleClick : void 0,
334
+ onKeyDown: interactive ? handleKeyDown : onKeyDown,
335
+ children: [
336
+ filterAdornment,
337
+ prependIconClassName && /* @__PURE__ */ jsx("i", { className: twMerge("text-[1em] leading-none", prependIconClassName), "aria-hidden": true }),
338
+ renderableChildren,
339
+ appendIconClassName && /* @__PURE__ */ jsx("i", { className: twMerge("text-[1em] leading-none", appendIconClassName), "aria-hidden": true }),
340
+ closable && /* @__PURE__ */ jsx(
341
+ "button",
342
+ {
343
+ type: "button",
344
+ disabled,
345
+ "aria-label": "Remove chip",
346
+ className: twMerge(closeButtonClasses),
347
+ onClick: handleCloseClick,
348
+ onKeyDown: handleCloseKeyDown,
349
+ children: closeIconClassName ? /* @__PURE__ */ jsx("i", { className: closeIconClassName, "aria-hidden": true }) : /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xD7" })
350
+ }
351
+ )
352
+ ]
353
+ }
354
+ );
355
+ }
356
+ );
357
+ Chip.displayName = "Chip";
358
+ var Chip_default = Chip;
359
+ var defaultListContext = {
360
+ density: "default",
361
+ lines: "one",
362
+ nav: false,
363
+ divided: false,
364
+ color: "primary"
365
+ };
366
+ var ListContext = React6.createContext(defaultListContext);
367
+ var useListContext = () => React6.useContext(ListContext);
368
+ var listItemBaseClasses = "relative flex w-full items-center gap-4 bg-transparent text-left text-sm transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white hover:bg-neutral-200";
369
+ var densityClasses = {
370
+ default: "px-4 py-3 text-base",
371
+ comfortable: "px-4 py-2.5 text-sm",
372
+ compact: "px-3 py-2 text-sm"
373
+ };
374
+ var lineClasses = {
375
+ one: "min-h-[3rem]",
376
+ two: "min-h-[3.75rem]",
377
+ three: "min-h-[4.5rem]"
378
+ };
379
+ var accentClasses = {
380
+ primary: { text: "text-primary", bg: "bg-primary/10", indicator: "bg-primary" },
381
+ neutral: { text: "text-gray-900", bg: "bg-gray-100", indicator: "bg-gray-900" },
382
+ info: { text: "text-sky-600", bg: "bg-sky-50", indicator: "bg-sky-500" },
383
+ success: { text: "text-emerald-600", bg: "bg-emerald-50", indicator: "bg-emerald-500" },
384
+ warning: { text: "text-amber-700", bg: "bg-amber-50", indicator: "bg-amber-500" },
385
+ danger: { text: "text-red-600", bg: "bg-red-50", indicator: "bg-red-500" },
386
+ surface: { text: "text-gray-900", bg: "bg-gray-100", indicator: "bg-gray-900" }
387
+ };
388
+ var ListItem = React6.forwardRef((props, ref) => {
389
+ const {
390
+ component,
391
+ href,
392
+ target,
393
+ rel,
394
+ type,
395
+ title,
396
+ subtitle,
397
+ overline,
398
+ prepend,
399
+ append,
400
+ active = false,
401
+ disabled = false,
402
+ inset = false,
403
+ density: densityOverride,
404
+ lines: linesOverride,
405
+ className,
406
+ children,
407
+ tabIndex,
408
+ role,
409
+ ...rest
410
+ } = props;
411
+ const listContext = useListContext();
412
+ const density = densityOverride ?? listContext.density;
413
+ const lines = linesOverride ?? listContext.lines;
414
+ const nav = listContext.nav;
415
+ const accent = accentClasses[listContext.color] ?? accentClasses.primary;
416
+ const shapeClass = listContext.divided ? "rounded-none" : "rounded-lg";
417
+ const Component = component ?? (href ? "a" : "div");
418
+ const interactive = typeof rest.onClick === "function" || Component === "a" || Component === "button";
419
+ const resolvedRole = role ?? "listitem";
420
+ const resolvedTabIndex = disabled ? -1 : tabIndex ?? (interactive && Component === "div" ? 0 : void 0);
421
+ const resolvedRel = Component === "a" ? rel : void 0;
422
+ const resolvedTarget = Component === "a" ? target : void 0;
423
+ const resolvedHref = Component === "a" ? href : void 0;
424
+ const resolvedType = Component === "button" ? type ?? "button" : void 0;
425
+ const disabledClass = disabled ? "pointer-events-none opacity-60" : "cursor-pointer";
426
+ const navPaddingClass = nav ? "pl-5" : void 0;
427
+ const insetClass = inset ? "pl-12" : void 0;
428
+ const activeClasses = active ? accent.bg : void 0;
117
429
  return /* @__PURE__ */ jsxs(
118
- "button",
430
+ Component,
119
431
  {
120
432
  ...rest,
121
- onClick,
122
- disabled: isDisabled,
123
- className: twMerge(base, cursor, variantClass, sizeClass, blockClass, gapClass, className),
124
- "data-loading": loading || void 0,
125
- "aria-busy": loading || void 0,
433
+ ref,
434
+ role: resolvedRole,
435
+ tabIndex: resolvedTabIndex,
436
+ "aria-disabled": disabled || void 0,
437
+ "aria-current": active ? "true" : void 0,
438
+ className: twMerge(
439
+ listItemBaseClasses,
440
+ densityClasses[density],
441
+ lineClasses[lines],
442
+ shapeClass,
443
+ navPaddingClass,
444
+ insetClass,
445
+ disabledClass,
446
+ activeClasses,
447
+ className
448
+ ),
449
+ href: resolvedHref,
450
+ target: resolvedTarget,
451
+ rel: resolvedRel,
452
+ type: resolvedType,
453
+ "data-active": active || void 0,
126
454
  children: [
127
- loading && /* @__PURE__ */ jsx("i", { className: loadingIconClass, "aria-hidden": true }),
128
- iconClassName && /* @__PURE__ */ jsx("i", { className: iconClassName, "aria-hidden": true }),
129
- children
455
+ nav && /* @__PURE__ */ jsx(
456
+ "span",
457
+ {
458
+ "aria-hidden": true,
459
+ className: twMerge(
460
+ "absolute left-1 top-2 bottom-2 w-0.5 rounded-full bg-transparent transition-colors duration-150",
461
+ active ? accent.indicator : void 0
462
+ )
463
+ }
464
+ ),
465
+ prepend && /* @__PURE__ */ jsx("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center text-base text-gray-500", children: prepend }),
466
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col gap-0.5 text-left", children: [
467
+ overline && /* @__PURE__ */ jsx("span", { className: "text-[0.65rem] font-semibold uppercase tracking-wide text-gray-500", children: overline }),
468
+ title && /* @__PURE__ */ jsx("span", { className: twMerge("truncate font-medium text-gray-900", active ? accent.text : void 0), children: title }),
469
+ subtitle && /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: subtitle }),
470
+ children
471
+ ] }),
472
+ append && /* @__PURE__ */ jsx("span", { className: "ml-auto flex items-center gap-2 whitespace-nowrap text-sm text-gray-500", children: append })
130
473
  ]
131
474
  }
132
475
  );
476
+ });
477
+ ListItem.displayName = "ListItem";
478
+ var Item_default = ListItem;
479
+ var listBaseClasses = "flex w-full min-w-0 flex-col text-gray-900 transition-colors duration-150";
480
+ var listVariantClasses = {
481
+ solid: "bg-white border border-gray-200 shadow-sm shadow-gray-900/5",
482
+ outline: "bg-transparent border border-gray-300",
483
+ ghost: "bg-gray-50 border border-transparent",
484
+ text: "bg-transparent border border-transparent",
485
+ bw: "bg-white text-black border border-black shadow-none"
133
486
  };
134
- var Button_default = Button;
487
+ var listRoundedClasses = {
488
+ none: "rounded-none",
489
+ sm: "rounded-sm",
490
+ md: "rounded-md",
491
+ lg: "rounded-lg",
492
+ xl: "rounded-xl",
493
+ pill: "rounded-full"
494
+ };
495
+ var List = React6.forwardRef((props, ref) => {
496
+ const {
497
+ variant = "solid",
498
+ density = "default",
499
+ lines = "one",
500
+ nav = false,
501
+ divided = false,
502
+ rounded = "lg",
503
+ color = "primary",
504
+ className,
505
+ role,
506
+ children,
507
+ ...rest
508
+ } = props;
509
+ const variantClass = listVariantClasses[variant] ?? listVariantClasses.solid;
510
+ const roundedClass = listRoundedClasses[rounded] ?? listRoundedClasses.lg;
511
+ const dividerClass = divided ? "divide-y divide-gray-100" : void 0;
512
+ const gapClass = divided ? "p-0" : "gap-1 p-1";
513
+ const navClass = nav ? "py-1" : void 0;
514
+ const accentColor = variant === "bw" ? "surface" : color;
515
+ const contextValue = React6.useMemo(
516
+ () => ({
517
+ density,
518
+ lines,
519
+ nav,
520
+ divided,
521
+ color: accentColor
522
+ }),
523
+ [accentColor, density, lines, nav, divided]
524
+ );
525
+ return /* @__PURE__ */ jsx(ListContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
526
+ "div",
527
+ {
528
+ ...rest,
529
+ ref,
530
+ role: role ?? "list",
531
+ className: twMerge(listBaseClasses, variantClass, roundedClass, dividerClass, gapClass, navClass, className),
532
+ children
533
+ }
534
+ ) });
535
+ });
536
+ List.displayName = "List";
537
+ var List_default = List;
538
+ var isBrowser = typeof window !== "undefined";
539
+ var useIsomorphicLayoutEffect = isBrowser ? React6.useLayoutEffect : React6.useEffect;
540
+ var placementClasses = {
541
+ "bottom-start": "left-0 top-full origin-top-left",
542
+ bottom: "left-1/2 top-full -translate-x-1/2 origin-top",
543
+ "bottom-end": "right-0 top-full origin-top-right",
544
+ "top-start": "left-0 bottom-full origin-bottom-left",
545
+ top: "left-1/2 bottom-full -translate-x-1/2 origin-bottom",
546
+ "top-end": "right-0 bottom-full origin-bottom-right"
547
+ };
548
+ var offsetClasses = {
549
+ top: "mb-2",
550
+ bottom: "mt-2"
551
+ };
552
+ var menuBaseClasses = "absolute z-50 min-w-[10rem] rounded-xl border border-gray-200/80 bg-white/95 p-2 text-sm text-gray-700 shadow-lg shadow-gray-900/10 ring-1 ring-black/5 backdrop-blur-md transition-all duration-150 data-[state=closed]:pointer-events-none data-[state=closed]:opacity-0 data-[state=closed]:scale-95 data-[state=open]:opacity-100 data-[state=open]:scale-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2";
553
+ var overlayBaseClasses = "fixed inset-0 z-40 bg-gray-900/30 backdrop-blur-[1px]";
554
+ var Menu = React6.forwardRef((props, ref) => {
555
+ const {
556
+ activator,
557
+ children,
558
+ open: openProp,
559
+ defaultOpen = false,
560
+ onOpenChange,
561
+ placement = "bottom-start",
562
+ openOnHover = false,
563
+ closeOnContentClick = true,
564
+ matchActivatorWidth = false,
565
+ keepMounted = false,
566
+ disabled = false,
567
+ scrim = false,
568
+ contentClassName,
569
+ contentProps,
570
+ overlayClassName,
571
+ className,
572
+ onMouseEnter: rootMouseEnter,
573
+ onMouseLeave: rootMouseLeave,
574
+ ...rest
575
+ } = props;
576
+ const baseId = React6.useId();
577
+ const menuId = `${baseId}-menu`;
578
+ const activatorId = `${baseId}-activator`;
579
+ const isControlled = typeof openProp === "boolean";
580
+ const [internalOpen, setInternalOpen] = React6.useState(defaultOpen);
581
+ const open = isControlled ? Boolean(openProp) : internalOpen;
582
+ const localRootRef = React6.useRef(null);
583
+ const menuRef = React6.useRef(null);
584
+ const activatorRef = React6.useRef(null);
585
+ const closeTimeoutRef = React6.useRef(null);
586
+ const mergedRootRef = React6.useCallback(
587
+ (node) => {
588
+ localRootRef.current = node;
589
+ if (typeof ref === "function") {
590
+ ref(node);
591
+ } else if (ref) {
592
+ ref.current = node;
593
+ }
594
+ },
595
+ [ref]
596
+ );
597
+ const [activatorWidth, setActivatorWidth] = React6.useState();
598
+ const updateActivatorWidth = React6.useCallback(() => {
599
+ if (!matchActivatorWidth) {
600
+ setActivatorWidth(void 0);
601
+ return;
602
+ }
603
+ const node = activatorRef.current;
604
+ if (!node) {
605
+ return;
606
+ }
607
+ setActivatorWidth(node.getBoundingClientRect().width);
608
+ }, [matchActivatorWidth]);
609
+ useIsomorphicLayoutEffect(() => {
610
+ if (!matchActivatorWidth) {
611
+ return;
612
+ }
613
+ updateActivatorWidth();
614
+ if (!activatorRef.current || typeof ResizeObserver === "undefined") {
615
+ return;
616
+ }
617
+ const observer = new ResizeObserver(() => updateActivatorWidth());
618
+ observer.observe(activatorRef.current);
619
+ return () => observer.disconnect();
620
+ }, [matchActivatorWidth, updateActivatorWidth]);
621
+ const setOpen = React6.useCallback(
622
+ (nextOpen) => {
623
+ if (disabled || open === nextOpen) {
624
+ return;
625
+ }
626
+ if (!isControlled) {
627
+ setInternalOpen(nextOpen);
628
+ }
629
+ onOpenChange?.(nextOpen);
630
+ },
631
+ [disabled, isControlled, onOpenChange, open]
632
+ );
633
+ React6.useEffect(() => {
634
+ if (!disabled || !open) {
635
+ return;
636
+ }
637
+ if (!isControlled) {
638
+ setInternalOpen(false);
639
+ }
640
+ onOpenChange?.(false);
641
+ }, [disabled, open, isControlled, onOpenChange]);
642
+ React6.useEffect(() => {
643
+ if (!open) {
644
+ return;
645
+ }
646
+ const handlePointerDown = (event) => {
647
+ const target = event.target;
648
+ if (!target) {
649
+ return;
650
+ }
651
+ if (localRootRef.current?.contains(target)) {
652
+ return;
653
+ }
654
+ setOpen(false);
655
+ };
656
+ const handleKeyDown = (event) => {
657
+ if (event.key === "Escape") {
658
+ event.stopPropagation();
659
+ setOpen(false);
660
+ activatorRef.current?.focus();
661
+ }
662
+ };
663
+ document.addEventListener("pointerdown", handlePointerDown);
664
+ document.addEventListener("keydown", handleKeyDown);
665
+ return () => {
666
+ document.removeEventListener("pointerdown", handlePointerDown);
667
+ document.removeEventListener("keydown", handleKeyDown);
668
+ };
669
+ }, [open, setOpen]);
670
+ React6.useEffect(() => {
671
+ if (!open) {
672
+ return;
673
+ }
674
+ const node = menuRef.current;
675
+ if (!node) {
676
+ return;
677
+ }
678
+ const id = window.requestAnimationFrame(() => {
679
+ node.focus({ preventScroll: true });
680
+ });
681
+ return () => window.cancelAnimationFrame(id);
682
+ }, [open]);
683
+ const setActivatorNode = React6.useCallback(
684
+ (node) => {
685
+ activatorRef.current = node;
686
+ if (node && matchActivatorWidth) {
687
+ setActivatorWidth(node.getBoundingClientRect().width);
688
+ }
689
+ },
690
+ [matchActivatorWidth]
691
+ );
692
+ const handleActivatorClick = React6.useCallback(
693
+ (event) => {
694
+ event.preventDefault();
695
+ if (disabled) {
696
+ return;
697
+ }
698
+ setOpen(!open);
699
+ },
700
+ [disabled, open, setOpen]
701
+ );
702
+ const handleActivatorKeyDown = React6.useCallback(
703
+ (event) => {
704
+ if (event.key === "Enter" || event.key === " ") {
705
+ event.preventDefault();
706
+ setOpen(!open);
707
+ }
708
+ if (event.key === "ArrowDown") {
709
+ event.preventDefault();
710
+ setOpen(true);
711
+ }
712
+ },
713
+ [open, setOpen]
714
+ );
715
+ const clearCloseTimeout = React6.useCallback(() => {
716
+ if (closeTimeoutRef.current !== null) {
717
+ if (isBrowser) {
718
+ window.clearTimeout(closeTimeoutRef.current);
719
+ }
720
+ closeTimeoutRef.current = null;
721
+ }
722
+ }, []);
723
+ const scheduleClose = React6.useCallback(() => {
724
+ if (!isBrowser) {
725
+ setOpen(false);
726
+ return;
727
+ }
728
+ clearCloseTimeout();
729
+ closeTimeoutRef.current = window.setTimeout(() => {
730
+ setOpen(false);
731
+ closeTimeoutRef.current = null;
732
+ }, 150);
733
+ }, [clearCloseTimeout, setOpen]);
734
+ React6.useEffect(() => {
735
+ return () => clearCloseTimeout();
736
+ }, [clearCloseTimeout]);
737
+ const isMovingWithinMenu = React6.useCallback(
738
+ (event) => {
739
+ const nextTarget = event.relatedTarget;
740
+ if (!nextTarget || !localRootRef.current) {
741
+ return false;
742
+ }
743
+ return localRootRef.current.contains(nextTarget);
744
+ },
745
+ [localRootRef]
746
+ );
747
+ const handleRootMouseEnter = React6.useCallback(
748
+ (event) => {
749
+ rootMouseEnter?.(event);
750
+ if (event.defaultPrevented) {
751
+ return;
752
+ }
753
+ if (openOnHover) {
754
+ clearCloseTimeout();
755
+ setOpen(true);
756
+ }
757
+ },
758
+ [clearCloseTimeout, openOnHover, rootMouseEnter, setOpen]
759
+ );
760
+ const handleRootMouseLeave = React6.useCallback(
761
+ (event) => {
762
+ rootMouseLeave?.(event);
763
+ if (event.defaultPrevented) {
764
+ return;
765
+ }
766
+ if (openOnHover) {
767
+ if (isMovingWithinMenu(event)) {
768
+ return;
769
+ }
770
+ scheduleClose();
771
+ }
772
+ },
773
+ [isMovingWithinMenu, openOnHover, rootMouseLeave, scheduleClose]
774
+ );
775
+ const handleActivatorMouseEnter = React6.useCallback(
776
+ (_event) => {
777
+ if (disabled) {
778
+ return;
779
+ }
780
+ clearCloseTimeout();
781
+ setOpen(true);
782
+ },
783
+ [clearCloseTimeout, disabled, setOpen]
784
+ );
785
+ const handleActivatorMouseLeave = React6.useCallback(
786
+ (event) => {
787
+ if (disabled || !openOnHover) {
788
+ return;
789
+ }
790
+ if (isMovingWithinMenu(event)) {
791
+ return;
792
+ }
793
+ scheduleClose();
794
+ },
795
+ [disabled, isMovingWithinMenu, openOnHover, scheduleClose]
796
+ );
797
+ const {
798
+ className: contentClass,
799
+ style: contentStyle,
800
+ onClick: contentOnClick,
801
+ onMouseEnter: contentOnMouseEnter,
802
+ onMouseLeave: contentOnMouseLeave,
803
+ role: contentRole,
804
+ tabIndex: contentTabIndex,
805
+ ["aria-labelledby"]: ariaLabelledBy,
806
+ ...restContentProps
807
+ } = contentProps ?? {};
808
+ const shouldRenderContent = open || keepMounted;
809
+ const verticalPlacement = placement.startsWith("top") ? "top" : "bottom";
810
+ const activatorElement = activator({
811
+ ref: setActivatorNode,
812
+ id: activatorId,
813
+ "aria-haspopup": "menu",
814
+ "aria-expanded": open,
815
+ "aria-controls": menuId,
816
+ onClick: handleActivatorClick,
817
+ onKeyDown: handleActivatorKeyDown,
818
+ onMouseEnter: openOnHover ? handleActivatorMouseEnter : void 0,
819
+ onMouseLeave: openOnHover ? handleActivatorMouseLeave : void 0,
820
+ disabled,
821
+ open
822
+ });
823
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
824
+ scrim && open ? /* @__PURE__ */ jsx(
825
+ "div",
826
+ {
827
+ className: twMerge(overlayBaseClasses, overlayClassName),
828
+ "aria-hidden": true,
829
+ onClick: () => setOpen(false),
830
+ onMouseDown: (event) => event.preventDefault()
831
+ }
832
+ ) : null,
833
+ /* @__PURE__ */ jsxs(
834
+ "div",
835
+ {
836
+ ...rest,
837
+ ref: mergedRootRef,
838
+ className: twMerge("relative inline-flex min-w-0", className),
839
+ "data-open": open || void 0,
840
+ onMouseEnter: openOnHover ? handleRootMouseEnter : rootMouseEnter,
841
+ onMouseLeave: openOnHover ? handleRootMouseLeave : rootMouseLeave,
842
+ children: [
843
+ activatorElement,
844
+ shouldRenderContent ? /* @__PURE__ */ jsx(
845
+ "div",
846
+ {
847
+ ...restContentProps,
848
+ ref: menuRef,
849
+ id: menuId,
850
+ role: contentRole ?? "menu",
851
+ tabIndex: contentTabIndex ?? -1,
852
+ "aria-labelledby": ariaLabelledBy ?? activatorId,
853
+ "data-state": open ? "open" : "closed",
854
+ className: twMerge(
855
+ menuBaseClasses,
856
+ placementClasses[placement],
857
+ offsetClasses[verticalPlacement],
858
+ contentClassName,
859
+ contentClass
860
+ ),
861
+ style: {
862
+ ...contentStyle,
863
+ ...matchActivatorWidth && activatorWidth ? { minWidth: activatorWidth, width: activatorWidth } : void 0
864
+ },
865
+ onMouseEnter: (event) => {
866
+ contentOnMouseEnter?.(event);
867
+ if (event.defaultPrevented) {
868
+ return;
869
+ }
870
+ if (openOnHover) {
871
+ clearCloseTimeout();
872
+ setOpen(true);
873
+ }
874
+ },
875
+ onMouseLeave: (event) => {
876
+ contentOnMouseLeave?.(event);
877
+ if (event.defaultPrevented) {
878
+ return;
879
+ }
880
+ if (openOnHover) {
881
+ if (isMovingWithinMenu(event)) {
882
+ return;
883
+ }
884
+ scheduleClose();
885
+ }
886
+ },
887
+ onClick: (event) => {
888
+ contentOnClick?.(event);
889
+ if (event.defaultPrevented) {
890
+ return;
891
+ }
892
+ if (closeOnContentClick) {
893
+ setOpen(false);
894
+ }
895
+ },
896
+ children
897
+ }
898
+ ) : null
899
+ ]
900
+ }
901
+ )
902
+ ] });
903
+ });
904
+ Menu.displayName = "Menu";
905
+ var Menu_default = Menu;
135
906
 
136
907
  // src/Form/Input/states.input.ts
137
- var resolveIconClassName2 = (icon) => {
908
+ var resolveIconClassName3 = (icon) => {
138
909
  if (!icon) {
139
910
  return void 0;
140
911
  }
@@ -160,7 +931,7 @@ var resolveIconClassName2 = (icon) => {
160
931
  return Array.from(new Set(classes)).join(" ");
161
932
  };
162
933
  var Input = ({ variant = "outline", success, error, warn, icon, className, ...props }) => {
163
- const classBase = "input-base px-3 py-2 focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed";
934
+ const classBase = "input-base px-3 py-2 focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed w-full";
164
935
  const variantClasses = {
165
936
  outline: "rounded border border-gray-300 focus:border-primary focus:ring-1 focus:ring-primary",
166
937
  filled: "rounded bg-gray-100 border border-gray-300 focus:border-primary focus:ring-1 focus:ring-primary",
@@ -179,7 +950,7 @@ var Input = ({ variant = "outline", success, error, warn, icon, className, ...pr
179
950
  };
180
951
  const variantClass = variantClasses[variant] ?? variantClasses.outline;
181
952
  const toneClass = status ? statusClasses[status.tone] : void 0;
182
- const prependIconClass = resolveIconClassName2(icon);
953
+ const prependIconClass = resolveIconClassName3(icon);
183
954
  const prependPadding = prependIconClass ? "pl-10" : void 0;
184
955
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
185
956
  /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
@@ -191,6 +962,6 @@ var Input = ({ variant = "outline", success, error, warn, icon, className, ...pr
191
962
  };
192
963
  var Input_default = Input;
193
964
 
194
- export { Button_default as Button, Input_default as Input };
965
+ export { Button_default as Button, Chip_default as Chip, Input_default as Input, List_default as List, Item_default as ListItem, Menu_default as Menu };
195
966
  //# sourceMappingURL=index.js.map
196
967
  //# sourceMappingURL=index.js.map