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