@takeoff-ui/react-spar 0.1.2 → 0.3.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.mjs CHANGED
@@ -1,7 +1,19 @@
1
- import { createContext, Children, isValidElement, useState, useEffect, useMemo, createElement, useContext } from 'react';
2
- import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { Accordion as Accordion$1, AccordionContent as AccordionContent$1, useAccordionItemContext, AccordionTrigger as AccordionTrigger$1, AccordionHeader as AccordionHeader$1, AccordionItem as AccordionItem$1, Checkbox as Checkbox$1, Dialog, DialogClose, DialogDescription, DialogTitle, DialogContent, DialogOverlay, DialogTrigger, Field as Field$1, FieldErrorMessage as FieldErrorMessage$1, FieldDescription as FieldDescription$1, useFieldContext, FieldLabel as FieldLabel$1, Input as Input$1, InputField as InputField$1, useInputContext, Radio as Radio$1, RadioItem as RadioItem$1, Popover as Popover$1, PopoverClose as PopoverClose$1, PopoverArrow as PopoverArrow$1, PopoverContent as PopoverContent$1, PopoverTrigger as PopoverTrigger$1, Select as Select$1, SelectSeparator as SelectSeparator$1, SelectLabel as SelectLabel$1, SelectGroup as SelectGroup$1, SelectItem as SelectItem$1, useSelectContext, SelectContent as SelectContent$1, SelectTrigger as SelectTrigger$1, Switch as Switch$1, Tooltip as Tooltip$1, TooltipArrow as TooltipArrow$1, TooltipContent as TooltipContent$1, TooltipTrigger as TooltipTrigger$1, TooltipProvider as TooltipProvider$1, Button as Button$1 } from '@turkish-technology/spar';
1
+ import { createContext, Children, isValidElement, useMemo, useRef, useState, useCallback, useEffect, useId, createElement, useContext, Fragment as Fragment$1 } from 'react';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { Accordion as Accordion$1, AccordionContent as AccordionContent$1, useAccordionItemContext, AccordionTrigger as AccordionTrigger$1, AccordionHeader as AccordionHeader$1, AccordionItem as AccordionItem$1, Breadcrumb as Breadcrumb$1, BreadcrumbSeparator as BreadcrumbSeparator$1, BreadcrumbPage as BreadcrumbPage$1, BreadcrumbLink as BreadcrumbLink$1, BreadcrumbItem as BreadcrumbItem$1, BreadcrumbList as BreadcrumbList$1, Checkbox as Checkbox$1, Dialog as Dialog$1, DialogClose as DialogClose$1, DialogDescription as DialogDescription$1, DialogTitle as DialogTitle$1, DialogContent, DialogOverlay as DialogOverlay$1, DialogTrigger as DialogTrigger$1, DropdownMenu, DropdownMenuArrow, DropdownMenuSeparator, DropdownMenuLabel, DropdownMenuGroup, DropdownMenuItem, DropdownMenuViewport, useDropdownMenuContext, DropdownMenuContent, DropdownMenuTrigger, Field as Field$1, FieldErrorMessage as FieldErrorMessage$1, FieldDescription as FieldDescription$1, useFieldContext, FieldLabel as FieldLabel$1, Input as Input$1, useInputContext, InputField as InputField$1, Radio as Radio$1, RadioItem as RadioItem$1, Popover as Popover$1, PopoverClose as PopoverClose$1, PopoverArrow as PopoverArrow$1, PopoverContent as PopoverContent$1, PopoverTrigger as PopoverTrigger$1, useOptionalFieldContext, Select as Select$1, SelectArrow as SelectArrow$1, SelectSeparator as SelectSeparator$1, SelectLabel as SelectLabel$1, SelectGroup as SelectGroup$1, SelectItem as SelectItem$1, SelectViewport as SelectViewport$1, useSelectContext, SelectContent as SelectContent$1, SelectTrigger as SelectTrigger$1, Switch as Switch$1, Tabs as Tabs$1, TabsContent as TabsContent$1, TabsTrigger as TabsTrigger$1, TabsList as TabsList$1, Tooltip as Tooltip$1, TooltipArrow as TooltipArrow$1, TooltipContent as TooltipContent$1, TooltipTrigger as TooltipTrigger$1, TooltipProvider as TooltipProvider$1, Button as Button$1, Label as Label$1, Toast as Toast$1, Toaster as Toaster$1 } from '@turkish-technology/spar';
4
+ export { createToaster } from '@turkish-technology/spar';
4
5
  import { clsx } from 'clsx';
6
+ import { ChevronBottomIconOutlinedRounded } from '@takeoff-icons/react/chevron-bottom';
7
+ import { ChevronTopIconOutlinedRounded } from '@takeoff-icons/react/chevron-top';
8
+ import { ChevronRightIconOutlinedRounded } from '@takeoff-icons/react/chevron-right';
9
+ import { CheckIconOutlinedRounded } from '@takeoff-icons/react/check';
10
+ import { CloseIconOutlinedRounded } from '@takeoff-icons/react/close';
11
+ import { useReactTable, getPaginationRowModel, getExpandedRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel, functionalUpdate, flexRender } from '@tanstack/react-table';
12
+ import { SwapIconOutlinedRounded } from '@takeoff-icons/react/swap';
13
+ import { SearchIconOutlinedRounded } from '@takeoff-icons/react/search';
14
+ import { ArrowLeftIconOutlinedRounded } from '@takeoff-icons/react/arrow-left';
15
+ import { ArrowRightIconOutlinedRounded } from '@takeoff-icons/react/arrow-right';
16
+ import { ChevronLeftIconOutlinedRounded } from '@takeoff-icons/react/chevron-left';
5
17
 
6
18
  // src/provider.tsx
7
19
 
@@ -52,6 +64,12 @@ var useComponentTheme = (componentName) => {
52
64
  const context = useContext(TakeoffSparContext);
53
65
  return context?.components?.[componentName];
54
66
  };
67
+
68
+ // src/core/blockDismiss.ts
69
+ var blockDismiss = (handler) => (event) => {
70
+ event.preventDefault();
71
+ handler?.(event);
72
+ };
55
73
  var buildSlotAttrs = (canonicalAttrs, slotKey, layers = {}) => {
56
74
  const { themeSlotProps, themeClassNames, themeClassName, instanceSlotProps, instanceClassNames } = layers;
57
75
  const themeForSlot = themeSlotProps?.[slotKey];
@@ -94,6 +112,9 @@ var composeRootAttrs = (base, props, theme, options) => {
94
112
  rest
95
113
  };
96
114
  };
115
+
116
+ // src/core/isRenderableNode.ts
117
+ var isRenderableNode = (node) => node !== null && node !== void 0 && node !== "" && typeof node !== "boolean";
97
118
  var toDataSlotName = (slot) => slot.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
98
119
  var createComponentBase = (config) => {
99
120
  const { name, slots, classes, defaultProps = {} } = config;
@@ -120,6 +141,16 @@ var createComponentBase = (config) => {
120
141
  resolveProps
121
142
  };
122
143
  };
144
+ var DEFAULT_DISCLOSURE_EXPAND_ICON = /* @__PURE__ */ jsx(ChevronBottomIconOutlinedRounded, {});
145
+ var DEFAULT_DISCLOSURE_COLLAPSE_ICON = /* @__PURE__ */ jsx(ChevronTopIconOutlinedRounded, {});
146
+ var resolveDisclosureIndicator = (children, isOpen) => {
147
+ if (typeof children === "function") return children({ isOpen });
148
+ return children ?? (isOpen ? DEFAULT_DISCLOSURE_COLLAPSE_ICON : DEFAULT_DISCLOSURE_EXPAND_ICON);
149
+ };
150
+ var renderPointerArrow = () => /* @__PURE__ */ jsxs(Fragment, { children: [
151
+ /* @__PURE__ */ jsx("polygon", { className: "tk-arrow-border", points: "0,0 5,5 10,0" }),
152
+ /* @__PURE__ */ jsx("polygon", { className: "tk-arrow-fill", points: "-0.086,-1.5 5,3.586 10.086,-1.5" })
153
+ ] });
123
154
 
124
155
  // src/components/accordion/base.ts
125
156
  var AccordionBase = createComponentBase({
@@ -170,6 +201,52 @@ function createSafeContext(displayName) {
170
201
  };
171
202
  return [Provider, useSafeContext];
172
203
  }
204
+ var resolveStaticWidth = (mode) => {
205
+ if (mode === "trigger" || mode === "content") return void 0;
206
+ return typeof mode === "number" ? `${mode}px` : mode;
207
+ };
208
+ var useContentWidthStyle = (mode, triggerRef) => {
209
+ const [triggerWidth, setTriggerWidth] = useState(null);
210
+ useEffect(() => {
211
+ if (mode !== "trigger") return;
212
+ const node = triggerRef.current;
213
+ if (!node) return;
214
+ const measure = () => setTriggerWidth(Math.round(node.getBoundingClientRect().width));
215
+ measure();
216
+ let frame = 0;
217
+ const observer = new ResizeObserver(() => {
218
+ cancelAnimationFrame(frame);
219
+ frame = requestAnimationFrame(measure);
220
+ });
221
+ observer.observe(node);
222
+ return () => {
223
+ cancelAnimationFrame(frame);
224
+ observer.disconnect();
225
+ };
226
+ }, [mode, triggerRef]);
227
+ return useMemo(() => {
228
+ if (mode === "trigger") {
229
+ return triggerWidth != null ? { width: triggerWidth } : void 0;
230
+ }
231
+ const staticWidth = resolveStaticWidth(mode);
232
+ return staticWidth != null ? { width: staticWidth } : void 0;
233
+ }, [mode, triggerWidth]);
234
+ };
235
+ function useControllableState(controlledValue, defaultValue, onChange) {
236
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
237
+ const { current: isControlled } = useRef(controlledValue !== void 0);
238
+ const value = isControlled ? controlledValue : uncontrolledValue;
239
+ const setValue = useCallback(
240
+ (newValue) => {
241
+ if (!isControlled) {
242
+ setUncontrolledValue(newValue);
243
+ }
244
+ onChange?.(newValue);
245
+ },
246
+ [isControlled, onChange]
247
+ );
248
+ return [value, setValue];
249
+ }
173
250
 
174
251
  // src/components/accordion/context.ts
175
252
  var [AccordionProvider, useAccordionOwnContext] = createSafeContext("AccordionProvider");
@@ -222,15 +299,13 @@ var AccordionHeader = (props) => {
222
299
  return /* @__PURE__ */ jsx(AccordionHeader$1, { ...spar, level, ...rootAttrs, ref, children });
223
300
  };
224
301
  AccordionHeader.displayName = "Accordion.Header";
225
- var DEFAULT_EXPAND_ICON = /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: "M4 6L8 10L12 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
226
- var DEFAULT_COLLAPSE_ICON = /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: "M4 10L8 6L12 10", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
227
302
  var AccordionIndicator = (props) => {
228
303
  const theme = useComponentTheme("AccordionIndicator");
229
304
  const { isOpen } = useAccordionItemContext();
230
305
  const Component = props.as ?? "span";
231
306
  const { rootAttrs, rest } = composeRootAttrs(AccordionIndicatorBase, props, theme);
232
307
  const { as: _as, children, ref, ...rendered } = rest;
233
- const resolved = typeof children === "function" ? children({ isOpen }) : children ?? (isOpen ? DEFAULT_COLLAPSE_ICON : DEFAULT_EXPAND_ICON);
308
+ const resolved = resolveDisclosureIndicator(children, isOpen);
234
309
  return /* @__PURE__ */ jsx(Component, { ...rendered, ref, "aria-hidden": "true", ...rootAttrs, children: resolved });
235
310
  };
236
311
  AccordionIndicator.displayName = "Accordion.Indicator";
@@ -287,6 +362,161 @@ var Accordion2 = Object.assign(Accordion, {
287
362
  Content: AccordionContent
288
363
  });
289
364
 
365
+ // src/components/alert/base.ts
366
+ var AlertBase = createComponentBase({
367
+ name: "Alert",
368
+ slots: ["root"],
369
+ classes: { root: "tk-alert" }
370
+ });
371
+ var AlertContentBase = createComponentBase({
372
+ name: "AlertContent",
373
+ slots: ["root"],
374
+ classes: { root: "tk-alert-content" }
375
+ });
376
+ var AlertTitleBase = createComponentBase({
377
+ name: "AlertTitle",
378
+ slots: ["root"],
379
+ classes: { root: "tk-alert-title" }
380
+ });
381
+ var AlertDescriptionBase = createComponentBase({
382
+ name: "AlertDescription",
383
+ slots: ["root"],
384
+ classes: { root: "tk-alert-description" }
385
+ });
386
+ var AlertActionsBase = createComponentBase({
387
+ name: "AlertActions",
388
+ slots: ["root"],
389
+ classes: { root: "tk-alert-actions" }
390
+ });
391
+ var AlertCloseBase = createComponentBase({
392
+ name: "AlertClose",
393
+ slots: ["root"],
394
+ classes: { root: "tk-alert-close" }
395
+ });
396
+
397
+ // src/components/alert/context.ts
398
+ var [AlertProvider, useAlertContext] = createSafeContext("AlertProvider");
399
+
400
+ // src/components/alert/defaults.ts
401
+ var DEFAULT_VARIANT = "neutral";
402
+ var DEFAULT_APPEARANCE = "filled";
403
+ var DEFAULT_CLOSE_LABEL = "Close";
404
+ var Alert = (props) => {
405
+ const theme = useComponentTheme("Alert");
406
+ const { rootAttrs, rest } = composeRootAttrs(AlertBase, props, theme, {
407
+ stateAttrs: ({ variant = DEFAULT_VARIANT, appearance = DEFAULT_APPEARANCE }) => ({
408
+ "data-variant": variant,
409
+ "data-type": appearance
410
+ })
411
+ });
412
+ const { as, variant: _variant, appearance: _appearance, onClose, children, ref, role = "status", ...alertProps } = rest;
413
+ const Component = as ?? "div";
414
+ return /* @__PURE__ */ jsx(AlertProvider, { value: { onClose }, children: /* @__PURE__ */ jsx(Component, { ...alertProps, ref, role, ...rootAttrs, children }) });
415
+ };
416
+ Alert.displayName = "Alert";
417
+ var AlertActions = (props) => {
418
+ const theme = useComponentTheme("AlertActions");
419
+ const { rootAttrs, rest } = composeRootAttrs(AlertActionsBase, props, theme);
420
+ const { as, children, ref, ...actionsProps } = rest;
421
+ const Component = as ?? "div";
422
+ return /* @__PURE__ */ jsx(Component, { ...actionsProps, ref, ...rootAttrs, children });
423
+ };
424
+ AlertActions.displayName = "Alert.Actions";
425
+ var baseSvgProps = {
426
+ "xmlns": "http://www.w3.org/2000/svg",
427
+ "width": "1em",
428
+ "height": "1em",
429
+ "viewBox": "0 0 24 24",
430
+ "fill": "none",
431
+ "stroke": "currentColor",
432
+ "strokeWidth": 2,
433
+ "strokeLinecap": "round",
434
+ "strokeLinejoin": "round",
435
+ "focusable": false,
436
+ "aria-hidden": true
437
+ };
438
+ var filledSvgProps = {
439
+ "xmlns": "http://www.w3.org/2000/svg",
440
+ "width": "1em",
441
+ "height": "1em",
442
+ "viewBox": "0 0 24 24",
443
+ "fill": "currentColor",
444
+ "focusable": false,
445
+ "aria-hidden": true
446
+ };
447
+ var PlaceholderChevronDown = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "chevron-down", ...props, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
448
+ var PlaceholderChevronUp = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "chevron-up", ...props, children: /* @__PURE__ */ jsx("path", { d: "m18 15-6-6-6 6" }) });
449
+ var PlaceholderClose = (props) => /* @__PURE__ */ jsxs("svg", { ...baseSvgProps, "data-placeholder-icon": "close", ...props, children: [
450
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
451
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
452
+ ] });
453
+ var PlaceholderInfo = (props) => /* @__PURE__ */ jsx("svg", { ...filledSvgProps, "data-placeholder-icon": "info", ...props, children: /* @__PURE__ */ jsx("g", { transform: "translate(2 2) scale(1.714)", children: /* @__PURE__ */ jsx("path", { d: "M5.83333 0C2.61333 0 0 2.61333 0 5.83333C0 9.05333 2.61333 11.6667 5.83333 11.6667C9.05333 11.6667 11.6667 9.05333 11.6667 5.83333C11.6667 2.61333 9.05333 0 5.83333 0ZM5.83333 8.75C5.5125 8.75 5.25 8.4875 5.25 8.16667V5.83333C5.25 5.5125 5.5125 5.25 5.83333 5.25C6.15417 5.25 6.41667 5.5125 6.41667 5.83333V8.16667C6.41667 8.4875 6.15417 8.75 5.83333 8.75ZM6.41667 4.08333H5.25V2.91667H6.41667V4.08333Z" }) }) });
454
+ var PlaceholderError = (props) => /* @__PURE__ */ jsx("svg", { ...filledSvgProps, "data-placeholder-icon": "error", ...props, children: /* @__PURE__ */ jsx("g", { transform: "translate(2 2) scale(1.714)", fillRule: "evenodd", clipRule: "evenodd", children: /* @__PURE__ */ jsx("path", { d: "M5.83333 0C2.61333 0 0 2.61333 0 5.83333C0 9.05333 2.61333 11.6667 5.83333 11.6667C9.05333 11.6667 11.6667 9.05333 11.6667 5.83333C11.6667 2.61333 9.05333 0 5.83333 0ZM5.83333 2.91667C6.15417 2.91667 6.41667 3.17917 6.41667 3.5V5.83333C6.41667 6.15417 6.15417 6.41667 5.83333 6.41667C5.5125 6.41667 5.25 6.15417 5.25 5.83333V3.5C5.25 3.17917 5.5125 2.91667 5.83333 2.91667ZM5.25 7.58333H6.41667V8.75H5.25V7.58333Z" }) }) });
455
+ var PlaceholderCheck = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "check", ...props, children: /* @__PURE__ */ jsx("path", { d: "M5 12l5 5L20 7" }) });
456
+ var PlaceholderRemove = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "remove", ...props, children: /* @__PURE__ */ jsx("path", { d: "M5 12h14" }) });
457
+ var PlaceholderEye = (props) => /* @__PURE__ */ jsx("svg", { ...filledSvgProps, "data-placeholder-icon": "eye", ...props, children: /* @__PURE__ */ jsx("g", { transform: "translate(1 4.5) scale(1.2)", fillRule: "evenodd", clipRule: "evenodd", children: /* @__PURE__ */ jsx("path", { d: "M9.16667 1.66667C12.325 1.66667 15.1417 3.44167 16.5167 6.25C15.1417 9.05833 12.325 10.8333 9.16667 10.8333C6.00833 10.8333 3.19167 9.05833 1.81667 6.25C3.19167 3.44167 6.00833 1.66667 9.16667 1.66667ZM9.16667 0C5 0 1.44167 2.59167 0 6.25C1.44167 9.90833 5 12.5 9.16667 12.5C13.3333 12.5 16.8917 9.90833 18.3333 6.25C16.8917 2.59167 13.3333 0 9.16667 0ZM9.16667 4.16667C10.3167 4.16667 11.25 5.1 11.25 6.25C11.25 7.4 10.3167 8.33333 9.16667 8.33333C8.01667 8.33333 7.08333 7.4 7.08333 6.25C7.08333 5.1 8.01667 4.16667 9.16667 4.16667ZM9.16667 2.5C7.1 2.5 5.41667 4.18333 5.41667 6.25C5.41667 8.31667 7.1 10 9.16667 10C11.2333 10 12.9167 8.31667 12.9167 6.25C12.9167 4.18333 11.2333 2.5 9.16667 2.5Z" }) }) });
458
+ var PlaceholderEyeOff = (props) => /* @__PURE__ */ jsx("svg", { ...filledSvgProps, "data-placeholder-icon": "eye-off", ...props, children: /* @__PURE__ */ jsx("g", { transform: "translate(1 2.42) scale(1.2)", fillRule: "evenodd", clipRule: "evenodd", children: /* @__PURE__ */ jsx("path", { d: "M9.16667 2.95833C12.325 2.95833 15.1417 4.73333 16.5167 7.54167C16.025 8.55833 15.3333 9.43333 14.5083 10.1417L15.6833 11.3167C16.8417 10.2917 17.7583 9.00833 18.3333 7.54167C16.8917 3.88333 13.3333 1.29167 9.16667 1.29167C8.10833 1.29167 7.09167 1.45833 6.13333 1.76667L7.50833 3.14167C8.05 3.03333 8.6 2.95833 9.16667 2.95833ZM8.275 3.90833L10 5.63333C10.475 5.84167 10.8583 6.225 11.0667 6.7L12.7917 8.425C12.8583 8.14167 12.9083 7.84167 12.9083 7.53333C12.9167 5.46667 11.2333 3.79167 9.16667 3.79167C8.85833 3.79167 8.56667 3.83333 8.275 3.90833ZM0.841667 1.18333L3.075 3.41667C1.71667 4.48333 0.641667 5.9 0 7.54167C1.44167 11.2 5 13.7917 9.16667 13.7917C10.4333 13.7917 11.65 13.55 12.7667 13.1083L15.6167 15.9583L16.7917 14.7833L2.01667 0L0.841667 1.18333ZM7.09167 7.43333L9.26667 9.60833C9.23333 9.61667 9.2 9.625 9.16667 9.625C8.01667 9.625 7.08333 8.69167 7.08333 7.54167C7.08333 7.5 7.09167 7.475 7.09167 7.43333ZM4.25833 4.6L5.71667 6.05833C5.525 6.51667 5.41667 7.01667 5.41667 7.54167C5.41667 9.60833 7.1 11.2917 9.16667 11.2917C9.69167 11.2917 10.1917 11.1833 10.6417 10.9917L11.4583 11.8083C10.725 12.0083 9.95833 12.125 9.16667 12.125C6.00833 12.125 3.19167 10.35 1.81667 7.54167C2.4 6.35 3.25 5.36667 4.25833 4.6Z" }) }) });
459
+ var AlertClose = (props) => {
460
+ const theme = useComponentTheme("AlertClose");
461
+ const { onClose } = useAlertContext("Alert.Close");
462
+ const { rootAttrs, rest } = composeRootAttrs(AlertCloseBase, props, theme);
463
+ const { as, children, onClick, ref, type, "aria-label": ariaLabel, ...closeProps } = rest;
464
+ const { onClick: slotOnClick, ...closeRootAttrs } = rootAttrs;
465
+ const Component = as ?? "button";
466
+ const handleClick = (event) => {
467
+ onClick?.(event);
468
+ slotOnClick?.(event);
469
+ onClose?.();
470
+ };
471
+ const hasCustomChildren = isRenderableNode(children);
472
+ return /* @__PURE__ */ jsx(
473
+ Component,
474
+ {
475
+ ...closeProps,
476
+ ref,
477
+ type: as ? type : type ?? "button",
478
+ "aria-label": ariaLabel ?? (hasCustomChildren ? void 0 : DEFAULT_CLOSE_LABEL),
479
+ onClick: handleClick,
480
+ ...closeRootAttrs,
481
+ children: hasCustomChildren ? children : /* @__PURE__ */ jsx(PlaceholderClose, {})
482
+ }
483
+ );
484
+ };
485
+ AlertClose.displayName = "Alert.Close";
486
+ var AlertContent = (props) => {
487
+ const theme = useComponentTheme("AlertContent");
488
+ const { rootAttrs, rest } = composeRootAttrs(AlertContentBase, props, theme);
489
+ const { as, children, ref, ...contentProps } = rest;
490
+ const Component = as ?? "div";
491
+ return /* @__PURE__ */ jsx(Component, { ...contentProps, ref, ...rootAttrs, children });
492
+ };
493
+ AlertContent.displayName = "Alert.Content";
494
+ var AlertDescription = (props) => {
495
+ const theme = useComponentTheme("AlertDescription");
496
+ const { rootAttrs, rest } = composeRootAttrs(AlertDescriptionBase, props, theme);
497
+ const { as, children, ref, ...descriptionProps } = rest;
498
+ const Component = as ?? "p";
499
+ return /* @__PURE__ */ jsx(Component, { ...descriptionProps, ref, ...rootAttrs, children });
500
+ };
501
+ AlertDescription.displayName = "Alert.Description";
502
+ var AlertTitle = (props) => {
503
+ const theme = useComponentTheme("AlertTitle");
504
+ const { rootAttrs, rest } = composeRootAttrs(AlertTitleBase, props, theme);
505
+ const { as, level = 5, children, ref, ...titleProps } = rest;
506
+ const Component = as ?? `h${level}`;
507
+ return /* @__PURE__ */ jsx(Component, { ...titleProps, ref, ...rootAttrs, children });
508
+ };
509
+ AlertTitle.displayName = "Alert.Title";
510
+
511
+ // src/components/alert/index.ts
512
+ var Alert2 = Object.assign(Alert, {
513
+ Content: AlertContent,
514
+ Title: AlertTitle,
515
+ Description: AlertDescription,
516
+ Actions: AlertActions,
517
+ Close: AlertClose
518
+ });
519
+
290
520
  // src/components/badge/base.ts
291
521
  var BadgeBase = createComponentBase({
292
522
  name: "Badge",
@@ -299,13 +529,13 @@ var BadgeBase = createComponentBase({
299
529
  });
300
530
 
301
531
  // src/components/badge/defaults.ts
302
- var DEFAULT_VARIANT = "primary";
303
- var DEFAULT_APPEARANCE = "filled";
532
+ var DEFAULT_VARIANT2 = "primary";
533
+ var DEFAULT_APPEARANCE2 = "filled";
304
534
  var DEFAULT_SIZE2 = "base";
305
535
  var Badge = (props) => {
306
536
  const theme = useComponentTheme("Badge");
307
537
  const { rootAttrs, rest } = composeRootAttrs(BadgeBase, props, theme, {
308
- stateAttrs: ({ variant = DEFAULT_VARIANT, appearance = DEFAULT_APPEARANCE, size = DEFAULT_SIZE2, rounded, dot: dot2 }) => ({
538
+ stateAttrs: ({ variant = DEFAULT_VARIANT2, appearance = DEFAULT_APPEARANCE2, size = DEFAULT_SIZE2, rounded, dot: dot2 }) => ({
309
539
  "data-variant": variant,
310
540
  "data-type": appearance,
311
541
  "data-size": dot2 ? void 0 : size,
@@ -330,13 +560,109 @@ var Badge = (props) => {
330
560
  return /* @__PURE__ */ jsx("span", { ...nativeProps, ...rootAttrs, ref });
331
561
  }
332
562
  return /* @__PURE__ */ jsxs("span", { ...nativeProps, ...rootAttrs, ref, children: [
333
- startContent && /* @__PURE__ */ jsx("span", { ...iconSlotAttrs, children: startContent }),
334
- children && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }),
335
- endContent && /* @__PURE__ */ jsx("span", { ...iconSlotAttrs, children: endContent })
563
+ isRenderableNode(startContent) && /* @__PURE__ */ jsx("span", { ...iconSlotAttrs, children: startContent }),
564
+ isRenderableNode(children) && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }),
565
+ isRenderableNode(endContent) && /* @__PURE__ */ jsx("span", { ...iconSlotAttrs, children: endContent })
336
566
  ] });
337
567
  };
338
568
  Badge.displayName = "Badge";
339
569
 
570
+ // src/components/breadcrumb/base.ts
571
+ var BreadcrumbBase = createComponentBase({
572
+ name: "Breadcrumb",
573
+ slots: ["root"],
574
+ classes: { root: "tk-breadcrumb" }
575
+ });
576
+ var BreadcrumbListBase = createComponentBase({
577
+ name: "BreadcrumbList",
578
+ slots: ["root"],
579
+ classes: { root: "tk-breadcrumb-list" }
580
+ });
581
+ var BreadcrumbItemBase = createComponentBase({
582
+ name: "BreadcrumbItem",
583
+ slots: ["root"],
584
+ classes: { root: "tk-breadcrumb-item" }
585
+ });
586
+ var BreadcrumbLinkBase = createComponentBase({
587
+ name: "BreadcrumbLink",
588
+ slots: ["root"],
589
+ classes: { root: "tk-breadcrumb-link" }
590
+ });
591
+ var BreadcrumbPageBase = createComponentBase({
592
+ name: "BreadcrumbPage",
593
+ slots: ["root"],
594
+ classes: { root: "tk-breadcrumb-page" }
595
+ });
596
+ var BreadcrumbSeparatorBase = createComponentBase({
597
+ name: "BreadcrumbSeparator",
598
+ slots: ["root"],
599
+ classes: { root: "tk-breadcrumb-separator" }
600
+ });
601
+
602
+ // src/components/breadcrumb/context.ts
603
+ var [BreadcrumbProvider] = createSafeContext("BreadcrumbProvider");
604
+
605
+ // src/components/breadcrumb/defaults.ts
606
+ var DEFAULT_SIZE3 = "base";
607
+ var DEFAULT_TYPE2 = "basic";
608
+ var Breadcrumb = (props) => {
609
+ const theme = useComponentTheme("Breadcrumb");
610
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbBase, props, theme, {
611
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE3, type: type2 = DEFAULT_TYPE2 }) => ({
612
+ "data-size": size2,
613
+ "data-type": type2
614
+ })
615
+ });
616
+ const { size = DEFAULT_SIZE3, type = DEFAULT_TYPE2, children, ref, ...sparProps } = rest;
617
+ const contextValue = useMemo(() => ({ size, type }), [size, type]);
618
+ return /* @__PURE__ */ jsx(BreadcrumbProvider, { value: contextValue, children: /* @__PURE__ */ jsx(Breadcrumb$1, { ...sparProps, ref, ...rootAttrs, children }) });
619
+ };
620
+ Breadcrumb.displayName = "Breadcrumb";
621
+ var BreadcrumbList = (props) => {
622
+ const theme = useComponentTheme("BreadcrumbList");
623
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbListBase, props, theme);
624
+ const { children, ref, ...spar } = rest;
625
+ return /* @__PURE__ */ jsx(BreadcrumbList$1, { ...spar, ref, ...rootAttrs, children });
626
+ };
627
+ BreadcrumbList.displayName = "Breadcrumb.List";
628
+ var BreadcrumbItem = (props) => {
629
+ const theme = useComponentTheme("BreadcrumbItem");
630
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbItemBase, props, theme);
631
+ const { children, ref, ...spar } = rest;
632
+ return /* @__PURE__ */ jsx(BreadcrumbItem$1, { ...spar, ref, ...rootAttrs, children });
633
+ };
634
+ BreadcrumbItem.displayName = "Breadcrumb.Item";
635
+ var BreadcrumbLink = (props) => {
636
+ const theme = useComponentTheme("BreadcrumbLink");
637
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbLinkBase, props, theme);
638
+ const { children, ref, ...spar } = rest;
639
+ return /* @__PURE__ */ jsx(BreadcrumbLink$1, { ...spar, ref, ...rootAttrs, children });
640
+ };
641
+ BreadcrumbLink.displayName = "Breadcrumb.Link";
642
+ var BreadcrumbPage = (props) => {
643
+ const theme = useComponentTheme("BreadcrumbPage");
644
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbPageBase, props, theme);
645
+ const { children, ref, ...spar } = rest;
646
+ return /* @__PURE__ */ jsx(BreadcrumbPage$1, { ...spar, ref, ...rootAttrs, children });
647
+ };
648
+ BreadcrumbPage.displayName = "Breadcrumb.Page";
649
+ var BreadcrumbSeparator = (props) => {
650
+ const theme = useComponentTheme("BreadcrumbSeparator");
651
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbSeparatorBase, props, theme);
652
+ const { children, ref, ...spar } = rest;
653
+ return /* @__PURE__ */ jsx(BreadcrumbSeparator$1, { ...spar, ref, ...rootAttrs, children: children ?? /* @__PURE__ */ jsx(ChevronRightIconOutlinedRounded, { "aria-hidden": "true", focusable: "false" }) });
654
+ };
655
+ BreadcrumbSeparator.displayName = "Breadcrumb.Separator";
656
+
657
+ // src/components/breadcrumb/index.ts
658
+ var Breadcrumb2 = Object.assign(Breadcrumb, {
659
+ List: BreadcrumbList,
660
+ Item: BreadcrumbItem,
661
+ Link: BreadcrumbLink,
662
+ Page: BreadcrumbPage,
663
+ Separator: BreadcrumbSeparator
664
+ });
665
+
340
666
  // src/components/button/base.ts
341
667
  var ButtonBase = createComponentBase({
342
668
  name: "Button",
@@ -350,9 +676,9 @@ var ButtonBase = createComponentBase({
350
676
  });
351
677
 
352
678
  // src/components/button/defaults.ts
353
- var DEFAULT_VARIANT2 = "primary";
354
- var DEFAULT_APPEARANCE2 = "filled";
355
- var DEFAULT_SIZE3 = "base";
679
+ var DEFAULT_VARIANT3 = "primary";
680
+ var DEFAULT_APPEARANCE3 = "filled";
681
+ var DEFAULT_SIZE4 = "base";
356
682
  var Button = (props) => {
357
683
  const theme = useComponentTheme("Button");
358
684
  const { rootAttrs, rest } = composeRootAttrs(ButtonBase, props, theme, {
@@ -360,9 +686,9 @@ var Button = (props) => {
360
686
  // Spar's Button already emits them (see SparButton dataAttributes), so
361
687
  // setting them again would create two sources of truth that drift the
362
688
  // moment Spar renames or extends its vocabulary.
363
- stateAttrs: ({ variant = DEFAULT_VARIANT2, appearance = DEFAULT_APPEARANCE2, size = DEFAULT_SIZE3, rounded, startContent: startContent2, endContent: endContent2, children: children2 }) => {
364
- const hasIcon = !!(startContent2 || endContent2);
365
- const isIconOnly = hasIcon && !children2;
689
+ stateAttrs: ({ variant = DEFAULT_VARIANT3, appearance = DEFAULT_APPEARANCE3, size = DEFAULT_SIZE4, rounded, startContent: startContent2, endContent: endContent2, children: children2 }) => {
690
+ const hasIcon = isRenderableNode(startContent2) || isRenderableNode(endContent2);
691
+ const isIconOnly = hasIcon && !isRenderableNode(children2);
366
692
  return {
367
693
  "data-variant": variant,
368
694
  "data-type": appearance,
@@ -380,7 +706,8 @@ var Button = (props) => {
380
706
  appearance: _appearance,
381
707
  size: _size,
382
708
  rounded: _rounded,
383
- isLoading = false,
709
+ loading = false,
710
+ pressed,
384
711
  startContent,
385
712
  endContent,
386
713
  disabled = false,
@@ -406,15 +733,122 @@ var Button = (props) => {
406
733
  instanceSlotProps: props.slotProps,
407
734
  instanceClassNames: props.classNames
408
735
  });
409
- return /* @__PURE__ */ jsxs(Button$1, { ...sparProps, disabled, isLoading, ref, ...rootAttrs, children: [
410
- isLoading && /* @__PURE__ */ jsx("span", { ...spinnerSlotAttrs }),
411
- startContent && !isLoading && /* @__PURE__ */ jsx("span", { ...contentSlotAttrs, children: startContent }),
412
- children && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }),
413
- endContent && !isLoading && /* @__PURE__ */ jsx("span", { ...contentSlotAttrs, children: endContent })
736
+ return /* @__PURE__ */ jsxs(Button$1, { ...sparProps, disabled, isLoading: loading, isPressed: pressed, ref, ...rootAttrs, children: [
737
+ loading && /* @__PURE__ */ jsx("span", { ...spinnerSlotAttrs }),
738
+ isRenderableNode(startContent) && !loading && /* @__PURE__ */ jsx("span", { ...contentSlotAttrs, children: startContent }),
739
+ isRenderableNode(children) && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }),
740
+ isRenderableNode(endContent) && !loading && /* @__PURE__ */ jsx("span", { ...contentSlotAttrs, children: endContent })
414
741
  ] });
415
742
  };
416
743
  Button.displayName = "Button";
417
744
 
745
+ // src/components/card/base.ts
746
+ var CardBase = createComponentBase({
747
+ name: "Card",
748
+ slots: ["root"],
749
+ classes: { root: "tk-card" }
750
+ });
751
+ var CardHeaderBase = createComponentBase({
752
+ name: "CardHeader",
753
+ slots: ["root"],
754
+ classes: { root: "tk-card-header" }
755
+ });
756
+ var CardTitleBase = createComponentBase({
757
+ name: "CardTitle",
758
+ slots: ["root"],
759
+ classes: { root: "tk-card-title" }
760
+ });
761
+ var CardDescriptionBase = createComponentBase({
762
+ name: "CardDescription",
763
+ slots: ["root"],
764
+ classes: { root: "tk-card-description" }
765
+ });
766
+ var CardBodyBase = createComponentBase({
767
+ name: "CardBody",
768
+ slots: ["root"],
769
+ classes: { root: "tk-card-body" }
770
+ });
771
+ var CardFooterBase = createComponentBase({
772
+ name: "CardFooter",
773
+ slots: ["root"],
774
+ classes: { root: "tk-card-footer" }
775
+ });
776
+ var Card = (props) => {
777
+ const theme = useComponentTheme("Card");
778
+ const { rootAttrs, rest } = composeRootAttrs(CardBase, props, theme);
779
+ const { as, children, ref, ...cardProps } = rest;
780
+ const Component = as ?? "div";
781
+ return /* @__PURE__ */ jsx(Component, { ...cardProps, ref, ...rootAttrs, children });
782
+ };
783
+ Card.displayName = "Card";
784
+
785
+ // src/components/card/defaults.ts
786
+ var DEFAULT_HEADER_TYPE = "basic";
787
+ var DEFAULT_FOOTER_TYPE = "basic";
788
+ var CardHeader = (props) => {
789
+ const theme = useComponentTheme("CardHeader");
790
+ const { rootAttrs, rest } = composeRootAttrs(CardHeaderBase, props, theme, {
791
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE }) => ({
792
+ "data-header-type": headerType
793
+ })
794
+ });
795
+ const { as, headerType: _headerType, children, ref, ...headerProps } = rest;
796
+ const Component = as ?? "div";
797
+ return /* @__PURE__ */ jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
798
+ };
799
+ CardHeader.displayName = "CardHeader";
800
+ var CardTitle = (props) => {
801
+ const theme = useComponentTheme("CardTitle");
802
+ const { rootAttrs, rest } = composeRootAttrs(CardTitleBase, props, theme, {
803
+ // `data-level` reflects the rendered heading element, so emit it only when
804
+ // `level` actually drives the element — i.e. when `as` is not overriding it.
805
+ stateAttrs: ({ as: as2, level: level2 = 5 }) => ({
806
+ "data-level": as2 ? void 0 : String(level2)
807
+ })
808
+ });
809
+ const { as, level = 5, children, ref, ...titleProps } = rest;
810
+ const Component = as ?? `h${level}`;
811
+ return /* @__PURE__ */ jsx(Component, { ...titleProps, ref, ...rootAttrs, children });
812
+ };
813
+ CardTitle.displayName = "CardTitle";
814
+ var CardDescription = (props) => {
815
+ const theme = useComponentTheme("CardDescription");
816
+ const { rootAttrs, rest } = composeRootAttrs(CardDescriptionBase, props, theme);
817
+ const { as, children, ref, ...descriptionProps } = rest;
818
+ const Component = as ?? "p";
819
+ return /* @__PURE__ */ jsx(Component, { ...descriptionProps, ref, ...rootAttrs, children });
820
+ };
821
+ CardDescription.displayName = "CardDescription";
822
+ var CardBody = (props) => {
823
+ const theme = useComponentTheme("CardBody");
824
+ const { rootAttrs, rest } = composeRootAttrs(CardBodyBase, props, theme);
825
+ const { as, children, ref, ...bodyProps } = rest;
826
+ const Component = as ?? "div";
827
+ return /* @__PURE__ */ jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
828
+ };
829
+ CardBody.displayName = "CardBody";
830
+ var CardFooter = (props) => {
831
+ const theme = useComponentTheme("CardFooter");
832
+ const { rootAttrs, rest } = composeRootAttrs(CardFooterBase, props, theme, {
833
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE }) => ({
834
+ "data-footer-type": footerType
835
+ })
836
+ });
837
+ const { as, footerType: _footerType, children, ref, ...footerProps } = rest;
838
+ const Component = as ?? "div";
839
+ return /* @__PURE__ */ jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
840
+ };
841
+ CardFooter.displayName = "CardFooter";
842
+
843
+ // src/components/card/index.ts
844
+ var Card2 = Object.assign(Card, {
845
+ Header: CardHeader,
846
+ Title: CardTitle,
847
+ Description: CardDescription,
848
+ Body: CardBody,
849
+ Footer: CardFooter
850
+ });
851
+
418
852
  // src/components/checkbox/base.ts
419
853
  var CheckboxBase = createComponentBase({
420
854
  name: "Checkbox",
@@ -432,14 +866,12 @@ var CheckboxBase = createComponentBase({
432
866
  var [CheckboxProvider, useCheckboxOwnContext] = createSafeContext("CheckboxProvider");
433
867
 
434
868
  // src/components/checkbox/defaults.ts
435
- var DEFAULT_SIZE4 = "base";
436
- var DEFAULT_TYPE2 = "default";
869
+ var DEFAULT_SIZE5 = "base";
437
870
  var Checkbox = (props) => {
438
871
  const theme = useComponentTheme("Checkbox");
439
872
  const { rootAttrs, rest } = composeRootAttrs(CheckboxBase, props, theme, {
440
- stateAttrs: ({ size = DEFAULT_SIZE4, type = DEFAULT_TYPE2 }) => ({
441
- "data-size": size,
442
- "data-type": type
873
+ stateAttrs: ({ size = DEFAULT_SIZE5 }) => ({
874
+ "data-size": size
443
875
  })
444
876
  });
445
877
  const { classNames, slotProps } = props;
@@ -447,74 +879,49 @@ var Checkbox = (props) => {
447
879
  // Visual props are consumed via `stateAttrs`; destructured to keep them
448
880
  // off the rendered DOM where they would leak as raw HTML attributes.
449
881
  size: _size,
450
- type: _type,
451
- // `invalid` is forwarded to Spar as `invalid` (same name).
452
- invalid = false,
453
882
  // takeoff-spar tri-state vocabulary; mapped to Spar's `CheckedState` below.
454
883
  checked,
455
884
  defaultChecked,
456
885
  indeterminate = false,
457
886
  onChange,
458
- // Behavior props owned by Spar — defaults are restated here so they also
459
- // flow into the context for compound sub-components (asterisk on Label).
460
- disabled = false,
461
- readOnly = false,
462
- required = false,
463
887
  children,
464
888
  ref,
889
+ // `invalid`, `disabled`, `readOnly` and `required` are intentionally NOT
890
+ // destructured (so no eager `= false` default is applied) — they flow to
891
+ // Spar via `...sparProps` untouched. Defaulting them here would turn an
892
+ // omitted prop into an explicit `false`, defeating Spar's
893
+ // `prop ?? fieldCtx?.x` inheritance and silently overriding a wrapping
894
+ // `<Field disabled>`. Their resolved values are read back off Spar's
895
+ // render-prop `state` below for the compound context. See Radio/Input/
896
+ // Select wrappers for the same pass-through pattern.
465
897
  ...sparProps
466
898
  } = rest;
467
899
  const sparChecked = indeterminate ? "indeterminate" : checked;
468
900
  const sparDefaultChecked = indeterminate ? "indeterminate" : defaultChecked;
469
901
  const handleSparChange = onChange ? (next) => onChange(next === true) : void 0;
470
- return /* @__PURE__ */ jsx(
471
- Checkbox$1,
902
+ return /* @__PURE__ */ jsx(Checkbox$1, { ...sparProps, checked: sparChecked, defaultChecked: sparDefaultChecked, onChange: handleSparChange, ref, ...rootAttrs, children: (state) => /* @__PURE__ */ jsx(
903
+ CheckboxProvider,
472
904
  {
473
- ...sparProps,
474
- checked: sparChecked,
475
- defaultChecked: sparDefaultChecked,
476
- onChange: handleSparChange,
477
- disabled,
478
- readOnly,
479
- required,
480
- invalid,
481
- ref,
482
- ...rootAttrs,
483
- children: (state) => /* @__PURE__ */ jsx(
484
- CheckboxProvider,
485
- {
486
- value: {
487
- classNames,
488
- slotProps,
489
- required,
490
- invalid,
491
- disabled: state.disabled,
492
- readOnly: state.readOnly,
493
- checked: state.checked === true,
494
- indeterminate: state.checked === "indeterminate"
495
- },
496
- children: typeof children === "function" ? children(state) : children
497
- }
498
- )
905
+ value: {
906
+ classNames,
907
+ slotProps,
908
+ // Read the *resolved* behavior state off Spar's render-prop so the
909
+ // compound context reflects Field-inherited values, not the raw
910
+ // props. `state.required` / `state.invalid` already fold in
911
+ // `fieldCtx`, so `<Field disabled>` / `<Field invalid>` reach the
912
+ // Label asterisk and slotted styling correctly.
913
+ required: state.required,
914
+ invalid: state.invalid,
915
+ disabled: state.disabled,
916
+ readOnly: state.readOnly,
917
+ checked: state.checked === true,
918
+ indeterminate: state.checked === "indeterminate"
919
+ },
920
+ children: typeof children === "function" ? children(state) : children
499
921
  }
500
- );
922
+ ) });
501
923
  };
502
924
  Checkbox.displayName = "Checkbox";
503
- var baseSvgProps = {
504
- "xmlns": "http://www.w3.org/2000/svg",
505
- "width": "1em",
506
- "height": "1em",
507
- "viewBox": "0 0 24 24",
508
- "fill": "none",
509
- "stroke": "currentColor",
510
- "strokeWidth": 2,
511
- "strokeLinecap": "round",
512
- "strokeLinejoin": "round",
513
- "focusable": false,
514
- "aria-hidden": true
515
- };
516
- var PlaceholderCheck = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "check", ...props, children: /* @__PURE__ */ jsx("path", { d: "M5 12l5 5L20 7" }) });
517
- var PlaceholderRemove = (props) => /* @__PURE__ */ jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "remove", ...props, children: /* @__PURE__ */ jsx("path", { d: "M5 12h14" }) });
518
925
  var CheckboxIndicator = (props) => {
519
926
  const theme = useComponentTheme("Checkbox");
520
927
  const { classNames, slotProps, checked, indeterminate } = useCheckboxOwnContext("Checkbox.Indicator");
@@ -541,19 +948,141 @@ var Checkbox2 = Object.assign(Checkbox, {
541
948
  Indicator: CheckboxIndicator
542
949
  });
543
950
 
951
+ // src/components/chip/base.ts
952
+ var ChipBase = createComponentBase({
953
+ name: "Chip",
954
+ slots: ["root", "label", "remove"],
955
+ classes: {
956
+ root: "tk-chip",
957
+ label: "tk-chip-label",
958
+ remove: "tk-chip-remove"
959
+ }
960
+ });
961
+
962
+ // src/components/chip/defaults.ts
963
+ var DEFAULT_VARIANT4 = "primary";
964
+ var DEFAULT_APPEARANCE4 = "filled";
965
+ var DEFAULT_SIZE6 = "base";
966
+ var DEFAULT_REMOVE_LABEL = "Remove";
967
+ var Chip = (props) => {
968
+ const theme = useComponentTheme("Chip");
969
+ const [dismissed, setDismissed] = useState(false);
970
+ const { rootAttrs, rest } = composeRootAttrs(ChipBase, props, theme, {
971
+ stateAttrs: ({ variant = DEFAULT_VARIANT4, appearance = DEFAULT_APPEARANCE4, size = DEFAULT_SIZE6, clickable: clickable2 = false, disabled: disabled2 = false, removable: removable2 = false }) => ({
972
+ "data-variant": variant,
973
+ "data-type": appearance,
974
+ "data-size": size,
975
+ "data-clickable": clickable2 ? "" : void 0,
976
+ "data-disabled": disabled2 ? "" : void 0,
977
+ "data-removable": removable2 ? "" : void 0
978
+ })
979
+ });
980
+ const {
981
+ onClick: rootSlotOnClick,
982
+ onKeyDown: rootSlotOnKeyDown,
983
+ ...chipRootAttrs
984
+ } = rootAttrs;
985
+ const {
986
+ variant: _variant,
987
+ appearance: _appearance,
988
+ size: _size,
989
+ autoDismiss = true,
990
+ clickable = false,
991
+ disabled = false,
992
+ removable = false,
993
+ onRemove,
994
+ children,
995
+ ref,
996
+ role,
997
+ tabIndex,
998
+ onClick,
999
+ ...nativeProps
1000
+ } = rest;
1001
+ const labelSlotAttrs = buildSlotAttrs(ChipBase.getSlotProps("label"), "label", {
1002
+ themeSlotProps: theme?.slotProps,
1003
+ themeClassNames: theme?.classNames,
1004
+ instanceSlotProps: props.slotProps,
1005
+ instanceClassNames: props.classNames
1006
+ });
1007
+ const removeSlotAttrs = buildSlotAttrs(ChipBase.getSlotProps("remove"), "remove", {
1008
+ themeSlotProps: theme?.slotProps,
1009
+ themeClassNames: theme?.classNames,
1010
+ instanceSlotProps: props.slotProps,
1011
+ instanceClassNames: props.classNames
1012
+ });
1013
+ const { onClick: removeSlotOnClick, ...removeButtonAttrs } = removeSlotAttrs;
1014
+ const resolvedTabIndex = clickable ? disabled ? -1 : tabIndex ?? 0 : tabIndex;
1015
+ const resolvedRole = role ?? (clickable ? "button" : void 0);
1016
+ if (dismissed) {
1017
+ return null;
1018
+ }
1019
+ const remove = () => {
1020
+ if (disabled || !removable) return;
1021
+ onRemove?.();
1022
+ if (!autoDismiss) return;
1023
+ setDismissed(true);
1024
+ };
1025
+ const handleRemoveClick = (event) => {
1026
+ if (clickable) event.stopPropagation();
1027
+ removeSlotOnClick?.(event);
1028
+ if (event.defaultPrevented) return;
1029
+ remove();
1030
+ };
1031
+ const handleRootClick = (event) => {
1032
+ if (disabled) return;
1033
+ onClick?.(event);
1034
+ rootSlotOnClick?.(event);
1035
+ };
1036
+ const handleKeyDown = (event) => {
1037
+ if (disabled) return;
1038
+ nativeProps.onKeyDown?.(event);
1039
+ rootSlotOnKeyDown?.(event);
1040
+ if (event.defaultPrevented) return;
1041
+ if (clickable && removable && (event.key === "Backspace" || event.key === "Delete")) {
1042
+ event.preventDefault();
1043
+ remove();
1044
+ return;
1045
+ }
1046
+ if (clickable && (event.key === "Enter" || event.key === " ")) {
1047
+ event.preventDefault();
1048
+ event.currentTarget.click();
1049
+ }
1050
+ };
1051
+ return /* @__PURE__ */ jsxs(
1052
+ "span",
1053
+ {
1054
+ ...nativeProps,
1055
+ ...chipRootAttrs,
1056
+ "aria-disabled": disabled || void 0,
1057
+ onClick: handleRootClick,
1058
+ onKeyDown: handleKeyDown,
1059
+ ref,
1060
+ role: resolvedRole,
1061
+ tabIndex: resolvedTabIndex,
1062
+ children: [
1063
+ isRenderableNode(children) && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }),
1064
+ removable && // The icon-only remove control needs an accessible name. Default it,
1065
+ // but let `slotProps.remove` (spread after) override via `aria-label`.
1066
+ /* @__PURE__ */ jsx("button", { "aria-label": DEFAULT_REMOVE_LABEL, ...removeButtonAttrs, disabled, onClick: handleRemoveClick, type: "button", children: /* @__PURE__ */ jsx(PlaceholderClose, {}) })
1067
+ ]
1068
+ }
1069
+ );
1070
+ };
1071
+ Chip.displayName = "Chip";
1072
+
544
1073
  // src/components/drawer/context.ts
545
1074
  var [DrawerProvider, useDrawerOwnContext] = createSafeContext("DrawerProvider");
546
1075
 
547
1076
  // src/components/drawer/defaults.ts
548
1077
  var DEFAULT_PLACEMENT = "right";
549
- var DEFAULT_HEADER_TYPE = "basic";
550
- var DEFAULT_FOOTER_TYPE = "basic";
1078
+ var DEFAULT_HEADER_TYPE2 = "basic";
1079
+ var DEFAULT_FOOTER_TYPE2 = "basic";
551
1080
  var DEFAULT_INTENSITY = "base";
552
1081
  var Drawer = (props) => {
553
1082
  const theme = useComponentTheme("Drawer");
554
1083
  const merged = { ...theme?.defaultProps, ...props };
555
- const { placement = DEFAULT_PLACEMENT, dismissable = true, disabled = false, children, ...sparProps } = merged;
556
- return /* @__PURE__ */ jsx(DrawerProvider, { value: { placement, dismissable }, children: /* @__PURE__ */ jsx(Dialog, { ...sparProps, disabled, forceMount: true, children }) });
1084
+ const { placement = DEFAULT_PLACEMENT, dismissible = true, disabled = false, children, ...sparProps } = merged;
1085
+ return /* @__PURE__ */ jsx(DrawerProvider, { value: { placement, dismissible }, children: /* @__PURE__ */ jsx(Dialog$1, { ...sparProps, disabled, forceMount: true, children }) });
557
1086
  };
558
1087
  Drawer.displayName = "Drawer";
559
1088
 
@@ -598,10 +1127,10 @@ var DrawerFooterBase = createComponentBase({
598
1127
  slots: ["root"],
599
1128
  classes: { root: "tk-drawer-footer" }
600
1129
  });
601
- var DrawerCloseButtonBase = createComponentBase({
602
- name: "DrawerCloseButton",
1130
+ var DrawerCloseBase = createComponentBase({
1131
+ name: "DrawerClose",
603
1132
  slots: ["root"],
604
- classes: { root: "tk-drawer-close-button" }
1133
+ classes: { root: "tk-drawer-close" }
605
1134
  });
606
1135
  var DrawerTriggerBase = createComponentBase({
607
1136
  name: "DrawerTrigger",
@@ -612,42 +1141,43 @@ var DrawerTrigger = (props) => {
612
1141
  const theme = useComponentTheme("DrawerTrigger");
613
1142
  const { rootAttrs, rest } = composeRootAttrs(DrawerTriggerBase, props, theme);
614
1143
  const { children, ref, ...triggerProps } = rest;
615
- return /* @__PURE__ */ jsx(DialogTrigger, { ...triggerProps, ref, ...rootAttrs, children });
1144
+ return /* @__PURE__ */ jsx(DialogTrigger$1, { ...triggerProps, ref, ...rootAttrs, children });
616
1145
  };
617
- DrawerTrigger.displayName = "DrawerTrigger";
1146
+ DrawerTrigger.displayName = "Drawer.Trigger";
618
1147
  var DrawerOverlay = (props) => {
619
1148
  const theme = useComponentTheme("DrawerOverlay");
620
1149
  const { rootAttrs, rest } = composeRootAttrs(DrawerOverlayBase, props, theme, {
621
- stateAttrs: ({ intensity = DEFAULT_INTENSITY, invisible }) => ({
1150
+ stateAttrs: ({ intensity = DEFAULT_INTENSITY, invisible, blur }) => ({
622
1151
  "data-intensity": intensity,
623
- "data-invisible": invisible ? "" : void 0
1152
+ "data-invisible": invisible ? "" : void 0,
1153
+ "data-blur": blur ? "" : void 0
624
1154
  })
625
1155
  });
626
- const { intensity: _intensity, invisible: _invisible, children, ref, ...overlayProps } = rest;
627
- return /* @__PURE__ */ jsx(DialogOverlay, { ...overlayProps, ref, ...rootAttrs, children });
1156
+ const { intensity: _intensity, invisible: _invisible, blur: _blur, children, ref, ...overlayProps } = rest;
1157
+ return /* @__PURE__ */ jsx(DialogOverlay$1, { ...overlayProps, ref, ...rootAttrs, children });
628
1158
  };
629
- DrawerOverlay.displayName = "DrawerOverlay";
630
- var preventDefault = (e) => e.preventDefault();
1159
+ DrawerOverlay.displayName = "Drawer.Overlay";
631
1160
  var DrawerPanel = (props) => {
632
1161
  const theme = useComponentTheme("DrawerPanel");
633
- const { placement, dismissable } = useDrawerOwnContext();
1162
+ const { placement, dismissible } = useDrawerOwnContext();
634
1163
  const { rootAttrs, rest } = composeRootAttrs(DrawerPanelBase, props, theme, {
635
1164
  stateAttrs: () => ({
636
1165
  "data-placement": placement
637
1166
  })
638
1167
  });
639
1168
  const { container, children, ref, ...panelProps } = rest;
640
- const dismissHandlers = !dismissable && {
641
- onEscapeKeyDown: preventDefault,
642
- onPointerDownOutside: preventDefault
1169
+ const dismissHandlers = !dismissible && {
1170
+ onEscapeKeyDown: blockDismiss(panelProps.onEscapeKeyDown),
1171
+ onPointerDownOutside: blockDismiss(panelProps.onPointerDownOutside),
1172
+ onInteractOutside: blockDismiss(panelProps.onInteractOutside)
643
1173
  };
644
1174
  return /* @__PURE__ */ jsx(DialogContent, { ...panelProps, container, ref, ...rootAttrs, ...dismissHandlers, children });
645
1175
  };
646
- DrawerPanel.displayName = "DrawerPanel";
1176
+ DrawerPanel.displayName = "Drawer.Panel";
647
1177
  var DrawerHeader = (props) => {
648
1178
  const theme = useComponentTheme("DrawerHeader");
649
1179
  const { rootAttrs, rest } = composeRootAttrs(DrawerHeaderBase, props, theme, {
650
- stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE }) => ({
1180
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE2 }) => ({
651
1181
  "data-header-type": headerType
652
1182
  })
653
1183
  });
@@ -655,21 +1185,21 @@ var DrawerHeader = (props) => {
655
1185
  const Component = as ?? "div";
656
1186
  return /* @__PURE__ */ jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
657
1187
  };
658
- DrawerHeader.displayName = "DrawerHeader";
1188
+ DrawerHeader.displayName = "Drawer.Header";
659
1189
  var DrawerTitle = (props) => {
660
1190
  const theme = useComponentTheme("DrawerTitle");
661
1191
  const { rootAttrs, rest } = composeRootAttrs(DrawerTitleBase, props, theme);
662
1192
  const { level = 5, children, ref, ...titleProps } = rest;
663
- return /* @__PURE__ */ jsx(DialogTitle, { ...titleProps, level, ref, ...rootAttrs, children });
1193
+ return /* @__PURE__ */ jsx(DialogTitle$1, { ...titleProps, level, ref, ...rootAttrs, children });
664
1194
  };
665
- DrawerTitle.displayName = "DrawerTitle";
1195
+ DrawerTitle.displayName = "Drawer.Title";
666
1196
  var DrawerDescription = (props) => {
667
1197
  const theme = useComponentTheme("DrawerDescription");
668
1198
  const { rootAttrs, rest } = composeRootAttrs(DrawerDescriptionBase, props, theme);
669
1199
  const { children, ref, ...descProps } = rest;
670
- return /* @__PURE__ */ jsx(DialogDescription, { ...descProps, ref, ...rootAttrs, children });
1200
+ return /* @__PURE__ */ jsx(DialogDescription$1, { ...descProps, ref, ...rootAttrs, children });
671
1201
  };
672
- DrawerDescription.displayName = "DrawerDescription";
1202
+ DrawerDescription.displayName = "Drawer.Description";
673
1203
  var DrawerBody = (props) => {
674
1204
  const theme = useComponentTheme("DrawerBody");
675
1205
  const { rootAttrs, rest } = composeRootAttrs(DrawerBodyBase, props, theme);
@@ -677,11 +1207,11 @@ var DrawerBody = (props) => {
677
1207
  const Component = as ?? "div";
678
1208
  return /* @__PURE__ */ jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
679
1209
  };
680
- DrawerBody.displayName = "DrawerBody";
1210
+ DrawerBody.displayName = "Drawer.Body";
681
1211
  var DrawerFooter = (props) => {
682
1212
  const theme = useComponentTheme("DrawerFooter");
683
1213
  const { rootAttrs, rest } = composeRootAttrs(DrawerFooterBase, props, theme, {
684
- stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE }) => ({
1214
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE2 }) => ({
685
1215
  "data-footer-type": footerType
686
1216
  })
687
1217
  });
@@ -689,14 +1219,14 @@ var DrawerFooter = (props) => {
689
1219
  const Component = as ?? "div";
690
1220
  return /* @__PURE__ */ jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
691
1221
  };
692
- DrawerFooter.displayName = "DrawerFooter";
693
- var DrawerCloseButton = (props) => {
694
- const theme = useComponentTheme("DrawerCloseButton");
695
- const { rootAttrs, rest } = composeRootAttrs(DrawerCloseButtonBase, props, theme);
1222
+ DrawerFooter.displayName = "Drawer.Footer";
1223
+ var DrawerClose = (props) => {
1224
+ const theme = useComponentTheme("DrawerClose");
1225
+ const { rootAttrs, rest } = composeRootAttrs(DrawerCloseBase, props, theme);
696
1226
  const { children, ref, ...closeProps } = rest;
697
- return /* @__PURE__ */ jsx(DialogClose, { ...closeProps, ref, ...rootAttrs, children });
1227
+ return /* @__PURE__ */ jsx(DialogClose$1, { ...closeProps, ref, ...rootAttrs, children });
698
1228
  };
699
- DrawerCloseButton.displayName = "DrawerCloseButton";
1229
+ DrawerClose.displayName = "Drawer.Close";
700
1230
 
701
1231
  // src/components/drawer/index.ts
702
1232
  var Drawer2 = Object.assign(Drawer, {
@@ -708,29 +1238,384 @@ var Drawer2 = Object.assign(Drawer, {
708
1238
  Description: DrawerDescription,
709
1239
  Body: DrawerBody,
710
1240
  Footer: DrawerFooter,
711
- CloseButton: DrawerCloseButton
1241
+ Close: DrawerClose
712
1242
  });
713
1243
 
714
- // src/components/field/base.ts
715
- var FieldBase = createComponentBase({
716
- name: "Field",
1244
+ // src/components/dialog/context.ts
1245
+ var [DialogProvider, useDialogOwnContext] = createSafeContext("DialogProvider");
1246
+ var Dialog = (props) => {
1247
+ const theme = useComponentTheme("Dialog");
1248
+ const merged = { ...theme?.defaultProps, ...props };
1249
+ const { dismissible = true, forceMount = true, children, ...sparProps } = merged;
1250
+ return /* @__PURE__ */ jsx(DialogProvider, { value: { dismissible }, children: /* @__PURE__ */ jsx(Dialog$1, { ...sparProps, forceMount, children }) });
1251
+ };
1252
+ Dialog.displayName = "Dialog";
1253
+
1254
+ // src/components/dialog/base.ts
1255
+ var DialogTriggerBase = createComponentBase({
1256
+ name: "DialogTrigger",
717
1257
  slots: ["root"],
718
- classes: { root: "tk-field" }
719
- });
720
- var FieldLabelBase = createComponentBase({
721
- name: "FieldLabel",
722
- slots: ["root", "asterisk"],
723
- classes: { root: "tk-field-label", asterisk: "tk-field-asterisk" }
1258
+ classes: {
1259
+ root: "tk-dialog-trigger"
1260
+ }
724
1261
  });
725
- var FieldDescriptionBase = createComponentBase({
726
- name: "FieldDescription",
1262
+ var DialogOverlayBase = createComponentBase({
1263
+ name: "DialogOverlay",
727
1264
  slots: ["root"],
728
- classes: { root: "tk-field-description" }
1265
+ classes: {
1266
+ root: "tk-dialog-overlay"
1267
+ }
1268
+ });
1269
+ var DialogPanelBase = createComponentBase({
1270
+ name: "DialogPanel",
1271
+ slots: ["root"],
1272
+ classes: {
1273
+ root: "tk-dialog-panel"
1274
+ }
1275
+ });
1276
+ var DialogHeaderBase = createComponentBase({
1277
+ name: "DialogHeader",
1278
+ slots: ["root"],
1279
+ classes: {
1280
+ root: "tk-dialog-header"
1281
+ }
1282
+ });
1283
+ var DialogTitleBase = createComponentBase({
1284
+ name: "DialogTitle",
1285
+ slots: ["root"],
1286
+ classes: {
1287
+ root: "tk-dialog-title"
1288
+ }
1289
+ });
1290
+ var DialogDescriptionBase = createComponentBase({
1291
+ name: "DialogDescription",
1292
+ slots: ["root"],
1293
+ classes: {
1294
+ root: "tk-dialog-description"
1295
+ }
1296
+ });
1297
+ var DialogBodyBase = createComponentBase({
1298
+ name: "DialogBody",
1299
+ slots: ["root"],
1300
+ classes: {
1301
+ root: "tk-dialog-body"
1302
+ }
1303
+ });
1304
+ var DialogFooterBase = createComponentBase({
1305
+ name: "DialogFooter",
1306
+ slots: ["root"],
1307
+ classes: {
1308
+ root: "tk-dialog-footer"
1309
+ }
1310
+ });
1311
+ var DialogCloseBase = createComponentBase({
1312
+ name: "DialogClose",
1313
+ slots: ["root"],
1314
+ classes: {
1315
+ root: "tk-dialog-close"
1316
+ }
1317
+ });
1318
+ var DialogTrigger = (props) => {
1319
+ const theme = useComponentTheme("DialogTrigger");
1320
+ const { rootAttrs, rest } = composeRootAttrs(DialogTriggerBase, props, theme);
1321
+ const { children, ref, ...sparProps } = rest;
1322
+ return /* @__PURE__ */ jsx(DialogTrigger$1, { ...sparProps, ...rootAttrs, ref, children });
1323
+ };
1324
+ DialogTrigger.displayName = "Dialog.Trigger";
1325
+
1326
+ // src/components/dialog/defaults.ts
1327
+ var DEFAULT_INTENSITY2 = "base";
1328
+ var DEFAULT_HEADER_TYPE3 = "basic";
1329
+ var DEFAULT_FOOTER_TYPE3 = "basic";
1330
+ var DialogOverlay = (props) => {
1331
+ const theme = useComponentTheme("DialogOverlay");
1332
+ const { rootAttrs, rest } = composeRootAttrs(DialogOverlayBase, props, theme, {
1333
+ stateAttrs: ({ intensity = DEFAULT_INTENSITY2, invisible, blur }) => ({
1334
+ "data-intensity": intensity,
1335
+ "data-invisible": invisible ? "" : void 0,
1336
+ "data-blur": blur ? "" : void 0
1337
+ })
1338
+ });
1339
+ const { intensity: _intensity, invisible: _invisible, blur: _blur, children, ref, ...sparProps } = rest;
1340
+ return /* @__PURE__ */ jsx(DialogOverlay$1, { ...sparProps, ...rootAttrs, ref, children });
1341
+ };
1342
+ DialogOverlay.displayName = "Dialog.Overlay";
1343
+ var DialogPanel = (props) => {
1344
+ const theme = useComponentTheme("DialogPanel");
1345
+ const { dismissible } = useDialogOwnContext();
1346
+ const { rootAttrs, rest } = composeRootAttrs(DialogPanelBase, props, theme);
1347
+ const { children, ref, ...sparProps } = rest;
1348
+ const dismissHandlers = !dismissible && {
1349
+ onEscapeKeyDown: blockDismiss(sparProps.onEscapeKeyDown),
1350
+ onPointerDownOutside: blockDismiss(sparProps.onPointerDownOutside),
1351
+ onInteractOutside: blockDismiss(sparProps.onInteractOutside)
1352
+ };
1353
+ return /* @__PURE__ */ jsx(DialogContent, { ...sparProps, ...rootAttrs, ref, ...dismissHandlers, children });
1354
+ };
1355
+ DialogPanel.displayName = "Dialog.Panel";
1356
+ var DialogHeader = (props) => {
1357
+ const theme = useComponentTheme("DialogHeader");
1358
+ const { rootAttrs, rest } = composeRootAttrs(DialogHeaderBase, props, theme, {
1359
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE3 }) => ({
1360
+ "data-header-type": headerType
1361
+ })
1362
+ });
1363
+ const { as, headerType: _headerType, children, ref, ...headerProps } = rest;
1364
+ const Component = as ?? "div";
1365
+ return /* @__PURE__ */ jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
1366
+ };
1367
+ DialogHeader.displayName = "Dialog.Header";
1368
+ var DialogTitle = (props) => {
1369
+ const theme = useComponentTheme("DialogTitle");
1370
+ const { rootAttrs, rest } = composeRootAttrs(DialogTitleBase, props, theme);
1371
+ const { level = 5, children, ref, ...titleProps } = rest;
1372
+ return /* @__PURE__ */ jsx(DialogTitle$1, { ...titleProps, level, ref, ...rootAttrs, children });
1373
+ };
1374
+ DialogTitle.displayName = "Dialog.Title";
1375
+ var DialogDescription = (props) => {
1376
+ const theme = useComponentTheme("DialogDescription");
1377
+ const { rootAttrs, rest } = composeRootAttrs(DialogDescriptionBase, props, theme);
1378
+ const { children, ref, ...sparProps } = rest;
1379
+ return /* @__PURE__ */ jsx(DialogDescription$1, { ...sparProps, ...rootAttrs, ref, children });
1380
+ };
1381
+ DialogDescription.displayName = "Dialog.Description";
1382
+ var DialogBody = (props) => {
1383
+ const theme = useComponentTheme("DialogBody");
1384
+ const { rootAttrs, rest } = composeRootAttrs(DialogBodyBase, props, theme);
1385
+ const { as, children, ref, ...bodyProps } = rest;
1386
+ const Component = as ?? "div";
1387
+ return /* @__PURE__ */ jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
1388
+ };
1389
+ DialogBody.displayName = "Dialog.Body";
1390
+ var DialogFooter = (props) => {
1391
+ const theme = useComponentTheme("DialogFooter");
1392
+ const { rootAttrs, rest } = composeRootAttrs(DialogFooterBase, props, theme, {
1393
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE3 }) => ({
1394
+ "data-footer-type": footerType
1395
+ })
1396
+ });
1397
+ const { as, footerType: _footerType, children, ref, ...footerProps } = rest;
1398
+ const Component = as ?? "div";
1399
+ return /* @__PURE__ */ jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
1400
+ };
1401
+ DialogFooter.displayName = "Dialog.Footer";
1402
+ var DialogClose = (props) => {
1403
+ const theme = useComponentTheme("DialogClose");
1404
+ const { rootAttrs, rest } = composeRootAttrs(DialogCloseBase, props, theme);
1405
+ const { children, ref, ...sparProps } = rest;
1406
+ return /* @__PURE__ */ jsx(DialogClose$1, { ...sparProps, ...rootAttrs, ref, children });
1407
+ };
1408
+ DialogClose.displayName = "Dialog.Close";
1409
+
1410
+ // src/components/dialog/index.ts
1411
+ var Dialog2 = Object.assign(Dialog, {
1412
+ Trigger: DialogTrigger,
1413
+ Overlay: DialogOverlay,
1414
+ Panel: DialogPanel,
1415
+ Header: DialogHeader,
1416
+ Title: DialogTitle,
1417
+ Description: DialogDescription,
1418
+ Body: DialogBody,
1419
+ Footer: DialogFooter,
1420
+ Close: DialogClose
1421
+ });
1422
+
1423
+ // src/components/divider/base.ts
1424
+ var DividerBase = createComponentBase({
1425
+ name: "Divider",
1426
+ slots: ["root", "label"],
1427
+ classes: {
1428
+ root: "tk-divider",
1429
+ label: "tk-divider-label"
1430
+ }
1431
+ });
1432
+
1433
+ // src/components/divider/defaults.ts
1434
+ var DEFAULT_ORIENTATION = "horizontal";
1435
+ var DEFAULT_APPEARANCE5 = "solid";
1436
+ var DEFAULT_ALIGN = "center";
1437
+ var hasRenderableDividerLabel = (node) => Array.isArray(node) ? node.some(hasRenderableDividerLabel) : isRenderableNode(node);
1438
+ var Divider = (props) => {
1439
+ const theme = useComponentTheme("Divider");
1440
+ const { rootAttrs, rest } = composeRootAttrs(DividerBase, props, theme, {
1441
+ // role/aria-orientation live here alongside the data-* hooks so consumer
1442
+ // slotProps cannot silently strip the separator semantics.
1443
+ stateAttrs: ({ orientation: orientation2 = DEFAULT_ORIENTATION, appearance = DEFAULT_APPEARANCE5, align = DEFAULT_ALIGN, decorative: decorative2 = false }) => ({
1444
+ "role": decorative2 ? "none" : "separator",
1445
+ "data-orientation": orientation2,
1446
+ "data-type": appearance,
1447
+ "data-align": align
1448
+ })
1449
+ });
1450
+ const { orientation = DEFAULT_ORIENTATION, appearance: _appearance, align: _align, decorative = false, children, ref, ...nativeProps } = rest;
1451
+ const labelSlotAttrs = buildSlotAttrs(DividerBase.getSlotProps("label"), "label", {
1452
+ themeSlotProps: theme?.slotProps,
1453
+ themeClassNames: theme?.classNames,
1454
+ instanceSlotProps: props.slotProps,
1455
+ instanceClassNames: props.classNames
1456
+ });
1457
+ return /* @__PURE__ */ jsx("div", { ...nativeProps, ...rootAttrs, "aria-orientation": decorative ? void 0 : orientation, ref, children: hasRenderableDividerLabel(children) && /* @__PURE__ */ jsx("span", { ...labelSlotAttrs, children }) });
1458
+ };
1459
+ Divider.displayName = "Divider";
1460
+
1461
+ // src/components/dropdown/context.ts
1462
+ var [DropdownProvider, useDropdownOwnContext] = createSafeContext("DropdownProvider");
1463
+
1464
+ // src/components/dropdown/defaults.ts
1465
+ var DEFAULT_SIZE7 = "base";
1466
+ var DEFAULT_CONTENT_WIDTH = "content";
1467
+ var Dropdown = (props) => {
1468
+ const theme = useComponentTheme("Dropdown");
1469
+ const merged = { ...theme?.defaultProps, ...props };
1470
+ const { size = DEFAULT_SIZE7, contentWidth = DEFAULT_CONTENT_WIDTH, children, ...sparProps } = merged;
1471
+ return /* @__PURE__ */ jsx(DropdownProvider, { value: { size, contentWidth }, children: /* @__PURE__ */ jsx(DropdownMenu, { ...sparProps, children }) });
1472
+ };
1473
+ Dropdown.displayName = "Dropdown";
1474
+
1475
+ // src/components/dropdown/base.ts
1476
+ var DropdownTriggerBase = createComponentBase({
1477
+ name: "DropdownTrigger",
1478
+ slots: ["root"],
1479
+ classes: { root: "tk-dropdown-trigger" }
1480
+ });
1481
+ var DropdownContentBase = createComponentBase({
1482
+ name: "DropdownContent",
1483
+ slots: ["root"],
1484
+ classes: { root: "tk-dropdown-content" }
1485
+ });
1486
+ var DropdownViewportBase = createComponentBase({
1487
+ name: "DropdownViewport",
1488
+ slots: ["root"],
1489
+ classes: { root: "tk-dropdown-viewport" }
1490
+ });
1491
+ var DropdownItemBase = createComponentBase({
1492
+ name: "DropdownItem",
1493
+ slots: ["root"],
1494
+ classes: { root: "tk-dropdown-item" }
1495
+ });
1496
+ var DropdownGroupBase = createComponentBase({
1497
+ name: "DropdownGroup",
1498
+ slots: ["root"],
1499
+ classes: { root: "tk-dropdown-group" }
1500
+ });
1501
+ var DropdownLabelBase = createComponentBase({
1502
+ name: "DropdownLabel",
1503
+ slots: ["root"],
1504
+ classes: { root: "tk-dropdown-label" }
1505
+ });
1506
+ var DropdownSeparatorBase = createComponentBase({
1507
+ name: "DropdownSeparator",
1508
+ slots: ["root"],
1509
+ classes: { root: "tk-dropdown-separator" }
1510
+ });
1511
+ var DropdownArrowBase = createComponentBase({
1512
+ name: "DropdownArrow",
1513
+ slots: ["root"],
1514
+ classes: { root: "tk-dropdown-arrow" }
1515
+ });
1516
+ var DropdownArrow = (props) => {
1517
+ const theme = useComponentTheme("DropdownArrow");
1518
+ const { rootAttrs, rest } = composeRootAttrs(DropdownArrowBase, props, theme);
1519
+ const { children, ref, ...sparProps } = rest;
1520
+ return /* @__PURE__ */ jsx(DropdownMenuArrow, { ...sparProps, ...rootAttrs, ref, children: children ?? renderPointerArrow() });
1521
+ };
1522
+ DropdownArrow.displayName = "Dropdown.Arrow";
1523
+ var DropdownContent = (props) => {
1524
+ const theme = useComponentTheme("DropdownContent");
1525
+ const { size, contentWidth } = useDropdownOwnContext("Dropdown.Content");
1526
+ const { triggerRef } = useDropdownMenuContext();
1527
+ const widthStyle = useContentWidthStyle(contentWidth, triggerRef);
1528
+ const { rootAttrs, rest } = composeRootAttrs(DropdownContentBase, props, theme, {
1529
+ stateAttrs: () => ({
1530
+ "data-size": size
1531
+ })
1532
+ });
1533
+ const { children, ref, style: userStyle, ...sparProps } = rest;
1534
+ const { style: rootStyle, ...rootRest } = rootAttrs;
1535
+ const mergedStyle = widthStyle || rootStyle || userStyle ? { ...widthStyle, ...rootStyle, ...userStyle } : void 0;
1536
+ return /* @__PURE__ */ jsx(DropdownMenuContent, { ...sparProps, ...rootRest, ref, style: mergedStyle, children });
1537
+ };
1538
+ DropdownContent.displayName = "Dropdown.Content";
1539
+ var DropdownGroup = (props) => {
1540
+ const theme = useComponentTheme("DropdownGroup");
1541
+ const { rootAttrs, rest } = composeRootAttrs(DropdownGroupBase, props, theme);
1542
+ const { children, ref, ...sparProps } = rest;
1543
+ return /* @__PURE__ */ jsx(DropdownMenuGroup, { ...sparProps, ...rootAttrs, ref, children });
1544
+ };
1545
+ DropdownGroup.displayName = "Dropdown.Group";
1546
+ var DropdownItem = (props) => {
1547
+ const theme = useComponentTheme("DropdownItem");
1548
+ const { rootAttrs, rest } = composeRootAttrs(DropdownItemBase, props, theme);
1549
+ const { children, ref, ...sparProps } = rest;
1550
+ return /* @__PURE__ */ jsx(DropdownMenuItem, { ...sparProps, ...rootAttrs, ref, children });
1551
+ };
1552
+ DropdownItem.displayName = "Dropdown.Item";
1553
+ var DropdownLabel = (props) => {
1554
+ const theme = useComponentTheme("DropdownLabel");
1555
+ const { rootAttrs, rest } = composeRootAttrs(DropdownLabelBase, props, theme);
1556
+ const { children, ref, ...sparProps } = rest;
1557
+ return /* @__PURE__ */ jsx(DropdownMenuLabel, { ...sparProps, ...rootAttrs, ref, children });
1558
+ };
1559
+ DropdownLabel.displayName = "Dropdown.Label";
1560
+ var DropdownSeparator = (props) => {
1561
+ const theme = useComponentTheme("DropdownSeparator");
1562
+ const { rootAttrs, rest } = composeRootAttrs(DropdownSeparatorBase, props, theme);
1563
+ const { children, ref, ...sparProps } = rest;
1564
+ return /* @__PURE__ */ jsx(DropdownMenuSeparator, { ...sparProps, ...rootAttrs, ref, children });
1565
+ };
1566
+ DropdownSeparator.displayName = "Dropdown.Separator";
1567
+ var DropdownTrigger = (props) => {
1568
+ const theme = useComponentTheme("DropdownTrigger");
1569
+ const { size } = useDropdownOwnContext("Dropdown.Trigger");
1570
+ const { rootAttrs, rest } = composeRootAttrs(DropdownTriggerBase, props, theme, {
1571
+ stateAttrs: () => ({
1572
+ "data-size": size
1573
+ })
1574
+ });
1575
+ const { children, ref, ...sparProps } = rest;
1576
+ return /* @__PURE__ */ jsx(DropdownMenuTrigger, { ...sparProps, ...rootAttrs, ref, children });
1577
+ };
1578
+ DropdownTrigger.displayName = "Dropdown.Trigger";
1579
+ var DropdownViewport = (props) => {
1580
+ const theme = useComponentTheme("DropdownViewport");
1581
+ const { rootAttrs, rest } = composeRootAttrs(DropdownViewportBase, props, theme);
1582
+ const { children, ref, ...sparProps } = rest;
1583
+ return /* @__PURE__ */ jsx(DropdownMenuViewport, { ...sparProps, ...rootAttrs, ref, children });
1584
+ };
1585
+ DropdownViewport.displayName = "Dropdown.Viewport";
1586
+
1587
+ // src/components/dropdown/index.ts
1588
+ var Dropdown2 = Object.assign(Dropdown, {
1589
+ Trigger: DropdownTrigger,
1590
+ Content: DropdownContent,
1591
+ Viewport: DropdownViewport,
1592
+ Item: DropdownItem,
1593
+ Group: DropdownGroup,
1594
+ Label: DropdownLabel,
1595
+ Separator: DropdownSeparator,
1596
+ Arrow: DropdownArrow
1597
+ });
1598
+
1599
+ // src/components/field/base.ts
1600
+ var FieldBase = createComponentBase({
1601
+ name: "Field",
1602
+ slots: ["root"],
1603
+ classes: { root: "tk-field" }
1604
+ });
1605
+ var FieldLabelBase = createComponentBase({
1606
+ name: "FieldLabel",
1607
+ slots: ["root", "asterisk"],
1608
+ classes: { root: "tk-field-label", asterisk: "tk-field-asterisk" }
1609
+ });
1610
+ var FieldDescriptionBase = createComponentBase({
1611
+ name: "FieldDescription",
1612
+ slots: ["root", "icon"],
1613
+ classes: { root: "tk-field-description", icon: "tk-field-description-icon" }
729
1614
  });
730
1615
  var FieldErrorMessageBase = createComponentBase({
731
1616
  name: "FieldErrorMessage",
732
- slots: ["root"],
733
- classes: { root: "tk-field-error-message" }
1617
+ slots: ["root", "icon"],
1618
+ classes: { root: "tk-field-error-message", icon: "tk-field-error-message-icon" }
734
1619
  });
735
1620
  var Field = (props) => {
736
1621
  const theme = useComponentTheme("Field");
@@ -760,14 +1645,34 @@ var FieldDescription = (props) => {
760
1645
  const theme = useComponentTheme("FieldDescription");
761
1646
  const { rootAttrs, rest } = composeRootAttrs(FieldDescriptionBase, props, theme);
762
1647
  const { children, ref, ...spar } = rest;
763
- return /* @__PURE__ */ jsx(FieldDescription$1, { ...spar, ref, ...rootAttrs, children });
1648
+ const iconAttrs = buildSlotAttrs(FieldDescriptionBase.getSlotProps("icon"), "icon", {
1649
+ themeSlotProps: theme?.slotProps,
1650
+ themeClassNames: theme?.classNames,
1651
+ instanceSlotProps: props.slotProps,
1652
+ instanceClassNames: props.classNames
1653
+ });
1654
+ const hasContent = children != null && children !== "";
1655
+ return /* @__PURE__ */ jsxs(FieldDescription$1, { ...spar, ref, ...rootAttrs, children: [
1656
+ hasContent && /* @__PURE__ */ jsx("span", { ...iconAttrs, "aria-hidden": "true", children: /* @__PURE__ */ jsx(PlaceholderInfo, {}) }),
1657
+ children
1658
+ ] });
764
1659
  };
765
1660
  FieldDescription.displayName = "Field.Description";
766
1661
  var FieldErrorMessage = (props) => {
767
1662
  const theme = useComponentTheme("FieldErrorMessage");
768
1663
  const { rootAttrs, rest } = composeRootAttrs(FieldErrorMessageBase, props, theme);
769
1664
  const { children, ref, ...spar } = rest;
770
- return /* @__PURE__ */ jsx(FieldErrorMessage$1, { ...spar, ref, ...rootAttrs, children });
1665
+ const iconAttrs = buildSlotAttrs(FieldErrorMessageBase.getSlotProps("icon"), "icon", {
1666
+ themeSlotProps: theme?.slotProps,
1667
+ themeClassNames: theme?.classNames,
1668
+ instanceSlotProps: props.slotProps,
1669
+ instanceClassNames: props.classNames
1670
+ });
1671
+ const hasContent = children != null && children !== "";
1672
+ return /* @__PURE__ */ jsxs(FieldErrorMessage$1, { ...spar, ref, ...rootAttrs, children: [
1673
+ hasContent && /* @__PURE__ */ jsx("span", { ...iconAttrs, "aria-hidden": "true", children: /* @__PURE__ */ jsx(PlaceholderError, {}) }),
1674
+ children
1675
+ ] });
771
1676
  };
772
1677
  FieldErrorMessage.displayName = "Field.ErrorMessage";
773
1678
 
@@ -784,15 +1689,6 @@ var InputBase = createComponentBase({
784
1689
  slots: ["root"],
785
1690
  classes: { root: "tk-input" }
786
1691
  });
787
- var InputContainerBase = createComponentBase({
788
- name: "InputContainer",
789
- slots: ["root", "startContent", "endContent"],
790
- classes: {
791
- root: "tk-input-container",
792
- startContent: "tk-input-start-content",
793
- endContent: "tk-input-end-content"
794
- }
795
- });
796
1692
  var InputFieldBase = createComponentBase({
797
1693
  name: "InputField",
798
1694
  slots: ["root"],
@@ -808,84 +1704,541 @@ var InputSuffixBase = createComponentBase({
808
1704
  slots: ["root"],
809
1705
  classes: { root: "tk-input-suffix" }
810
1706
  });
1707
+ var InputLeadingIconBase = createComponentBase({
1708
+ name: "InputLeadingIcon",
1709
+ slots: ["root"],
1710
+ classes: { root: "tk-input-leading-icon" }
1711
+ });
1712
+ var InputTrailingIconBase = createComponentBase({
1713
+ name: "InputTrailingIcon",
1714
+ slots: ["root"],
1715
+ classes: { root: "tk-input-trailing-icon" }
1716
+ });
1717
+ var InputClearButtonBase = createComponentBase({
1718
+ name: "InputClearButton",
1719
+ slots: ["root"],
1720
+ classes: { root: "tk-input-clear-button" }
1721
+ });
1722
+ var InputSpinnerBase = createComponentBase({
1723
+ name: "InputSpinner",
1724
+ slots: ["root"],
1725
+ classes: { root: "tk-input-spinner" }
1726
+ });
1727
+ var InputRevealButtonBase = createComponentBase({
1728
+ name: "InputRevealButton",
1729
+ slots: ["root"],
1730
+ classes: { root: "tk-input-reveal-button" }
1731
+ });
1732
+ var InputStrengthBase = createComponentBase({
1733
+ name: "InputStrength",
1734
+ slots: ["root"],
1735
+ classes: { root: "tk-input-strength" }
1736
+ });
1737
+ var InputStepperBase = createComponentBase({
1738
+ name: "InputStepper",
1739
+ slots: ["root"],
1740
+ classes: { root: "tk-input-stepper" }
1741
+ });
1742
+ var InputDecrementBase = createComponentBase({
1743
+ name: "InputDecrement",
1744
+ slots: ["root"],
1745
+ classes: { root: "tk-input-decrement" }
1746
+ });
1747
+ var InputIncrementBase = createComponentBase({
1748
+ name: "InputIncrement",
1749
+ slots: ["root"],
1750
+ classes: { root: "tk-input-increment" }
1751
+ });
1752
+ var InputChipsBase = createComponentBase({
1753
+ name: "InputChips",
1754
+ slots: ["root"],
1755
+ classes: { root: "tk-input-chips" }
1756
+ });
811
1757
 
812
1758
  // src/components/input/context.ts
813
1759
  var [InputProvider, useInputOwnContext] = createSafeContext("InputProvider");
814
1760
 
815
1761
  // src/components/input/defaults.ts
816
- var DEFAULT_SIZE5 = "base";
1762
+ var DEFAULT_SIZE8 = "base";
1763
+ var SEGMENT_COUNT = 4;
1764
+ var computeStrength = (value) => {
1765
+ let strength = 0;
1766
+ if (value.length >= 8) strength += 1;
1767
+ if (/[A-Z]/.test(value)) strength += 1;
1768
+ if (/[a-z]/.test(value)) strength += 1;
1769
+ if (/[0-9]/.test(value)) strength += 1;
1770
+ if (/[^A-Za-z0-9]/.test(value)) strength += 1;
1771
+ return strength;
1772
+ };
1773
+ var levelFor = (strength) => strength < 3 ? "weak" : strength < 4 ? "medium" : "strong";
1774
+ var InputStrength = (props) => {
1775
+ const theme = useComponentTheme("InputStrength");
1776
+ const { fieldValue } = useInputOwnContext("Input.Strength");
1777
+ const Component = props.as ?? "div";
1778
+ const { rootAttrs, rest } = composeRootAttrs(InputStrengthBase, props, theme);
1779
+ const { as: _as, children: _children, ref, ...rendered } = rest;
1780
+ const strength = computeStrength(fieldValue);
1781
+ const filled = Math.min(strength, SEGMENT_COUNT);
1782
+ const level = levelFor(strength);
1783
+ return /* @__PURE__ */ jsx(Component, { ...rendered, ref, ...rootAttrs, children: Array.from({ length: SEGMENT_COUNT }, (_, index) => /* @__PURE__ */ jsx("span", { className: "tk-input-strength-segment", "data-level": index < filled ? level : void 0 }, index)) });
1784
+ };
1785
+ InputStrength.displayName = "Input.Strength";
817
1786
  var Input = (props) => {
818
1787
  const theme = useComponentTheme("Input");
1788
+ const fieldRef = useRef(null);
1789
+ const [fieldNode, setFieldNode] = useState(null);
1790
+ const [fieldValue, setFieldValue] = useState("");
1791
+ const [revealed, setRevealed] = useState(false);
1792
+ const toggleReveal = useCallback(() => setRevealed((value) => !value), []);
1793
+ const clearablesRef = useRef(/* @__PURE__ */ new Map());
1794
+ const [hasAuxContent, setHasAuxContent] = useState(false);
1795
+ const setClearable = useCallback((id, entry) => {
1796
+ if (entry) {
1797
+ clearablesRef.current.set(id, entry);
1798
+ } else {
1799
+ clearablesRef.current.delete(id);
1800
+ }
1801
+ let any = false;
1802
+ for (const value of clearablesRef.current.values()) {
1803
+ if (value.hasContent) {
1804
+ any = true;
1805
+ break;
1806
+ }
1807
+ }
1808
+ setHasAuxContent(any);
1809
+ }, []);
1810
+ const clearAux = useCallback(() => {
1811
+ for (const value of clearablesRef.current.values()) value.clear();
1812
+ }, []);
819
1813
  const { rootAttrs, rest } = composeRootAttrs(InputBase, props, theme, {
820
- stateAttrs: ({ size: size2 = DEFAULT_SIZE5 }) => ({
1814
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE8 }) => ({
821
1815
  "data-size": size2
822
1816
  })
823
1817
  });
824
- const { size = DEFAULT_SIZE5, children, ref, ...sparProps } = rest;
825
- return /* @__PURE__ */ jsx(InputProvider, { value: { size }, children: /* @__PURE__ */ jsx(Input$1, { ...sparProps, ref, ...rootAttrs, children }) });
1818
+ const { size = DEFAULT_SIZE8, children, ref, ...sparProps } = rest;
1819
+ const contextValue = useMemo(
1820
+ () => ({
1821
+ size,
1822
+ fieldRef,
1823
+ fieldNode,
1824
+ setFieldNode,
1825
+ fieldValue,
1826
+ setFieldValue,
1827
+ revealed,
1828
+ setRevealed,
1829
+ toggleReveal,
1830
+ setClearable,
1831
+ hasAuxContent,
1832
+ clearAux
1833
+ }),
1834
+ [size, fieldNode, fieldValue, revealed, setFieldValue, setRevealed, toggleReveal, setClearable, hasAuxContent, clearAux]
1835
+ );
1836
+ const rowChildren = [];
1837
+ const belowChildren = [];
1838
+ Children.forEach(children, (child) => {
1839
+ if (isValidElement(child) && child.type === InputStrength) {
1840
+ belowChildren.push(child);
1841
+ } else {
1842
+ rowChildren.push(child);
1843
+ }
1844
+ });
1845
+ return /* @__PURE__ */ jsxs(InputProvider, { value: contextValue, children: [
1846
+ /* @__PURE__ */ jsx(Input$1, { ...sparProps, ref, ...rootAttrs, children: rowChildren }),
1847
+ belowChildren
1848
+ ] });
826
1849
  };
827
1850
  Input.displayName = "Input";
828
- var InputContainer = (props) => {
829
- const theme = useComponentTheme("InputContainer");
830
- const { invalid, disabled, readOnly } = useInputContext();
831
- const Component = props.as ?? "div";
832
- const { rootAttrs, rest } = composeRootAttrs(InputContainerBase, props, theme, {
833
- stateAttrs: () => ({
834
- "data-invalid": invalid ? "" : void 0,
835
- "data-disabled": disabled ? "" : void 0,
836
- "data-readonly": readOnly ? "" : void 0
837
- })
838
- });
839
- const { as: _as, children, startContent, endContent, ref, ...rendered } = rest;
840
- const slotAttrs = (slot) => buildSlotAttrs(InputContainerBase.getSlotProps(slot), slot, {
841
- themeSlotProps: theme?.slotProps,
842
- themeClassNames: theme?.classNames,
843
- instanceSlotProps: props.slotProps,
844
- instanceClassNames: props.classNames
845
- });
1851
+
1852
+ // src/components/input/dom.ts
1853
+ var setNativeValue = (field, value) => {
1854
+ const prototype = field instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
1855
+ const valueSetter = Object.getOwnPropertyDescriptor(prototype, "value")?.set;
1856
+ valueSetter?.call(field, value);
1857
+ field.dispatchEvent(new Event("input", { bubbles: true }));
1858
+ };
1859
+ var stepField = (field, direction) => {
1860
+ if (!(field instanceof HTMLInputElement)) return;
1861
+ try {
1862
+ if (direction === "up") {
1863
+ field.stepUp();
1864
+ } else {
1865
+ field.stepDown();
1866
+ }
1867
+ } catch {
1868
+ return;
1869
+ }
1870
+ field.dispatchEvent(new Event("input", { bubbles: true }));
1871
+ field.focus();
1872
+ };
1873
+ var InputChips = (props) => {
1874
+ const theme = useComponentTheme("InputChips");
1875
+ const { disabled, readOnly } = useInputContext();
1876
+ const { size, fieldNode, setClearable } = useInputOwnContext("Input.Chips");
1877
+ const { rootAttrs, rest } = composeRootAttrs(InputChipsBase, props, theme);
1878
+ const { as, value, defaultValue, onValueChange, separator, max, allowDuplicates = false, children, ref, ...rendered } = rest;
1879
+ const Component = as ?? "div";
1880
+ const [chips = [], setChips] = useControllableState(value, defaultValue ?? [], onValueChange);
1881
+ const addChip = useCallback(
1882
+ (raw) => {
1883
+ if (disabled || readOnly) return;
1884
+ const label = raw.trim();
1885
+ if (!label) return;
1886
+ if (max !== void 0 && chips.length >= max) return;
1887
+ if (!allowDuplicates && chips.includes(label)) return;
1888
+ setChips([...chips, label]);
1889
+ },
1890
+ [chips, disabled, readOnly, max, allowDuplicates, setChips]
1891
+ );
1892
+ const removeChip = useCallback(
1893
+ (index) => {
1894
+ if (disabled || readOnly) return;
1895
+ setChips(chips.filter((_, i) => i !== index));
1896
+ },
1897
+ [chips, disabled, readOnly, setChips]
1898
+ );
1899
+ const removeLast = useCallback(() => {
1900
+ if (disabled || readOnly || chips.length === 0) return;
1901
+ setChips(chips.slice(0, -1));
1902
+ }, [chips, disabled, readOnly, setChips]);
1903
+ const clearId = useRef(/* @__PURE__ */ Symbol("input-chips")).current;
1904
+ const clearAll = useCallback(() => {
1905
+ if (disabled || readOnly) return;
1906
+ setChips([]);
1907
+ }, [disabled, readOnly, setChips]);
1908
+ useEffect(() => {
1909
+ setClearable(clearId, { hasContent: chips.length > 0, clear: clearAll });
1910
+ return () => setClearable(clearId, null);
1911
+ }, [clearId, chips.length, clearAll, setClearable]);
1912
+ useEffect(() => {
1913
+ const field = fieldNode;
1914
+ if (!field) return;
1915
+ const handleKeyDown = (event) => {
1916
+ if (event.isComposing) return;
1917
+ if (event.key === "Enter" || separator && event.key === separator) {
1918
+ if (!field.value.trim()) return;
1919
+ event.preventDefault();
1920
+ addChip(field.value);
1921
+ setNativeValue(field, "");
1922
+ } else if (event.key === "Backspace" && field.value === "") {
1923
+ removeLast();
1924
+ }
1925
+ };
1926
+ field.addEventListener("keydown", handleKeyDown);
1927
+ return () => field.removeEventListener("keydown", handleKeyDown);
1928
+ }, [fieldNode, addChip, removeLast, separator]);
846
1929
  return /* @__PURE__ */ jsxs(Component, { ...rendered, ref, ...rootAttrs, children: [
847
- startContent != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", ...slotAttrs("startContent"), children: startContent }),
848
- children,
849
- endContent != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", ...slotAttrs("endContent"), children: endContent })
1930
+ chips.map((chip, index) => (
1931
+ // Render the shared Chip token in the input's neutral/outlined parity
1932
+ // look. `autoDismiss={false}` because Input.Chips owns the tag array
1933
+ // removal must flow through onRemove into our state, not the chip's own.
1934
+ /* @__PURE__ */ jsx(
1935
+ Chip,
1936
+ {
1937
+ appearance: "outlined",
1938
+ variant: "neutral",
1939
+ size,
1940
+ removable: !disabled && !readOnly,
1941
+ disabled: disabled || readOnly,
1942
+ autoDismiss: false,
1943
+ slotProps: { remove: { "aria-label": `Remove ${chip}` } },
1944
+ onRemove: () => removeChip(index),
1945
+ children: chip
1946
+ },
1947
+ `${chip}-${index}`
1948
+ )
1949
+ )),
1950
+ children
850
1951
  ] });
851
1952
  };
852
- InputContainer.displayName = "Input.Container";
1953
+ InputChips.displayName = "Input.Chips";
1954
+ var InputClearButton = (props) => {
1955
+ const theme = useComponentTheme("InputClearButton");
1956
+ const { disabled, readOnly } = useInputContext();
1957
+ const { size, fieldRef, fieldValue, setFieldValue, hasAuxContent, clearAux } = useInputOwnContext("Input.ClearButton");
1958
+ const { rootAttrs, rest } = composeRootAttrs(InputClearButtonBase, props, theme);
1959
+ const {
1960
+ onClick: slotOnClick,
1961
+ onKeyDown: slotOnKeyDown,
1962
+ ...clearRootAttrs
1963
+ } = rootAttrs;
1964
+ const { children, onClear, onClick, onKeyDown, ref, "type": _type, "aria-label": ariaLabel = "Clear input", ...buttonProps } = rest;
1965
+ if (disabled || readOnly || fieldValue === "" && !hasAuxContent) return null;
1966
+ const clear = () => {
1967
+ clearAux();
1968
+ const field = fieldRef.current;
1969
+ if (field) {
1970
+ setNativeValue(field, "");
1971
+ setFieldValue("");
1972
+ }
1973
+ onClear?.();
1974
+ field?.focus();
1975
+ };
1976
+ const handleClick = (event) => {
1977
+ onClick?.(event);
1978
+ slotOnClick?.(event);
1979
+ if (event.defaultPrevented) return;
1980
+ clear();
1981
+ };
1982
+ const handleKeyDown = (event) => {
1983
+ onKeyDown?.(event);
1984
+ slotOnKeyDown?.(event);
1985
+ if (event.defaultPrevented || event.key !== "Escape") return;
1986
+ event.preventDefault();
1987
+ clear();
1988
+ };
1989
+ return /* @__PURE__ */ jsx(
1990
+ Button,
1991
+ {
1992
+ ...buttonProps,
1993
+ ...clearRootAttrs,
1994
+ ref,
1995
+ type: "button",
1996
+ appearance: "text",
1997
+ rounded: true,
1998
+ size,
1999
+ "aria-label": ariaLabel,
2000
+ onClick: handleClick,
2001
+ onKeyDown: handleKeyDown,
2002
+ startContent: children ?? /* @__PURE__ */ jsx(PlaceholderClose, {})
2003
+ }
2004
+ );
2005
+ };
2006
+ InputClearButton.displayName = "Input.ClearButton";
2007
+ var InputDecrement = (props) => {
2008
+ const theme = useComponentTheme("InputDecrement");
2009
+ const { disabled, readOnly } = useInputContext();
2010
+ const { size, fieldRef } = useInputOwnContext("Input.Decrement");
2011
+ const { rootAttrs, rest } = composeRootAttrs(InputDecrementBase, props, theme);
2012
+ const { onClick: slotOnClick, ...decrementRootAttrs } = rootAttrs;
2013
+ const { children, onClick, ref, "type": _type, "disabled": _disabled, "aria-label": ariaLabel = "Decrement value", ...buttonProps } = rest;
2014
+ const handleClick = (event) => {
2015
+ onClick?.(event);
2016
+ slotOnClick?.(event);
2017
+ if (event.defaultPrevented) return;
2018
+ stepField(fieldRef.current, "down");
2019
+ };
2020
+ return /* @__PURE__ */ jsx(
2021
+ Button,
2022
+ {
2023
+ ...buttonProps,
2024
+ ...decrementRootAttrs,
2025
+ ref,
2026
+ type: "button",
2027
+ appearance: "text",
2028
+ rounded: true,
2029
+ size,
2030
+ disabled: disabled || readOnly,
2031
+ "aria-label": ariaLabel,
2032
+ onClick: handleClick,
2033
+ startContent: children ?? /* @__PURE__ */ jsx(PlaceholderChevronDown, {})
2034
+ }
2035
+ );
2036
+ };
2037
+ InputDecrement.displayName = "Input.Decrement";
853
2038
  var InputField = (props) => {
854
2039
  const theme = useComponentTheme("InputField");
855
- const { size } = useInputOwnContext("Input.Field");
856
- const { rootAttrs, rest } = composeRootAttrs(InputFieldBase, props, theme, {
857
- stateAttrs: () => ({
858
- "data-size": size
859
- })
860
- });
861
- const { ref, ...spar } = rest;
862
- return /* @__PURE__ */ jsx(InputField$1, { ...spar, ref, ...rootAttrs });
2040
+ const { fieldRef, setFieldNode, setFieldValue, revealed, setRevealed } = useInputOwnContext("Input.Field");
2041
+ const { rootAttrs, rest } = composeRootAttrs(InputFieldBase, props, theme);
2042
+ const { as, ref, type, onInput, onChange, ...spar } = rest;
2043
+ const effectiveType = type === "password" && revealed ? "text" : type;
2044
+ const renderedType = as === "textarea" ? void 0 : effectiveType;
2045
+ const setFieldRef = useCallback(
2046
+ (node) => {
2047
+ fieldRef.current = node;
2048
+ setFieldNode(node);
2049
+ if (node) setFieldValue(node.value);
2050
+ if (typeof ref === "function") {
2051
+ ref(node);
2052
+ } else if (ref) {
2053
+ ref.current = node;
2054
+ }
2055
+ },
2056
+ [fieldRef, ref, setFieldNode, setFieldValue]
2057
+ );
2058
+ useEffect(() => {
2059
+ const node = fieldRef.current;
2060
+ if (node) setFieldValue(node.value);
2061
+ }, [fieldRef, setFieldValue, spar.value, spar.defaultValue]);
2062
+ useEffect(() => () => setRevealed(false), [setRevealed]);
2063
+ const handleInput = (event) => {
2064
+ onInput?.(event);
2065
+ setFieldValue(event.currentTarget.value);
2066
+ };
2067
+ const handleChange = (event) => {
2068
+ onChange?.(event);
2069
+ setFieldValue(event.currentTarget.value);
2070
+ };
2071
+ return /* @__PURE__ */ jsx(
2072
+ InputField$1,
2073
+ {
2074
+ ...spar,
2075
+ as,
2076
+ type: renderedType,
2077
+ onInput: handleInput,
2078
+ onChange: handleChange,
2079
+ ref: setFieldRef,
2080
+ ...rootAttrs
2081
+ }
2082
+ );
863
2083
  };
864
2084
  InputField.displayName = "Input.Field";
865
- var InputPrefix = (props) => {
866
- const theme = useComponentTheme("InputPrefix");
867
- const Component = props.as ?? "span";
868
- const { rootAttrs, rest } = composeRootAttrs(InputPrefixBase, props, theme);
869
- const { as: _as, children, ref, ...rendered } = rest;
870
- return /* @__PURE__ */ jsx(Component, { ...rendered, ref, ...rootAttrs, children });
2085
+ var InputIncrement = (props) => {
2086
+ const theme = useComponentTheme("InputIncrement");
2087
+ const { disabled, readOnly } = useInputContext();
2088
+ const { size, fieldRef } = useInputOwnContext("Input.Increment");
2089
+ const { rootAttrs, rest } = composeRootAttrs(InputIncrementBase, props, theme);
2090
+ const { onClick: slotOnClick, ...incrementRootAttrs } = rootAttrs;
2091
+ const { children, onClick, ref, "type": _type, "disabled": _disabled, "aria-label": ariaLabel = "Increment value", ...buttonProps } = rest;
2092
+ const handleClick = (event) => {
2093
+ onClick?.(event);
2094
+ slotOnClick?.(event);
2095
+ if (event.defaultPrevented) return;
2096
+ stepField(fieldRef.current, "up");
2097
+ };
2098
+ return /* @__PURE__ */ jsx(
2099
+ Button,
2100
+ {
2101
+ ...buttonProps,
2102
+ ...incrementRootAttrs,
2103
+ ref,
2104
+ type: "button",
2105
+ appearance: "text",
2106
+ rounded: true,
2107
+ size,
2108
+ disabled: disabled || readOnly,
2109
+ "aria-label": ariaLabel,
2110
+ onClick: handleClick,
2111
+ startContent: children ?? /* @__PURE__ */ jsx(PlaceholderChevronUp, {})
2112
+ }
2113
+ );
2114
+ };
2115
+ InputIncrement.displayName = "Input.Increment";
2116
+ var InputLeadingIcon = (props) => {
2117
+ const theme = useComponentTheme("InputLeadingIcon");
2118
+ useInputOwnContext("Input.LeadingIcon");
2119
+ const Component = props.as ?? "span";
2120
+ const { rootAttrs, rest } = composeRootAttrs(InputLeadingIconBase, props, theme);
2121
+ const { as: _as, children, ref, ...rendered } = rest;
2122
+ return /* @__PURE__ */ jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children });
2123
+ };
2124
+ InputLeadingIcon.displayName = "Input.LeadingIcon";
2125
+ var InputPrefix = (props) => {
2126
+ const theme = useComponentTheme("InputPrefix");
2127
+ useInputOwnContext("Input.Prefix");
2128
+ const Component = props.as ?? "span";
2129
+ const { rootAttrs, rest } = composeRootAttrs(InputPrefixBase, props, theme);
2130
+ const { as: _as, children, ref, ...rendered } = rest;
2131
+ return /* @__PURE__ */ jsx(Component, { ...rendered, ref, ...rootAttrs, children });
871
2132
  };
872
2133
  InputPrefix.displayName = "Input.Prefix";
2134
+ var InputRevealButton = (props) => {
2135
+ const theme = useComponentTheme("InputRevealButton");
2136
+ const { disabled, readOnly } = useInputContext();
2137
+ const { size, fieldRef, revealed, setRevealed, toggleReveal } = useInputOwnContext("Input.RevealButton");
2138
+ const { rootAttrs, rest } = composeRootAttrs(InputRevealButtonBase, props, theme);
2139
+ const { onClick: slotOnClick, ...revealRootAttrs } = rootAttrs;
2140
+ const { children, onClick, ref, "type": _type, "aria-label": _ariaLabel, "aria-pressed": _ariaPressed, ...buttonProps } = rest;
2141
+ useEffect(() => {
2142
+ if (!revealed) return;
2143
+ const form = fieldRef.current?.form;
2144
+ if (!form) return;
2145
+ const handleSubmit = () => setRevealed(false);
2146
+ form.addEventListener("submit", handleSubmit);
2147
+ return () => form.removeEventListener("submit", handleSubmit);
2148
+ }, [revealed, fieldRef, setRevealed]);
2149
+ const handleClick = (event) => {
2150
+ onClick?.(event);
2151
+ slotOnClick?.(event);
2152
+ if (event.defaultPrevented) return;
2153
+ toggleReveal();
2154
+ fieldRef.current?.focus();
2155
+ };
2156
+ return /* @__PURE__ */ jsx(
2157
+ Button,
2158
+ {
2159
+ ...buttonProps,
2160
+ ...revealRootAttrs,
2161
+ ref,
2162
+ type: "button",
2163
+ appearance: "text",
2164
+ rounded: true,
2165
+ size,
2166
+ disabled: disabled || readOnly,
2167
+ "aria-label": "Toggle password visibility",
2168
+ "aria-pressed": revealed,
2169
+ onClick: handleClick,
2170
+ startContent: children ?? (revealed ? /* @__PURE__ */ jsx(PlaceholderEyeOff, {}) : /* @__PURE__ */ jsx(PlaceholderEye, {}))
2171
+ }
2172
+ );
2173
+ };
2174
+ InputRevealButton.displayName = "Input.RevealButton";
2175
+ var InputSpinner = (props) => {
2176
+ const theme = useComponentTheme("InputSpinner");
2177
+ useInputOwnContext("Input.Spinner");
2178
+ const Component = props.as ?? "span";
2179
+ const { rootAttrs, rest } = composeRootAttrs(InputSpinnerBase, props, theme);
2180
+ const { as: _as, children, ref, ...rendered } = rest;
2181
+ return /* @__PURE__ */ jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children: children ?? /* @__PURE__ */ jsx("span", { className: "tk-input-default-spinner" }) });
2182
+ };
2183
+ InputSpinner.displayName = "Input.Spinner";
2184
+ var InputStepper = (props) => {
2185
+ const theme = useComponentTheme("InputStepper");
2186
+ useInputOwnContext("Input.Stepper");
2187
+ const Component = props.as ?? "div";
2188
+ const { rootAttrs, rest } = composeRootAttrs(InputStepperBase, props, theme);
2189
+ const { as: _as, children, ref, ...rendered } = rest;
2190
+ return /* @__PURE__ */ jsx(Component, { ...rendered, ref, ...rootAttrs, children });
2191
+ };
2192
+ InputStepper.displayName = "Input.Stepper";
873
2193
  var InputSuffix = (props) => {
874
2194
  const theme = useComponentTheme("InputSuffix");
2195
+ useInputOwnContext("Input.Suffix");
875
2196
  const Component = props.as ?? "span";
876
2197
  const { rootAttrs, rest } = composeRootAttrs(InputSuffixBase, props, theme);
877
2198
  const { as: _as, children, ref, ...rendered } = rest;
878
2199
  return /* @__PURE__ */ jsx(Component, { ...rendered, ref, ...rootAttrs, children });
879
2200
  };
880
2201
  InputSuffix.displayName = "Input.Suffix";
2202
+ var InputTrailingIcon = (props) => {
2203
+ const theme = useComponentTheme("InputTrailingIcon");
2204
+ useInputOwnContext("Input.TrailingIcon");
2205
+ const Component = props.as ?? "span";
2206
+ const { rootAttrs, rest } = composeRootAttrs(InputTrailingIconBase, props, theme);
2207
+ const { as: _as, children, ref, ...rendered } = rest;
2208
+ return /* @__PURE__ */ jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children });
2209
+ };
2210
+ InputTrailingIcon.displayName = "Input.TrailingIcon";
881
2211
 
882
2212
  // src/components/input/index.ts
883
2213
  var Input2 = Object.assign(Input, {
884
- Container: InputContainer,
885
2214
  Field: InputField,
886
2215
  Prefix: InputPrefix,
887
- Suffix: InputSuffix
2216
+ Suffix: InputSuffix,
2217
+ LeadingIcon: InputLeadingIcon,
2218
+ TrailingIcon: InputTrailingIcon,
2219
+ ClearButton: InputClearButton,
2220
+ Spinner: InputSpinner,
2221
+ RevealButton: InputRevealButton,
2222
+ Strength: InputStrength,
2223
+ Stepper: InputStepper,
2224
+ Decrement: InputDecrement,
2225
+ Increment: InputIncrement,
2226
+ Chips: InputChips
2227
+ });
2228
+
2229
+ // src/components/label/base.ts
2230
+ var LabelBase = createComponentBase({
2231
+ name: "Label",
2232
+ slots: ["root"],
2233
+ classes: { root: "tk-label" }
888
2234
  });
2235
+ var Label = (props) => {
2236
+ const theme = useComponentTheme("Label");
2237
+ const { rootAttrs, rest } = composeRootAttrs(LabelBase, props, theme);
2238
+ const { as, children, ref, ...sparProps } = rest;
2239
+ return /* @__PURE__ */ jsx(Label$1, { ...sparProps, as, ref, ...rootAttrs, children });
2240
+ };
2241
+ Label.displayName = "Label";
889
2242
 
890
2243
  // src/components/radio/base.ts
891
2244
  var RadioBase = createComponentBase({
@@ -918,22 +2271,19 @@ var RADIO_ITEM_CONTEXT_VALUE = { inside: true };
918
2271
  var [RadioItemProvider, useRadioItemOwnContext] = createSafeContext("RadioItemProvider");
919
2272
 
920
2273
  // src/components/radio/defaults.ts
921
- var DEFAULT_SIZE6 = "base";
922
- var DEFAULT_TYPE3 = "default";
2274
+ var DEFAULT_SIZE9 = "base";
923
2275
  var DEFAULT_POSITION = "left";
924
2276
  var Radio = (props) => {
925
2277
  const theme = useComponentTheme("Radio");
926
2278
  const { rootAttrs, rest } = composeRootAttrs(RadioBase, props, theme, {
927
- stateAttrs: ({ size: size2 = DEFAULT_SIZE6, type: type2 = DEFAULT_TYPE3, position: position2 = DEFAULT_POSITION, spread }) => ({
2279
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE9, position: position2 = DEFAULT_POSITION, spread }) => ({
928
2280
  "data-size": size2,
929
- "data-type": type2,
930
2281
  "data-position": position2,
931
2282
  "data-spread": spread ? "" : void 0
932
2283
  })
933
2284
  });
934
2285
  const {
935
- size = DEFAULT_SIZE6,
936
- type = DEFAULT_TYPE3,
2286
+ size = DEFAULT_SIZE9,
937
2287
  position = DEFAULT_POSITION,
938
2288
  invalid,
939
2289
  // `spread` is consumed only as a data-attr above; destructure to keep it
@@ -944,7 +2294,7 @@ var Radio = (props) => {
944
2294
  ref,
945
2295
  ...sparProps
946
2296
  } = rest;
947
- return /* @__PURE__ */ jsx(RadioGroupProvider, { value: { size, type, position }, children: /* @__PURE__ */ jsx(Radio$1, { ...sparProps, invalid, ...rootAttrs, ref, children }) });
2297
+ return /* @__PURE__ */ jsx(RadioGroupProvider, { value: { size, position }, children: /* @__PURE__ */ jsx(Radio$1, { ...sparProps, invalid, ...rootAttrs, ref, children }) });
948
2298
  };
949
2299
  Radio.displayName = "Radio";
950
2300
  var RadioIndicator = (props) => {
@@ -968,7 +2318,6 @@ var RadioItem = (props) => {
968
2318
  const { rootAttrs, rest } = composeRootAttrs(RadioItemBase, props, theme, {
969
2319
  stateAttrs: ({ position }) => ({
970
2320
  "data-size": group.size,
971
- "data-type": group.type,
972
2321
  "data-position": position ?? group.position
973
2322
  })
974
2323
  });
@@ -1052,11 +2401,11 @@ var PopoverTrigger = (props) => {
1052
2401
  PopoverTrigger.displayName = "Popover.Trigger";
1053
2402
 
1054
2403
  // src/components/popover/defaults.ts
1055
- var DEFAULT_VARIANT3 = "dark";
2404
+ var DEFAULT_VARIANT5 = "white";
1056
2405
  var PopoverContent = (props) => {
1057
2406
  const theme = useComponentTheme("PopoverContent");
1058
2407
  const { rootAttrs, rest } = composeRootAttrs(PopoverContentBase, props, theme, {
1059
- stateAttrs: ({ variant = DEFAULT_VARIANT3 }) => ({
2408
+ stateAttrs: ({ variant = DEFAULT_VARIANT5 }) => ({
1060
2409
  "data-variant": variant
1061
2410
  })
1062
2411
  });
@@ -1081,8 +2430,8 @@ PopoverDescription.displayName = "Popover.Description";
1081
2430
  var PopoverArrow = (props) => {
1082
2431
  const theme = useComponentTheme("PopoverArrow");
1083
2432
  const { rootAttrs, rest } = composeRootAttrs(PopoverArrowBase, props, theme);
1084
- const { ref, ...sparProps } = rest;
1085
- return /* @__PURE__ */ jsx(PopoverArrow$1, { ...sparProps, ...rootAttrs, ref });
2433
+ const { ref, children, ...sparProps } = rest;
2434
+ return /* @__PURE__ */ jsx(PopoverArrow$1, { ...sparProps, ...rootAttrs, ref, children: children ?? renderPointerArrow() });
1086
2435
  };
1087
2436
  PopoverArrow.displayName = "Popover.Arrow";
1088
2437
  var PopoverClose = (props) => {
@@ -1103,6 +2452,193 @@ var Popover2 = Object.assign(Popover, {
1103
2452
  Close: PopoverClose
1104
2453
  });
1105
2454
 
2455
+ // src/components/progress/base.ts
2456
+ var ProgressBase = createComponentBase({
2457
+ name: "Progress",
2458
+ slots: ["root"],
2459
+ classes: { root: "tk-progress" }
2460
+ });
2461
+ var ProgressTrackBase = createComponentBase({
2462
+ name: "ProgressTrack",
2463
+ slots: ["root", "rail"],
2464
+ classes: { root: "tk-progress-track", rail: "tk-progress-rail" }
2465
+ });
2466
+ var ProgressIndicatorBase = createComponentBase({
2467
+ name: "ProgressIndicator",
2468
+ slots: ["root"],
2469
+ classes: { root: "tk-progress-indicator" }
2470
+ });
2471
+ var ProgressValueBase = createComponentBase({
2472
+ name: "ProgressValue",
2473
+ slots: ["root"],
2474
+ classes: { root: "tk-progress-value" }
2475
+ });
2476
+
2477
+ // src/components/progress/context.ts
2478
+ var [ProgressProvider, useProgressContext] = createSafeContext("ProgressProvider");
2479
+
2480
+ // src/components/progress/defaults.ts
2481
+ var DEFAULT_APPEARANCE6 = "linear";
2482
+ var DEFAULT_SIZE10 = "base";
2483
+ var DEFAULT_VARIANT6 = "primary";
2484
+ var DEFAULT_MIN = 0;
2485
+ var DEFAULT_MAX = 100;
2486
+ var DEFAULT_RANGE = 100;
2487
+ var DEFAULT_ARIA_LABEL = "Progress";
2488
+ var RING_VIEWBOX = "0 0 40 40";
2489
+ var RING_CENTER = 20;
2490
+ var RING_RADIUS = 18;
2491
+ var ProgressIndicator = (props) => {
2492
+ const theme = useComponentTheme("ProgressIndicator");
2493
+ const { value, min, max, appearance, indeterminate } = useProgressContext("Progress.Indicator");
2494
+ const percent = Math.min(100, Math.max(0, (value - min) * 100 / (max - min)));
2495
+ const { rootAttrs, rest } = composeRootAttrs(ProgressIndicatorBase, props, theme, {
2496
+ stateAttrs: () => ({
2497
+ "data-type": appearance,
2498
+ "data-indeterminate": indeterminate ? "" : void 0
2499
+ })
2500
+ });
2501
+ const { ref, style, ...nativeProps } = rest;
2502
+ const { style: slotStyle, ...slotAttrs } = rootAttrs;
2503
+ if (appearance === "circular") {
2504
+ return /* @__PURE__ */ jsx(
2505
+ "circle",
2506
+ {
2507
+ cx: RING_CENTER,
2508
+ cy: RING_CENTER,
2509
+ r: RING_RADIUS,
2510
+ ...nativeProps,
2511
+ ...slotAttrs,
2512
+ pathLength: "100",
2513
+ style: { ...style, ...slotStyle, strokeDasharray: 100, strokeDashoffset: indeterminate ? void 0 : 100 - percent },
2514
+ ref
2515
+ }
2516
+ );
2517
+ }
2518
+ return /* @__PURE__ */ jsx("span", { ...nativeProps, ...slotAttrs, "aria-hidden": "true", style: { ...style, ...slotStyle, width: indeterminate ? void 0 : `${percent}%` }, ref });
2519
+ };
2520
+ ProgressIndicator.displayName = "Progress.Indicator";
2521
+ var ProgressTrack = (props) => {
2522
+ const theme = useComponentTheme("ProgressTrack");
2523
+ const { appearance } = useProgressContext("Progress.Track");
2524
+ const { rootAttrs, rest } = composeRootAttrs(ProgressTrackBase, props, theme, {
2525
+ stateAttrs: () => ({ "data-type": appearance })
2526
+ });
2527
+ const { children, ref, ...nativeProps } = rest;
2528
+ const content = children ?? /* @__PURE__ */ jsx(ProgressIndicator, {});
2529
+ if (appearance === "circular") {
2530
+ const railAttrs = buildSlotAttrs(ProgressTrackBase.getSlotProps("rail"), "rail", {
2531
+ themeSlotProps: theme?.slotProps,
2532
+ themeClassNames: theme?.classNames,
2533
+ instanceSlotProps: props.slotProps,
2534
+ instanceClassNames: props.classNames
2535
+ });
2536
+ return (
2537
+ // The decorative role and the ring geometry are design-system
2538
+ // invariants (the value is announced by the root; the viewBox must
2539
+ // agree with the rail/arc circles) — layered after the spreads so
2540
+ // neither instance nor slot props can override them.
2541
+ /* @__PURE__ */ jsxs("svg", { ...nativeProps, ...rootAttrs, "aria-hidden": "true", focusable: "false", viewBox: RING_VIEWBOX, ref, children: [
2542
+ /* @__PURE__ */ jsx("circle", { ...railAttrs, cx: RING_CENTER, cy: RING_CENTER, r: RING_RADIUS }),
2543
+ content
2544
+ ] })
2545
+ );
2546
+ }
2547
+ return /* @__PURE__ */ jsx("div", { ...nativeProps, ...rootAttrs, ref, children: content });
2548
+ };
2549
+ ProgressTrack.displayName = "Progress.Track";
2550
+ var resolveRange = ({ value: rawValue, min: rawMin = DEFAULT_MIN, max: rawMax = DEFAULT_MAX }) => {
2551
+ const min = Number.isFinite(rawMin) ? rawMin : DEFAULT_MIN;
2552
+ const max = Number.isFinite(rawMax) && rawMax > min ? rawMax : min + DEFAULT_RANGE;
2553
+ const value = typeof rawValue === "number" && Number.isFinite(rawValue) ? Math.min(Math.max(rawValue, min), max) : min;
2554
+ return { min, max, value };
2555
+ };
2556
+ var warnedRanges = /* @__PURE__ */ new Set();
2557
+ var Progress = (props) => {
2558
+ const theme = useComponentTheme("Progress");
2559
+ const field = useOptionalFieldContext();
2560
+ const resolveState = ({
2561
+ indeterminate: indeterminate2 = false,
2562
+ appearance: appearance2 = DEFAULT_APPEARANCE6,
2563
+ size: size2 = DEFAULT_SIZE10,
2564
+ variant: variant2 = DEFAULT_VARIANT6,
2565
+ disabled: disabled2 = field?.disabled ?? false
2566
+ }) => ({ indeterminate: indeterminate2, appearance: appearance2, size: size2, variant: variant2, disabled: disabled2 });
2567
+ const { rootAttrs, rest } = composeRootAttrs(ProgressBase, props, theme);
2568
+ const {
2569
+ // Consumed through resolveState/resolveRange (and as the root data-* hooks
2570
+ // below); destructured so the <div> doesn't receive unknown DOM
2571
+ // attributes.
2572
+ value: _value,
2573
+ min: _min,
2574
+ max: rawMax,
2575
+ indeterminate: _indeterminate,
2576
+ appearance: _appearance,
2577
+ disabled: _disabled,
2578
+ size: _size,
2579
+ variant: _variant,
2580
+ as,
2581
+ children,
2582
+ ref,
2583
+ ...nativeProps
2584
+ } = rest;
2585
+ const { indeterminate, appearance, size, variant, disabled } = resolveState(rest);
2586
+ const { min, max, value } = resolveRange(rest);
2587
+ const dataAttrs = {
2588
+ "data-type": appearance,
2589
+ "data-size": size,
2590
+ "data-variant": variant,
2591
+ "data-disabled": disabled ? "" : void 0,
2592
+ "data-indeterminate": indeterminate ? "" : void 0,
2593
+ // Styling hook for the finished state (e.g. a success fill at 100%);
2594
+ // meaningless while indeterminate, so dropped alongside the value.
2595
+ "data-complete": !indeterminate && value === max ? "" : void 0
2596
+ };
2597
+ if (isDevelopment() && typeof rawMax === "number" && Number.isFinite(rawMax) && rawMax <= min) {
2598
+ const message = `[Progress] \`max\` (${rawMax}) must be greater than \`min\` (${min}); falling back to ${max}.`;
2599
+ if (!warnedRanges.has(message)) {
2600
+ warnedRanges.add(message);
2601
+ console.warn(message);
2602
+ }
2603
+ }
2604
+ const consumerLabelledBy = nativeProps["aria-labelledby"];
2605
+ const accessibilityAttrs = {
2606
+ "role": nativeProps.role ?? "progressbar",
2607
+ "aria-valuemin": min,
2608
+ "aria-valuemax": max,
2609
+ // Per the progressbar pattern, an indeterminate bar exposes no
2610
+ // aria-valuenow — assistive tech then announces it as busy rather than
2611
+ // stuck at a bogus percentage.
2612
+ "aria-valuenow": indeterminate ? void 0 : value,
2613
+ // aria-valuetext accompanies aria-valuenow; drop it while indeterminate so
2614
+ // a consumer-formatted value can't linger next to a busy bar.
2615
+ "aria-valuetext": indeterminate ? void 0 : nativeProps["aria-valuetext"],
2616
+ "aria-labelledby": consumerLabelledBy ?? field?.labelId,
2617
+ "aria-label": nativeProps["aria-label"] ?? (consumerLabelledBy ? void 0 : DEFAULT_ARIA_LABEL),
2618
+ "aria-disabled": disabled || void 0
2619
+ };
2620
+ const Component = as ?? "div";
2621
+ return /* @__PURE__ */ jsx(ProgressProvider, { value: { value, min, max, appearance, indeterminate }, children: /* @__PURE__ */ jsx(Component, { ...nativeProps, ...accessibilityAttrs, ...rootAttrs, ...dataAttrs, ref, children: children ?? /* @__PURE__ */ jsx(ProgressTrack, {}) }) });
2622
+ };
2623
+ Progress.displayName = "Progress";
2624
+ var ProgressValue = (props) => {
2625
+ const theme = useComponentTheme("ProgressValue");
2626
+ const { appearance } = useProgressContext("Progress.Value");
2627
+ const { rootAttrs, rest } = composeRootAttrs(ProgressValueBase, props, theme, {
2628
+ stateAttrs: () => ({ "data-type": appearance })
2629
+ });
2630
+ const { children, ref, ...nativeProps } = rest;
2631
+ return /* @__PURE__ */ jsx("span", { ...nativeProps, ...rootAttrs, "aria-hidden": "true", ref, children });
2632
+ };
2633
+ ProgressValue.displayName = "Progress.Value";
2634
+
2635
+ // src/components/progress/index.ts
2636
+ var Progress2 = Object.assign(Progress, {
2637
+ Track: ProgressTrack,
2638
+ Indicator: ProgressIndicator,
2639
+ Value: ProgressValue
2640
+ });
2641
+
1106
2642
  // src/components/select/base.ts
1107
2643
  var SelectBase = createComponentBase({
1108
2644
  name: "Select",
@@ -1111,14 +2647,33 @@ var SelectBase = createComponentBase({
1111
2647
  });
1112
2648
  var SelectTriggerBase = createComponentBase({
1113
2649
  name: "SelectTrigger",
2650
+ slots: ["root", "value", "indicator"],
2651
+ classes: {
2652
+ root: "tk-select-trigger",
2653
+ // Truncating value region wrapping the selected label/placeholder; pins the
2654
+ // indicator to the trailing edge of the `space-between` trigger.
2655
+ value: "tk-select-value",
2656
+ // Wrapper around the built-in trigger indicator. Shares the
2657
+ // `tk-select-indicator` recipe with the standalone Select.Indicator so both
2658
+ // entry points style identically.
2659
+ indicator: "tk-select-indicator"
2660
+ }
2661
+ });
2662
+ var SelectIndicatorBase = createComponentBase({
2663
+ name: "SelectIndicator",
1114
2664
  slots: ["root"],
1115
- classes: { root: "tk-select-trigger" }
2665
+ classes: { root: "tk-select-indicator" }
1116
2666
  });
1117
2667
  var SelectContentBase = createComponentBase({
1118
2668
  name: "SelectContent",
1119
2669
  slots: ["root"],
1120
2670
  classes: { root: "tk-select-content" }
1121
2671
  });
2672
+ var SelectViewportBase = createComponentBase({
2673
+ name: "SelectViewport",
2674
+ slots: ["root"],
2675
+ classes: { root: "tk-select-viewport" }
2676
+ });
1122
2677
  var SelectItemBase = createComponentBase({
1123
2678
  name: "SelectItem",
1124
2679
  slots: ["root"],
@@ -1139,22 +2694,27 @@ var SelectSeparatorBase = createComponentBase({
1139
2694
  slots: ["root"],
1140
2695
  classes: { root: "tk-select-separator" }
1141
2696
  });
2697
+ var SelectArrowBase = createComponentBase({
2698
+ name: "SelectArrow",
2699
+ slots: ["root"],
2700
+ classes: { root: "tk-select-arrow" }
2701
+ });
1142
2702
 
1143
2703
  // src/components/select/context.ts
1144
2704
  var [SelectProvider, useSelectOwnContext] = createSafeContext("SelectProvider");
1145
2705
 
1146
2706
  // src/components/select/defaults.ts
1147
- var DEFAULT_SIZE7 = "base";
1148
- var DEFAULT_CONTENT_WIDTH = "trigger";
2707
+ var DEFAULT_SIZE11 = "base";
2708
+ var DEFAULT_CONTENT_WIDTH2 = "trigger";
1149
2709
  var Select = (props) => {
1150
2710
  const theme = useComponentTheme("Select");
1151
2711
  const { rootAttrs, rest } = composeRootAttrs(SelectBase, props, theme, {
1152
- stateAttrs: ({ size: size2 = DEFAULT_SIZE7, invalid: invalid2 }) => ({
2712
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE11, invalid: invalid2 }) => ({
1153
2713
  "data-size": size2,
1154
2714
  "data-invalid": invalid2 ? "" : void 0
1155
2715
  })
1156
2716
  });
1157
- const { size = DEFAULT_SIZE7, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH, children, ref, ...sparProps } = rest;
2717
+ const { size = DEFAULT_SIZE11, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH2, children, ref, ...sparProps } = rest;
1158
2718
  return /* @__PURE__ */ jsx(SelectProvider, { value: { size, invalid, contentWidth }, children: /* @__PURE__ */ jsx(Select$1, { ...sparProps, ref, ...rootAttrs, children }) });
1159
2719
  };
1160
2720
  Select.displayName = "Select";
@@ -1167,85 +2727,1095 @@ var SelectTrigger = (props) => {
1167
2727
  "data-invalid": invalid ? "" : void 0
1168
2728
  })
1169
2729
  });
1170
- const { children, ref, ...spar } = rest;
1171
- return /* @__PURE__ */ jsx(SelectTrigger$1, { ...spar, ref, ...rootAttrs, children });
2730
+ const { children, indicator, ref, ...spar } = rest;
2731
+ const showIndicator = indicator !== false && indicator !== null;
2732
+ const consumerOwnsLayout = typeof children === "function";
2733
+ if (!showIndicator || consumerOwnsLayout) {
2734
+ return /* @__PURE__ */ jsx(SelectTrigger$1, { ...spar, ref, ...rootAttrs, children });
2735
+ }
2736
+ const resolveIndicatorNode = (state) => {
2737
+ if (indicator === void 0 || indicator === true) return state.isOpen ? DEFAULT_DISCLOSURE_COLLAPSE_ICON : DEFAULT_DISCLOSURE_EXPAND_ICON;
2738
+ if (typeof indicator === "function") return indicator(state);
2739
+ return indicator;
2740
+ };
2741
+ const slotLayers = {
2742
+ themeSlotProps: theme?.slotProps,
2743
+ themeClassNames: theme?.classNames,
2744
+ instanceSlotProps: props.slotProps,
2745
+ instanceClassNames: props.classNames
2746
+ };
2747
+ const valueAttrs = buildSlotAttrs(SelectTriggerBase.getSlotProps("value"), "value", slotLayers);
2748
+ const indicatorAttrs = buildSlotAttrs(SelectTriggerBase.getSlotProps("indicator"), "indicator", slotLayers);
2749
+ return /* @__PURE__ */ jsx(SelectTrigger$1, { ...spar, ref, ...rootAttrs, children: (state) => {
2750
+ const value = children ?? (state.label || spar.placeholder);
2751
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2752
+ /* @__PURE__ */ jsx("span", { ...valueAttrs, children: value }),
2753
+ /* @__PURE__ */ jsx("span", { ...indicatorAttrs, "aria-hidden": "true", children: resolveIndicatorNode({ isOpen: state.isOpen }) })
2754
+ ] });
2755
+ } });
1172
2756
  };
1173
2757
  SelectTrigger.displayName = "Select.Trigger";
1174
- var resolveStaticWidth = (mode) => {
1175
- if (mode === "trigger" || mode === "content") return void 0;
1176
- return typeof mode === "number" ? `${mode}px` : mode;
2758
+ var SelectIndicator = (props) => {
2759
+ const theme = useComponentTheme("SelectIndicator");
2760
+ const { isOpen } = useSelectContext();
2761
+ const Component = props.as ?? "span";
2762
+ const { rootAttrs, rest } = composeRootAttrs(SelectIndicatorBase, props, theme);
2763
+ const { as: _as, children, ref, ...rendered } = rest;
2764
+ const resolved = resolveDisclosureIndicator(children, isOpen);
2765
+ return /* @__PURE__ */ jsx(Component, { ...rendered, ref, "aria-hidden": "true", ...rootAttrs, children: resolved });
2766
+ };
2767
+ SelectIndicator.displayName = "Select.Indicator";
2768
+ var SelectContent = (props) => {
2769
+ const theme = useComponentTheme("SelectContent");
2770
+ const { size, contentWidth } = useSelectOwnContext("Select.Content");
2771
+ const { triggerRef } = useSelectContext();
2772
+ const widthStyle = useContentWidthStyle(contentWidth, triggerRef);
2773
+ const { rootAttrs, rest } = composeRootAttrs(SelectContentBase, props, theme, {
2774
+ stateAttrs: () => ({
2775
+ "data-size": size
2776
+ })
2777
+ });
2778
+ const { children, ref, style: userStyle, ...spar } = rest;
2779
+ const { style: rootStyle, ...rootRest } = rootAttrs;
2780
+ const mergedStyle = widthStyle || rootStyle || userStyle ? { ...widthStyle, ...rootStyle, ...userStyle } : void 0;
2781
+ return /* @__PURE__ */ jsx(SelectContent$1, { ...spar, ...rootRest, ref, style: mergedStyle, children });
2782
+ };
2783
+ SelectContent.displayName = "Select.Content";
2784
+ var SelectViewport = (props) => {
2785
+ const theme = useComponentTheme("SelectViewport");
2786
+ const { rootAttrs, rest } = composeRootAttrs(SelectViewportBase, props, theme);
2787
+ const { children, ref, ...spar } = rest;
2788
+ return /* @__PURE__ */ jsx(SelectViewport$1, { ...spar, ref, ...rootAttrs, children });
2789
+ };
2790
+ SelectViewport.displayName = "Select.Viewport";
2791
+ var SelectItem = (props) => {
2792
+ const theme = useComponentTheme("SelectItem");
2793
+ const { rootAttrs, rest } = composeRootAttrs(SelectItemBase, props, theme);
2794
+ const { value, disabled, label, children, ref, ...spar } = rest;
2795
+ return /* @__PURE__ */ jsx(SelectItem$1, { ...spar, value, disabled, label, ref, ...rootAttrs, children });
2796
+ };
2797
+ SelectItem.displayName = "Select.Item";
2798
+ var SelectGroup = (props) => {
2799
+ const theme = useComponentTheme("SelectGroup");
2800
+ const { rootAttrs, rest } = composeRootAttrs(SelectGroupBase, props, theme);
2801
+ const { children, ref, ...spar } = rest;
2802
+ return /* @__PURE__ */ jsx(SelectGroup$1, { ...spar, ref, ...rootAttrs, children });
2803
+ };
2804
+ SelectGroup.displayName = "Select.Group";
2805
+ var SelectLabel = (props) => {
2806
+ const theme = useComponentTheme("SelectLabel");
2807
+ const { rootAttrs, rest } = composeRootAttrs(SelectLabelBase, props, theme);
2808
+ const { children, ref, ...spar } = rest;
2809
+ return /* @__PURE__ */ jsx(SelectLabel$1, { ...spar, ref, ...rootAttrs, children });
2810
+ };
2811
+ SelectLabel.displayName = "Select.Label";
2812
+ var SelectSeparator = (props) => {
2813
+ const theme = useComponentTheme("SelectSeparator");
2814
+ const { rootAttrs, rest } = composeRootAttrs(SelectSeparatorBase, props, theme);
2815
+ const { children, ref, ...spar } = rest;
2816
+ return /* @__PURE__ */ jsx(SelectSeparator$1, { ...spar, ref, ...rootAttrs, children });
2817
+ };
2818
+ SelectSeparator.displayName = "Select.Separator";
2819
+ var SelectArrow = (props) => {
2820
+ const theme = useComponentTheme("SelectArrow");
2821
+ const { rootAttrs, rest } = composeRootAttrs(SelectArrowBase, props, theme);
2822
+ const { children, ref, ...sparProps } = rest;
2823
+ return /* @__PURE__ */ jsx(SelectArrow$1, { ...sparProps, ...rootAttrs, ref, children: children ?? renderPointerArrow() });
2824
+ };
2825
+ SelectArrow.displayName = "Select.Arrow";
2826
+
2827
+ // src/components/select/index.ts
2828
+ var Select2 = Object.assign(Select, {
2829
+ Trigger: SelectTrigger,
2830
+ Indicator: SelectIndicator,
2831
+ Content: SelectContent,
2832
+ Viewport: SelectViewport,
2833
+ Item: SelectItem,
2834
+ Group: SelectGroup,
2835
+ Label: SelectLabel,
2836
+ Separator: SelectSeparator,
2837
+ Arrow: SelectArrow
2838
+ });
2839
+
2840
+ // src/components/slider/base.ts
2841
+ var SliderBase = createComponentBase({
2842
+ name: "Slider",
2843
+ slots: ["root"],
2844
+ classes: { root: "tk-slider" }
2845
+ });
2846
+ var SliderTrackBase = createComponentBase({
2847
+ name: "SliderTrack",
2848
+ slots: ["root"],
2849
+ classes: { root: "tk-slider-track" }
2850
+ });
2851
+ var SliderRangeBase = createComponentBase({
2852
+ name: "SliderRange",
2853
+ slots: ["root"],
2854
+ classes: { root: "tk-slider-range" }
2855
+ });
2856
+ var SliderThumbBase = createComponentBase({
2857
+ name: "SliderThumb",
2858
+ slots: ["root", "tooltip", "arrow"],
2859
+ classes: { root: "tk-slider-thumb", tooltip: "tk-slider-tooltip", arrow: "tk-slider-arrow" }
2860
+ });
2861
+ var SliderTicksBase = createComponentBase({
2862
+ name: "SliderTicks",
2863
+ slots: ["root", "tick"],
2864
+ classes: { root: "tk-slider-ticks", tick: "tk-slider-tick" }
2865
+ });
2866
+ var SliderValueBase = createComponentBase({
2867
+ name: "SliderValue",
2868
+ slots: ["root"],
2869
+ classes: { root: "tk-slider-value" }
2870
+ });
2871
+
2872
+ // src/components/slider/context.ts
2873
+ var [SliderProvider, useSliderContext] = createSafeContext("SliderProvider");
2874
+
2875
+ // src/components/slider/defaults.ts
2876
+ var DEFAULT_ORIENTATION2 = "horizontal";
2877
+ var DEFAULT_SIZE12 = "base";
2878
+ var DEFAULT_VARIANT7 = "primary";
2879
+ var DEFAULT_TOOLTIP = "auto";
2880
+ var DEFAULT_TRACK = "normal";
2881
+ var DEFAULT_MIN_DISTANCE = 0;
2882
+ var DEFAULT_MIN2 = 0;
2883
+ var DEFAULT_MAX2 = 100;
2884
+ var DEFAULT_STEP = 1;
2885
+ var DEFAULT_SPAN = 100;
2886
+ var PAGE_STEP_MULTIPLIER = 10;
2887
+ var MAX_TICKS = 100;
2888
+ var RANGE_VALUE_SEPARATOR = " \u2013 ";
2889
+ var RANGE_THUMB_LABELS = ["Minimum", "Maximum"];
2890
+
2891
+ // src/components/slider/helpers.ts
2892
+ var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
2893
+ var decimalsOf = (value) => {
2894
+ if (!Number.isFinite(value)) return 0;
2895
+ const text = String(value);
2896
+ const exponent = text.indexOf("e-");
2897
+ if (exponent !== -1) {
2898
+ const fraction = text.slice(0, exponent).split(".")[1]?.length ?? 0;
2899
+ return fraction + Number(text.slice(exponent + 2));
2900
+ }
2901
+ const dot = text.indexOf(".");
2902
+ return dot === -1 ? 0 : text.length - dot - 1;
2903
+ };
2904
+ var roundTo = (value, decimals) => decimals > 0 ? Number(value.toFixed(Math.min(decimals, 15))) : Math.round(value);
2905
+ var resolveBounds = (rawMin = DEFAULT_MIN2, rawMax = DEFAULT_MAX2, rawStep = DEFAULT_STEP) => {
2906
+ const min = Number.isFinite(rawMin) ? rawMin : DEFAULT_MIN2;
2907
+ const max = Number.isFinite(rawMax) && rawMax > min ? rawMax : min + DEFAULT_SPAN;
2908
+ const step = Number.isFinite(rawStep) && rawStep > 0 ? rawStep : DEFAULT_STEP;
2909
+ return { min, max, step };
2910
+ };
2911
+ var snap = (value, { min, max, step }) => {
2912
+ if (!Number.isFinite(value)) return min;
2913
+ const steps = Math.round((value - min) / step);
2914
+ const snapped = min + steps * step;
2915
+ return clamp(roundTo(snapped, Math.max(decimalsOf(step), decimalsOf(min))), min, max);
2916
+ };
2917
+ var toPercent = (value, { min, max }) => clamp((value - min) * 100 / (max - min), 0, 100);
2918
+ var fromRatio = (ratio, { min, max }) => min + ratio * (max - min);
2919
+ var pointerCoord = (event, orientation) => orientation === "vertical" ? event.clientY : event.clientX;
2920
+ var valueFromPointer = (rect, point, bounds, orientation) => {
2921
+ const ratio = orientation === "vertical" ? rect.height === 0 ? 0 : (rect.bottom - point) / rect.height : rect.width === 0 ? 0 : (point - rect.left) / rect.width;
2922
+ return snap(fromRatio(clamp(ratio, 0, 1), bounds), bounds);
2923
+ };
2924
+ var offsetStyle = (percent, orientation) => orientation === "vertical" ? { insetBlockEnd: `${percent}%` } : { insetInlineStart: `${percent}%` };
2925
+ var bandStyle = (start, end, orientation) => orientation === "vertical" ? { insetBlockEnd: `${start}%`, height: `${end - start}%` } : { insetInlineStart: `${start}%`, width: `${end - start}%` };
2926
+ var normalizeValues = (value, range, bounds) => {
2927
+ if (range) {
2928
+ const seeded = Array.isArray(value) && value.length >= 2 ? value : [bounds.min, bounds.max];
2929
+ return seeded.map((entry) => snap(entry, bounds)).sort((a, b) => a - b);
2930
+ }
2931
+ return [snap(Array.isArray(value) ? value[0] : value ?? bounds.min, bounds)];
2932
+ };
2933
+ var toCommittedValue = (values, range) => range ? [...values] : values[0];
2934
+ var rangeInputName = (name, index, count) => count === 2 ? index === 0 ? `${name}-min` : `${name}-max` : `${name}-${index + 1}`;
2935
+ var valuesEqual = (a, b) => a.length === b.length && a.every((entry, index) => entry === b[index]);
2936
+ var thumbLabel = (index, count) => {
2937
+ if (count < 2) return void 0;
2938
+ if (count === 2) return RANGE_THUMB_LABELS[index];
2939
+ return `Value ${index + 1}`;
2940
+ };
2941
+ var closestThumbIndex = (values, target, disabled = []) => {
2942
+ let index = 0;
2943
+ let best = Infinity;
2944
+ let found = false;
2945
+ values.forEach((entry, current) => {
2946
+ if (disabled[current]) return;
2947
+ const distance = Math.abs(entry - target);
2948
+ if (distance <= best) {
2949
+ best = distance;
2950
+ index = current;
2951
+ found = true;
2952
+ }
2953
+ });
2954
+ if (found) return index;
2955
+ values.forEach((entry, current) => {
2956
+ const distance = Math.abs(entry - target);
2957
+ if (distance <= best) {
2958
+ best = distance;
2959
+ index = current;
2960
+ }
2961
+ });
2962
+ return index;
2963
+ };
2964
+ var thumbBounds = (values, index, bounds, minDistance = 0) => {
2965
+ const hardLower = index > 0 ? values[index - 1] : bounds.min;
2966
+ const hardUpper = index < values.length - 1 ? values[index + 1] : bounds.max;
2967
+ const lower = index > 0 ? hardLower + minDistance : bounds.min;
2968
+ const upper = index < values.length - 1 ? hardUpper - minDistance : bounds.max;
2969
+ return lower <= upper ? { min: lower, max: upper } : { min: hardLower, max: hardUpper };
2970
+ };
2971
+ var withThumbClamped = (values, index, next, bounds, minDistance = 0) => {
2972
+ const { min: lower, max: upper } = thumbBounds(values, index, bounds, minDistance);
2973
+ const updated = [...values];
2974
+ updated[index] = clamp(snap(next, bounds), lower, upper);
2975
+ return updated;
2976
+ };
2977
+ var withThumbSwapped = (values, index, next, bounds, minDistance = 0, disabled = []) => {
2978
+ const lowerBlocked = index > 0 && disabled[index - 1];
2979
+ const upperBlocked = index < values.length - 1 && disabled[index + 1];
2980
+ if (minDistance > 0 || lowerBlocked || upperBlocked) {
2981
+ const { min: lower, max: upper } = thumbBounds(values, index, bounds, minDistance);
2982
+ const updated2 = [...values];
2983
+ updated2[index] = clamp(snap(next, bounds), lower, upper);
2984
+ return { values: updated2, index };
2985
+ }
2986
+ const updated = [...values];
2987
+ updated[index] = snap(next, bounds);
2988
+ let active = index;
2989
+ while (active > 0 && updated[active] < updated[active - 1]) {
2990
+ [updated[active], updated[active - 1]] = [updated[active - 1], updated[active]];
2991
+ active -= 1;
2992
+ }
2993
+ while (active < updated.length - 1 && updated[active] > updated[active + 1]) {
2994
+ [updated[active], updated[active + 1]] = [updated[active + 1], updated[active]];
2995
+ active += 1;
2996
+ }
2997
+ return { values: updated, index: active };
2998
+ };
2999
+ var formatValueText = (value, formatValue) => formatValue?.(value) ?? String(value);
3000
+ var tickPercents = ({ min, max, step }, limit) => {
3001
+ const raw = (max - min) / step;
3002
+ const steps = Math.abs(raw - Math.round(raw)) < 1e-9 ? Math.round(raw) : Math.floor(raw);
3003
+ const count = steps + 1;
3004
+ if (count > limit) return null;
3005
+ return Array.from({ length: count }, (_, index) => toPercent(min + index * step, { min, max}));
3006
+ };
3007
+ var SliderRange = (props) => {
3008
+ const theme = useComponentTheme("SliderRange");
3009
+ const { values, bounds, range, orientation } = useSliderContext("Slider.Range");
3010
+ const start = range ? toPercent(values[0], bounds) : 0;
3011
+ const end = toPercent(range ? values[values.length - 1] : values[0], bounds);
3012
+ const { rootAttrs, rest } = composeRootAttrs(SliderRangeBase, props, theme);
3013
+ const { ref, style, ...nativeProps } = rest;
3014
+ const { style: slotStyle, ...slotAttrs } = rootAttrs;
3015
+ return /* @__PURE__ */ jsx("span", { ...nativeProps, ...slotAttrs, "aria-hidden": "true", style: { ...style, ...slotStyle, ...bandStyle(start, end, orientation) }, ref });
3016
+ };
3017
+ SliderRange.displayName = "Slider.Range";
3018
+ var SliderThumb = (props) => {
3019
+ const theme = useComponentTheme("SliderThumb");
3020
+ const {
3021
+ values,
3022
+ bounds,
3023
+ range,
3024
+ minDistance,
3025
+ orientation,
3026
+ disabled,
3027
+ readOnly,
3028
+ invalid,
3029
+ required,
3030
+ draggingIndex,
3031
+ formatValue,
3032
+ setThumbValue,
3033
+ startDrag,
3034
+ thumbRefs,
3035
+ thumbDisabledRef,
3036
+ fieldId,
3037
+ labelId,
3038
+ describedBy,
3039
+ rootAriaLabel,
3040
+ rootAriaLabelledby
3041
+ } = useSliderContext("Slider.Thumb");
3042
+ const [isFocused, setIsFocused] = useState(false);
3043
+ const { rootAttrs, rest } = composeRootAttrs(SliderThumbBase, props, theme);
3044
+ const { index = 0, disabled: ownDisabled, children, ref, style, onKeyDown, onPointerDown, onFocus, onBlur, ...nativeProps } = rest;
3045
+ const value = values[index] ?? bounds.min;
3046
+ const isDragging = draggingIndex === index;
3047
+ const isDisabled = disabled || Boolean(ownDisabled);
3048
+ thumbDisabledRef.current[index] = isDisabled;
3049
+ const { min: lowerBound, max: upperBound } = thumbBounds(values, index, bounds, minDistance);
3050
+ const handleKeyDown = (event) => {
3051
+ onKeyDown?.(event);
3052
+ if (isDisabled || readOnly || event.defaultPrevented) return;
3053
+ const page = bounds.step * PAGE_STEP_MULTIPLIER;
3054
+ const next = {
3055
+ ArrowRight: value + bounds.step,
3056
+ ArrowUp: value + bounds.step,
3057
+ ArrowLeft: value - bounds.step,
3058
+ ArrowDown: value - bounds.step,
3059
+ PageUp: value + page,
3060
+ PageDown: value - page,
3061
+ Home: bounds.min,
3062
+ End: bounds.max
3063
+ }[event.key];
3064
+ if (next === void 0) return;
3065
+ event.preventDefault();
3066
+ setThumbValue(index, next);
3067
+ };
3068
+ const handlePointerDown = (event) => {
3069
+ onPointerDown?.(event);
3070
+ if (isDisabled || readOnly || event.defaultPrevented || event.button !== 0) return;
3071
+ event.preventDefault();
3072
+ event.stopPropagation();
3073
+ startDrag(index, pointerCoord(event, orientation), false, event.pointerId);
3074
+ };
3075
+ const tooltipAttrs = buildSlotAttrs(SliderThumbBase.getSlotProps("tooltip"), "tooltip", {
3076
+ themeSlotProps: theme?.slotProps,
3077
+ themeClassNames: theme?.classNames,
3078
+ instanceSlotProps: props.slotProps,
3079
+ instanceClassNames: props.classNames
3080
+ });
3081
+ const arrowAttrs = buildSlotAttrs(SliderThumbBase.getSlotProps("arrow"), "arrow", {
3082
+ themeSlotProps: theme?.slotProps,
3083
+ themeClassNames: theme?.classNames,
3084
+ instanceSlotProps: props.slotProps,
3085
+ instanceClassNames: props.classNames
3086
+ });
3087
+ const formattedText = formatValueText(value, formatValue);
3088
+ const formatted = formatValue ? formattedText : void 0;
3089
+ const { style: slotStyle, ...slotAttrs } = rootAttrs;
3090
+ const bubbleContent = children === void 0 ? formattedText : typeof children === "function" ? children({ value, formatted: formattedText, index, isDragging, isFocused }) : children;
3091
+ return /* @__PURE__ */ jsx(
3092
+ "span",
3093
+ {
3094
+ ...nativeProps,
3095
+ ...slotAttrs,
3096
+ role: "slider",
3097
+ tabIndex: isDisabled ? -1 : 0,
3098
+ "aria-valuemin": lowerBound,
3099
+ "aria-valuemax": upperBound,
3100
+ "aria-valuenow": value,
3101
+ "aria-valuetext": formatted,
3102
+ "aria-orientation": orientation,
3103
+ "aria-disabled": isDisabled || void 0,
3104
+ "aria-readonly": readOnly || void 0,
3105
+ "aria-invalid": invalid || void 0,
3106
+ "aria-required": required || void 0,
3107
+ "aria-label": nativeProps["aria-label"] ?? thumbLabel(index, values.length) ?? rootAriaLabel,
3108
+ "aria-labelledby": nativeProps["aria-labelledby"] ?? (range ? void 0 : rootAriaLabelledby ?? labelId),
3109
+ "aria-describedby": nativeProps["aria-describedby"] ?? describedBy,
3110
+ id: nativeProps.id ?? (index === 0 ? fieldId : void 0),
3111
+ "data-thumb": range ? index === 0 ? "min" : index === values.length - 1 ? "max" : void 0 : void 0,
3112
+ "data-dragging": isDragging ? "" : void 0,
3113
+ "data-focus": isFocused ? "" : void 0,
3114
+ "data-disabled": isDisabled ? "" : void 0,
3115
+ onKeyDown: handleKeyDown,
3116
+ onPointerDown: handlePointerDown,
3117
+ onFocus: (event) => {
3118
+ onFocus?.(event);
3119
+ setIsFocused(true);
3120
+ },
3121
+ onBlur: (event) => {
3122
+ onBlur?.(event);
3123
+ setIsFocused(false);
3124
+ },
3125
+ style: { ...style, ...slotStyle, ...offsetStyle(toPercent(value, bounds), orientation) },
3126
+ ref: (node) => {
3127
+ thumbRefs.current[index] = node;
3128
+ if (typeof ref === "function") ref(node);
3129
+ else if (ref) ref.current = node;
3130
+ },
3131
+ children: /* @__PURE__ */ jsxs("span", { ...tooltipAttrs, "aria-hidden": "true", children: [
3132
+ bubbleContent,
3133
+ /* @__PURE__ */ jsx("span", { ...arrowAttrs, "aria-hidden": "true" })
3134
+ ] })
3135
+ }
3136
+ );
3137
+ };
3138
+ SliderThumb.displayName = "Slider.Thumb";
3139
+ var SliderTrack = (props) => {
3140
+ const theme = useComponentTheme("SliderTrack");
3141
+ const { values, disabled, readOnly, orientation, valueFromPoint, startDrag, trackRef, thumbDisabledRef } = useSliderContext("Slider.Track");
3142
+ const { rootAttrs, rest } = composeRootAttrs(SliderTrackBase, props, theme);
3143
+ const { children, ref, onPointerDown, ...nativeProps } = rest;
3144
+ const handlePointerDown = (event) => {
3145
+ onPointerDown?.(event);
3146
+ if (disabled || readOnly || event.defaultPrevented || event.button !== 0) return;
3147
+ event.preventDefault();
3148
+ const point = pointerCoord(event, orientation);
3149
+ startDrag(closestThumbIndex(values, valueFromPoint(point), thumbDisabledRef.current), point, true, event.pointerId);
3150
+ };
3151
+ return /* @__PURE__ */ jsx(
3152
+ "div",
3153
+ {
3154
+ ...nativeProps,
3155
+ ...rootAttrs,
3156
+ onPointerDown: handlePointerDown,
3157
+ ref: (node) => {
3158
+ trackRef.current = node;
3159
+ if (typeof ref === "function") ref(node);
3160
+ else if (ref) ref.current = node;
3161
+ },
3162
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
3163
+ /* @__PURE__ */ jsx(SliderRange, {}),
3164
+ values.map((_, index) => /* @__PURE__ */ jsx(SliderThumb, { index }, index))
3165
+ ] })
3166
+ }
3167
+ );
3168
+ };
3169
+ SliderTrack.displayName = "Slider.Track";
3170
+ var warnedRanges2 = /* @__PURE__ */ new Set();
3171
+ var Slider = (props) => {
3172
+ const theme = useComponentTheme("Slider");
3173
+ const field = useOptionalFieldContext();
3174
+ const { rootAttrs, rest } = composeRootAttrs(SliderBase, props, theme, {
3175
+ stateAttrs: (merged) => {
3176
+ const {
3177
+ size = DEFAULT_SIZE12,
3178
+ variant = DEFAULT_VARIANT7,
3179
+ orientation: orientation2 = DEFAULT_ORIENTATION2,
3180
+ tooltip = DEFAULT_TOOLTIP,
3181
+ track = DEFAULT_TRACK,
3182
+ range: range2,
3183
+ disabled: disabled2,
3184
+ readOnly: readOnly2,
3185
+ invalid: invalid2,
3186
+ required: required2
3187
+ } = merged;
3188
+ return {
3189
+ "data-size": size,
3190
+ "data-variant": variant,
3191
+ "data-orientation": orientation2,
3192
+ "data-tooltip": tooltip,
3193
+ "data-track": track,
3194
+ "data-range": range2 ? "" : void 0,
3195
+ "data-disabled": disabled2 ?? field?.disabled ? "" : void 0,
3196
+ "data-readonly": readOnly2 ?? field?.readOnly ? "" : void 0,
3197
+ "data-invalid": invalid2 ?? field?.invalid ? "" : void 0,
3198
+ "data-required": required2 ?? field?.required ? "" : void 0
3199
+ };
3200
+ }
3201
+ });
3202
+ const {
3203
+ // Consumed through the resolved state below (and as the root data-* hooks);
3204
+ // destructured so the <div> doesn't receive unknown DOM attributes.
3205
+ min: rawMin,
3206
+ max: rawMax,
3207
+ step: rawStep,
3208
+ range = false,
3209
+ value,
3210
+ defaultValue,
3211
+ onValueChange,
3212
+ onValueChangeEnd,
3213
+ disabled: ownDisabled,
3214
+ readOnly: ownReadOnly,
3215
+ invalid: ownInvalid,
3216
+ required: ownRequired,
3217
+ minDistance = DEFAULT_MIN_DISTANCE,
3218
+ orientation = DEFAULT_ORIENTATION2,
3219
+ size: _size,
3220
+ variant: _variant,
3221
+ // Consumed as the `data-tooltip` / `data-track` root hooks above (the recipe
3222
+ // drives the value bubble and the inverted/none fill off them); pulled out
3223
+ // so they never land on the <div> as unknown attributes.
3224
+ tooltip: _tooltip,
3225
+ track: _track,
3226
+ formatValue,
3227
+ name,
3228
+ form,
3229
+ as,
3230
+ children,
3231
+ ref,
3232
+ ...nativeProps
3233
+ } = rest;
3234
+ const disabled = ownDisabled ?? field?.disabled ?? false;
3235
+ const readOnly = ownReadOnly ?? field?.readOnly ?? false;
3236
+ const invalid = ownInvalid ?? field?.invalid ?? false;
3237
+ const required = ownRequired ?? field?.required ?? false;
3238
+ const bounds = resolveBounds(rawMin, rawMax, rawStep);
3239
+ if (isDevelopment() && typeof rawMax === "number" && Number.isFinite(rawMax) && rawMax <= bounds.min) {
3240
+ const message = `[Slider] \`max\` (${rawMax}) must be greater than \`min\` (${bounds.min}); falling back to ${bounds.max}.`;
3241
+ if (!warnedRanges2.has("inverted-range")) {
3242
+ warnedRanges2.add("inverted-range");
3243
+ console.warn(message);
3244
+ }
3245
+ }
3246
+ const controlledValues = value === void 0 ? void 0 : normalizeValues(value, range, bounds);
3247
+ const initialValues = normalizeValues(defaultValue, range, bounds);
3248
+ const onValueChangeRef = useRef(onValueChange);
3249
+ onValueChangeRef.current = onValueChange;
3250
+ const handleCommit = useCallback((next) => onValueChangeRef.current?.(toCommittedValue(next, range)), [range]);
3251
+ const [rawValues = initialValues, setValues] = useControllableState(controlledValues, initialValues, handleCommit);
3252
+ const values = useMemo(() => normalizeValues(toCommittedValue(rawValues, range), range, bounds), [rawValues, range, bounds.min, bounds.max, bounds.step]);
3253
+ const onValueChangeEndRef = useRef(onValueChangeEnd);
3254
+ onValueChangeEndRef.current = onValueChangeEnd;
3255
+ const emitChangeEnd = useCallback((vals) => onValueChangeEndRef.current?.(toCommittedValue(vals, range)), [range]);
3256
+ const emitChangeEndRef = useRef(emitChangeEnd);
3257
+ emitChangeEndRef.current = emitChangeEnd;
3258
+ const [draggingIndex, setDraggingIndex] = useState(null);
3259
+ const trackRef = useRef(null);
3260
+ const thumbRefs = useRef([]);
3261
+ const thumbDisabledRef = useRef([]);
3262
+ const gestureStartRef = useRef(null);
3263
+ const dragPointerRef = useRef(null);
3264
+ const valuesRef = useRef(values);
3265
+ valuesRef.current = values;
3266
+ thumbDisabledRef.current.length = values.length;
3267
+ const valueFromPoint = useCallback(
3268
+ (point) => {
3269
+ const track = trackRef.current;
3270
+ if (!track) return bounds.min;
3271
+ return valueFromPointer(track.getBoundingClientRect(), point, bounds, orientation);
3272
+ },
3273
+ [bounds.min, bounds.max, bounds.step, orientation]
3274
+ );
3275
+ const commit = useCallback(
3276
+ (next) => {
3277
+ if (!valuesEqual(next, valuesRef.current)) setValues(next);
3278
+ },
3279
+ [setValues]
3280
+ );
3281
+ const setThumbValue = useCallback(
3282
+ (index, next) => {
3283
+ if (disabled || readOnly || thumbDisabledRef.current[index]) return;
3284
+ const before = valuesRef.current;
3285
+ const updated = withThumbClamped(before, index, next, bounds, minDistance);
3286
+ commit(updated);
3287
+ if (!valuesEqual(updated, before)) emitChangeEnd(updated);
3288
+ },
3289
+ [disabled, readOnly, commit, emitChangeEnd, minDistance, bounds.min, bounds.max, bounds.step]
3290
+ );
3291
+ const startDrag = useCallback(
3292
+ (index, point, seek, pointerId) => {
3293
+ if (disabled || readOnly || thumbDisabledRef.current[index]) return;
3294
+ gestureStartRef.current = valuesRef.current;
3295
+ dragPointerRef.current = pointerId;
3296
+ if (!seek) {
3297
+ setDraggingIndex(index);
3298
+ thumbRefs.current[index]?.focus();
3299
+ return;
3300
+ }
3301
+ const { values: next, index: active } = withThumbSwapped(valuesRef.current, index, valueFromPoint(point), bounds, minDistance, thumbDisabledRef.current);
3302
+ setDraggingIndex(active);
3303
+ thumbRefs.current[active]?.focus();
3304
+ commit(next);
3305
+ },
3306
+ [disabled, readOnly, commit, valueFromPoint, minDistance, bounds.min, bounds.max, bounds.step]
3307
+ );
3308
+ useEffect(() => {
3309
+ if (draggingIndex === null) return;
3310
+ const ownerId = dragPointerRef.current;
3311
+ const isOwner = (event) => ownerId === null || event.pointerId === ownerId;
3312
+ const settle = () => {
3313
+ setDraggingIndex(null);
3314
+ if (gestureStartRef.current && !valuesEqual(valuesRef.current, gestureStartRef.current)) emitChangeEnd(valuesRef.current);
3315
+ gestureStartRef.current = null;
3316
+ dragPointerRef.current = null;
3317
+ };
3318
+ const handleMove = (event) => {
3319
+ if (!isOwner(event)) return;
3320
+ if (event.buttons === 0) {
3321
+ settle();
3322
+ return;
3323
+ }
3324
+ const { values: next, index: active } = withThumbSwapped(
3325
+ valuesRef.current,
3326
+ draggingIndex,
3327
+ valueFromPoint(pointerCoord(event, orientation)),
3328
+ bounds,
3329
+ minDistance,
3330
+ thumbDisabledRef.current
3331
+ );
3332
+ if (active !== draggingIndex) {
3333
+ setDraggingIndex(active);
3334
+ thumbRefs.current[active]?.focus();
3335
+ }
3336
+ commit(next);
3337
+ };
3338
+ const handleEnd = (event) => {
3339
+ if (!isOwner(event)) return;
3340
+ settle();
3341
+ };
3342
+ document.addEventListener("pointermove", handleMove);
3343
+ document.addEventListener("pointerup", handleEnd);
3344
+ document.addEventListener("pointercancel", handleEnd);
3345
+ return () => {
3346
+ document.removeEventListener("pointermove", handleMove);
3347
+ document.removeEventListener("pointerup", handleEnd);
3348
+ document.removeEventListener("pointercancel", handleEnd);
3349
+ };
3350
+ }, [draggingIndex, valueFromPoint, commit, emitChangeEnd, minDistance, orientation, bounds.min, bounds.max, bounds.step]);
3351
+ useEffect(
3352
+ () => () => {
3353
+ if (gestureStartRef.current && !valuesEqual(valuesRef.current, gestureStartRef.current)) emitChangeEndRef.current(valuesRef.current);
3354
+ gestureStartRef.current = null;
3355
+ },
3356
+ []
3357
+ );
3358
+ const Component = as ?? "div";
3359
+ const htmlProps = nativeProps;
3360
+ const groupAttrs = range ? {
3361
+ "role": htmlProps.role ?? "group",
3362
+ "aria-labelledby": htmlProps["aria-labelledby"] ?? field?.labelId
3363
+ } : {};
3364
+ const { "aria-label": rootAriaLabel, "aria-labelledby": rootAriaLabelledby, ...singleWrapperProps } = htmlProps;
3365
+ const wrapperProps = range ? nativeProps : singleWrapperProps;
3366
+ return /* @__PURE__ */ jsx(
3367
+ SliderProvider,
3368
+ {
3369
+ value: {
3370
+ values,
3371
+ bounds,
3372
+ range,
3373
+ minDistance,
3374
+ orientation,
3375
+ disabled,
3376
+ readOnly,
3377
+ invalid,
3378
+ required,
3379
+ draggingIndex,
3380
+ trackRef,
3381
+ thumbRefs,
3382
+ thumbDisabledRef,
3383
+ formatValue,
3384
+ setThumbValue,
3385
+ startDrag,
3386
+ valueFromPoint,
3387
+ fieldId: field?.fieldId,
3388
+ labelId: field?.labelId,
3389
+ describedBy: invalid ? field?.errorId : field?.descriptionId,
3390
+ // Only a single slider forwards the root name to its thumb; a range
3391
+ // carries it on the group wrapper above.
3392
+ rootAriaLabel: range ? void 0 : rootAriaLabel,
3393
+ rootAriaLabelledby: range ? void 0 : rootAriaLabelledby
3394
+ },
3395
+ children: /* @__PURE__ */ jsxs(Component, { ...wrapperProps, ...groupAttrs, ...rootAttrs, ref, children: [
3396
+ children ?? /* @__PURE__ */ jsx(SliderTrack, {}),
3397
+ name && !disabled && (range ? (
3398
+ // One input per handle so a 3+ thumb range submits every value; a
3399
+ // two-handle range keeps the conventional `-min` / `-max` pair.
3400
+ values.map((entry, index) => /* @__PURE__ */ jsx("input", { type: "hidden", name: rangeInputName(name, index, values.length), value: entry, form }, index))
3401
+ ) : /* @__PURE__ */ jsx("input", { type: "hidden", name, value: values[0], form }))
3402
+ ] })
3403
+ }
3404
+ );
3405
+ };
3406
+ Slider.displayName = "Slider";
3407
+ var warnedGrids = /* @__PURE__ */ new Set();
3408
+ var SliderTicks = (props) => {
3409
+ const theme = useComponentTheme("SliderTicks");
3410
+ const { bounds, orientation } = useSliderContext("Slider.Ticks");
3411
+ const { rootAttrs, rest } = composeRootAttrs(SliderTicksBase, props, theme);
3412
+ const { ref, ...nativeProps } = rest;
3413
+ const percents = tickPercents(bounds, MAX_TICKS);
3414
+ if (percents === null) {
3415
+ if (isDevelopment()) {
3416
+ const message = `[Slider.Ticks] needs at most ${MAX_TICKS} marks, but min ${bounds.min} / max ${bounds.max} / step ${bounds.step} produces more; the ticks are not rendered.`;
3417
+ if (!warnedGrids.has("ticks-too-dense")) {
3418
+ warnedGrids.add("ticks-too-dense");
3419
+ console.warn(message);
3420
+ }
3421
+ }
3422
+ return null;
3423
+ }
3424
+ const tickAttrs = buildSlotAttrs(SliderTicksBase.getSlotProps("tick"), "tick", {
3425
+ themeSlotProps: theme?.slotProps,
3426
+ themeClassNames: theme?.classNames,
3427
+ instanceSlotProps: props.slotProps,
3428
+ instanceClassNames: props.classNames
3429
+ });
3430
+ return /* @__PURE__ */ jsx("div", { ...nativeProps, ...rootAttrs, "aria-hidden": "true", ref, children: percents.map((percent, index) => /* @__PURE__ */ jsx("span", { ...tickAttrs, style: offsetStyle(percent, orientation) }, index)) });
3431
+ };
3432
+ SliderTicks.displayName = "Slider.Ticks";
3433
+ var SliderValue = (props) => {
3434
+ const theme = useComponentTheme("SliderValue");
3435
+ const { values, range, formatValue } = useSliderContext("Slider.Value");
3436
+ const { rootAttrs, rest } = composeRootAttrs(SliderValueBase, props, theme);
3437
+ const { children, ref, ...nativeProps } = rest;
3438
+ const formatted = values.map((value) => formatValueText(value, formatValue));
3439
+ const state = { values, formatted, range };
3440
+ return /* @__PURE__ */ jsx("span", { ...nativeProps, ...rootAttrs, "aria-hidden": "true", ref, children: typeof children === "function" ? children(state) : children ?? formatted.join(RANGE_VALUE_SEPARATOR) });
3441
+ };
3442
+ SliderValue.displayName = "Slider.Value";
3443
+
3444
+ // src/components/slider/index.ts
3445
+ var Slider2 = Object.assign(Slider, {
3446
+ Track: SliderTrack,
3447
+ Range: SliderRange,
3448
+ Thumb: SliderThumb,
3449
+ Ticks: SliderTicks,
3450
+ Value: SliderValue
3451
+ });
3452
+
3453
+ // src/components/spinner/base.ts
3454
+ var SpinnerBase = createComponentBase({
3455
+ name: "Spinner",
3456
+ slots: ["root", "indicator"],
3457
+ classes: {
3458
+ root: "tk-spinner",
3459
+ indicator: "tk-spinner-indicator"
3460
+ }
3461
+ });
3462
+
3463
+ // src/components/spinner/defaults.ts
3464
+ var DEFAULT_APPEARANCE7 = "rounded";
3465
+ var DEFAULT_SIZE13 = "base";
3466
+ var DEFAULT_VARIANT8 = "neutral";
3467
+ var DEFAULT_ARIA_LABEL2 = "Loading";
3468
+ var SPINNER_RADIAL_PARTS = 8;
3469
+ var SPINNER_THREE_DOT_PARTS = 3;
3470
+ var renderIndicatorContent = (appearance) => {
3471
+ if (appearance === "rounded") {
3472
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3473
+ /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 40 40", children: /* @__PURE__ */ jsx("circle", { cx: "20", cy: "20", r: "16.6667" }) }),
3474
+ /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 40 40", children: /* @__PURE__ */ jsx("path", { d: "M20 3.3333A16.6667 16.6667 0 0 1 36.6667 20" }) })
3475
+ ] });
3476
+ }
3477
+ if (appearance === "loader") {
3478
+ return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 40 40", children: /* @__PURE__ */ jsx("path", { d: "M20 3.3333A16.6667 16.6667 0 0 1 31.7851 8.2149" }) });
3479
+ }
3480
+ if (appearance === "dots") {
3481
+ return Array.from({ length: SPINNER_RADIAL_PARTS }, (_, index) => /* @__PURE__ */ jsx("span", { className: "tk-spinner-dot" }, index));
3482
+ }
3483
+ if (appearance === "lines") {
3484
+ return Array.from({ length: SPINNER_RADIAL_PARTS }, (_, index) => /* @__PURE__ */ jsx("span", { className: "tk-spinner-line" }, index));
3485
+ }
3486
+ if (appearance === "threeDots") {
3487
+ return Array.from({ length: SPINNER_THREE_DOT_PARTS }, (_, index) => /* @__PURE__ */ jsx("span", { className: "tk-spinner-dot" }, index));
3488
+ }
3489
+ if (appearance === "logo") {
3490
+ return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 48 48", children: /* @__PURE__ */ jsx(
3491
+ "path",
3492
+ {
3493
+ clipRule: "evenodd",
3494
+ d: "M24 0C10.7452 0 0 10.7452 0 24C0 37.2548 10.7452 48 24 48C37.2548 48 48 37.2548 48 24V4C48 1.79086 46.2091 0 44 0H24ZM24 8C15.1634 8 8 15.1634 8 24C8 32.8366 15.1634 40 24 40C32.8366 40 40 32.8366 40 24C40 15.1634 32.8366 8 24 8Z",
3495
+ fillRule: "evenodd"
3496
+ }
3497
+ ) });
3498
+ }
3499
+ return null;
3500
+ };
3501
+ var Spinner = (props) => {
3502
+ const theme = useComponentTheme("Spinner");
3503
+ const { rootAttrs, rest } = composeRootAttrs(SpinnerBase, props, theme, {
3504
+ stateAttrs: ({ variant = DEFAULT_VARIANT8, size = DEFAULT_SIZE13, appearance: appearance2 = DEFAULT_APPEARANCE7 }) => ({
3505
+ "data-variant": variant,
3506
+ "data-size": size,
3507
+ "data-type": appearance2
3508
+ })
3509
+ });
3510
+ const { variant: _variant, size: _size, appearance = DEFAULT_APPEARANCE7, ref, ...nativeProps } = rest;
3511
+ const indicatorSlotAttrs = buildSlotAttrs(SpinnerBase.getSlotProps("indicator"), "indicator", {
3512
+ themeSlotProps: theme?.slotProps,
3513
+ themeClassNames: theme?.classNames,
3514
+ instanceSlotProps: props.slotProps,
3515
+ instanceClassNames: props.classNames
3516
+ });
3517
+ const isDecorative = nativeProps["aria-hidden"] === true || nativeProps["aria-hidden"] === "true";
3518
+ const accessibilityAttrs = isDecorative ? {} : {
3519
+ "role": nativeProps.role ?? "status",
3520
+ "aria-label": nativeProps["aria-label"] ?? (nativeProps["aria-labelledby"] ? void 0 : DEFAULT_ARIA_LABEL2)
3521
+ };
3522
+ return /* @__PURE__ */ jsx("span", { ...accessibilityAttrs, ...nativeProps, ...rootAttrs, ref, children: /* @__PURE__ */ jsx("span", { ...indicatorSlotAttrs, "aria-hidden": "true", children: renderIndicatorContent(appearance) }) });
3523
+ };
3524
+ Spinner.displayName = "Spinner";
3525
+
3526
+ // src/components/stepper/base.ts
3527
+ var StepperBase = createComponentBase({
3528
+ name: "Stepper",
3529
+ slots: ["root"],
3530
+ classes: { root: "tk-stepper" }
3531
+ });
3532
+ var StepperItemBase = createComponentBase({
3533
+ name: "StepperItem",
3534
+ slots: ["root", "trigger", "rail", "indicator", "content"],
3535
+ classes: {
3536
+ root: "tk-stepper-item",
3537
+ trigger: "tk-stepper-trigger",
3538
+ rail: "tk-stepper-rail",
3539
+ indicator: "tk-stepper-indicator",
3540
+ content: "tk-stepper-content"
3541
+ }
3542
+ });
3543
+ var StepperTitleBase = createComponentBase({
3544
+ name: "StepperTitle",
3545
+ slots: ["root"],
3546
+ classes: { root: "tk-stepper-title" }
3547
+ });
3548
+ var StepperDescriptionBase = createComponentBase({
3549
+ name: "StepperDescription",
3550
+ slots: ["root"],
3551
+ classes: { root: "tk-stepper-description" }
3552
+ });
3553
+
3554
+ // src/components/stepper/context.ts
3555
+ var [StepperProvider, useStepperContext] = createSafeContext("StepperProvider");
3556
+ var [StepperItemIndexProvider, useStepperItemIndex] = createSafeContext("StepperItemIndexProvider");
3557
+ var [StepperItemProvider, useStepperItem] = createSafeContext("Stepper.Item");
3558
+
3559
+ // src/components/stepper/defaults.ts
3560
+ var DEFAULT_ORIENTATION3 = "horizontal";
3561
+ var DEFAULT_MODE2 = "default";
3562
+ var DEFAULT_SIZE14 = "base";
3563
+ var DEFAULT_ACTIVE = 0;
3564
+ var DEFAULT_COMPLETED_LABEL = "completed";
3565
+ var DEFAULT_ERROR_LABEL = "error";
3566
+ var FOCUSABLE_TRIGGER_SELECTOR = '.tk-stepper-trigger:not(:disabled):not([tabindex="-1"])';
3567
+ var Stepper = (props) => {
3568
+ const theme = useComponentTheme("Stepper");
3569
+ const { rootAttrs, rest } = composeRootAttrs(StepperBase, props, theme, {
3570
+ stateAttrs: ({ orientation: orientation2 = DEFAULT_ORIENTATION3, mode: mode2 = DEFAULT_MODE2, size = DEFAULT_SIZE14, linear: linear2 = false, reverse = false }) => ({
3571
+ "data-orientation": orientation2,
3572
+ "data-mode": mode2,
3573
+ "data-size": size,
3574
+ "data-linear": linear2 ? "" : void 0,
3575
+ "data-reverse": reverse ? "" : void 0
3576
+ })
3577
+ });
3578
+ const {
3579
+ active: controlledActive,
3580
+ defaultActive = DEFAULT_ACTIVE,
3581
+ onActiveChange,
3582
+ onStepClick,
3583
+ orientation = DEFAULT_ORIENTATION3,
3584
+ mode = DEFAULT_MODE2,
3585
+ // Consumed only as root data-* hooks above; destructured so the <ol>
3586
+ // doesn't receive unknown DOM attributes.
3587
+ size: _size,
3588
+ linear = false,
3589
+ reverse: _reverse,
3590
+ completedLabel = DEFAULT_COMPLETED_LABEL,
3591
+ errorLabel = DEFAULT_ERROR_LABEL,
3592
+ onKeyDown: nativeOnKeyDown,
3593
+ as,
3594
+ children,
3595
+ ref,
3596
+ ...nativeProps
3597
+ } = rest;
3598
+ const onActiveChangeRef = useRef(onActiveChange);
3599
+ onActiveChangeRef.current = onActiveChange;
3600
+ const stableOnActiveChange = useCallback((index) => {
3601
+ onActiveChangeRef.current?.(index);
3602
+ }, []);
3603
+ const onStepClickRef = useRef(onStepClick);
3604
+ onStepClickRef.current = onStepClick;
3605
+ const stableOnStepClick = useCallback((detail) => {
3606
+ onStepClickRef.current?.(detail);
3607
+ }, []);
3608
+ const [activeValue, setActive] = useControllableState(controlledActive, defaultActive, stableOnActiveChange);
3609
+ const active = activeValue ?? DEFAULT_ACTIVE;
3610
+ const [stepsMeta, setStepsMeta] = useState(/* @__PURE__ */ new Map());
3611
+ const { items, renderStepsMeta } = useMemo(() => {
3612
+ const meta = /* @__PURE__ */ new Map();
3613
+ let stepIndex = 0;
3614
+ const items2 = Children.toArray(children).map((child) => {
3615
+ if (!isValidElement(child)) return child;
3616
+ const index = stepIndex++;
3617
+ const { error = false, disabled = false, isClickable = true } = child.props;
3618
+ meta.set(index, { error, disabled, isClickable });
3619
+ return /* @__PURE__ */ jsx(StepperItemIndexProvider, { value: { index }, children: child }, child.key ?? index);
3620
+ });
3621
+ return { items: items2, renderStepsMeta: meta };
3622
+ }, [children]);
3623
+ const registerStep = useCallback((index, meta) => {
3624
+ setStepsMeta((previous) => new Map(previous).set(index, meta));
3625
+ return () => {
3626
+ setStepsMeta((previous) => {
3627
+ const next = new Map(previous);
3628
+ next.delete(index);
3629
+ return next;
3630
+ });
3631
+ };
3632
+ }, []);
3633
+ const contextValue = useMemo(() => {
3634
+ const canSelectStep = (index, selfMeta) => {
3635
+ const target = stepsMeta.get(index) ?? selfMeta ?? renderStepsMeta.get(index);
3636
+ if (!target || target.disabled || !target.isClickable) return false;
3637
+ if (!linear) return true;
3638
+ if (index < active) return true;
3639
+ if (index === active + 1) {
3640
+ const current = stepsMeta.get(active) ?? renderStepsMeta.get(active);
3641
+ return !current?.error && !current?.disabled;
3642
+ }
3643
+ return false;
3644
+ };
3645
+ const getStepStatus = (options) => {
3646
+ const { index } = options;
3647
+ if (index < active) return "completed";
3648
+ if (index === active) return "active";
3649
+ return "inactive";
3650
+ };
3651
+ return {
3652
+ active,
3653
+ mode,
3654
+ completedLabel,
3655
+ errorLabel,
3656
+ getStepStatus,
3657
+ registerStep,
3658
+ canSelectStep,
3659
+ selectStep: (index) => {
3660
+ if (index !== active && canSelectStep(index)) {
3661
+ setActive(index);
3662
+ }
3663
+ },
3664
+ emitStepClick: (detail) => {
3665
+ stableOnStepClick(detail);
3666
+ }
3667
+ };
3668
+ }, [active, mode, completedLabel, errorLabel, linear, stepsMeta, renderStepsMeta, registerStep, setActive, stableOnStepClick]);
3669
+ const { onKeyDown: slotOnKeyDown, ...restRootAttrs } = rootAttrs;
3670
+ const userOnKeyDown = slotOnKeyDown ?? nativeOnKeyDown;
3671
+ const handleKeyDown = (event) => {
3672
+ userOnKeyDown?.(event);
3673
+ if (event.defaultPrevented) return;
3674
+ const forwardKey = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
3675
+ const backwardKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
3676
+ if (event.key !== forwardKey && event.key !== backwardKey && event.key !== "Home" && event.key !== "End") return;
3677
+ const pressedTrigger = event.target instanceof HTMLElement ? event.target.closest(".tk-stepper-trigger") : null;
3678
+ if (!pressedTrigger || pressedTrigger.closest(".tk-stepper") !== event.currentTarget) return;
3679
+ event.preventDefault();
3680
+ const triggers = Array.from(event.currentTarget.querySelectorAll(FOCUSABLE_TRIGGER_SELECTOR)).filter(
3681
+ (trigger) => trigger.closest(".tk-stepper") === event.currentTarget
3682
+ );
3683
+ const currentIndex = triggers.indexOf(pressedTrigger);
3684
+ if (triggers.length === 0 || currentIndex === -1 && event.key !== "Home" && event.key !== "End") return;
3685
+ const nextIndex = event.key === "Home" ? 0 : event.key === "End" ? triggers.length - 1 : event.key === forwardKey ? currentIndex + 1 : currentIndex - 1;
3686
+ triggers[nextIndex]?.focus();
3687
+ };
3688
+ const Component = as ?? "ol";
3689
+ return /* @__PURE__ */ jsx(StepperProvider, { value: contextValue, children: /* @__PURE__ */ jsx(Component, { ...nativeProps, ...restRootAttrs, ref, onKeyDown: handleKeyDown, children: items }) });
3690
+ };
3691
+ Stepper.displayName = "Stepper";
3692
+ var StepperTitle = (props) => {
3693
+ const theme = useComponentTheme("StepperTitle");
3694
+ useStepperContext("Stepper.Title");
3695
+ const { rootAttrs, rest } = composeRootAttrs(StepperTitleBase, props, theme);
3696
+ const { as, children, ref, ...nativeProps } = rest;
3697
+ const Component = as ?? "span";
3698
+ return /* @__PURE__ */ jsx(Component, { ...nativeProps, ...rootAttrs, ref, children });
1177
3699
  };
1178
- var SelectContent = (props) => {
1179
- const theme = useComponentTheme("SelectContent");
1180
- const { size, contentWidth } = useSelectOwnContext("Select.Content");
1181
- const { triggerRef } = useSelectContext();
1182
- const [triggerWidth, setTriggerWidth] = useState(null);
1183
- useEffect(() => {
1184
- if (contentWidth !== "trigger") return;
1185
- const node = triggerRef.current;
1186
- if (!node) return;
1187
- setTriggerWidth(node.offsetWidth);
1188
- const observer = new ResizeObserver((entries) => {
1189
- const entry = entries[0];
1190
- if (entry) setTriggerWidth(Math.round(entry.contentRect.width + 2));
1191
- });
1192
- observer.observe(node);
1193
- return () => observer.disconnect();
1194
- }, [contentWidth, triggerRef]);
1195
- const { rootAttrs, rest } = composeRootAttrs(SelectContentBase, props, theme, {
1196
- stateAttrs: () => ({
1197
- "data-size": size
3700
+ StepperTitle.displayName = "Stepper.Title";
3701
+ var visuallyHidden = {
3702
+ position: "absolute",
3703
+ width: 1,
3704
+ height: 1,
3705
+ margin: -1,
3706
+ padding: 0,
3707
+ overflow: "hidden",
3708
+ clip: "rect(0 0 0 0)",
3709
+ whiteSpace: "nowrap",
3710
+ border: 0
3711
+ };
3712
+ var StepperItem = (props) => {
3713
+ const theme = useComponentTheme("StepperItem");
3714
+ const { active, mode, completedLabel, errorLabel, getStepStatus, registerStep, canSelectStep, selectStep, emitStepClick } = useStepperContext("Stepper.Item");
3715
+ const { index } = useStepperItemIndex("Stepper.Item");
3716
+ const { rootAttrs, rest } = composeRootAttrs(StepperItemBase, props, theme, {
3717
+ stateAttrs: ({ error: error2 = false, disabled: disabled2 = false, isClickable: isClickable2 = true }) => ({
3718
+ "data-state": getStepStatus({ index }),
3719
+ "data-error": error2 ? "" : void 0,
3720
+ "data-disabled": disabled2 ? "" : void 0,
3721
+ // The active step is excluded: pressing it re-emits `onStepClick` but
3722
+ // can never change the selection, which is what this hook advertises.
3723
+ "data-clickable": index !== active && canSelectStep(index, { error: error2, disabled: disabled2, isClickable: isClickable2 }) ? "" : void 0
1198
3724
  })
1199
3725
  });
1200
- const { children, ref, style: userStyle, ...spar } = rest;
1201
- const widthStyle = useMemo(() => {
1202
- if (contentWidth === "trigger") {
1203
- return triggerWidth != null ? { width: triggerWidth } : void 0;
3726
+ const { error = false, disabled = false, isClickable = true, indicator, as, children, ref, ...nativeProps } = rest;
3727
+ useEffect(() => registerStep(index, { error, disabled, isClickable }), [registerStep, index, error, disabled, isClickable]);
3728
+ const status = getStepStatus({ index });
3729
+ const selectable = canSelectStep(index, { error, disabled, isClickable });
3730
+ const isActive = index === active;
3731
+ const ariaDisabled = selectable || isActive ? void 0 : true;
3732
+ const statusLabel = error ? errorLabel : status === "completed" ? completedLabel : void 0;
3733
+ const [descriptionId, setDescriptionId] = useState();
3734
+ const registerDescription = useCallback((id) => {
3735
+ setDescriptionId(id);
3736
+ return () => {
3737
+ setDescriptionId((current) => current === id ? void 0 : current);
3738
+ };
3739
+ }, []);
3740
+ const itemContextValue = useMemo(() => ({ registerDescription }), [registerDescription]);
3741
+ const slotLayering = {
3742
+ themeSlotProps: theme?.slotProps,
3743
+ themeClassNames: theme?.classNames,
3744
+ instanceSlotProps: props.slotProps,
3745
+ instanceClassNames: props.classNames
3746
+ };
3747
+ const triggerSlotAttrs = buildSlotAttrs(StepperItemBase.getSlotProps("trigger"), "trigger", slotLayering);
3748
+ const { onClick: triggerSlotOnClick, ...triggerAttrs } = triggerSlotAttrs;
3749
+ const railAttrs = buildSlotAttrs(StepperItemBase.getSlotProps("rail"), "rail", slotLayering);
3750
+ const indicatorAttrs = buildSlotAttrs(StepperItemBase.getSlotProps("indicator"), "indicator", slotLayering);
3751
+ const contentAttrs = buildSlotAttrs(StepperItemBase.getSlotProps("content"), "content", slotLayering);
3752
+ const resolvedIndicator = typeof indicator === "function" ? indicator({ status, index }) : indicator;
3753
+ let indicatorContent = null;
3754
+ if (!disabled) {
3755
+ if (resolvedIndicator != null) {
3756
+ indicatorContent = resolvedIndicator;
3757
+ } else if (error) {
3758
+ indicatorContent = /* @__PURE__ */ jsx(CloseIconOutlinedRounded, {});
3759
+ } else if (status === "completed") {
3760
+ indicatorContent = /* @__PURE__ */ jsx(CheckIconOutlinedRounded, {});
1204
3761
  }
1205
- const staticWidth = resolveStaticWidth(contentWidth);
1206
- return staticWidth != null ? { width: staticWidth } : void 0;
1207
- }, [contentWidth, triggerWidth]);
1208
- const mergedStyle = widthStyle || userStyle ? { ...widthStyle, ...userStyle } : void 0;
1209
- return /* @__PURE__ */ jsx(SelectContent$1, { ...spar, ref, style: mergedStyle, ...rootAttrs, children });
1210
- };
1211
- SelectContent.displayName = "Select.Content";
1212
- var SelectItem = (props) => {
1213
- const theme = useComponentTheme("SelectItem");
1214
- const { rootAttrs, rest } = composeRootAttrs(SelectItemBase, props, theme);
1215
- const { value, disabled, label, children, ref, ...spar } = rest;
1216
- return /* @__PURE__ */ jsx(SelectItem$1, { ...spar, value, disabled, label, ref, ...rootAttrs, children });
1217
- };
1218
- SelectItem.displayName = "Select.Item";
1219
- var SelectGroup = (props) => {
1220
- const theme = useComponentTheme("SelectGroup");
1221
- const { rootAttrs, rest } = composeRootAttrs(SelectGroupBase, props, theme);
1222
- const { children, ref, ...spar } = rest;
1223
- return /* @__PURE__ */ jsx(SelectGroup$1, { ...spar, ref, ...rootAttrs, children });
1224
- };
1225
- SelectGroup.displayName = "Select.Group";
1226
- var SelectLabel = (props) => {
1227
- const theme = useComponentTheme("SelectLabel");
1228
- const { rootAttrs, rest } = composeRootAttrs(SelectLabelBase, props, theme);
1229
- const { children, ref, ...spar } = rest;
1230
- return /* @__PURE__ */ jsx(SelectLabel$1, { ...spar, ref, ...rootAttrs, children });
3762
+ }
3763
+ const handleTriggerClick = (event) => {
3764
+ triggerSlotOnClick?.(event);
3765
+ if (event.defaultPrevented) return;
3766
+ if (!selectable && !(isActive && isClickable)) return;
3767
+ emitStepClick({ index, status });
3768
+ selectStep(index);
3769
+ };
3770
+ const Component = as ?? "li";
3771
+ return /* @__PURE__ */ jsx(StepperItemProvider, { value: itemContextValue, children: /* @__PURE__ */ jsxs(Component, { ...nativeProps, ...rootAttrs, ref, children: [
3772
+ mode !== "compact" && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", ...railAttrs }),
3773
+ /* @__PURE__ */ jsxs(
3774
+ "button",
3775
+ {
3776
+ ...triggerAttrs,
3777
+ type: "button",
3778
+ disabled,
3779
+ onClick: handleTriggerClick,
3780
+ "aria-current": isActive ? "step" : void 0,
3781
+ "aria-disabled": ariaDisabled,
3782
+ "aria-describedby": descriptionId,
3783
+ tabIndex: isClickable ? void 0 : -1,
3784
+ children: [
3785
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", ...indicatorAttrs, children: indicatorContent }),
3786
+ /* @__PURE__ */ jsx("span", { ...contentAttrs, children }),
3787
+ statusLabel ? /* @__PURE__ */ jsx("span", { style: visuallyHidden, children: `, ${statusLabel}` }) : null
3788
+ ]
3789
+ }
3790
+ )
3791
+ ] }) });
1231
3792
  };
1232
- SelectLabel.displayName = "Select.Label";
1233
- var SelectSeparator = (props) => {
1234
- const theme = useComponentTheme("SelectSeparator");
1235
- const { rootAttrs, rest } = composeRootAttrs(SelectSeparatorBase, props, theme);
1236
- const { children, ref, ...spar } = rest;
1237
- return /* @__PURE__ */ jsx(SelectSeparator$1, { ...spar, ref, ...rootAttrs, children });
3793
+ StepperItem.displayName = "Stepper.Item";
3794
+ var StepperDescription = (props) => {
3795
+ const theme = useComponentTheme("StepperDescription");
3796
+ const { registerDescription } = useStepperItem("Stepper.Description");
3797
+ const { rootAttrs, rest } = composeRootAttrs(StepperDescriptionBase, props, theme);
3798
+ const { as, children, ref, id: idProp, ...nativeProps } = rest;
3799
+ const autoId = useId();
3800
+ const id = idProp ?? autoId;
3801
+ useEffect(() => registerDescription(id), [registerDescription, id]);
3802
+ const Component = as ?? "span";
3803
+ return (
3804
+ // Locked after the spread: the id must match the trigger's
3805
+ // `aria-describedby` registration, and `aria-hidden` keeps the description
3806
+ // out of the trigger's accessible NAME — it still reaches assistive
3807
+ // technology as the trigger's description, since `aria-describedby` may
3808
+ // reference hidden elements.
3809
+ /* @__PURE__ */ jsx(Component, { ...nativeProps, ...rootAttrs, ref, id, "aria-hidden": "true", children })
3810
+ );
1238
3811
  };
1239
- SelectSeparator.displayName = "Select.Separator";
3812
+ StepperDescription.displayName = "Stepper.Description";
1240
3813
 
1241
- // src/components/select/index.ts
1242
- var Select2 = Object.assign(Select, {
1243
- Trigger: SelectTrigger,
1244
- Content: SelectContent,
1245
- Item: SelectItem,
1246
- Group: SelectGroup,
1247
- Label: SelectLabel,
1248
- Separator: SelectSeparator
3814
+ // src/components/stepper/index.ts
3815
+ var Stepper2 = Object.assign(Stepper, {
3816
+ Item: StepperItem,
3817
+ Title: StepperTitle,
3818
+ Description: StepperDescription
1249
3819
  });
1250
3820
 
1251
3821
  // src/components/switch/base.ts
@@ -1265,12 +3835,12 @@ var SwitchBase = createComponentBase({
1265
3835
  var [SwitchProvider, useSwitchOwnContext] = createSafeContext("SwitchProvider");
1266
3836
 
1267
3837
  // src/components/switch/defaults.ts
1268
- var DEFAULT_SIZE8 = "base";
1269
- var DEFAULT_VARIANT4 = "info";
3838
+ var DEFAULT_SIZE15 = "base";
3839
+ var DEFAULT_VARIANT9 = "info";
1270
3840
  var Switch = (props) => {
1271
3841
  const theme = useComponentTheme("Switch");
1272
3842
  const { rootAttrs, rest } = composeRootAttrs(SwitchBase, props, theme, {
1273
- stateAttrs: ({ size = DEFAULT_SIZE8, variant = DEFAULT_VARIANT4 }) => ({
3843
+ stateAttrs: ({ size = DEFAULT_SIZE15, variant = DEFAULT_VARIANT9 }) => ({
1274
3844
  "data-size": size,
1275
3845
  "data-variant": variant
1276
3846
  })
@@ -1281,34 +3851,29 @@ var Switch = (props) => {
1281
3851
  // off the rendered DOM where they would leak as raw HTML attributes.
1282
3852
  size: _size,
1283
3853
  variant: _variant,
1284
- // `invalid` is forwarded to Spar as `invalid` (same name).
1285
- invalid = false,
1286
3854
  children,
1287
3855
  ref,
3856
+ // `invalid`, `disabled`, `readOnly` and `required` are intentionally NOT
3857
+ // destructured (so no eager `= false` default is applied) — they flow to
3858
+ // Spar via `...sparProps` untouched. Defaulting `invalid` here would turn
3859
+ // an omitted prop into an explicit `false`, defeating Spar's
3860
+ // `invalid ?? fieldCtx?.invalid` inheritance and silently overriding a
3861
+ // wrapping `<Field invalid>`. Mirrors the Radio/Input/Select pass-through.
1288
3862
  ...sparProps
1289
3863
  } = rest;
1290
- return /* @__PURE__ */ jsx(
1291
- Switch$1,
3864
+ return /* @__PURE__ */ jsx(Switch$1, { ...sparProps, ref, ...rootAttrs, children: (state) => /* @__PURE__ */ jsx(
3865
+ SwitchProvider,
1292
3866
  {
1293
- ...sparProps,
1294
- invalid,
1295
- ref,
1296
- ...rootAttrs,
1297
- children: (state) => /* @__PURE__ */ jsx(
1298
- SwitchProvider,
1299
- {
1300
- value: {
1301
- classNames,
1302
- slotProps,
1303
- checked: state.checked,
1304
- disabled: state.disabled,
1305
- readOnly: state.readOnly
1306
- },
1307
- children: typeof children === "function" ? children(state) : children
1308
- }
1309
- )
3867
+ value: {
3868
+ classNames,
3869
+ slotProps,
3870
+ checked: state.checked,
3871
+ disabled: state.disabled,
3872
+ readOnly: state.readOnly
3873
+ },
3874
+ children: typeof children === "function" ? children(state) : children
1310
3875
  }
1311
- );
3876
+ ) });
1312
3877
  };
1313
3878
  Switch.displayName = "Switch";
1314
3879
  var SwitchIndicator = (props) => {
@@ -1336,6 +3901,870 @@ SwitchIndicator.displayName = "Switch.Indicator";
1336
3901
  var Switch2 = Object.assign(Switch, {
1337
3902
  Indicator: SwitchIndicator
1338
3903
  });
3904
+
3905
+ // src/components/table/base.ts
3906
+ var TableBase = createComponentBase({
3907
+ name: "Table",
3908
+ slots: [
3909
+ "root",
3910
+ "tableViewport",
3911
+ "table",
3912
+ "header",
3913
+ "headerRow",
3914
+ "headerCell",
3915
+ "headerContent",
3916
+ "sortTrigger",
3917
+ "sortIcon",
3918
+ "body",
3919
+ "row",
3920
+ "cell",
3921
+ "selectionCell",
3922
+ "expandCell",
3923
+ "expandButton",
3924
+ "expandedRow",
3925
+ "filterButton",
3926
+ "filterPanel",
3927
+ "pagination",
3928
+ "paginationInfo",
3929
+ "paginationNav",
3930
+ "paginationActions",
3931
+ "paginationSize",
3932
+ "paginationGoToPage",
3933
+ "empty",
3934
+ "loading"
3935
+ ],
3936
+ classes: {
3937
+ root: "tk-table",
3938
+ tableViewport: "tk-table-viewport",
3939
+ table: "tk-table-table",
3940
+ header: "tk-table-header",
3941
+ headerRow: "tk-table-header-row",
3942
+ headerCell: "tk-table-header-cell",
3943
+ headerContent: "tk-table-header-content",
3944
+ sortTrigger: "tk-table-sort-trigger",
3945
+ sortIcon: "tk-table-sort-icon",
3946
+ body: "tk-table-body",
3947
+ row: "tk-table-row",
3948
+ cell: "tk-table-cell",
3949
+ selectionCell: "tk-table-selection-cell",
3950
+ expandCell: "tk-table-expand-cell",
3951
+ expandButton: "tk-table-expand-button",
3952
+ expandedRow: "tk-table-expanded-row",
3953
+ filterButton: "tk-table-filter-button",
3954
+ filterPanel: "tk-table-filter-panel-body",
3955
+ pagination: "tk-table-pagination",
3956
+ paginationInfo: "tk-table-pagination-info",
3957
+ paginationNav: "tk-table-pagination-nav",
3958
+ paginationActions: "tk-table-pagination-actions",
3959
+ paginationSize: "tk-table-pagination-size",
3960
+ paginationGoToPage: "tk-table-pagination-go-to-page",
3961
+ empty: "tk-table-empty",
3962
+ loading: "tk-table-loading"
3963
+ }
3964
+ });
3965
+
3966
+ // src/components/table/context.ts
3967
+ var [TableProvider, useTableContext] = createSafeContext("Table");
3968
+
3969
+ // src/components/table/defaults.ts
3970
+ var DEFAULT_SIZE16 = "base";
3971
+ var DEFAULT_PAGE_SIZE = 10;
3972
+ var DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
3973
+ var DEFAULT_COLUMN_WIDTH = 150;
3974
+ var UTILITY_COLUMN_WIDTH = 48;
3975
+ var SELECTION_COLUMN_KEY = "__tk_selection__";
3976
+ var EXPAND_COLUMN_KEY = "__tk_expand__";
3977
+ var toRenderableValue = (value, columnId) => {
3978
+ if (value == null || typeof value !== "object" || isValidElement(value)) return value;
3979
+ if (isDevelopment()) {
3980
+ console.error(
3981
+ `[Table] Column "${columnId}" resolved to a non-renderable object value. Provide a \`cell\` render-prop (or an accessor that returns a primitive/element) \u2014 falling back to JSON.stringify.`
3982
+ );
3983
+ }
3984
+ try {
3985
+ return JSON.stringify(value);
3986
+ } catch {
3987
+ return String(value);
3988
+ }
3989
+ };
3990
+ var defaultCell = (ctx) => toRenderableValue(ctx.getValue(), ctx.column.id);
3991
+ var isEmptyFilterValue = (value) => value == null || value === "" || Array.isArray(value) && value.length === 0;
3992
+ var substringFilterFn = (row, columnId, filterValue) => {
3993
+ if (isEmptyFilterValue(filterValue)) return true;
3994
+ return String(row.getValue(columnId)).toLowerCase().includes(String(filterValue).toLowerCase());
3995
+ };
3996
+ substringFilterFn.autoRemove = isEmptyFilterValue;
3997
+ var equalsFilterFn = (row, columnId, filterValue) => {
3998
+ if (isEmptyFilterValue(filterValue)) return true;
3999
+ return String(row.getValue(columnId)) === String(filterValue);
4000
+ };
4001
+ equalsFilterFn.autoRemove = isEmptyFilterValue;
4002
+ var membershipFilterFn = (row, columnId, filterValue) => {
4003
+ if (!Array.isArray(filterValue) || filterValue.length === 0) return true;
4004
+ return filterValue.map(String).includes(String(row.getValue(columnId)));
4005
+ };
4006
+ membershipFilterFn.autoRemove = (value) => !Array.isArray(value) || value.length === 0;
4007
+ var PRESET_FILTER_FN = {
4008
+ "text": substringFilterFn,
4009
+ "select": equalsFilterFn,
4010
+ "radio": equalsFilterFn,
4011
+ "multi-select": membershipFilterFn,
4012
+ "checkbox": membershipFilterFn
4013
+ };
4014
+ var defaultFilterFn = (row, columnId, filterValue) => {
4015
+ if (isEmptyFilterValue(filterValue)) return true;
4016
+ const cell = row.getValue(columnId);
4017
+ if (typeof filterValue === "string") return String(cell).toLowerCase().includes(filterValue.toLowerCase());
4018
+ if (Array.isArray(filterValue)) return filterValue.map(String).includes(String(cell));
4019
+ return String(cell) === String(filterValue);
4020
+ };
4021
+ defaultFilterFn.autoRemove = isEmptyFilterValue;
4022
+ var normalizeColumnFilter = (filter) => {
4023
+ if (filter == null) return void 0;
4024
+ return typeof filter === "string" ? { type: filter } : filter;
4025
+ };
4026
+ var resolveFilterFn = (filter) => {
4027
+ if (filter.filterFn) return filter.filterFn;
4028
+ if (filter.render == null && filter.type) return PRESET_FILTER_FN[filter.type];
4029
+ return defaultFilterFn;
4030
+ };
4031
+ var toTanStackColumns = (columns) => columns.map((col) => {
4032
+ const { id, header, accessor, cell, sortable, filter, sticky, width, align, meta } = col;
4033
+ const normalizedFilter = normalizeColumnFilter(filter);
4034
+ const def = {
4035
+ id,
4036
+ header,
4037
+ enableSorting: sortable ?? false,
4038
+ enableColumnFilter: normalizedFilter != null,
4039
+ meta: {
4040
+ align,
4041
+ sticky,
4042
+ width,
4043
+ className: meta?.className,
4044
+ headerClassName: meta?.headerClassName,
4045
+ headerAlign: meta?.headerAlign,
4046
+ filter: normalizedFilter
4047
+ }
4048
+ };
4049
+ def.cell = cell ?? defaultCell;
4050
+ if (width != null) def.size = width;
4051
+ if (typeof accessor === "function") {
4052
+ def.accessorFn = accessor;
4053
+ } else if (accessor != null) {
4054
+ def.accessorKey = accessor;
4055
+ }
4056
+ if (normalizedFilter) {
4057
+ def.filterFn = resolveFilterFn(normalizedFilter);
4058
+ }
4059
+ return def;
4060
+ });
4061
+ var computeStickyLayout = (ordered) => {
4062
+ const layout = /* @__PURE__ */ new Map();
4063
+ if (isDevelopment()) warnNonContiguousPinning(ordered);
4064
+ let leftOffset = 0;
4065
+ for (const column of ordered) {
4066
+ if (column.side === "left") {
4067
+ layout.set(column.key, { side: "left", offset: leftOffset });
4068
+ leftOffset += column.width;
4069
+ }
4070
+ }
4071
+ let rightOffset = 0;
4072
+ for (let i = ordered.length - 1; i >= 0; i -= 1) {
4073
+ const column = ordered[i];
4074
+ if (column?.side === "right") {
4075
+ layout.set(column.key, { side: "right", offset: rightOffset });
4076
+ rightOffset += column.width;
4077
+ }
4078
+ }
4079
+ return layout;
4080
+ };
4081
+ var warnNonContiguousPinning = (ordered) => {
4082
+ let seenNonLeft = false;
4083
+ for (const column of ordered) {
4084
+ if (column.side === "left") {
4085
+ if (seenNonLeft) return warnPinning("left");
4086
+ } else {
4087
+ seenNonLeft = true;
4088
+ }
4089
+ }
4090
+ let seenNonRight = false;
4091
+ for (let i = ordered.length - 1; i >= 0; i -= 1) {
4092
+ const column = ordered[i];
4093
+ if (column?.side === "right") {
4094
+ if (seenNonRight) return warnPinning("right");
4095
+ } else {
4096
+ seenNonRight = true;
4097
+ }
4098
+ }
4099
+ };
4100
+ var warnPinning = (side) => {
4101
+ console.error(
4102
+ `[Table] Non-contiguous ${side} column pinning detected. Pinned columns must be contiguous against the ${side} edge (no unpinned column between them); otherwise the sticky offset math overlaps the unpinned column. Move the pinned columns together or unpin the gap.`
4103
+ );
4104
+ };
4105
+ var buildOrderedColumns = (table, options) => {
4106
+ const leaf = table.getVisibleLeafColumns();
4107
+ const hasLeftPinned = leaf.some((column) => column.columnDef.meta?.sticky === "left");
4108
+ const utilitySide = hasLeftPinned ? "left" : void 0;
4109
+ const ordered = [];
4110
+ if (options.hasSelection) ordered.push({ key: SELECTION_COLUMN_KEY, side: utilitySide, width: UTILITY_COLUMN_WIDTH });
4111
+ if (options.hasExpansion) ordered.push({ key: EXPAND_COLUMN_KEY, side: utilitySide, width: UTILITY_COLUMN_WIDTH });
4112
+ for (const column of leaf) {
4113
+ ordered.push({
4114
+ key: column.id,
4115
+ side: column.columnDef.meta?.sticky,
4116
+ width: column.getSize() || DEFAULT_COLUMN_WIDTH
4117
+ });
4118
+ }
4119
+ return ordered;
4120
+ };
4121
+ var getExportRows = (table) => {
4122
+ if (!table) return [];
4123
+ const columns = table.getAllLeafColumns();
4124
+ return table.getSortedRowModel().rows.map((row) => {
4125
+ const record = {};
4126
+ for (const column of columns) {
4127
+ if (column.accessorFn || column.columnDef.accessorKey != null) {
4128
+ record[column.id] = row.getValue(column.id);
4129
+ }
4130
+ }
4131
+ return record;
4132
+ });
4133
+ };
4134
+ var resolveStickyCell = (layout, key, options) => {
4135
+ const placement = layout.get(key);
4136
+ const isStickyColumn = !!placement;
4137
+ const stickyHeaderActive = options.isHeader && options.stickyHeader;
4138
+ if (!isStickyColumn && !stickyHeaderActive) return {};
4139
+ const style = { position: "sticky" };
4140
+ if (placement) {
4141
+ if (placement.side === "left") style.left = placement.offset;
4142
+ else style.right = placement.offset;
4143
+ }
4144
+ if (stickyHeaderActive) style.top = 0;
4145
+ style.zIndex = isStickyColumn && stickyHeaderActive ? 3 : stickyHeaderActive ? 2 : 1;
4146
+ return { style, dataSticky: placement?.side };
4147
+ };
4148
+ var resolveCellWidth = (column, stickyLayout) => {
4149
+ const hasWidth = column.columnDef.meta?.width != null || stickyLayout.has(column.id);
4150
+ return hasWidth ? { width: column.getSize() } : void 0;
4151
+ };
4152
+ var TableCell = ({ cell }) => {
4153
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.Cell");
4154
+ const column = cell.column;
4155
+ const meta = column.columnDef.meta;
4156
+ const sticky = resolveStickyCell(stickyLayout, column.id, { isHeader: false, stickyHeader });
4157
+ const attrs = slotAttrs("cell", { className: meta?.className });
4158
+ const content = flexRender(column.columnDef.cell, cell.getContext());
4159
+ return /* @__PURE__ */ jsx("td", { ...attrs, "data-align": meta?.align, "data-sticky": sticky.dataSticky, style: { ...attrs.style, ...sticky.style, ...resolveCellWidth(column, stickyLayout) }, children: content });
4160
+ };
4161
+ TableCell.displayName = "Table.Cell";
4162
+ var mergeStyle = (...styles) => Object.assign({}, ...styles);
4163
+ var SelectionHeaderCell = () => {
4164
+ const { table, slotAttrs, selectionMode, stickyLayout, stickyHeader } = useTableContext("Table.SelectionHeaderCell");
4165
+ const sticky = resolveStickyCell(stickyLayout, SELECTION_COLUMN_KEY, { isHeader: true, stickyHeader });
4166
+ const attrs = slotAttrs("selectionCell");
4167
+ const allSelected = table.getIsAllPageRowsSelected();
4168
+ return /* @__PURE__ */ jsx("th", { ...attrs, scope: "col", "data-sticky": sticky.dataSticky, "data-selection-mode": selectionMode, style: mergeStyle(attrs.style, sticky.style, { width: UTILITY_COLUMN_WIDTH }), children: selectionMode === "multiple" && /* @__PURE__ */ jsx(
4169
+ Checkbox2,
4170
+ {
4171
+ "aria-label": "Select all rows",
4172
+ checked: allSelected,
4173
+ indeterminate: table.getIsSomePageRowsSelected() && !allSelected,
4174
+ onChange: (checked) => table.toggleAllPageRowsSelected(checked),
4175
+ children: /* @__PURE__ */ jsx(Checkbox2.Indicator, {})
4176
+ }
4177
+ ) });
4178
+ };
4179
+ SelectionHeaderCell.displayName = "Table.SelectionHeaderCell";
4180
+ var SelectionBodyCell = ({ row }) => {
4181
+ const { slotAttrs, selectionMode, stickyLayout, stickyHeader } = useTableContext("Table.SelectionBodyCell");
4182
+ const sticky = resolveStickyCell(stickyLayout, SELECTION_COLUMN_KEY, { isHeader: false, stickyHeader });
4183
+ const attrs = slotAttrs("selectionCell");
4184
+ return /* @__PURE__ */ jsx("td", { ...attrs, "data-sticky": sticky.dataSticky, "data-selection-mode": selectionMode, style: mergeStyle(attrs.style, sticky.style, { width: UTILITY_COLUMN_WIDTH }), children: selectionMode === "single" ? /* @__PURE__ */ jsx(Radio2, { "aria-label": "Select row", value: row.getIsSelected() ? row.id : "", onChange: () => row.toggleSelected(true), children: /* @__PURE__ */ jsx(Radio2.Item, { value: row.id, disabled: !row.getCanSelect(), children: /* @__PURE__ */ jsx(Radio2.Indicator, {}) }) }) : /* @__PURE__ */ jsx(Checkbox2, { "aria-label": "Select row", checked: row.getIsSelected(), disabled: !row.getCanSelect(), onChange: (checked) => row.toggleSelected(checked), children: /* @__PURE__ */ jsx(Checkbox2.Indicator, {}) }) });
4185
+ };
4186
+ SelectionBodyCell.displayName = "Table.SelectionBodyCell";
4187
+ var ExpandHeaderCell = () => {
4188
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.ExpandHeaderCell");
4189
+ const sticky = resolveStickyCell(stickyLayout, EXPAND_COLUMN_KEY, { isHeader: true, stickyHeader });
4190
+ const attrs = slotAttrs("expandCell");
4191
+ return /* @__PURE__ */ jsx("th", { ...attrs, scope: "col", "data-sticky": sticky.dataSticky, style: mergeStyle(attrs.style, sticky.style, { width: UTILITY_COLUMN_WIDTH }) });
4192
+ };
4193
+ ExpandHeaderCell.displayName = "Table.ExpandHeaderCell";
4194
+ var ExpandBodyCell = ({ row }) => {
4195
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.ExpandBodyCell");
4196
+ const sticky = resolveStickyCell(stickyLayout, EXPAND_COLUMN_KEY, { isHeader: false, stickyHeader });
4197
+ const attrs = slotAttrs("expandCell");
4198
+ const expanded = row.getIsExpanded();
4199
+ return /* @__PURE__ */ jsx("td", { ...attrs, "data-sticky": sticky.dataSticky, style: mergeStyle(attrs.style, sticky.style, { width: UTILITY_COLUMN_WIDTH }), children: row.getCanExpand() && /* @__PURE__ */ jsx(
4200
+ "button",
4201
+ {
4202
+ ...slotAttrs("expandButton"),
4203
+ type: "button",
4204
+ "aria-label": expanded ? "Collapse row" : "Expand row",
4205
+ "aria-expanded": expanded,
4206
+ onClick: row.getToggleExpandedHandler(),
4207
+ children: expanded ? /* @__PURE__ */ jsx(ChevronBottomIconOutlinedRounded, {}) : /* @__PURE__ */ jsx(ChevronRightIconOutlinedRounded, {})
4208
+ }
4209
+ ) });
4210
+ };
4211
+ ExpandBodyCell.displayName = "Table.ExpandBodyCell";
4212
+ var TableRow = ({ row }) => {
4213
+ const { slotAttrs, hasSelection, hasExpansion, treeMode, expansionRender, totalColumnCount } = useTableContext("Table.Row");
4214
+ const selected = row.getIsSelected();
4215
+ const showDetailPanel = hasExpansion && !treeMode && !!expansionRender && row.getIsExpanded();
4216
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
4217
+ /* @__PURE__ */ jsxs("tr", { ...slotAttrs("row"), "data-selected": selected ? "" : void 0, children: [
4218
+ hasSelection && /* @__PURE__ */ jsx(SelectionBodyCell, { row }),
4219
+ hasExpansion && /* @__PURE__ */ jsx(ExpandBodyCell, { row }),
4220
+ row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { cell }, cell.id))
4221
+ ] }),
4222
+ showDetailPanel && /* @__PURE__ */ jsx("tr", { ...slotAttrs("expandedRow"), children: /* @__PURE__ */ jsx("td", { colSpan: totalColumnCount, children: expansionRender(row.original) }) })
4223
+ ] });
4224
+ };
4225
+ TableRow.displayName = "Table.Row";
4226
+ var TableBody = () => {
4227
+ const { table, slotAttrs, totalColumnCount, emptyState, loading } = useTableContext("Table.Body");
4228
+ const rows = table.getRowModel().rows;
4229
+ return /* @__PURE__ */ jsx("tbody", { ...slotAttrs("body"), children: rows.length === 0 ? /* @__PURE__ */ jsx("tr", { ...slotAttrs("row"), children: /* @__PURE__ */ jsx("td", { ...slotAttrs("empty"), colSpan: totalColumnCount, children: loading ? null : emptyState ?? "No data" }) }) : rows.map((row) => /* @__PURE__ */ jsx(TableRow, { row }, row.id)) });
4230
+ };
4231
+ TableBody.displayName = "Table.Body";
4232
+ var FILTER_BUTTON_CLASS = TableBase.getSlotProps("filterButton").className;
4233
+ var defaultIsActive = (value) => !isEmptyFilterValue(value);
4234
+ var TableColumnFilter = ({ header }) => {
4235
+ const { slotAttrs } = useTableContext("Table.ColumnFilter");
4236
+ const [open, setOpen] = useState(false);
4237
+ const column = header.column;
4238
+ const filter = column.columnDef.meta?.filter;
4239
+ if (!filter) return null;
4240
+ const value = column.getFilterValue();
4241
+ const active = (filter.isActive ?? defaultIsActive)(value);
4242
+ const ctx = {
4243
+ value,
4244
+ setValue: (next) => column.setFilterValue(next),
4245
+ clear: () => column.setFilterValue(void 0),
4246
+ column,
4247
+ close: () => setOpen(false)
4248
+ };
4249
+ return /* @__PURE__ */ jsxs(Popover2, { open, onOpenChange: setOpen, children: [
4250
+ /* @__PURE__ */ jsx(Popover2.Trigger, { className: FILTER_BUTTON_CLASS, "aria-label": "Filter column", "data-active": active ? "" : void 0, children: /* @__PURE__ */ jsx(SearchIconOutlinedRounded, { "aria-hidden": "true" }) }),
4251
+ /* @__PURE__ */ jsxs(Popover2.Content, { className: "tk-table-filter-panel", children: [
4252
+ /* @__PURE__ */ jsx("div", { ...slotAttrs("filterPanel"), children: filter.render ? filter.render(ctx) : /* @__PURE__ */ jsx(PresetFilterControl, { filter, ctx }) }),
4253
+ active && /* @__PURE__ */ jsx(Button, { size: "small", appearance: "text", onClick: ctx.clear, children: "Clear" })
4254
+ ] })
4255
+ ] });
4256
+ };
4257
+ TableColumnFilter.displayName = "Table.ColumnFilter";
4258
+ var PresetFilterControl = ({ filter, ctx }) => {
4259
+ const { type, options = [], placeholder } = filter;
4260
+ const { value, setValue } = ctx;
4261
+ if (type === "text") {
4262
+ return /* @__PURE__ */ jsx(Input2, { children: /* @__PURE__ */ jsx(
4263
+ Input2.Field,
4264
+ {
4265
+ type: "search",
4266
+ placeholder,
4267
+ value: typeof value === "string" ? value : "",
4268
+ onChange: (event) => setValue(event.target.value || void 0)
4269
+ }
4270
+ ) });
4271
+ }
4272
+ if (type === "select") {
4273
+ return /* @__PURE__ */ jsx(SelectFilter, { options, placeholder, value: typeof value === "string" ? value : "", onChange: (next) => setValue(next || void 0) });
4274
+ }
4275
+ if (type === "radio") {
4276
+ return /* @__PURE__ */ jsx(Radio2, { value: typeof value === "string" ? value : "", onChange: (next) => setValue(next || void 0), children: options.map((option) => /* @__PURE__ */ jsx(Radio2.Item, { value: option.value, children: /* @__PURE__ */ jsx(Radio2.Label, { children: option.label }) }, option.value)) });
4277
+ }
4278
+ if (type === "checkbox" || type === "multi-select") {
4279
+ return /* @__PURE__ */ jsx(CheckboxListFilter, { options, value: Array.isArray(value) ? value : [], onChange: setValue });
4280
+ }
4281
+ return null;
4282
+ };
4283
+ PresetFilterControl.displayName = "Table.PresetFilterControl";
4284
+ var SelectFilter = ({
4285
+ options,
4286
+ placeholder,
4287
+ value,
4288
+ onChange
4289
+ }) => {
4290
+ const selected = options.find((option) => option.value === value);
4291
+ return /* @__PURE__ */ jsxs(Select2, { value, onChange, children: [
4292
+ /* @__PURE__ */ jsx(Select2.Trigger, { children: selected ? selected.label : placeholder ?? "Select" }),
4293
+ /* @__PURE__ */ jsx(Select2.Content, { children: options.map((option) => /* @__PURE__ */ jsx(Select2.Item, { value: option.value, children: option.label }, option.value)) })
4294
+ ] });
4295
+ };
4296
+ var CheckboxListFilter = ({ options, value, onChange }) => /* @__PURE__ */ jsx(Fragment, { children: options.map((option) => {
4297
+ const checked = value.includes(option.value);
4298
+ return /* @__PURE__ */ jsxs(
4299
+ Checkbox2,
4300
+ {
4301
+ checked,
4302
+ onChange: (next) => {
4303
+ const updated = next ? [...value, option.value] : value.filter((item) => item !== option.value);
4304
+ onChange(updated.length ? updated : void 0);
4305
+ },
4306
+ children: [
4307
+ /* @__PURE__ */ jsx(Checkbox2.Indicator, {}),
4308
+ option.label
4309
+ ]
4310
+ },
4311
+ option.value
4312
+ );
4313
+ }) });
4314
+ var TableHeaderCell = ({ header }) => {
4315
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.HeaderCell");
4316
+ const column = header.column;
4317
+ const meta = column.columnDef.meta;
4318
+ const align = meta?.headerAlign ?? meta?.align;
4319
+ const canSort = column.getCanSort();
4320
+ const canFilter = column.getCanFilter() && !!meta?.filter;
4321
+ const sorted = column.getIsSorted();
4322
+ const sticky = resolveStickyCell(stickyLayout, column.id, { isHeader: true, stickyHeader });
4323
+ const attrs = slotAttrs("headerCell", { className: meta?.headerClassName });
4324
+ const ariaSort = canSort ? sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none" : void 0;
4325
+ const content = header.isPlaceholder ? null : flexRender(column.columnDef.header, header.getContext());
4326
+ return /* @__PURE__ */ jsx(
4327
+ "th",
4328
+ {
4329
+ ...attrs,
4330
+ scope: "col",
4331
+ colSpan: header.colSpan,
4332
+ "aria-sort": ariaSort,
4333
+ "data-align": align,
4334
+ "data-sticky": sticky.dataSticky,
4335
+ "data-sortable": canSort ? "" : void 0,
4336
+ style: { ...attrs.style, ...sticky.style, ...resolveCellWidth(column, stickyLayout) },
4337
+ children: /* @__PURE__ */ jsxs("div", { ...slotAttrs("headerContent"), children: [
4338
+ canSort ? /* @__PURE__ */ jsxs("button", { ...slotAttrs("sortTrigger"), type: "button", onClick: column.getToggleSortingHandler(), children: [
4339
+ content,
4340
+ /* @__PURE__ */ jsx("span", { ...slotAttrs("sortIcon"), "data-direction": sorted || "none", "aria-hidden": "true", children: sorted === "asc" ? /* @__PURE__ */ jsx(ChevronTopIconOutlinedRounded, {}) : sorted === "desc" ? /* @__PURE__ */ jsx(ChevronBottomIconOutlinedRounded, {}) : /* @__PURE__ */ jsx(SwapIconOutlinedRounded, {}) })
4341
+ ] }) : content,
4342
+ canFilter && /* @__PURE__ */ jsx(TableColumnFilter, { header })
4343
+ ] })
4344
+ }
4345
+ );
4346
+ };
4347
+ TableHeaderCell.displayName = "Table.HeaderCell";
4348
+ var TableHeader = () => {
4349
+ const { table, slotAttrs, hasSelection, hasExpansion } = useTableContext("Table.Header");
4350
+ return /* @__PURE__ */ jsx("thead", { ...slotAttrs("header"), children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxs("tr", { ...slotAttrs("headerRow"), children: [
4351
+ hasSelection && /* @__PURE__ */ jsx(SelectionHeaderCell, {}),
4352
+ hasExpansion && /* @__PURE__ */ jsx(ExpandHeaderCell, {}),
4353
+ headerGroup.headers.map((header) => /* @__PURE__ */ jsx(TableHeaderCell, { header }, header.id))
4354
+ ] }, headerGroup.id)) });
4355
+ };
4356
+ TableHeader.displayName = "Table.Header";
4357
+ var getPaginationItems = (pageIndex, pageCount) => {
4358
+ if (pageCount <= 7) return Array.from({ length: pageCount }, (_, index) => index);
4359
+ if (pageIndex <= 3) return [0, 1, 2, 3, 4, "end-ellipsis", pageCount - 1];
4360
+ if (pageIndex >= pageCount - 4) return [0, "start-ellipsis", pageCount - 5, pageCount - 4, pageCount - 3, pageCount - 2, pageCount - 1];
4361
+ return [0, "start-ellipsis", pageIndex - 1, pageIndex, pageIndex + 1, "end-ellipsis", pageCount - 1];
4362
+ };
4363
+ var TablePagination = () => {
4364
+ const { table, slotAttrs, pageSizeOptions } = useTableContext("Table.Pagination");
4365
+ const { pageIndex, pageSize } = table.getState().pagination;
4366
+ const pageCount = table.getPageCount();
4367
+ const paginationItems = getPaginationItems(pageIndex, pageCount);
4368
+ const [pageInput, setPageInput] = useState("");
4369
+ const totalRows = table.getRowCount();
4370
+ const startItem = pageIndex * pageSize + 1;
4371
+ const endItem = Math.min((pageIndex + 1) * pageSize, totalRows);
4372
+ const itemsLabel = totalRows === 0 ? "0 items" : `Items ${startItem}-${endItem} of ${totalRows}`;
4373
+ const sizeOptions = pageSizeOptions.includes(pageSize) ? pageSizeOptions : [...pageSizeOptions, pageSize].sort((a, b) => a - b);
4374
+ const goToPage = () => {
4375
+ const requestedPage = Number(pageInput);
4376
+ if (!Number.isFinite(requestedPage) || pageCount <= 0 || pageInput === "") return;
4377
+ const targetPage = Math.min(Math.max(Math.trunc(requestedPage), 1), pageCount);
4378
+ table.setPageIndex(targetPage - 1);
4379
+ setPageInput("");
4380
+ };
4381
+ return /* @__PURE__ */ jsxs("div", { ...slotAttrs("pagination"), role: "navigation", "aria-label": "Pagination", children: [
4382
+ /* @__PURE__ */ jsxs("div", { ...slotAttrs("paginationInfo"), children: [
4383
+ /* @__PURE__ */ jsx("span", { "aria-live": "polite", children: pageCount > 0 ? `Page ${pageIndex + 1} of ${pageCount}` : `Page ${pageIndex + 1}` }),
4384
+ /* @__PURE__ */ jsx("span", { "aria-live": "polite", children: itemsLabel })
4385
+ ] }),
4386
+ /* @__PURE__ */ jsxs("div", { ...slotAttrs("paginationNav"), children: [
4387
+ /* @__PURE__ */ jsx(
4388
+ Button,
4389
+ {
4390
+ size: "small",
4391
+ variant: "neutral",
4392
+ appearance: "text",
4393
+ "aria-label": "First page",
4394
+ startContent: /* @__PURE__ */ jsx(ArrowLeftIconOutlinedRounded, {}),
4395
+ disabled: !table.getCanPreviousPage(),
4396
+ onClick: () => table.setPageIndex(0)
4397
+ }
4398
+ ),
4399
+ /* @__PURE__ */ jsx(
4400
+ Button,
4401
+ {
4402
+ size: "small",
4403
+ variant: "neutral",
4404
+ appearance: "text",
4405
+ "aria-label": "Previous page",
4406
+ startContent: /* @__PURE__ */ jsx(ChevronLeftIconOutlinedRounded, {}),
4407
+ disabled: !table.getCanPreviousPage(),
4408
+ onClick: () => table.previousPage()
4409
+ }
4410
+ ),
4411
+ paginationItems.map((item) => {
4412
+ if (typeof item !== "number") {
4413
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2026" }, item);
4414
+ }
4415
+ const pageNumber = item + 1;
4416
+ const current = item === pageIndex;
4417
+ return /* @__PURE__ */ jsx(
4418
+ Button,
4419
+ {
4420
+ type: "button",
4421
+ size: "small",
4422
+ variant: "neutral",
4423
+ appearance: current ? "outlined" : "text",
4424
+ "aria-label": current ? `Page ${pageNumber}, current page` : `Go to page ${pageNumber}`,
4425
+ "aria-current": current ? "page" : void 0,
4426
+ onClick: () => table.setPageIndex(item),
4427
+ children: pageNumber
4428
+ },
4429
+ item
4430
+ );
4431
+ }),
4432
+ /* @__PURE__ */ jsx(
4433
+ Button,
4434
+ {
4435
+ size: "small",
4436
+ variant: "neutral",
4437
+ appearance: "text",
4438
+ "aria-label": "Next page",
4439
+ startContent: /* @__PURE__ */ jsx(ChevronRightIconOutlinedRounded, {}),
4440
+ disabled: !table.getCanNextPage() || pageCount <= 0,
4441
+ onClick: () => table.nextPage()
4442
+ }
4443
+ ),
4444
+ /* @__PURE__ */ jsx(
4445
+ Button,
4446
+ {
4447
+ size: "small",
4448
+ variant: "neutral",
4449
+ appearance: "text",
4450
+ "aria-label": "Last page",
4451
+ startContent: /* @__PURE__ */ jsx(ArrowRightIconOutlinedRounded, {}),
4452
+ disabled: !table.getCanNextPage() || pageCount <= 0,
4453
+ onClick: () => table.setPageIndex(pageCount - 1)
4454
+ }
4455
+ )
4456
+ ] }),
4457
+ /* @__PURE__ */ jsxs("div", { ...slotAttrs("paginationActions"), children: [
4458
+ /* @__PURE__ */ jsx("div", { ...slotAttrs("paginationSize"), children: /* @__PURE__ */ jsxs(Select2, { size: "small", value: String(pageSize), onChange: (value) => table.setPageSize(Number(value)), children: [
4459
+ /* @__PURE__ */ jsx(Select2.Trigger, { "aria-label": "Rows per page", children: pageSize }),
4460
+ /* @__PURE__ */ jsx(Select2.Content, { children: sizeOptions.map((option) => /* @__PURE__ */ jsx(Select2.Item, { value: String(option), children: option }, option)) })
4461
+ ] }) }),
4462
+ /* @__PURE__ */ jsx("div", { ...slotAttrs("paginationGoToPage"), children: /* @__PURE__ */ jsxs(Input2, { size: "small", children: [
4463
+ /* @__PURE__ */ jsx(
4464
+ Input2.Field,
4465
+ {
4466
+ type: "number",
4467
+ min: 1,
4468
+ max: Math.max(pageCount, 1),
4469
+ inputMode: "numeric",
4470
+ "aria-label": "Go to page",
4471
+ placeholder: String(pageIndex + 1),
4472
+ value: pageInput,
4473
+ disabled: pageCount <= 0,
4474
+ onChange: (event) => setPageInput(event.currentTarget.value),
4475
+ onKeyDown: (event) => {
4476
+ if (event.key === "Enter") goToPage();
4477
+ }
4478
+ }
4479
+ ),
4480
+ /* @__PURE__ */ jsx(Input2.TrailingIcon, { as: "button", type: "button", "aria-label": "Go to page", disabled: pageCount <= 0, onClick: goToPage, children: /* @__PURE__ */ jsx(ChevronRightIconOutlinedRounded, {}) })
4481
+ ] }) })
4482
+ ] })
4483
+ ] });
4484
+ };
4485
+ TablePagination.displayName = "Table.Pagination";
4486
+ var EMPTY_SORTING = [];
4487
+ var EMPTY_FILTERS = [];
4488
+ var EMPTY_SELECTION = {};
4489
+ var EMPTY_EXPANDED = {};
4490
+ var Table = (props) => {
4491
+ const theme = useComponentTheme("Table");
4492
+ const { rootAttrs, rest } = composeRootAttrs(TableBase, props, theme, {
4493
+ // Visual vocabulary lives on the root so recipes cascade
4494
+ // to the portal-free table descendants. `data-loading` mirrors the
4495
+ // boolean-presence convention (rule 5).
4496
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE16, striped: striped2, bordered: bordered2, stickyHeader: stickyHeader2, loading: loading2 }) => ({
4497
+ "data-size": size2,
4498
+ "data-striped": striped2 ? "" : void 0,
4499
+ "data-bordered": bordered2 ? "" : void 0,
4500
+ "data-sticky-header": stickyHeader2 ? "" : void 0,
4501
+ "data-loading": loading2 ? "" : void 0
4502
+ })
4503
+ });
4504
+ const {
4505
+ data,
4506
+ columns,
4507
+ getRowId,
4508
+ manual = false,
4509
+ loading = false,
4510
+ size = DEFAULT_SIZE16,
4511
+ striped = false,
4512
+ bordered = false,
4513
+ stickyHeader = false,
4514
+ selection,
4515
+ sorting: sortingConfig,
4516
+ filtering,
4517
+ expansion,
4518
+ pagination,
4519
+ onDataRequest,
4520
+ emptyState,
4521
+ getSubRows,
4522
+ tableRef,
4523
+ ref
4524
+ } = rest;
4525
+ const { classNames, slotProps } = props;
4526
+ const tanstackColumns = useMemo(() => toTanStackColumns(columns), [columns]);
4527
+ const hasSelection = !!selection;
4528
+ const selectionMode = selection?.mode;
4529
+ const hasExpansion = !!expansion;
4530
+ const treeMode = !!getSubRows;
4531
+ const hasColumnFilters = !!filtering || columns.some((column) => !!column.filter);
4532
+ const hasSortableColumn = columns.some((column) => !!column.sortable);
4533
+ const paginationConfig = typeof pagination === "object" ? pagination : void 0;
4534
+ const paginationEnabled = pagination === true || !!paginationConfig;
4535
+ const pageSizeOptions = paginationConfig?.pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS;
4536
+ const [tableViewportScrolled, setTableViewportScrolled] = useState(false);
4537
+ const [sortingState, setSorting] = useControllableState(sortingConfig?.value, sortingConfig?.defaultValue ?? EMPTY_SORTING, sortingConfig?.onChange);
4538
+ const [filtersState, setFilters] = useControllableState(filtering?.value, filtering?.defaultValue ?? EMPTY_FILTERS, filtering?.onChange);
4539
+ const [selectionState, setSelection] = useControllableState(selection?.value, selection?.defaultValue ?? EMPTY_SELECTION, selection?.onChange);
4540
+ const [expandedState, setExpanded] = useControllableState(expansion?.value, expansion?.defaultValue ?? EMPTY_EXPANDED, expansion?.onChange);
4541
+ const readPaginationSlice = () => ({ pageIndex: paginationConfig?.pageIndex ?? 0, pageSize: paginationConfig?.pageSize ?? DEFAULT_PAGE_SIZE });
4542
+ const initialPagination = useMemo(readPaginationSlice, []);
4543
+ const paginationControlled = manual && !!paginationConfig;
4544
+ const controlledPagination = useMemo(
4545
+ () => paginationControlled ? readPaginationSlice() : void 0,
4546
+ [paginationControlled, paginationConfig?.pageIndex, paginationConfig?.pageSize]
4547
+ );
4548
+ const [paginationStateRaw, setPagination] = useControllableState(controlledPagination, initialPagination, paginationConfig?.onChange);
4549
+ const sorting = sortingState ?? EMPTY_SORTING;
4550
+ const columnFilters = filtersState ?? EMPTY_FILTERS;
4551
+ const rowSelection = selectionState ?? EMPTY_SELECTION;
4552
+ const expanded = expandedState ?? EMPTY_EXPANDED;
4553
+ const paginationValue = paginationStateRaw ?? initialPagination;
4554
+ const resetPageOnManual = () => {
4555
+ if (manual && paginationValue.pageIndex !== 0) setPagination({ ...paginationValue, pageIndex: 0 });
4556
+ };
4557
+ const onSortingChange = (updater) => {
4558
+ setSorting(functionalUpdate(updater, sorting));
4559
+ resetPageOnManual();
4560
+ };
4561
+ const onColumnFiltersChange = (updater) => {
4562
+ setFilters(functionalUpdate(updater, columnFilters));
4563
+ resetPageOnManual();
4564
+ };
4565
+ const onRowSelectionChange = (updater) => setSelection(functionalUpdate(updater, rowSelection));
4566
+ const onExpandedChange = (updater) => setExpanded(functionalUpdate(updater, expanded));
4567
+ const onPaginationChange = (updater) => setPagination(functionalUpdate(updater, paginationValue));
4568
+ const table = useReactTable({
4569
+ data,
4570
+ columns: tanstackColumns,
4571
+ getRowId: (row, index) => getRowId(row, index),
4572
+ state: {
4573
+ sorting,
4574
+ columnFilters,
4575
+ rowSelection,
4576
+ expanded,
4577
+ pagination: paginationValue
4578
+ },
4579
+ onSortingChange,
4580
+ onColumnFiltersChange,
4581
+ onRowSelectionChange,
4582
+ onExpandedChange,
4583
+ onPaginationChange,
4584
+ // Table-level sort switch. Per-column `sortable` is the real gate
4585
+ // (`column.getCanSort()` ANDs both), so a `sorting` config without any
4586
+ // `sortable` column makes no header interactive — keying off the columns
4587
+ // alone is sufficient and avoids implying otherwise.
4588
+ enableSorting: hasSortableColumn,
4589
+ enableMultiSort: sortingConfig?.multi ?? false,
4590
+ enableRowSelection: hasSelection,
4591
+ enableMultiRowSelection: selectionMode === "multiple",
4592
+ enableColumnFilters: hasColumnFilters,
4593
+ manualSorting: manual,
4594
+ manualFiltering: manual,
4595
+ manualPagination: manual,
4596
+ autoResetPageIndex: !manual,
4597
+ rowCount: manual ? paginationConfig?.rowCount : void 0,
4598
+ getCoreRowModel: getCoreRowModel(),
4599
+ getSortedRowModel: manual ? void 0 : getSortedRowModel(),
4600
+ getFilteredRowModel: manual ? void 0 : getFilteredRowModel(),
4601
+ getExpandedRowModel: hasExpansion ? getExpandedRowModel() : void 0,
4602
+ getPaginationRowModel: paginationEnabled && !manual ? getPaginationRowModel() : void 0,
4603
+ getSubRows,
4604
+ getRowCanExpand: hasExpansion && !getSubRows ? () => true : void 0
4605
+ });
4606
+ useEffect(() => {
4607
+ if (!tableRef) return;
4608
+ if (typeof tableRef === "function") tableRef(table);
4609
+ else tableRef.current = table;
4610
+ return () => {
4611
+ if (typeof tableRef === "function") tableRef(null);
4612
+ else tableRef.current = null;
4613
+ };
4614
+ }, [tableRef, table]);
4615
+ const onDataRequestRef = useRef(onDataRequest);
4616
+ onDataRequestRef.current = onDataRequest;
4617
+ const dataRequestKey = useMemo(() => JSON.stringify({ pagination: paginationValue, sorting, filters: columnFilters }), [paginationValue, sorting, columnFilters]);
4618
+ useEffect(() => {
4619
+ if (!manual) return;
4620
+ onDataRequestRef.current?.({ pagination: paginationValue, sorting, filters: columnFilters });
4621
+ }, [manual, dataRequestKey]);
4622
+ useEffect(() => {
4623
+ if (paginationControlled || paginationConfig?.pageSize == null) return;
4624
+ if (table.getState().pagination.pageSize === paginationConfig.pageSize) return;
4625
+ table.setPageSize(paginationConfig.pageSize);
4626
+ }, [paginationControlled, paginationConfig?.pageSize, table]);
4627
+ useEffect(() => {
4628
+ if (paginationControlled || paginationConfig?.pageIndex == null) return;
4629
+ if (table.getState().pagination.pageIndex === paginationConfig.pageIndex) return;
4630
+ table.setPageIndex(paginationConfig.pageIndex);
4631
+ }, [paginationControlled, paginationConfig?.pageIndex, table]);
4632
+ const slotAttrs = useCallback(
4633
+ (slot, attrs) => buildSlotAttrs(TableBase.getSlotProps(slot, attrs), slot, {
4634
+ themeSlotProps: theme?.slotProps,
4635
+ themeClassNames: theme?.classNames,
4636
+ themeClassName: theme?.className,
4637
+ instanceSlotProps: slotProps,
4638
+ instanceClassNames: classNames
4639
+ }),
4640
+ [theme, slotProps, classNames]
4641
+ );
4642
+ const stickyLayout = useMemo(() => computeStickyLayout(buildOrderedColumns(table, { hasSelection, hasExpansion })), [table, tanstackColumns, hasSelection, hasExpansion]);
4643
+ const totalColumnCount = tanstackColumns.length + (hasSelection ? 1 : 0) + (hasExpansion ? 1 : 0);
4644
+ const contextValue = {
4645
+ table,
4646
+ size,
4647
+ striped,
4648
+ bordered,
4649
+ stickyHeader,
4650
+ loading,
4651
+ hasSelection,
4652
+ selectionMode,
4653
+ hasExpansion,
4654
+ treeMode,
4655
+ expansionRender: expansion?.render,
4656
+ hasColumnFilters,
4657
+ stickyLayout,
4658
+ totalColumnCount,
4659
+ emptyState,
4660
+ paginationEnabled,
4661
+ pageSizeOptions,
4662
+ slotAttrs
4663
+ };
4664
+ const tableViewportAttrs = slotAttrs("tableViewport");
4665
+ const handleTableViewportScroll = (event) => {
4666
+ tableViewportAttrs.onScroll?.(event);
4667
+ const nextScrolled = event.currentTarget.scrollTop > 0;
4668
+ setTableViewportScrolled((current) => current === nextScrolled ? current : nextScrolled);
4669
+ };
4670
+ return /* @__PURE__ */ jsx(TableProvider, { value: contextValue, children: /* @__PURE__ */ jsxs("div", { ...rootAttrs, ref, children: [
4671
+ /* @__PURE__ */ jsx("div", { ...tableViewportAttrs, "data-scrolled": tableViewportScrolled ? "" : void 0, onScroll: handleTableViewportScroll, children: /* @__PURE__ */ jsxs("table", { ...slotAttrs("table"), "aria-busy": loading || void 0, children: [
4672
+ /* @__PURE__ */ jsx(TableHeader, {}),
4673
+ /* @__PURE__ */ jsx(TableBody, {})
4674
+ ] }) }),
4675
+ paginationEnabled && /* @__PURE__ */ jsx(TablePagination, {}),
4676
+ loading && // No `aria-hidden`: the Spar Spinner ships `role="status"` +
4677
+ // `aria-label="Loading"`, so the overlay politely announces the
4678
+ // loading transition (the table also carries `aria-busy`).
4679
+ /* @__PURE__ */ jsx("div", { ...slotAttrs("loading"), children: /* @__PURE__ */ jsx(Spinner, {}) })
4680
+ ] }) });
4681
+ };
4682
+ Table.displayName = "Table";
4683
+
4684
+ // src/components/tabs/base.ts
4685
+ var TabsBase = createComponentBase({
4686
+ name: "Tabs",
4687
+ slots: ["root"],
4688
+ classes: { root: "tk-tabs" }
4689
+ });
4690
+ var TabsListBase = createComponentBase({
4691
+ name: "TabsList",
4692
+ slots: ["root"],
4693
+ classes: { root: "tk-tabs-list" }
4694
+ });
4695
+ var TabsTriggerBase = createComponentBase({
4696
+ name: "TabsTrigger",
4697
+ slots: ["root"],
4698
+ classes: { root: "tk-tabs-trigger" }
4699
+ });
4700
+ var TabsContentBase = createComponentBase({
4701
+ name: "TabsContent",
4702
+ slots: ["root"],
4703
+ classes: { root: "tk-tabs-content" }
4704
+ });
4705
+
4706
+ // src/components/tabs/context.ts
4707
+ var [TabsOwnProvider, useTabsOwnContext] = createSafeContext("Tabs");
4708
+
4709
+ // src/components/tabs/defaults.ts
4710
+ var DEFAULT_SIZE17 = "base";
4711
+ var DEFAULT_VARIANT10 = "primary";
4712
+ var DEFAULT_APPEARANCE8 = "basic";
4713
+ var Tabs = (props) => {
4714
+ const theme = useComponentTheme("Tabs");
4715
+ const { rootAttrs, rest } = composeRootAttrs(TabsBase, props, theme, {
4716
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE17, variant: variant2 = DEFAULT_VARIANT10, appearance: appearance2 = DEFAULT_APPEARANCE8 }) => ({
4717
+ "data-size": size2,
4718
+ "data-variant": variant2,
4719
+ "data-type": appearance2
4720
+ })
4721
+ });
4722
+ const { size = DEFAULT_SIZE17, variant = DEFAULT_VARIANT10, appearance = DEFAULT_APPEARANCE8, children, ref, ...sparProps } = rest;
4723
+ return /* @__PURE__ */ jsx(TabsOwnProvider, { value: { size, variant, appearance }, children: /* @__PURE__ */ jsx(Tabs$1, { ...sparProps, ...rootAttrs, ref, children }) });
4724
+ };
4725
+ Tabs.displayName = "Tabs";
4726
+ var TabsList = (props) => {
4727
+ const theme = useComponentTheme("TabsList");
4728
+ const { size, variant, appearance } = useTabsOwnContext("Tabs.List");
4729
+ const { rootAttrs, rest } = composeRootAttrs(TabsListBase, props, theme, {
4730
+ stateAttrs: () => ({
4731
+ "data-size": size,
4732
+ "data-variant": variant,
4733
+ "data-type": appearance
4734
+ })
4735
+ });
4736
+ const { children, ref, ...sparProps } = rest;
4737
+ return /* @__PURE__ */ jsx(TabsList$1, { ...sparProps, ...rootAttrs, ref, children });
4738
+ };
4739
+ TabsList.displayName = "Tabs.List";
4740
+ var TabsTrigger = (props) => {
4741
+ const theme = useComponentTheme("TabsTrigger");
4742
+ const { size, variant, appearance } = useTabsOwnContext("Tabs.Trigger");
4743
+ const { rootAttrs, rest } = composeRootAttrs(TabsTriggerBase, props, theme, {
4744
+ stateAttrs: () => ({
4745
+ "data-size": size,
4746
+ "data-variant": variant,
4747
+ "data-type": appearance
4748
+ })
4749
+ });
4750
+ const { children, ref, ...sparProps } = rest;
4751
+ return /* @__PURE__ */ jsx(TabsTrigger$1, { ...sparProps, ...rootAttrs, ref, children });
4752
+ };
4753
+ TabsTrigger.displayName = "Tabs.Trigger";
4754
+ var TabsContent = (props) => {
4755
+ const theme = useComponentTheme("TabsContent");
4756
+ const { rootAttrs, rest } = composeRootAttrs(TabsContentBase, props, theme);
4757
+ const { children, ref, ...sparProps } = rest;
4758
+ return /* @__PURE__ */ jsx(TabsContent$1, { ...sparProps, ...rootAttrs, ref, children });
4759
+ };
4760
+ TabsContent.displayName = "Tabs.Content";
4761
+
4762
+ // src/components/tabs/index.ts
4763
+ var Tabs2 = Object.assign(Tabs, {
4764
+ List: TabsList,
4765
+ Trigger: TabsTrigger,
4766
+ Content: TabsContent
4767
+ });
1339
4768
  var Tooltip = ({ children, id, open, defaultOpen, onOpenChange, delay, hideDelay, disabled }) => {
1340
4769
  return /* @__PURE__ */ jsx(Tooltip$1, { id, open, defaultOpen, onOpenChange, delay, hideDelay, disabled, children });
1341
4770
  };
@@ -1390,11 +4819,11 @@ var TooltipTrigger = (props) => {
1390
4819
  TooltipTrigger.displayName = "Tooltip.Trigger";
1391
4820
 
1392
4821
  // src/components/tooltip/defaults.ts
1393
- var DEFAULT_VARIANT5 = "dark";
4822
+ var DEFAULT_VARIANT11 = "white";
1394
4823
  var TooltipContent = (props) => {
1395
4824
  const theme = useComponentTheme("TooltipContent");
1396
4825
  const { rootAttrs, rest } = composeRootAttrs(TooltipContentBase, props, theme, {
1397
- stateAttrs: ({ variant = DEFAULT_VARIANT5 }) => ({
4826
+ stateAttrs: ({ variant = DEFAULT_VARIANT11 }) => ({
1398
4827
  "data-variant": variant
1399
4828
  })
1400
4829
  });
@@ -1419,8 +4848,8 @@ TooltipDescription.displayName = "Tooltip.Description";
1419
4848
  var TooltipArrow = (props) => {
1420
4849
  const theme = useComponentTheme("TooltipArrow");
1421
4850
  const { rootAttrs, rest } = composeRootAttrs(TooltipArrowBase, props, theme);
1422
- const { ref, ...sparProps } = rest;
1423
- return /* @__PURE__ */ jsx(TooltipArrow$1, { ...sparProps, ...rootAttrs, ref });
4851
+ const { ref, children, ...sparProps } = rest;
4852
+ return /* @__PURE__ */ jsx(TooltipArrow$1, { ...sparProps, ...rootAttrs, ref, children: children ?? renderPointerArrow() });
1424
4853
  };
1425
4854
  TooltipArrow.displayName = "Tooltip.Arrow";
1426
4855
 
@@ -1434,4 +4863,112 @@ var Tooltip2 = Object.assign(Tooltip, {
1434
4863
  Arrow: TooltipArrow
1435
4864
  });
1436
4865
 
1437
- export { Accordion2 as Accordion, Badge, Button, Checkbox2 as Checkbox, Drawer2 as Drawer, Field2 as Field, Input2 as Input, Popover2 as Popover, Radio2 as Radio, Select2 as Select, Switch2 as Switch, TakeoffSparProvider, Tooltip2 as Tooltip, useComponentTheme, useTheme };
4866
+ // src/components/toast/base.ts
4867
+ var ToasterBase = createComponentBase({
4868
+ name: "Toaster",
4869
+ slots: ["root"],
4870
+ classes: {
4871
+ root: "tk-toaster"
4872
+ }
4873
+ });
4874
+ var ToastBase = createComponentBase({
4875
+ name: "Toast",
4876
+ slots: ["root"],
4877
+ classes: {
4878
+ root: "tk-toast"
4879
+ }
4880
+ });
4881
+
4882
+ // src/components/toast/defaults.ts
4883
+ var DEFAULT_TOAST_APPEARANCE = "filled";
4884
+ var DEFAULT_CLOSE_LABEL2 = "Dismiss notification";
4885
+
4886
+ // src/components/toast/utils.ts
4887
+ var toastTypeToVariant = (type) => {
4888
+ switch (type) {
4889
+ case "success":
4890
+ return "success";
4891
+ case "error":
4892
+ return "danger";
4893
+ case "warning":
4894
+ return "warning";
4895
+ case "info":
4896
+ return "info";
4897
+ // 'default' and 'loading' have no dedicated Alert variant.
4898
+ default:
4899
+ return "neutral";
4900
+ }
4901
+ };
4902
+ var Toast = (props) => {
4903
+ const theme = useComponentTheme("Toast");
4904
+ const { rootAttrs, rest } = composeRootAttrs(ToastBase, props, theme);
4905
+ const { as, toast, toaster, appearance = DEFAULT_TOAST_APPEARANCE, closeLabel = DEFAULT_CLOSE_LABEL2, children, ref, ...toastProps } = rest;
4906
+ const Component = as ?? "div";
4907
+ const variant = toastTypeToVariant(toast.type);
4908
+ return /* @__PURE__ */ jsx(Toast$1.Root, { ...toastProps, as: Component, ref, toast, toaster, ...rootAttrs, children: children ?? /* @__PURE__ */ jsxs(Alert2, { variant, appearance, role: "presentation", children: [
4909
+ /* @__PURE__ */ jsxs(Alert2.Content, { children: [
4910
+ toast.title != null && /* @__PURE__ */ jsx(Toast$1.Title, { as: Alert2.Title, children: toast.title }),
4911
+ toast.description != null && /* @__PURE__ */ jsx(Toast$1.Description, { as: Alert2.Description, children: toast.description })
4912
+ ] }),
4913
+ /* @__PURE__ */ jsx(Toast$1.Close, { as: Alert2.Close, "aria-label": closeLabel }),
4914
+ toast.action && /* @__PURE__ */ jsx(Alert2.Actions, { children: /* @__PURE__ */ jsx(Toast$1.Action, { as: Button, className: "tk-alert-action", variant, appearance: "text", size: "small" }) })
4915
+ ] }) });
4916
+ };
4917
+ Toast.displayName = "Toast";
4918
+ var Toaster = (props) => {
4919
+ const theme = useComponentTheme("Toaster");
4920
+ const { rootAttrs, rest } = composeRootAttrs(ToasterBase, props, theme, {
4921
+ stateAttrs: ({ toaster: toaster2 }) => ({
4922
+ "data-placement": toaster2.placement
4923
+ })
4924
+ });
4925
+ const { as, toaster, appearance = DEFAULT_TOAST_APPEARANCE, closeLabel = DEFAULT_CLOSE_LABEL2, overlap = false, children, ref, ...toasterProps } = rest;
4926
+ const Component = as ?? "div";
4927
+ return /* @__PURE__ */ jsx(Toaster$1, { ...toasterProps, as: Component, ref, toaster, overlap, ...rootAttrs, children: (toast) => (
4928
+ // Spar renders each item directly into a mapped array, so the key must
4929
+ // live on the element this render prop returns. The default branch keys
4930
+ // <Toast>; a consumer `children` result is keyed via Fragment here.
4931
+ children ? /* @__PURE__ */ jsx(Fragment$1, { children: children(toast) }, toast.id) : /* @__PURE__ */ jsx(Toast, { toast, toaster, appearance, closeLabel }, toast.id)
4932
+ ) });
4933
+ };
4934
+ Toaster.displayName = "Toaster";
4935
+
4936
+ // src/components/skeleton/base.ts
4937
+ var SkeletonBase = createComponentBase({
4938
+ name: "Skeleton",
4939
+ slots: ["root", "shimmer"],
4940
+ classes: {
4941
+ root: "tk-skeleton",
4942
+ shimmer: "tk-skeleton-shimmer"
4943
+ }
4944
+ });
4945
+
4946
+ // src/components/skeleton/defaults.ts
4947
+ var DEFAULT_SHAPE = "rectangle";
4948
+ var DEFAULT_ANIMATION = "shimmer";
4949
+ var toCssSize = (value) => typeof value === "number" ? `${value}px` : value;
4950
+ var Skeleton = (props) => {
4951
+ const theme = useComponentTheme("Skeleton");
4952
+ const { rootAttrs, rest } = composeRootAttrs(SkeletonBase, props, theme, {
4953
+ stateAttrs: ({ shape = DEFAULT_SHAPE, animation = DEFAULT_ANIMATION }) => ({
4954
+ "data-type": shape,
4955
+ "data-animation": animation
4956
+ })
4957
+ });
4958
+ const { shape: _shape, animation: _animation, width, height, ref, style, ...nativeProps } = rest;
4959
+ const { style: slotStyle, ...slotAttrs } = rootAttrs;
4960
+ const shimmerSlotAttrs = buildSlotAttrs(SkeletonBase.getSlotProps("shimmer"), "shimmer", {
4961
+ themeSlotProps: theme?.slotProps,
4962
+ themeClassNames: theme?.classNames,
4963
+ instanceSlotProps: props.slotProps,
4964
+ instanceClassNames: props.classNames
4965
+ });
4966
+ const sizeVars = {
4967
+ ...width !== void 0 && { "--tk-skeleton-width": toCssSize(width) },
4968
+ ...height !== void 0 && { "--tk-skeleton-height": toCssSize(height) }
4969
+ };
4970
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", ...nativeProps, ...slotAttrs, style: { ...style, ...slotStyle, ...sizeVars }, ref, children: /* @__PURE__ */ jsx("span", { ...shimmerSlotAttrs, "aria-hidden": "true" }) });
4971
+ };
4972
+ Skeleton.displayName = "Skeleton";
4973
+
4974
+ export { Accordion2 as Accordion, Alert2 as Alert, Badge, Breadcrumb2 as Breadcrumb, Button, Card2 as Card, Checkbox2 as Checkbox, Chip, Dialog2 as Dialog, Divider, Drawer2 as Drawer, Dropdown2 as Dropdown, Field2 as Field, Input2 as Input, Label, Popover2 as Popover, Progress2 as Progress, Radio2 as Radio, Select2 as Select, Skeleton, Slider2 as Slider, Spinner, Stepper2 as Stepper, Switch2 as Switch, Table, Tabs2 as Tabs, TakeoffSparProvider, Toast, Toaster, Tooltip2 as Tooltip, getExportRows, useComponentTheme, useTheme };