@takeoff-ui/react-spar 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4,6 +4,15 @@ 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 reactTable = require('@tanstack/react-table');
10
+ var chevronRight = require('@takeoff-icons/react/chevron-right');
11
+ var swap = require('@takeoff-icons/react/swap');
12
+ var search = require('@takeoff-icons/react/search');
13
+ var arrowLeft = require('@takeoff-icons/react/arrow-left');
14
+ var arrowRight = require('@takeoff-icons/react/arrow-right');
15
+ var chevronLeft = require('@takeoff-icons/react/chevron-left');
7
16
 
8
17
  // src/provider.tsx
9
18
 
@@ -54,6 +63,12 @@ var useComponentTheme = (componentName) => {
54
63
  const context = react.useContext(TakeoffSparContext);
55
64
  return context?.components?.[componentName];
56
65
  };
66
+
67
+ // src/core/blockDismiss.ts
68
+ var blockDismiss = (handler) => (event) => {
69
+ event.preventDefault();
70
+ handler?.(event);
71
+ };
57
72
  var buildSlotAttrs = (canonicalAttrs, slotKey, layers = {}) => {
58
73
  const { themeSlotProps, themeClassNames, themeClassName, instanceSlotProps, instanceClassNames } = layers;
59
74
  const themeForSlot = themeSlotProps?.[slotKey];
@@ -96,6 +111,9 @@ var composeRootAttrs = (base, props, theme, options) => {
96
111
  rest
97
112
  };
98
113
  };
114
+
115
+ // src/core/isRenderableNode.ts
116
+ var isRenderableNode = (node) => node !== null && node !== void 0 && node !== "" && typeof node !== "boolean";
99
117
  var toDataSlotName = (slot) => slot.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
100
118
  var createComponentBase = (config) => {
101
119
  const { name, slots, classes, defaultProps = {} } = config;
@@ -122,6 +140,12 @@ var createComponentBase = (config) => {
122
140
  resolveProps
123
141
  };
124
142
  };
143
+ var DEFAULT_DISCLOSURE_EXPAND_ICON = /* @__PURE__ */ jsxRuntime.jsx(chevronBottom.ChevronBottomIconOutlinedRounded, {});
144
+ var DEFAULT_DISCLOSURE_COLLAPSE_ICON = /* @__PURE__ */ jsxRuntime.jsx(chevronTop.ChevronTopIconOutlinedRounded, {});
145
+ var resolveDisclosureIndicator = (children, isOpen) => {
146
+ if (typeof children === "function") return children({ isOpen });
147
+ return children ?? (isOpen ? DEFAULT_DISCLOSURE_COLLAPSE_ICON : DEFAULT_DISCLOSURE_EXPAND_ICON);
148
+ };
125
149
 
126
150
  // src/components/accordion/base.ts
127
151
  var AccordionBase = createComponentBase({
@@ -172,6 +196,21 @@ function createSafeContext(displayName) {
172
196
  };
173
197
  return [Provider, useSafeContext];
174
198
  }
199
+ function useControllableState(controlledValue, defaultValue, onChange) {
200
+ const [uncontrolledValue, setUncontrolledValue] = react.useState(defaultValue);
201
+ const { current: isControlled } = react.useRef(controlledValue !== void 0);
202
+ const value = isControlled ? controlledValue : uncontrolledValue;
203
+ const setValue = react.useCallback(
204
+ (newValue) => {
205
+ if (!isControlled) {
206
+ setUncontrolledValue(newValue);
207
+ }
208
+ onChange?.(newValue);
209
+ },
210
+ [isControlled, onChange]
211
+ );
212
+ return [value, setValue];
213
+ }
175
214
 
176
215
  // src/components/accordion/context.ts
177
216
  var [AccordionProvider, useAccordionOwnContext] = createSafeContext("AccordionProvider");
@@ -224,15 +263,13 @@ var AccordionHeader = (props) => {
224
263
  return /* @__PURE__ */ jsxRuntime.jsx(spar.AccordionHeader, { ...spar$1, level, ...rootAttrs, ref, children });
225
264
  };
226
265
  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
266
  var AccordionIndicator = (props) => {
230
267
  const theme = useComponentTheme("AccordionIndicator");
231
268
  const { isOpen } = spar.useAccordionItemContext();
232
269
  const Component = props.as ?? "span";
233
270
  const { rootAttrs, rest } = composeRootAttrs(AccordionIndicatorBase, props, theme);
234
271
  const { as: _as, children, ref, ...rendered } = rest;
235
- const resolved = typeof children === "function" ? children({ isOpen }) : children ?? (isOpen ? DEFAULT_COLLAPSE_ICON : DEFAULT_EXPAND_ICON);
272
+ const resolved = resolveDisclosureIndicator(children, isOpen);
236
273
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...rendered, ref, "aria-hidden": "true", ...rootAttrs, children: resolved });
237
274
  };
238
275
  AccordionIndicator.displayName = "Accordion.Indicator";
@@ -289,6 +326,161 @@ var Accordion2 = Object.assign(Accordion, {
289
326
  Content: AccordionContent
290
327
  });
291
328
 
329
+ // src/components/alert/base.ts
330
+ var AlertBase = createComponentBase({
331
+ name: "Alert",
332
+ slots: ["root"],
333
+ classes: { root: "tk-alert" }
334
+ });
335
+ var AlertContentBase = createComponentBase({
336
+ name: "AlertContent",
337
+ slots: ["root"],
338
+ classes: { root: "tk-alert-content" }
339
+ });
340
+ var AlertTitleBase = createComponentBase({
341
+ name: "AlertTitle",
342
+ slots: ["root"],
343
+ classes: { root: "tk-alert-title" }
344
+ });
345
+ var AlertDescriptionBase = createComponentBase({
346
+ name: "AlertDescription",
347
+ slots: ["root"],
348
+ classes: { root: "tk-alert-description" }
349
+ });
350
+ var AlertActionsBase = createComponentBase({
351
+ name: "AlertActions",
352
+ slots: ["root"],
353
+ classes: { root: "tk-alert-actions" }
354
+ });
355
+ var AlertCloseBase = createComponentBase({
356
+ name: "AlertClose",
357
+ slots: ["root"],
358
+ classes: { root: "tk-alert-close" }
359
+ });
360
+
361
+ // src/components/alert/context.ts
362
+ var [AlertProvider, useAlertContext] = createSafeContext("AlertProvider");
363
+
364
+ // src/components/alert/defaults.ts
365
+ var DEFAULT_VARIANT = "neutral";
366
+ var DEFAULT_APPEARANCE = "filled";
367
+ var DEFAULT_CLOSE_LABEL = "Close";
368
+ var Alert = (props) => {
369
+ const theme = useComponentTheme("Alert");
370
+ const { rootAttrs, rest } = composeRootAttrs(AlertBase, props, theme, {
371
+ stateAttrs: ({ variant = DEFAULT_VARIANT, appearance = DEFAULT_APPEARANCE }) => ({
372
+ "data-variant": variant,
373
+ "data-type": appearance
374
+ })
375
+ });
376
+ const { as, variant: _variant, appearance: _appearance, onClose, children, ref, role = "status", ...alertProps } = rest;
377
+ const Component = as ?? "div";
378
+ return /* @__PURE__ */ jsxRuntime.jsx(AlertProvider, { value: { onClose }, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { ...alertProps, ref, role, ...rootAttrs, children }) });
379
+ };
380
+ Alert.displayName = "Alert";
381
+ var AlertActions = (props) => {
382
+ const theme = useComponentTheme("AlertActions");
383
+ const { rootAttrs, rest } = composeRootAttrs(AlertActionsBase, props, theme);
384
+ const { as, children, ref, ...actionsProps } = rest;
385
+ const Component = as ?? "div";
386
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...actionsProps, ref, ...rootAttrs, children });
387
+ };
388
+ AlertActions.displayName = "Alert.Actions";
389
+ var baseSvgProps = {
390
+ "xmlns": "http://www.w3.org/2000/svg",
391
+ "width": "1em",
392
+ "height": "1em",
393
+ "viewBox": "0 0 24 24",
394
+ "fill": "none",
395
+ "stroke": "currentColor",
396
+ "strokeWidth": 2,
397
+ "strokeLinecap": "round",
398
+ "strokeLinejoin": "round",
399
+ "focusable": false,
400
+ "aria-hidden": true
401
+ };
402
+ var filledSvgProps = {
403
+ "xmlns": "http://www.w3.org/2000/svg",
404
+ "width": "1em",
405
+ "height": "1em",
406
+ "viewBox": "0 0 24 24",
407
+ "fill": "currentColor",
408
+ "focusable": false,
409
+ "aria-hidden": true
410
+ };
411
+ 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" }) });
412
+ 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" }) });
413
+ var PlaceholderClose = (props) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...baseSvgProps, "data-placeholder-icon": "close", ...props, children: [
414
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18" }),
415
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 6 12 12" })
416
+ ] });
417
+ 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" }) }) });
418
+ 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" }) }) });
419
+ var PlaceholderCheck = (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "check", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12l5 5L20 7" }) });
420
+ var PlaceholderRemove = (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...baseSvgProps, "data-placeholder-icon": "remove", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14" }) });
421
+ 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" }) }) });
422
+ 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" }) }) });
423
+ var AlertClose = (props) => {
424
+ const theme = useComponentTheme("AlertClose");
425
+ const { onClose } = useAlertContext("Alert.Close");
426
+ const { rootAttrs, rest } = composeRootAttrs(AlertCloseBase, props, theme);
427
+ const { as, children, onClick, ref, type, "aria-label": ariaLabel, ...closeProps } = rest;
428
+ const { onClick: slotOnClick, ...closeRootAttrs } = rootAttrs;
429
+ const Component = as ?? "button";
430
+ const handleClick = (event) => {
431
+ onClick?.(event);
432
+ slotOnClick?.(event);
433
+ onClose?.();
434
+ };
435
+ const hasCustomChildren = isRenderableNode(children);
436
+ return /* @__PURE__ */ jsxRuntime.jsx(
437
+ Component,
438
+ {
439
+ ...closeProps,
440
+ ref,
441
+ type: as ? type : type ?? "button",
442
+ "aria-label": ariaLabel ?? (hasCustomChildren ? void 0 : DEFAULT_CLOSE_LABEL),
443
+ onClick: handleClick,
444
+ ...closeRootAttrs,
445
+ children: hasCustomChildren ? children : /* @__PURE__ */ jsxRuntime.jsx(PlaceholderClose, {})
446
+ }
447
+ );
448
+ };
449
+ AlertClose.displayName = "Alert.Close";
450
+ var AlertContent = (props) => {
451
+ const theme = useComponentTheme("AlertContent");
452
+ const { rootAttrs, rest } = composeRootAttrs(AlertContentBase, props, theme);
453
+ const { as, children, ref, ...contentProps } = rest;
454
+ const Component = as ?? "div";
455
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...contentProps, ref, ...rootAttrs, children });
456
+ };
457
+ AlertContent.displayName = "Alert.Content";
458
+ var AlertDescription = (props) => {
459
+ const theme = useComponentTheme("AlertDescription");
460
+ const { rootAttrs, rest } = composeRootAttrs(AlertDescriptionBase, props, theme);
461
+ const { as, children, ref, ...descriptionProps } = rest;
462
+ const Component = as ?? "p";
463
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...descriptionProps, ref, ...rootAttrs, children });
464
+ };
465
+ AlertDescription.displayName = "Alert.Description";
466
+ var AlertTitle = (props) => {
467
+ const theme = useComponentTheme("AlertTitle");
468
+ const { rootAttrs, rest } = composeRootAttrs(AlertTitleBase, props, theme);
469
+ const { as, level = 5, children, ref, ...titleProps } = rest;
470
+ const Component = as ?? `h${level}`;
471
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...titleProps, ref, ...rootAttrs, children });
472
+ };
473
+ AlertTitle.displayName = "Alert.Title";
474
+
475
+ // src/components/alert/index.ts
476
+ var Alert2 = Object.assign(Alert, {
477
+ Content: AlertContent,
478
+ Title: AlertTitle,
479
+ Description: AlertDescription,
480
+ Actions: AlertActions,
481
+ Close: AlertClose
482
+ });
483
+
292
484
  // src/components/badge/base.ts
293
485
  var BadgeBase = createComponentBase({
294
486
  name: "Badge",
@@ -301,13 +493,13 @@ var BadgeBase = createComponentBase({
301
493
  });
302
494
 
303
495
  // src/components/badge/defaults.ts
304
- var DEFAULT_VARIANT = "primary";
305
- var DEFAULT_APPEARANCE = "filled";
496
+ var DEFAULT_VARIANT2 = "primary";
497
+ var DEFAULT_APPEARANCE2 = "filled";
306
498
  var DEFAULT_SIZE2 = "base";
307
499
  var Badge = (props) => {
308
500
  const theme = useComponentTheme("Badge");
309
501
  const { rootAttrs, rest } = composeRootAttrs(BadgeBase, props, theme, {
310
- stateAttrs: ({ variant = DEFAULT_VARIANT, appearance = DEFAULT_APPEARANCE, size = DEFAULT_SIZE2, rounded, dot: dot2 }) => ({
502
+ stateAttrs: ({ variant = DEFAULT_VARIANT2, appearance = DEFAULT_APPEARANCE2, size = DEFAULT_SIZE2, rounded, dot: dot2 }) => ({
311
503
  "data-variant": variant,
312
504
  "data-type": appearance,
313
505
  "data-size": dot2 ? void 0 : size,
@@ -332,13 +524,116 @@ var Badge = (props) => {
332
524
  return /* @__PURE__ */ jsxRuntime.jsx("span", { ...nativeProps, ...rootAttrs, ref });
333
525
  }
334
526
  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 })
527
+ isRenderableNode(startContent) && /* @__PURE__ */ jsxRuntime.jsx("span", { ...iconSlotAttrs, children: startContent }),
528
+ isRenderableNode(children) && /* @__PURE__ */ jsxRuntime.jsx("span", { ...labelSlotAttrs, children }),
529
+ isRenderableNode(endContent) && /* @__PURE__ */ jsxRuntime.jsx("span", { ...iconSlotAttrs, children: endContent })
338
530
  ] });
339
531
  };
340
532
  Badge.displayName = "Badge";
341
533
 
534
+ // src/components/breadcrumb/base.ts
535
+ var BreadcrumbBase = createComponentBase({
536
+ name: "Breadcrumb",
537
+ slots: ["root"],
538
+ classes: { root: "tk-breadcrumb" }
539
+ });
540
+ var BreadcrumbListBase = createComponentBase({
541
+ name: "BreadcrumbList",
542
+ slots: ["root"],
543
+ classes: { root: "tk-breadcrumb-list" }
544
+ });
545
+ var BreadcrumbItemBase = createComponentBase({
546
+ name: "BreadcrumbItem",
547
+ slots: ["root"],
548
+ classes: { root: "tk-breadcrumb-item" }
549
+ });
550
+ var BreadcrumbLinkBase = createComponentBase({
551
+ name: "BreadcrumbLink",
552
+ slots: ["root"],
553
+ classes: { root: "tk-breadcrumb-link" }
554
+ });
555
+ var BreadcrumbPageBase = createComponentBase({
556
+ name: "BreadcrumbPage",
557
+ slots: ["root"],
558
+ classes: { root: "tk-breadcrumb-page" }
559
+ });
560
+ var BreadcrumbSeparatorBase = createComponentBase({
561
+ name: "BreadcrumbSeparator",
562
+ slots: ["root"],
563
+ classes: { root: "tk-breadcrumb-separator" }
564
+ });
565
+
566
+ // src/components/breadcrumb/context.ts
567
+ var [BreadcrumbProvider] = createSafeContext("BreadcrumbProvider");
568
+
569
+ // src/components/breadcrumb/defaults.ts
570
+ var DEFAULT_SIZE3 = "base";
571
+ var DEFAULT_TYPE2 = "basic";
572
+ var DEFAULT_SEPARATOR_VARIANT = "chevron";
573
+ var Breadcrumb = (props) => {
574
+ const theme = useComponentTheme("Breadcrumb");
575
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbBase, props, theme, {
576
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE3, type: type2 = DEFAULT_TYPE2 }) => ({
577
+ "data-size": size2,
578
+ "data-type": type2
579
+ })
580
+ });
581
+ const { size = DEFAULT_SIZE3, type = DEFAULT_TYPE2, children, ref, ...sparProps } = rest;
582
+ const contextValue = react.useMemo(() => ({ size, type }), [size, type]);
583
+ return /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbProvider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Breadcrumb, { ...sparProps, ref, ...rootAttrs, children }) });
584
+ };
585
+ Breadcrumb.displayName = "Breadcrumb";
586
+ var BreadcrumbList = (props) => {
587
+ const theme = useComponentTheme("BreadcrumbList");
588
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbListBase, props, theme);
589
+ const { children, ref, ...spar$1 } = rest;
590
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.BreadcrumbList, { ...spar$1, ref, ...rootAttrs, children });
591
+ };
592
+ BreadcrumbList.displayName = "Breadcrumb.List";
593
+ var BreadcrumbItem = (props) => {
594
+ const theme = useComponentTheme("BreadcrumbItem");
595
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbItemBase, props, theme);
596
+ const { children, ref, ...spar$1 } = rest;
597
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.BreadcrumbItem, { ...spar$1, ref, ...rootAttrs, children });
598
+ };
599
+ BreadcrumbItem.displayName = "Breadcrumb.Item";
600
+ var BreadcrumbLink = (props) => {
601
+ const theme = useComponentTheme("BreadcrumbLink");
602
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbLinkBase, props, theme);
603
+ const { children, ref, ...spar$1 } = rest;
604
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.BreadcrumbLink, { ...spar$1, ref, ...rootAttrs, children });
605
+ };
606
+ BreadcrumbLink.displayName = "Breadcrumb.Link";
607
+ var BreadcrumbPage = (props) => {
608
+ const theme = useComponentTheme("BreadcrumbPage");
609
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbPageBase, props, theme);
610
+ const { children, ref, ...spar$1 } = rest;
611
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.BreadcrumbPage, { ...spar$1, ref, ...rootAttrs, children });
612
+ };
613
+ BreadcrumbPage.displayName = "Breadcrumb.Page";
614
+ var DEFAULT_SEPARATOR_ICON = /* @__PURE__ */ jsxRuntime.jsx("svg", { 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: "M6 4L10 8L6 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
615
+ var BreadcrumbSeparator = (props) => {
616
+ const theme = useComponentTheme("BreadcrumbSeparator");
617
+ const { rootAttrs, rest } = composeRootAttrs(BreadcrumbSeparatorBase, props, theme, {
618
+ stateAttrs: ({ variant: variant2 = DEFAULT_SEPARATOR_VARIANT }) => ({
619
+ "data-variant": variant2
620
+ })
621
+ });
622
+ const { variant = DEFAULT_SEPARATOR_VARIANT, children, ref, ...spar$1 } = rest;
623
+ const fallback = variant === "chevron" ? DEFAULT_SEPARATOR_ICON : null;
624
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.BreadcrumbSeparator, { ...spar$1, ref, ...rootAttrs, children: children ?? fallback });
625
+ };
626
+ BreadcrumbSeparator.displayName = "Breadcrumb.Separator";
627
+
628
+ // src/components/breadcrumb/index.ts
629
+ var Breadcrumb2 = Object.assign(Breadcrumb, {
630
+ List: BreadcrumbList,
631
+ Item: BreadcrumbItem,
632
+ Link: BreadcrumbLink,
633
+ Page: BreadcrumbPage,
634
+ Separator: BreadcrumbSeparator
635
+ });
636
+
342
637
  // src/components/button/base.ts
343
638
  var ButtonBase = createComponentBase({
344
639
  name: "Button",
@@ -352,9 +647,9 @@ var ButtonBase = createComponentBase({
352
647
  });
353
648
 
354
649
  // src/components/button/defaults.ts
355
- var DEFAULT_VARIANT2 = "primary";
356
- var DEFAULT_APPEARANCE2 = "filled";
357
- var DEFAULT_SIZE3 = "base";
650
+ var DEFAULT_VARIANT3 = "primary";
651
+ var DEFAULT_APPEARANCE3 = "filled";
652
+ var DEFAULT_SIZE4 = "base";
358
653
  var Button = (props) => {
359
654
  const theme = useComponentTheme("Button");
360
655
  const { rootAttrs, rest } = composeRootAttrs(ButtonBase, props, theme, {
@@ -362,9 +657,9 @@ var Button = (props) => {
362
657
  // Spar's Button already emits them (see SparButton dataAttributes), so
363
658
  // setting them again would create two sources of truth that drift the
364
659
  // 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;
660
+ stateAttrs: ({ variant = DEFAULT_VARIANT3, appearance = DEFAULT_APPEARANCE3, size = DEFAULT_SIZE4, rounded, startContent: startContent2, endContent: endContent2, children: children2 }) => {
661
+ const hasIcon = isRenderableNode(startContent2) || isRenderableNode(endContent2);
662
+ const isIconOnly = hasIcon && !isRenderableNode(children2);
368
663
  return {
369
664
  "data-variant": variant,
370
665
  "data-type": appearance,
@@ -382,7 +677,8 @@ var Button = (props) => {
382
677
  appearance: _appearance,
383
678
  size: _size,
384
679
  rounded: _rounded,
385
- isLoading = false,
680
+ loading = false,
681
+ pressed,
386
682
  startContent,
387
683
  endContent,
388
684
  disabled = false,
@@ -408,15 +704,122 @@ var Button = (props) => {
408
704
  instanceSlotProps: props.slotProps,
409
705
  instanceClassNames: props.classNames
410
706
  });
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 })
707
+ return /* @__PURE__ */ jsxRuntime.jsxs(spar.Button, { ...sparProps, disabled, isLoading: loading, isPressed: pressed, ref, ...rootAttrs, children: [
708
+ loading && /* @__PURE__ */ jsxRuntime.jsx("span", { ...spinnerSlotAttrs }),
709
+ isRenderableNode(startContent) && !loading && /* @__PURE__ */ jsxRuntime.jsx("span", { ...contentSlotAttrs, children: startContent }),
710
+ isRenderableNode(children) && /* @__PURE__ */ jsxRuntime.jsx("span", { ...labelSlotAttrs, children }),
711
+ isRenderableNode(endContent) && !loading && /* @__PURE__ */ jsxRuntime.jsx("span", { ...contentSlotAttrs, children: endContent })
416
712
  ] });
417
713
  };
418
714
  Button.displayName = "Button";
419
715
 
716
+ // src/components/card/base.ts
717
+ var CardBase = createComponentBase({
718
+ name: "Card",
719
+ slots: ["root"],
720
+ classes: { root: "tk-card" }
721
+ });
722
+ var CardHeaderBase = createComponentBase({
723
+ name: "CardHeader",
724
+ slots: ["root"],
725
+ classes: { root: "tk-card-header" }
726
+ });
727
+ var CardTitleBase = createComponentBase({
728
+ name: "CardTitle",
729
+ slots: ["root"],
730
+ classes: { root: "tk-card-title" }
731
+ });
732
+ var CardDescriptionBase = createComponentBase({
733
+ name: "CardDescription",
734
+ slots: ["root"],
735
+ classes: { root: "tk-card-description" }
736
+ });
737
+ var CardBodyBase = createComponentBase({
738
+ name: "CardBody",
739
+ slots: ["root"],
740
+ classes: { root: "tk-card-body" }
741
+ });
742
+ var CardFooterBase = createComponentBase({
743
+ name: "CardFooter",
744
+ slots: ["root"],
745
+ classes: { root: "tk-card-footer" }
746
+ });
747
+ var Card = (props) => {
748
+ const theme = useComponentTheme("Card");
749
+ const { rootAttrs, rest } = composeRootAttrs(CardBase, props, theme);
750
+ const { as, children, ref, ...cardProps } = rest;
751
+ const Component = as ?? "div";
752
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...cardProps, ref, ...rootAttrs, children });
753
+ };
754
+ Card.displayName = "Card";
755
+
756
+ // src/components/card/defaults.ts
757
+ var DEFAULT_HEADER_TYPE = "basic";
758
+ var DEFAULT_FOOTER_TYPE = "basic";
759
+ var CardHeader = (props) => {
760
+ const theme = useComponentTheme("CardHeader");
761
+ const { rootAttrs, rest } = composeRootAttrs(CardHeaderBase, props, theme, {
762
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE }) => ({
763
+ "data-header-type": headerType
764
+ })
765
+ });
766
+ const { as, headerType: _headerType, children, ref, ...headerProps } = rest;
767
+ const Component = as ?? "div";
768
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
769
+ };
770
+ CardHeader.displayName = "CardHeader";
771
+ var CardTitle = (props) => {
772
+ const theme = useComponentTheme("CardTitle");
773
+ const { rootAttrs, rest } = composeRootAttrs(CardTitleBase, props, theme, {
774
+ // `data-level` reflects the rendered heading element, so emit it only when
775
+ // `level` actually drives the element — i.e. when `as` is not overriding it.
776
+ stateAttrs: ({ as: as2, level: level2 = 5 }) => ({
777
+ "data-level": as2 ? void 0 : String(level2)
778
+ })
779
+ });
780
+ const { as, level = 5, children, ref, ...titleProps } = rest;
781
+ const Component = as ?? `h${level}`;
782
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...titleProps, ref, ...rootAttrs, children });
783
+ };
784
+ CardTitle.displayName = "CardTitle";
785
+ var CardDescription = (props) => {
786
+ const theme = useComponentTheme("CardDescription");
787
+ const { rootAttrs, rest } = composeRootAttrs(CardDescriptionBase, props, theme);
788
+ const { as, children, ref, ...descriptionProps } = rest;
789
+ const Component = as ?? "p";
790
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...descriptionProps, ref, ...rootAttrs, children });
791
+ };
792
+ CardDescription.displayName = "CardDescription";
793
+ var CardBody = (props) => {
794
+ const theme = useComponentTheme("CardBody");
795
+ const { rootAttrs, rest } = composeRootAttrs(CardBodyBase, props, theme);
796
+ const { as, children, ref, ...bodyProps } = rest;
797
+ const Component = as ?? "div";
798
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
799
+ };
800
+ CardBody.displayName = "CardBody";
801
+ var CardFooter = (props) => {
802
+ const theme = useComponentTheme("CardFooter");
803
+ const { rootAttrs, rest } = composeRootAttrs(CardFooterBase, props, theme, {
804
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE }) => ({
805
+ "data-footer-type": footerType
806
+ })
807
+ });
808
+ const { as, footerType: _footerType, children, ref, ...footerProps } = rest;
809
+ const Component = as ?? "div";
810
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
811
+ };
812
+ CardFooter.displayName = "CardFooter";
813
+
814
+ // src/components/card/index.ts
815
+ var Card2 = Object.assign(Card, {
816
+ Header: CardHeader,
817
+ Title: CardTitle,
818
+ Description: CardDescription,
819
+ Body: CardBody,
820
+ Footer: CardFooter
821
+ });
822
+
420
823
  // src/components/checkbox/base.ts
421
824
  var CheckboxBase = createComponentBase({
422
825
  name: "Checkbox",
@@ -434,14 +837,12 @@ var CheckboxBase = createComponentBase({
434
837
  var [CheckboxProvider, useCheckboxOwnContext] = createSafeContext("CheckboxProvider");
435
838
 
436
839
  // src/components/checkbox/defaults.ts
437
- var DEFAULT_SIZE4 = "base";
438
- var DEFAULT_TYPE2 = "default";
840
+ var DEFAULT_SIZE5 = "base";
439
841
  var Checkbox = (props) => {
440
842
  const theme = useComponentTheme("Checkbox");
441
843
  const { rootAttrs, rest } = composeRootAttrs(CheckboxBase, props, theme, {
442
- stateAttrs: ({ size = DEFAULT_SIZE4, type = DEFAULT_TYPE2 }) => ({
443
- "data-size": size,
444
- "data-type": type
844
+ stateAttrs: ({ size = DEFAULT_SIZE5 }) => ({
845
+ "data-size": size
445
846
  })
446
847
  });
447
848
  const { classNames, slotProps } = props;
@@ -449,7 +850,6 @@ var Checkbox = (props) => {
449
850
  // Visual props are consumed via `stateAttrs`; destructured to keep them
450
851
  // off the rendered DOM where they would leak as raw HTML attributes.
451
852
  size: _size,
452
- type: _type,
453
853
  // `invalid` is forwarded to Spar as `invalid` (same name).
454
854
  invalid = false,
455
855
  // takeoff-spar tri-state vocabulary; mapped to Spar's `CheckedState` below.
@@ -502,21 +902,6 @@ var Checkbox = (props) => {
502
902
  );
503
903
  };
504
904
  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
905
  var CheckboxIndicator = (props) => {
521
906
  const theme = useComponentTheme("Checkbox");
522
907
  const { classNames, slotProps, checked, indeterminate } = useCheckboxOwnContext("Checkbox.Indicator");
@@ -543,19 +928,141 @@ var Checkbox2 = Object.assign(Checkbox, {
543
928
  Indicator: CheckboxIndicator
544
929
  });
545
930
 
931
+ // src/components/chip/base.ts
932
+ var ChipBase = createComponentBase({
933
+ name: "Chip",
934
+ slots: ["root", "label", "remove"],
935
+ classes: {
936
+ root: "tk-chip",
937
+ label: "tk-chip-label",
938
+ remove: "tk-chip-remove"
939
+ }
940
+ });
941
+
942
+ // src/components/chip/defaults.ts
943
+ var DEFAULT_VARIANT4 = "primary";
944
+ var DEFAULT_APPEARANCE4 = "filled";
945
+ var DEFAULT_SIZE6 = "base";
946
+ var DEFAULT_REMOVE_LABEL = "Remove";
947
+ var Chip = (props) => {
948
+ const theme = useComponentTheme("Chip");
949
+ const [dismissed, setDismissed] = react.useState(false);
950
+ const { rootAttrs, rest } = composeRootAttrs(ChipBase, props, theme, {
951
+ stateAttrs: ({ variant = DEFAULT_VARIANT4, appearance = DEFAULT_APPEARANCE4, size = DEFAULT_SIZE6, clickable: clickable2 = false, disabled: disabled2 = false, removable: removable2 = false }) => ({
952
+ "data-variant": variant,
953
+ "data-type": appearance,
954
+ "data-size": size,
955
+ "data-clickable": clickable2 ? "" : void 0,
956
+ "data-disabled": disabled2 ? "" : void 0,
957
+ "data-removable": removable2 ? "" : void 0
958
+ })
959
+ });
960
+ const {
961
+ onClick: rootSlotOnClick,
962
+ onKeyDown: rootSlotOnKeyDown,
963
+ ...chipRootAttrs
964
+ } = rootAttrs;
965
+ const {
966
+ variant: _variant,
967
+ appearance: _appearance,
968
+ size: _size,
969
+ autoDismiss = true,
970
+ clickable = false,
971
+ disabled = false,
972
+ removable = false,
973
+ onRemove,
974
+ children,
975
+ ref,
976
+ role,
977
+ tabIndex,
978
+ onClick,
979
+ ...nativeProps
980
+ } = rest;
981
+ const labelSlotAttrs = buildSlotAttrs(ChipBase.getSlotProps("label"), "label", {
982
+ themeSlotProps: theme?.slotProps,
983
+ themeClassNames: theme?.classNames,
984
+ instanceSlotProps: props.slotProps,
985
+ instanceClassNames: props.classNames
986
+ });
987
+ const removeSlotAttrs = buildSlotAttrs(ChipBase.getSlotProps("remove"), "remove", {
988
+ themeSlotProps: theme?.slotProps,
989
+ themeClassNames: theme?.classNames,
990
+ instanceSlotProps: props.slotProps,
991
+ instanceClassNames: props.classNames
992
+ });
993
+ const { onClick: removeSlotOnClick, ...removeButtonAttrs } = removeSlotAttrs;
994
+ const resolvedTabIndex = clickable ? disabled ? -1 : tabIndex ?? 0 : tabIndex;
995
+ const resolvedRole = role ?? (clickable ? "button" : void 0);
996
+ if (dismissed) {
997
+ return null;
998
+ }
999
+ const remove = () => {
1000
+ if (disabled || !removable) return;
1001
+ onRemove?.();
1002
+ if (!autoDismiss) return;
1003
+ setDismissed(true);
1004
+ };
1005
+ const handleRemoveClick = (event) => {
1006
+ if (clickable) event.stopPropagation();
1007
+ removeSlotOnClick?.(event);
1008
+ if (event.defaultPrevented) return;
1009
+ remove();
1010
+ };
1011
+ const handleRootClick = (event) => {
1012
+ if (disabled) return;
1013
+ onClick?.(event);
1014
+ rootSlotOnClick?.(event);
1015
+ };
1016
+ const handleKeyDown = (event) => {
1017
+ if (disabled) return;
1018
+ nativeProps.onKeyDown?.(event);
1019
+ rootSlotOnKeyDown?.(event);
1020
+ if (event.defaultPrevented) return;
1021
+ if (clickable && removable && (event.key === "Backspace" || event.key === "Delete")) {
1022
+ event.preventDefault();
1023
+ remove();
1024
+ return;
1025
+ }
1026
+ if (clickable && (event.key === "Enter" || event.key === " ")) {
1027
+ event.preventDefault();
1028
+ event.currentTarget.click();
1029
+ }
1030
+ };
1031
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1032
+ "span",
1033
+ {
1034
+ ...nativeProps,
1035
+ ...chipRootAttrs,
1036
+ "aria-disabled": disabled || void 0,
1037
+ onClick: handleRootClick,
1038
+ onKeyDown: handleKeyDown,
1039
+ ref,
1040
+ role: resolvedRole,
1041
+ tabIndex: resolvedTabIndex,
1042
+ children: [
1043
+ isRenderableNode(children) && /* @__PURE__ */ jsxRuntime.jsx("span", { ...labelSlotAttrs, children }),
1044
+ removable && // The icon-only remove control needs an accessible name. Default it,
1045
+ // but let `slotProps.remove` (spread after) override via `aria-label`.
1046
+ /* @__PURE__ */ jsxRuntime.jsx("button", { "aria-label": DEFAULT_REMOVE_LABEL, ...removeButtonAttrs, disabled, onClick: handleRemoveClick, type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(PlaceholderClose, {}) })
1047
+ ]
1048
+ }
1049
+ );
1050
+ };
1051
+ Chip.displayName = "Chip";
1052
+
546
1053
  // src/components/drawer/context.ts
547
1054
  var [DrawerProvider, useDrawerOwnContext] = createSafeContext("DrawerProvider");
548
1055
 
549
1056
  // src/components/drawer/defaults.ts
550
1057
  var DEFAULT_PLACEMENT = "right";
551
- var DEFAULT_HEADER_TYPE = "basic";
552
- var DEFAULT_FOOTER_TYPE = "basic";
1058
+ var DEFAULT_HEADER_TYPE2 = "basic";
1059
+ var DEFAULT_FOOTER_TYPE2 = "basic";
553
1060
  var DEFAULT_INTENSITY = "base";
554
1061
  var Drawer = (props) => {
555
1062
  const theme = useComponentTheme("Drawer");
556
1063
  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 }) });
1064
+ const { placement = DEFAULT_PLACEMENT, dismissible = true, disabled = false, children, ...sparProps } = merged;
1065
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerProvider, { value: { placement, dismissible }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Dialog, { ...sparProps, disabled, forceMount: true, children }) });
559
1066
  };
560
1067
  Drawer.displayName = "Drawer";
561
1068
 
@@ -600,10 +1107,10 @@ var DrawerFooterBase = createComponentBase({
600
1107
  slots: ["root"],
601
1108
  classes: { root: "tk-drawer-footer" }
602
1109
  });
603
- var DrawerCloseButtonBase = createComponentBase({
604
- name: "DrawerCloseButton",
1110
+ var DrawerCloseBase = createComponentBase({
1111
+ name: "DrawerClose",
605
1112
  slots: ["root"],
606
- classes: { root: "tk-drawer-close-button" }
1113
+ classes: { root: "tk-drawer-close" }
607
1114
  });
608
1115
  var DrawerTriggerBase = createComponentBase({
609
1116
  name: "DrawerTrigger",
@@ -616,40 +1123,41 @@ var DrawerTrigger = (props) => {
616
1123
  const { children, ref, ...triggerProps } = rest;
617
1124
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogTrigger, { ...triggerProps, ref, ...rootAttrs, children });
618
1125
  };
619
- DrawerTrigger.displayName = "DrawerTrigger";
1126
+ DrawerTrigger.displayName = "Drawer.Trigger";
620
1127
  var DrawerOverlay = (props) => {
621
1128
  const theme = useComponentTheme("DrawerOverlay");
622
1129
  const { rootAttrs, rest } = composeRootAttrs(DrawerOverlayBase, props, theme, {
623
- stateAttrs: ({ intensity = DEFAULT_INTENSITY, invisible }) => ({
1130
+ stateAttrs: ({ intensity = DEFAULT_INTENSITY, invisible, blur }) => ({
624
1131
  "data-intensity": intensity,
625
- "data-invisible": invisible ? "" : void 0
1132
+ "data-invisible": invisible ? "" : void 0,
1133
+ "data-blur": blur ? "" : void 0
626
1134
  })
627
1135
  });
628
- const { intensity: _intensity, invisible: _invisible, children, ref, ...overlayProps } = rest;
1136
+ const { intensity: _intensity, invisible: _invisible, blur: _blur, children, ref, ...overlayProps } = rest;
629
1137
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogOverlay, { ...overlayProps, ref, ...rootAttrs, children });
630
1138
  };
631
- DrawerOverlay.displayName = "DrawerOverlay";
632
- var preventDefault = (e) => e.preventDefault();
1139
+ DrawerOverlay.displayName = "Drawer.Overlay";
633
1140
  var DrawerPanel = (props) => {
634
1141
  const theme = useComponentTheme("DrawerPanel");
635
- const { placement, dismissable } = useDrawerOwnContext();
1142
+ const { placement, dismissible } = useDrawerOwnContext();
636
1143
  const { rootAttrs, rest } = composeRootAttrs(DrawerPanelBase, props, theme, {
637
1144
  stateAttrs: () => ({
638
1145
  "data-placement": placement
639
1146
  })
640
1147
  });
641
1148
  const { container, children, ref, ...panelProps } = rest;
642
- const dismissHandlers = !dismissable && {
643
- onEscapeKeyDown: preventDefault,
644
- onPointerDownOutside: preventDefault
1149
+ const dismissHandlers = !dismissible && {
1150
+ onEscapeKeyDown: blockDismiss(panelProps.onEscapeKeyDown),
1151
+ onPointerDownOutside: blockDismiss(panelProps.onPointerDownOutside),
1152
+ onInteractOutside: blockDismiss(panelProps.onInteractOutside)
645
1153
  };
646
1154
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogContent, { ...panelProps, container, ref, ...rootAttrs, ...dismissHandlers, children });
647
1155
  };
648
- DrawerPanel.displayName = "DrawerPanel";
1156
+ DrawerPanel.displayName = "Drawer.Panel";
649
1157
  var DrawerHeader = (props) => {
650
1158
  const theme = useComponentTheme("DrawerHeader");
651
1159
  const { rootAttrs, rest } = composeRootAttrs(DrawerHeaderBase, props, theme, {
652
- stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE }) => ({
1160
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE2 }) => ({
653
1161
  "data-header-type": headerType
654
1162
  })
655
1163
  });
@@ -657,21 +1165,21 @@ var DrawerHeader = (props) => {
657
1165
  const Component = as ?? "div";
658
1166
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
659
1167
  };
660
- DrawerHeader.displayName = "DrawerHeader";
1168
+ DrawerHeader.displayName = "Drawer.Header";
661
1169
  var DrawerTitle = (props) => {
662
1170
  const theme = useComponentTheme("DrawerTitle");
663
1171
  const { rootAttrs, rest } = composeRootAttrs(DrawerTitleBase, props, theme);
664
1172
  const { level = 5, children, ref, ...titleProps } = rest;
665
1173
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogTitle, { ...titleProps, level, ref, ...rootAttrs, children });
666
1174
  };
667
- DrawerTitle.displayName = "DrawerTitle";
1175
+ DrawerTitle.displayName = "Drawer.Title";
668
1176
  var DrawerDescription = (props) => {
669
1177
  const theme = useComponentTheme("DrawerDescription");
670
1178
  const { rootAttrs, rest } = composeRootAttrs(DrawerDescriptionBase, props, theme);
671
1179
  const { children, ref, ...descProps } = rest;
672
1180
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogDescription, { ...descProps, ref, ...rootAttrs, children });
673
1181
  };
674
- DrawerDescription.displayName = "DrawerDescription";
1182
+ DrawerDescription.displayName = "Drawer.Description";
675
1183
  var DrawerBody = (props) => {
676
1184
  const theme = useComponentTheme("DrawerBody");
677
1185
  const { rootAttrs, rest } = composeRootAttrs(DrawerBodyBase, props, theme);
@@ -679,11 +1187,11 @@ var DrawerBody = (props) => {
679
1187
  const Component = as ?? "div";
680
1188
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
681
1189
  };
682
- DrawerBody.displayName = "DrawerBody";
1190
+ DrawerBody.displayName = "Drawer.Body";
683
1191
  var DrawerFooter = (props) => {
684
1192
  const theme = useComponentTheme("DrawerFooter");
685
1193
  const { rootAttrs, rest } = composeRootAttrs(DrawerFooterBase, props, theme, {
686
- stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE }) => ({
1194
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE2 }) => ({
687
1195
  "data-footer-type": footerType
688
1196
  })
689
1197
  });
@@ -691,14 +1199,14 @@ var DrawerFooter = (props) => {
691
1199
  const Component = as ?? "div";
692
1200
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
693
1201
  };
694
- DrawerFooter.displayName = "DrawerFooter";
695
- var DrawerCloseButton = (props) => {
696
- const theme = useComponentTheme("DrawerCloseButton");
697
- const { rootAttrs, rest } = composeRootAttrs(DrawerCloseButtonBase, props, theme);
1202
+ DrawerFooter.displayName = "Drawer.Footer";
1203
+ var DrawerClose = (props) => {
1204
+ const theme = useComponentTheme("DrawerClose");
1205
+ const { rootAttrs, rest } = composeRootAttrs(DrawerCloseBase, props, theme);
698
1206
  const { children, ref, ...closeProps } = rest;
699
1207
  return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogClose, { ...closeProps, ref, ...rootAttrs, children });
700
1208
  };
701
- DrawerCloseButton.displayName = "DrawerCloseButton";
1209
+ DrawerClose.displayName = "Drawer.Close";
702
1210
 
703
1211
  // src/components/drawer/index.ts
704
1212
  var Drawer2 = Object.assign(Drawer, {
@@ -710,37 +1218,216 @@ var Drawer2 = Object.assign(Drawer, {
710
1218
  Description: DrawerDescription,
711
1219
  Body: DrawerBody,
712
1220
  Footer: DrawerFooter,
713
- CloseButton: DrawerCloseButton
1221
+ Close: DrawerClose
714
1222
  });
715
1223
 
716
- // src/components/field/base.ts
717
- var FieldBase = createComponentBase({
718
- name: "Field",
1224
+ // src/components/dialog/context.ts
1225
+ var [DialogProvider, useDialogOwnContext] = createSafeContext("DialogProvider");
1226
+ var Dialog = (props) => {
1227
+ const theme = useComponentTheme("Dialog");
1228
+ const merged = { ...theme?.defaultProps, ...props };
1229
+ const { dismissible = true, forceMount = true, children, ...sparProps } = merged;
1230
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogProvider, { value: { dismissible }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Dialog, { ...sparProps, forceMount, children }) });
1231
+ };
1232
+ Dialog.displayName = "Dialog";
1233
+
1234
+ // src/components/dialog/base.ts
1235
+ var DialogTriggerBase = createComponentBase({
1236
+ name: "DialogTrigger",
719
1237
  slots: ["root"],
720
- classes: { root: "tk-field" }
1238
+ classes: {
1239
+ root: "tk-dialog-trigger"
1240
+ }
721
1241
  });
722
- var FieldLabelBase = createComponentBase({
723
- name: "FieldLabel",
724
- slots: ["root", "asterisk"],
725
- classes: { root: "tk-field-label", asterisk: "tk-field-asterisk" }
1242
+ var DialogOverlayBase = createComponentBase({
1243
+ name: "DialogOverlay",
1244
+ slots: ["root"],
1245
+ classes: {
1246
+ root: "tk-dialog-overlay"
1247
+ }
726
1248
  });
727
- var FieldDescriptionBase = createComponentBase({
728
- name: "FieldDescription",
1249
+ var DialogPanelBase = createComponentBase({
1250
+ name: "DialogPanel",
729
1251
  slots: ["root"],
730
- classes: { root: "tk-field-description" }
1252
+ classes: {
1253
+ root: "tk-dialog-panel"
1254
+ }
731
1255
  });
732
- var FieldErrorMessageBase = createComponentBase({
733
- name: "FieldErrorMessage",
1256
+ var DialogHeaderBase = createComponentBase({
1257
+ name: "DialogHeader",
734
1258
  slots: ["root"],
735
- classes: { root: "tk-field-error-message" }
1259
+ classes: {
1260
+ root: "tk-dialog-header"
1261
+ }
736
1262
  });
737
- var Field = (props) => {
738
- const theme = useComponentTheme("Field");
739
- const { rootAttrs, rest } = composeRootAttrs(FieldBase, props, theme);
1263
+ var DialogTitleBase = createComponentBase({
1264
+ name: "DialogTitle",
1265
+ slots: ["root"],
1266
+ classes: {
1267
+ root: "tk-dialog-title"
1268
+ }
1269
+ });
1270
+ var DialogDescriptionBase = createComponentBase({
1271
+ name: "DialogDescription",
1272
+ slots: ["root"],
1273
+ classes: {
1274
+ root: "tk-dialog-description"
1275
+ }
1276
+ });
1277
+ var DialogBodyBase = createComponentBase({
1278
+ name: "DialogBody",
1279
+ slots: ["root"],
1280
+ classes: {
1281
+ root: "tk-dialog-body"
1282
+ }
1283
+ });
1284
+ var DialogFooterBase = createComponentBase({
1285
+ name: "DialogFooter",
1286
+ slots: ["root"],
1287
+ classes: {
1288
+ root: "tk-dialog-footer"
1289
+ }
1290
+ });
1291
+ var DialogCloseBase = createComponentBase({
1292
+ name: "DialogClose",
1293
+ slots: ["root"],
1294
+ classes: {
1295
+ root: "tk-dialog-close"
1296
+ }
1297
+ });
1298
+ var DialogTrigger = (props) => {
1299
+ const theme = useComponentTheme("DialogTrigger");
1300
+ const { rootAttrs, rest } = composeRootAttrs(DialogTriggerBase, props, theme);
740
1301
  const { children, ref, ...sparProps } = rest;
741
- return /* @__PURE__ */ jsxRuntime.jsx(spar.Field, { ...sparProps, ref, ...rootAttrs, children });
1302
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogTrigger, { ...sparProps, ...rootAttrs, ref, children });
742
1303
  };
743
- Field.displayName = "Field";
1304
+ DialogTrigger.displayName = "Dialog.Trigger";
1305
+
1306
+ // src/components/dialog/defaults.ts
1307
+ var DEFAULT_INTENSITY2 = "base";
1308
+ var DEFAULT_HEADER_TYPE3 = "basic";
1309
+ var DEFAULT_FOOTER_TYPE3 = "basic";
1310
+ var DialogOverlay = (props) => {
1311
+ const theme = useComponentTheme("DialogOverlay");
1312
+ const { rootAttrs, rest } = composeRootAttrs(DialogOverlayBase, props, theme, {
1313
+ stateAttrs: ({ intensity = DEFAULT_INTENSITY2, invisible, blur }) => ({
1314
+ "data-intensity": intensity,
1315
+ "data-invisible": invisible ? "" : void 0,
1316
+ "data-blur": blur ? "" : void 0
1317
+ })
1318
+ });
1319
+ const { intensity: _intensity, invisible: _invisible, blur: _blur, children, ref, ...sparProps } = rest;
1320
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogOverlay, { ...sparProps, ...rootAttrs, ref, children });
1321
+ };
1322
+ DialogOverlay.displayName = "Dialog.Overlay";
1323
+ var DialogPanel = (props) => {
1324
+ const theme = useComponentTheme("DialogPanel");
1325
+ const { dismissible } = useDialogOwnContext();
1326
+ const { rootAttrs, rest } = composeRootAttrs(DialogPanelBase, props, theme);
1327
+ const { children, ref, ...sparProps } = rest;
1328
+ const dismissHandlers = !dismissible && {
1329
+ onEscapeKeyDown: blockDismiss(sparProps.onEscapeKeyDown),
1330
+ onPointerDownOutside: blockDismiss(sparProps.onPointerDownOutside),
1331
+ onInteractOutside: blockDismiss(sparProps.onInteractOutside)
1332
+ };
1333
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogContent, { ...sparProps, ...rootAttrs, ref, ...dismissHandlers, children });
1334
+ };
1335
+ DialogPanel.displayName = "Dialog.Panel";
1336
+ var DialogHeader = (props) => {
1337
+ const theme = useComponentTheme("DialogHeader");
1338
+ const { rootAttrs, rest } = composeRootAttrs(DialogHeaderBase, props, theme, {
1339
+ stateAttrs: ({ headerType = DEFAULT_HEADER_TYPE3 }) => ({
1340
+ "data-header-type": headerType
1341
+ })
1342
+ });
1343
+ const { as, headerType: _headerType, children, ref, ...headerProps } = rest;
1344
+ const Component = as ?? "div";
1345
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...headerProps, ref, ...rootAttrs, children });
1346
+ };
1347
+ DialogHeader.displayName = "Dialog.Header";
1348
+ var DialogTitle = (props) => {
1349
+ const theme = useComponentTheme("DialogTitle");
1350
+ const { rootAttrs, rest } = composeRootAttrs(DialogTitleBase, props, theme);
1351
+ const { level = 5, children, ref, ...titleProps } = rest;
1352
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogTitle, { ...titleProps, level, ref, ...rootAttrs, children });
1353
+ };
1354
+ DialogTitle.displayName = "Dialog.Title";
1355
+ var DialogDescription = (props) => {
1356
+ const theme = useComponentTheme("DialogDescription");
1357
+ const { rootAttrs, rest } = composeRootAttrs(DialogDescriptionBase, props, theme);
1358
+ const { children, ref, ...sparProps } = rest;
1359
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogDescription, { ...sparProps, ...rootAttrs, ref, children });
1360
+ };
1361
+ DialogDescription.displayName = "Dialog.Description";
1362
+ var DialogBody = (props) => {
1363
+ const theme = useComponentTheme("DialogBody");
1364
+ const { rootAttrs, rest } = composeRootAttrs(DialogBodyBase, props, theme);
1365
+ const { as, children, ref, ...bodyProps } = rest;
1366
+ const Component = as ?? "div";
1367
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...bodyProps, ref, ...rootAttrs, children });
1368
+ };
1369
+ DialogBody.displayName = "Dialog.Body";
1370
+ var DialogFooter = (props) => {
1371
+ const theme = useComponentTheme("DialogFooter");
1372
+ const { rootAttrs, rest } = composeRootAttrs(DialogFooterBase, props, theme, {
1373
+ stateAttrs: ({ footerType = DEFAULT_FOOTER_TYPE3 }) => ({
1374
+ "data-footer-type": footerType
1375
+ })
1376
+ });
1377
+ const { as, footerType: _footerType, children, ref, ...footerProps } = rest;
1378
+ const Component = as ?? "div";
1379
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...footerProps, ref, ...rootAttrs, children });
1380
+ };
1381
+ DialogFooter.displayName = "Dialog.Footer";
1382
+ var DialogClose = (props) => {
1383
+ const theme = useComponentTheme("DialogClose");
1384
+ const { rootAttrs, rest } = composeRootAttrs(DialogCloseBase, props, theme);
1385
+ const { children, ref, ...sparProps } = rest;
1386
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.DialogClose, { ...sparProps, ...rootAttrs, ref, children });
1387
+ };
1388
+ DialogClose.displayName = "Dialog.Close";
1389
+
1390
+ // src/components/dialog/index.ts
1391
+ var Dialog2 = Object.assign(Dialog, {
1392
+ Trigger: DialogTrigger,
1393
+ Overlay: DialogOverlay,
1394
+ Panel: DialogPanel,
1395
+ Header: DialogHeader,
1396
+ Title: DialogTitle,
1397
+ Description: DialogDescription,
1398
+ Body: DialogBody,
1399
+ Footer: DialogFooter,
1400
+ Close: DialogClose
1401
+ });
1402
+
1403
+ // src/components/field/base.ts
1404
+ var FieldBase = createComponentBase({
1405
+ name: "Field",
1406
+ slots: ["root"],
1407
+ classes: { root: "tk-field" }
1408
+ });
1409
+ var FieldLabelBase = createComponentBase({
1410
+ name: "FieldLabel",
1411
+ slots: ["root", "asterisk"],
1412
+ classes: { root: "tk-field-label", asterisk: "tk-field-asterisk" }
1413
+ });
1414
+ var FieldDescriptionBase = createComponentBase({
1415
+ name: "FieldDescription",
1416
+ slots: ["root", "icon"],
1417
+ classes: { root: "tk-field-description", icon: "tk-field-description-icon" }
1418
+ });
1419
+ var FieldErrorMessageBase = createComponentBase({
1420
+ name: "FieldErrorMessage",
1421
+ slots: ["root", "icon"],
1422
+ classes: { root: "tk-field-error-message", icon: "tk-field-error-message-icon" }
1423
+ });
1424
+ var Field = (props) => {
1425
+ const theme = useComponentTheme("Field");
1426
+ const { rootAttrs, rest } = composeRootAttrs(FieldBase, props, theme);
1427
+ const { children, ref, ...sparProps } = rest;
1428
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.Field, { ...sparProps, ref, ...rootAttrs, children });
1429
+ };
1430
+ Field.displayName = "Field";
744
1431
  var FieldLabel = (props) => {
745
1432
  const theme = useComponentTheme("FieldLabel");
746
1433
  const { required } = spar.useFieldContext();
@@ -762,14 +1449,34 @@ var FieldDescription = (props) => {
762
1449
  const theme = useComponentTheme("FieldDescription");
763
1450
  const { rootAttrs, rest } = composeRootAttrs(FieldDescriptionBase, props, theme);
764
1451
  const { children, ref, ...spar$1 } = rest;
765
- return /* @__PURE__ */ jsxRuntime.jsx(spar.FieldDescription, { ...spar$1, ref, ...rootAttrs, children });
1452
+ const iconAttrs = buildSlotAttrs(FieldDescriptionBase.getSlotProps("icon"), "icon", {
1453
+ themeSlotProps: theme?.slotProps,
1454
+ themeClassNames: theme?.classNames,
1455
+ instanceSlotProps: props.slotProps,
1456
+ instanceClassNames: props.classNames
1457
+ });
1458
+ const hasContent = children != null && children !== "";
1459
+ return /* @__PURE__ */ jsxRuntime.jsxs(spar.FieldDescription, { ...spar$1, ref, ...rootAttrs, children: [
1460
+ hasContent && /* @__PURE__ */ jsxRuntime.jsx("span", { ...iconAttrs, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInfo, {}) }),
1461
+ children
1462
+ ] });
766
1463
  };
767
1464
  FieldDescription.displayName = "Field.Description";
768
1465
  var FieldErrorMessage = (props) => {
769
1466
  const theme = useComponentTheme("FieldErrorMessage");
770
1467
  const { rootAttrs, rest } = composeRootAttrs(FieldErrorMessageBase, props, theme);
771
1468
  const { children, ref, ...spar$1 } = rest;
772
- return /* @__PURE__ */ jsxRuntime.jsx(spar.FieldErrorMessage, { ...spar$1, ref, ...rootAttrs, children });
1469
+ const iconAttrs = buildSlotAttrs(FieldErrorMessageBase.getSlotProps("icon"), "icon", {
1470
+ themeSlotProps: theme?.slotProps,
1471
+ themeClassNames: theme?.classNames,
1472
+ instanceSlotProps: props.slotProps,
1473
+ instanceClassNames: props.classNames
1474
+ });
1475
+ const hasContent = children != null && children !== "";
1476
+ return /* @__PURE__ */ jsxRuntime.jsxs(spar.FieldErrorMessage, { ...spar$1, ref, ...rootAttrs, children: [
1477
+ hasContent && /* @__PURE__ */ jsxRuntime.jsx("span", { ...iconAttrs, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(PlaceholderError, {}) }),
1478
+ children
1479
+ ] });
773
1480
  };
774
1481
  FieldErrorMessage.displayName = "Field.ErrorMessage";
775
1482
 
@@ -786,15 +1493,6 @@ var InputBase = createComponentBase({
786
1493
  slots: ["root"],
787
1494
  classes: { root: "tk-input" }
788
1495
  });
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
1496
  var InputFieldBase = createComponentBase({
799
1497
  name: "InputField",
800
1498
  slots: ["root"],
@@ -810,84 +1508,541 @@ var InputSuffixBase = createComponentBase({
810
1508
  slots: ["root"],
811
1509
  classes: { root: "tk-input-suffix" }
812
1510
  });
1511
+ var InputLeadingIconBase = createComponentBase({
1512
+ name: "InputLeadingIcon",
1513
+ slots: ["root"],
1514
+ classes: { root: "tk-input-leading-icon" }
1515
+ });
1516
+ var InputTrailingIconBase = createComponentBase({
1517
+ name: "InputTrailingIcon",
1518
+ slots: ["root"],
1519
+ classes: { root: "tk-input-trailing-icon" }
1520
+ });
1521
+ var InputClearButtonBase = createComponentBase({
1522
+ name: "InputClearButton",
1523
+ slots: ["root"],
1524
+ classes: { root: "tk-input-clear-button" }
1525
+ });
1526
+ var InputSpinnerBase = createComponentBase({
1527
+ name: "InputSpinner",
1528
+ slots: ["root"],
1529
+ classes: { root: "tk-input-spinner" }
1530
+ });
1531
+ var InputRevealButtonBase = createComponentBase({
1532
+ name: "InputRevealButton",
1533
+ slots: ["root"],
1534
+ classes: { root: "tk-input-reveal-button" }
1535
+ });
1536
+ var InputStrengthBase = createComponentBase({
1537
+ name: "InputStrength",
1538
+ slots: ["root"],
1539
+ classes: { root: "tk-input-strength" }
1540
+ });
1541
+ var InputStepperBase = createComponentBase({
1542
+ name: "InputStepper",
1543
+ slots: ["root"],
1544
+ classes: { root: "tk-input-stepper" }
1545
+ });
1546
+ var InputDecrementBase = createComponentBase({
1547
+ name: "InputDecrement",
1548
+ slots: ["root"],
1549
+ classes: { root: "tk-input-decrement" }
1550
+ });
1551
+ var InputIncrementBase = createComponentBase({
1552
+ name: "InputIncrement",
1553
+ slots: ["root"],
1554
+ classes: { root: "tk-input-increment" }
1555
+ });
1556
+ var InputChipsBase = createComponentBase({
1557
+ name: "InputChips",
1558
+ slots: ["root"],
1559
+ classes: { root: "tk-input-chips" }
1560
+ });
813
1561
 
814
1562
  // src/components/input/context.ts
815
1563
  var [InputProvider, useInputOwnContext] = createSafeContext("InputProvider");
816
1564
 
817
1565
  // src/components/input/defaults.ts
818
- var DEFAULT_SIZE5 = "base";
1566
+ var DEFAULT_SIZE7 = "base";
1567
+ var SEGMENT_COUNT = 4;
1568
+ var computeStrength = (value) => {
1569
+ let strength = 0;
1570
+ if (value.length >= 8) strength += 1;
1571
+ if (/[A-Z]/.test(value)) strength += 1;
1572
+ if (/[a-z]/.test(value)) strength += 1;
1573
+ if (/[0-9]/.test(value)) strength += 1;
1574
+ if (/[^A-Za-z0-9]/.test(value)) strength += 1;
1575
+ return strength;
1576
+ };
1577
+ var levelFor = (strength) => strength < 3 ? "weak" : strength < 4 ? "medium" : "strong";
1578
+ var InputStrength = (props) => {
1579
+ const theme = useComponentTheme("InputStrength");
1580
+ const { fieldValue } = useInputOwnContext("Input.Strength");
1581
+ const Component = props.as ?? "div";
1582
+ const { rootAttrs, rest } = composeRootAttrs(InputStrengthBase, props, theme);
1583
+ const { as: _as, children: _children, ref, ...rendered } = rest;
1584
+ const strength = computeStrength(fieldValue);
1585
+ const filled = Math.min(strength, SEGMENT_COUNT);
1586
+ const level = levelFor(strength);
1587
+ 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)) });
1588
+ };
1589
+ InputStrength.displayName = "Input.Strength";
819
1590
  var Input = (props) => {
820
1591
  const theme = useComponentTheme("Input");
1592
+ const fieldRef = react.useRef(null);
1593
+ const [fieldNode, setFieldNode] = react.useState(null);
1594
+ const [fieldValue, setFieldValue] = react.useState("");
1595
+ const [revealed, setRevealed] = react.useState(false);
1596
+ const toggleReveal = react.useCallback(() => setRevealed((value) => !value), []);
1597
+ const clearablesRef = react.useRef(/* @__PURE__ */ new Map());
1598
+ const [hasAuxContent, setHasAuxContent] = react.useState(false);
1599
+ const setClearable = react.useCallback((id, entry) => {
1600
+ if (entry) {
1601
+ clearablesRef.current.set(id, entry);
1602
+ } else {
1603
+ clearablesRef.current.delete(id);
1604
+ }
1605
+ let any = false;
1606
+ for (const value of clearablesRef.current.values()) {
1607
+ if (value.hasContent) {
1608
+ any = true;
1609
+ break;
1610
+ }
1611
+ }
1612
+ setHasAuxContent(any);
1613
+ }, []);
1614
+ const clearAux = react.useCallback(() => {
1615
+ for (const value of clearablesRef.current.values()) value.clear();
1616
+ }, []);
821
1617
  const { rootAttrs, rest } = composeRootAttrs(InputBase, props, theme, {
822
- stateAttrs: ({ size: size2 = DEFAULT_SIZE5 }) => ({
1618
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE7 }) => ({
823
1619
  "data-size": size2
824
1620
  })
825
1621
  });
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 }) });
1622
+ const { size = DEFAULT_SIZE7, children, ref, ...sparProps } = rest;
1623
+ const contextValue = react.useMemo(
1624
+ () => ({
1625
+ size,
1626
+ fieldRef,
1627
+ fieldNode,
1628
+ setFieldNode,
1629
+ fieldValue,
1630
+ setFieldValue,
1631
+ revealed,
1632
+ setRevealed,
1633
+ toggleReveal,
1634
+ setClearable,
1635
+ hasAuxContent,
1636
+ clearAux
1637
+ }),
1638
+ [size, fieldNode, fieldValue, revealed, setFieldValue, setRevealed, toggleReveal, setClearable, hasAuxContent, clearAux]
1639
+ );
1640
+ const rowChildren = [];
1641
+ const belowChildren = [];
1642
+ react.Children.forEach(children, (child) => {
1643
+ if (react.isValidElement(child) && child.type === InputStrength) {
1644
+ belowChildren.push(child);
1645
+ } else {
1646
+ rowChildren.push(child);
1647
+ }
1648
+ });
1649
+ return /* @__PURE__ */ jsxRuntime.jsxs(InputProvider, { value: contextValue, children: [
1650
+ /* @__PURE__ */ jsxRuntime.jsx(spar.Input, { ...sparProps, ref, ...rootAttrs, children: rowChildren }),
1651
+ belowChildren
1652
+ ] });
828
1653
  };
829
1654
  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
- });
1655
+
1656
+ // src/components/input/dom.ts
1657
+ var setNativeValue = (field, value) => {
1658
+ const prototype = field instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
1659
+ const valueSetter = Object.getOwnPropertyDescriptor(prototype, "value")?.set;
1660
+ valueSetter?.call(field, value);
1661
+ field.dispatchEvent(new Event("input", { bubbles: true }));
1662
+ };
1663
+ var stepField = (field, direction) => {
1664
+ if (!(field instanceof HTMLInputElement)) return;
1665
+ try {
1666
+ if (direction === "up") {
1667
+ field.stepUp();
1668
+ } else {
1669
+ field.stepDown();
1670
+ }
1671
+ } catch {
1672
+ return;
1673
+ }
1674
+ field.dispatchEvent(new Event("input", { bubbles: true }));
1675
+ field.focus();
1676
+ };
1677
+ var InputChips = (props) => {
1678
+ const theme = useComponentTheme("InputChips");
1679
+ const { disabled, readOnly } = spar.useInputContext();
1680
+ const { size, fieldNode, setClearable } = useInputOwnContext("Input.Chips");
1681
+ const { rootAttrs, rest } = composeRootAttrs(InputChipsBase, props, theme);
1682
+ const { as, value, defaultValue, onValueChange, separator, max, allowDuplicates = false, children, ref, ...rendered } = rest;
1683
+ const Component = as ?? "div";
1684
+ const [chips = [], setChips] = useControllableState(value, defaultValue ?? [], onValueChange);
1685
+ const addChip = react.useCallback(
1686
+ (raw) => {
1687
+ if (disabled || readOnly) return;
1688
+ const label = raw.trim();
1689
+ if (!label) return;
1690
+ if (max !== void 0 && chips.length >= max) return;
1691
+ if (!allowDuplicates && chips.includes(label)) return;
1692
+ setChips([...chips, label]);
1693
+ },
1694
+ [chips, disabled, readOnly, max, allowDuplicates, setChips]
1695
+ );
1696
+ const removeChip = react.useCallback(
1697
+ (index) => {
1698
+ if (disabled || readOnly) return;
1699
+ setChips(chips.filter((_, i) => i !== index));
1700
+ },
1701
+ [chips, disabled, readOnly, setChips]
1702
+ );
1703
+ const removeLast = react.useCallback(() => {
1704
+ if (disabled || readOnly || chips.length === 0) return;
1705
+ setChips(chips.slice(0, -1));
1706
+ }, [chips, disabled, readOnly, setChips]);
1707
+ const clearId = react.useRef(/* @__PURE__ */ Symbol("input-chips")).current;
1708
+ const clearAll = react.useCallback(() => {
1709
+ if (disabled || readOnly) return;
1710
+ setChips([]);
1711
+ }, [disabled, readOnly, setChips]);
1712
+ react.useEffect(() => {
1713
+ setClearable(clearId, { hasContent: chips.length > 0, clear: clearAll });
1714
+ return () => setClearable(clearId, null);
1715
+ }, [clearId, chips.length, clearAll, setClearable]);
1716
+ react.useEffect(() => {
1717
+ const field = fieldNode;
1718
+ if (!field) return;
1719
+ const handleKeyDown = (event) => {
1720
+ if (event.isComposing) return;
1721
+ if (event.key === "Enter" || separator && event.key === separator) {
1722
+ if (!field.value.trim()) return;
1723
+ event.preventDefault();
1724
+ addChip(field.value);
1725
+ setNativeValue(field, "");
1726
+ } else if (event.key === "Backspace" && field.value === "") {
1727
+ removeLast();
1728
+ }
1729
+ };
1730
+ field.addEventListener("keydown", handleKeyDown);
1731
+ return () => field.removeEventListener("keydown", handleKeyDown);
1732
+ }, [fieldNode, addChip, removeLast, separator]);
848
1733
  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 })
1734
+ chips.map((chip, index) => (
1735
+ // Render the shared Chip token in the input's neutral/outlined parity
1736
+ // look. `autoDismiss={false}` because Input.Chips owns the tag array
1737
+ // removal must flow through onRemove into our state, not the chip's own.
1738
+ /* @__PURE__ */ jsxRuntime.jsx(
1739
+ Chip,
1740
+ {
1741
+ appearance: "outlined",
1742
+ variant: "neutral",
1743
+ size,
1744
+ removable: !disabled && !readOnly,
1745
+ disabled: disabled || readOnly,
1746
+ autoDismiss: false,
1747
+ slotProps: { remove: { "aria-label": `Remove ${chip}` } },
1748
+ onRemove: () => removeChip(index),
1749
+ children: chip
1750
+ },
1751
+ `${chip}-${index}`
1752
+ )
1753
+ )),
1754
+ children
852
1755
  ] });
853
1756
  };
854
- InputContainer.displayName = "Input.Container";
1757
+ InputChips.displayName = "Input.Chips";
1758
+ var InputClearButton = (props) => {
1759
+ const theme = useComponentTheme("InputClearButton");
1760
+ const { disabled, readOnly } = spar.useInputContext();
1761
+ const { size, fieldRef, fieldValue, setFieldValue, hasAuxContent, clearAux } = useInputOwnContext("Input.ClearButton");
1762
+ const { rootAttrs, rest } = composeRootAttrs(InputClearButtonBase, props, theme);
1763
+ const {
1764
+ onClick: slotOnClick,
1765
+ onKeyDown: slotOnKeyDown,
1766
+ ...clearRootAttrs
1767
+ } = rootAttrs;
1768
+ const { children, onClear, onClick, onKeyDown, ref, "type": _type, "aria-label": ariaLabel = "Clear input", ...buttonProps } = rest;
1769
+ if (disabled || readOnly || fieldValue === "" && !hasAuxContent) return null;
1770
+ const clear = () => {
1771
+ clearAux();
1772
+ const field = fieldRef.current;
1773
+ if (field) {
1774
+ setNativeValue(field, "");
1775
+ setFieldValue("");
1776
+ }
1777
+ onClear?.();
1778
+ field?.focus();
1779
+ };
1780
+ const handleClick = (event) => {
1781
+ onClick?.(event);
1782
+ slotOnClick?.(event);
1783
+ if (event.defaultPrevented) return;
1784
+ clear();
1785
+ };
1786
+ const handleKeyDown = (event) => {
1787
+ onKeyDown?.(event);
1788
+ slotOnKeyDown?.(event);
1789
+ if (event.defaultPrevented || event.key !== "Escape") return;
1790
+ event.preventDefault();
1791
+ clear();
1792
+ };
1793
+ return /* @__PURE__ */ jsxRuntime.jsx(
1794
+ Button,
1795
+ {
1796
+ ...buttonProps,
1797
+ ...clearRootAttrs,
1798
+ ref,
1799
+ type: "button",
1800
+ appearance: "text",
1801
+ rounded: true,
1802
+ size,
1803
+ "aria-label": ariaLabel,
1804
+ onClick: handleClick,
1805
+ onKeyDown: handleKeyDown,
1806
+ startContent: children ?? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderClose, {})
1807
+ }
1808
+ );
1809
+ };
1810
+ InputClearButton.displayName = "Input.ClearButton";
1811
+ var InputDecrement = (props) => {
1812
+ const theme = useComponentTheme("InputDecrement");
1813
+ const { disabled, readOnly } = spar.useInputContext();
1814
+ const { size, fieldRef } = useInputOwnContext("Input.Decrement");
1815
+ const { rootAttrs, rest } = composeRootAttrs(InputDecrementBase, props, theme);
1816
+ const { onClick: slotOnClick, ...decrementRootAttrs } = rootAttrs;
1817
+ const { children, onClick, ref, "type": _type, "disabled": _disabled, "aria-label": ariaLabel = "Decrement value", ...buttonProps } = rest;
1818
+ const handleClick = (event) => {
1819
+ onClick?.(event);
1820
+ slotOnClick?.(event);
1821
+ if (event.defaultPrevented) return;
1822
+ stepField(fieldRef.current, "down");
1823
+ };
1824
+ return /* @__PURE__ */ jsxRuntime.jsx(
1825
+ Button,
1826
+ {
1827
+ ...buttonProps,
1828
+ ...decrementRootAttrs,
1829
+ ref,
1830
+ type: "button",
1831
+ appearance: "text",
1832
+ rounded: true,
1833
+ size,
1834
+ disabled: disabled || readOnly,
1835
+ "aria-label": ariaLabel,
1836
+ onClick: handleClick,
1837
+ startContent: children ?? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderChevronDown, {})
1838
+ }
1839
+ );
1840
+ };
1841
+ InputDecrement.displayName = "Input.Decrement";
855
1842
  var InputField = (props) => {
856
1843
  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 });
1844
+ const { fieldRef, setFieldNode, setFieldValue, revealed, setRevealed } = useInputOwnContext("Input.Field");
1845
+ const { rootAttrs, rest } = composeRootAttrs(InputFieldBase, props, theme);
1846
+ const { as, ref, type, onInput, onChange, ...spar$1 } = rest;
1847
+ const effectiveType = type === "password" && revealed ? "text" : type;
1848
+ const renderedType = as === "textarea" ? void 0 : effectiveType;
1849
+ const setFieldRef = react.useCallback(
1850
+ (node) => {
1851
+ fieldRef.current = node;
1852
+ setFieldNode(node);
1853
+ if (node) setFieldValue(node.value);
1854
+ if (typeof ref === "function") {
1855
+ ref(node);
1856
+ } else if (ref) {
1857
+ ref.current = node;
1858
+ }
1859
+ },
1860
+ [fieldRef, ref, setFieldNode, setFieldValue]
1861
+ );
1862
+ react.useEffect(() => {
1863
+ const node = fieldRef.current;
1864
+ if (node) setFieldValue(node.value);
1865
+ }, [fieldRef, setFieldValue, spar$1.value, spar$1.defaultValue]);
1866
+ react.useEffect(() => () => setRevealed(false), [setRevealed]);
1867
+ const handleInput = (event) => {
1868
+ onInput?.(event);
1869
+ setFieldValue(event.currentTarget.value);
1870
+ };
1871
+ const handleChange = (event) => {
1872
+ onChange?.(event);
1873
+ setFieldValue(event.currentTarget.value);
1874
+ };
1875
+ return /* @__PURE__ */ jsxRuntime.jsx(
1876
+ spar.InputField,
1877
+ {
1878
+ ...spar$1,
1879
+ as,
1880
+ type: renderedType,
1881
+ onInput: handleInput,
1882
+ onChange: handleChange,
1883
+ ref: setFieldRef,
1884
+ ...rootAttrs
1885
+ }
1886
+ );
865
1887
  };
866
1888
  InputField.displayName = "Input.Field";
1889
+ var InputIncrement = (props) => {
1890
+ const theme = useComponentTheme("InputIncrement");
1891
+ const { disabled, readOnly } = spar.useInputContext();
1892
+ const { size, fieldRef } = useInputOwnContext("Input.Increment");
1893
+ const { rootAttrs, rest } = composeRootAttrs(InputIncrementBase, props, theme);
1894
+ const { onClick: slotOnClick, ...incrementRootAttrs } = rootAttrs;
1895
+ const { children, onClick, ref, "type": _type, "disabled": _disabled, "aria-label": ariaLabel = "Increment value", ...buttonProps } = rest;
1896
+ const handleClick = (event) => {
1897
+ onClick?.(event);
1898
+ slotOnClick?.(event);
1899
+ if (event.defaultPrevented) return;
1900
+ stepField(fieldRef.current, "up");
1901
+ };
1902
+ return /* @__PURE__ */ jsxRuntime.jsx(
1903
+ Button,
1904
+ {
1905
+ ...buttonProps,
1906
+ ...incrementRootAttrs,
1907
+ ref,
1908
+ type: "button",
1909
+ appearance: "text",
1910
+ rounded: true,
1911
+ size,
1912
+ disabled: disabled || readOnly,
1913
+ "aria-label": ariaLabel,
1914
+ onClick: handleClick,
1915
+ startContent: children ?? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderChevronUp, {})
1916
+ }
1917
+ );
1918
+ };
1919
+ InputIncrement.displayName = "Input.Increment";
1920
+ var InputLeadingIcon = (props) => {
1921
+ const theme = useComponentTheme("InputLeadingIcon");
1922
+ useInputOwnContext("Input.LeadingIcon");
1923
+ const Component = props.as ?? "span";
1924
+ const { rootAttrs, rest } = composeRootAttrs(InputLeadingIconBase, props, theme);
1925
+ const { as: _as, children, ref, ...rendered } = rest;
1926
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children });
1927
+ };
1928
+ InputLeadingIcon.displayName = "Input.LeadingIcon";
867
1929
  var InputPrefix = (props) => {
868
1930
  const theme = useComponentTheme("InputPrefix");
1931
+ useInputOwnContext("Input.Prefix");
869
1932
  const Component = props.as ?? "span";
870
1933
  const { rootAttrs, rest } = composeRootAttrs(InputPrefixBase, props, theme);
871
1934
  const { as: _as, children, ref, ...rendered } = rest;
872
1935
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...rendered, ref, ...rootAttrs, children });
873
1936
  };
874
1937
  InputPrefix.displayName = "Input.Prefix";
1938
+ var InputRevealButton = (props) => {
1939
+ const theme = useComponentTheme("InputRevealButton");
1940
+ const { disabled, readOnly } = spar.useInputContext();
1941
+ const { size, fieldRef, revealed, setRevealed, toggleReveal } = useInputOwnContext("Input.RevealButton");
1942
+ const { rootAttrs, rest } = composeRootAttrs(InputRevealButtonBase, props, theme);
1943
+ const { onClick: slotOnClick, ...revealRootAttrs } = rootAttrs;
1944
+ const { children, onClick, ref, "type": _type, "aria-label": _ariaLabel, "aria-pressed": _ariaPressed, ...buttonProps } = rest;
1945
+ react.useEffect(() => {
1946
+ if (!revealed) return;
1947
+ const form = fieldRef.current?.form;
1948
+ if (!form) return;
1949
+ const handleSubmit = () => setRevealed(false);
1950
+ form.addEventListener("submit", handleSubmit);
1951
+ return () => form.removeEventListener("submit", handleSubmit);
1952
+ }, [revealed, fieldRef, setRevealed]);
1953
+ const handleClick = (event) => {
1954
+ onClick?.(event);
1955
+ slotOnClick?.(event);
1956
+ if (event.defaultPrevented) return;
1957
+ toggleReveal();
1958
+ fieldRef.current?.focus();
1959
+ };
1960
+ return /* @__PURE__ */ jsxRuntime.jsx(
1961
+ Button,
1962
+ {
1963
+ ...buttonProps,
1964
+ ...revealRootAttrs,
1965
+ ref,
1966
+ type: "button",
1967
+ appearance: "text",
1968
+ rounded: true,
1969
+ size,
1970
+ disabled: disabled || readOnly,
1971
+ "aria-label": "Toggle password visibility",
1972
+ "aria-pressed": revealed,
1973
+ onClick: handleClick,
1974
+ startContent: children ?? (revealed ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderEyeOff, {}) : /* @__PURE__ */ jsxRuntime.jsx(PlaceholderEye, {}))
1975
+ }
1976
+ );
1977
+ };
1978
+ InputRevealButton.displayName = "Input.RevealButton";
1979
+ var InputSpinner = (props) => {
1980
+ const theme = useComponentTheme("InputSpinner");
1981
+ useInputOwnContext("Input.Spinner");
1982
+ const Component = props.as ?? "span";
1983
+ const { rootAttrs, rest } = composeRootAttrs(InputSpinnerBase, props, theme);
1984
+ const { as: _as, children, ref, ...rendered } = rest;
1985
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children: children ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tk-input-default-spinner" }) });
1986
+ };
1987
+ InputSpinner.displayName = "Input.Spinner";
1988
+ var InputStepper = (props) => {
1989
+ const theme = useComponentTheme("InputStepper");
1990
+ useInputOwnContext("Input.Stepper");
1991
+ const Component = props.as ?? "div";
1992
+ const { rootAttrs, rest } = composeRootAttrs(InputStepperBase, props, theme);
1993
+ const { as: _as, children, ref, ...rendered } = rest;
1994
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...rendered, ref, ...rootAttrs, children });
1995
+ };
1996
+ InputStepper.displayName = "Input.Stepper";
875
1997
  var InputSuffix = (props) => {
876
1998
  const theme = useComponentTheme("InputSuffix");
1999
+ useInputOwnContext("Input.Suffix");
877
2000
  const Component = props.as ?? "span";
878
2001
  const { rootAttrs, rest } = composeRootAttrs(InputSuffixBase, props, theme);
879
2002
  const { as: _as, children, ref, ...rendered } = rest;
880
2003
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...rendered, ref, ...rootAttrs, children });
881
2004
  };
882
2005
  InputSuffix.displayName = "Input.Suffix";
2006
+ var InputTrailingIcon = (props) => {
2007
+ const theme = useComponentTheme("InputTrailingIcon");
2008
+ useInputOwnContext("Input.TrailingIcon");
2009
+ const Component = props.as ?? "span";
2010
+ const { rootAttrs, rest } = composeRootAttrs(InputTrailingIconBase, props, theme);
2011
+ const { as: _as, children, ref, ...rendered } = rest;
2012
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { "aria-hidden": "true", ...rendered, ref, ...rootAttrs, children });
2013
+ };
2014
+ InputTrailingIcon.displayName = "Input.TrailingIcon";
883
2015
 
884
2016
  // src/components/input/index.ts
885
2017
  var Input2 = Object.assign(Input, {
886
- Container: InputContainer,
887
2018
  Field: InputField,
888
2019
  Prefix: InputPrefix,
889
- Suffix: InputSuffix
2020
+ Suffix: InputSuffix,
2021
+ LeadingIcon: InputLeadingIcon,
2022
+ TrailingIcon: InputTrailingIcon,
2023
+ ClearButton: InputClearButton,
2024
+ Spinner: InputSpinner,
2025
+ RevealButton: InputRevealButton,
2026
+ Strength: InputStrength,
2027
+ Stepper: InputStepper,
2028
+ Decrement: InputDecrement,
2029
+ Increment: InputIncrement,
2030
+ Chips: InputChips
2031
+ });
2032
+
2033
+ // src/components/label/base.ts
2034
+ var LabelBase = createComponentBase({
2035
+ name: "Label",
2036
+ slots: ["root"],
2037
+ classes: { root: "tk-label" }
890
2038
  });
2039
+ var Label = (props) => {
2040
+ const theme = useComponentTheme("Label");
2041
+ const { rootAttrs, rest } = composeRootAttrs(LabelBase, props, theme);
2042
+ const { as, children, ref, ...sparProps } = rest;
2043
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.Label, { ...sparProps, as, ref, ...rootAttrs, children });
2044
+ };
2045
+ Label.displayName = "Label";
891
2046
 
892
2047
  // src/components/radio/base.ts
893
2048
  var RadioBase = createComponentBase({
@@ -920,22 +2075,19 @@ var RADIO_ITEM_CONTEXT_VALUE = { inside: true };
920
2075
  var [RadioItemProvider, useRadioItemOwnContext] = createSafeContext("RadioItemProvider");
921
2076
 
922
2077
  // src/components/radio/defaults.ts
923
- var DEFAULT_SIZE6 = "base";
924
- var DEFAULT_TYPE3 = "default";
2078
+ var DEFAULT_SIZE8 = "base";
925
2079
  var DEFAULT_POSITION = "left";
926
2080
  var Radio = (props) => {
927
2081
  const theme = useComponentTheme("Radio");
928
2082
  const { rootAttrs, rest } = composeRootAttrs(RadioBase, props, theme, {
929
- stateAttrs: ({ size: size2 = DEFAULT_SIZE6, type: type2 = DEFAULT_TYPE3, position: position2 = DEFAULT_POSITION, spread }) => ({
2083
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE8, position: position2 = DEFAULT_POSITION, spread }) => ({
930
2084
  "data-size": size2,
931
- "data-type": type2,
932
2085
  "data-position": position2,
933
2086
  "data-spread": spread ? "" : void 0
934
2087
  })
935
2088
  });
936
2089
  const {
937
- size = DEFAULT_SIZE6,
938
- type = DEFAULT_TYPE3,
2090
+ size = DEFAULT_SIZE8,
939
2091
  position = DEFAULT_POSITION,
940
2092
  invalid,
941
2093
  // `spread` is consumed only as a data-attr above; destructure to keep it
@@ -946,7 +2098,7 @@ var Radio = (props) => {
946
2098
  ref,
947
2099
  ...sparProps
948
2100
  } = rest;
949
- return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupProvider, { value: { size, type, position }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Radio, { ...sparProps, invalid, ...rootAttrs, ref, children }) });
2101
+ return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupProvider, { value: { size, position }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Radio, { ...sparProps, invalid, ...rootAttrs, ref, children }) });
950
2102
  };
951
2103
  Radio.displayName = "Radio";
952
2104
  var RadioIndicator = (props) => {
@@ -970,7 +2122,6 @@ var RadioItem = (props) => {
970
2122
  const { rootAttrs, rest } = composeRootAttrs(RadioItemBase, props, theme, {
971
2123
  stateAttrs: ({ position }) => ({
972
2124
  "data-size": group.size,
973
- "data-type": group.type,
974
2125
  "data-position": position ?? group.position
975
2126
  })
976
2127
  });
@@ -1054,11 +2205,11 @@ var PopoverTrigger = (props) => {
1054
2205
  PopoverTrigger.displayName = "Popover.Trigger";
1055
2206
 
1056
2207
  // src/components/popover/defaults.ts
1057
- var DEFAULT_VARIANT3 = "dark";
2208
+ var DEFAULT_VARIANT5 = "white";
1058
2209
  var PopoverContent = (props) => {
1059
2210
  const theme = useComponentTheme("PopoverContent");
1060
2211
  const { rootAttrs, rest } = composeRootAttrs(PopoverContentBase, props, theme, {
1061
- stateAttrs: ({ variant = DEFAULT_VARIANT3 }) => ({
2212
+ stateAttrs: ({ variant = DEFAULT_VARIANT5 }) => ({
1062
2213
  "data-variant": variant
1063
2214
  })
1064
2215
  });
@@ -1113,8 +2264,22 @@ var SelectBase = createComponentBase({
1113
2264
  });
1114
2265
  var SelectTriggerBase = createComponentBase({
1115
2266
  name: "SelectTrigger",
2267
+ slots: ["root", "value", "indicator"],
2268
+ classes: {
2269
+ root: "tk-select-trigger",
2270
+ // Truncating value region wrapping the selected label/placeholder; pins the
2271
+ // indicator to the trailing edge of the `space-between` trigger.
2272
+ value: "tk-select-value",
2273
+ // Wrapper around the built-in trigger indicator. Shares the
2274
+ // `tk-select-indicator` recipe with the standalone Select.Indicator so both
2275
+ // entry points style identically.
2276
+ indicator: "tk-select-indicator"
2277
+ }
2278
+ });
2279
+ var SelectIndicatorBase = createComponentBase({
2280
+ name: "SelectIndicator",
1116
2281
  slots: ["root"],
1117
- classes: { root: "tk-select-trigger" }
2282
+ classes: { root: "tk-select-indicator" }
1118
2283
  });
1119
2284
  var SelectContentBase = createComponentBase({
1120
2285
  name: "SelectContent",
@@ -1146,17 +2311,17 @@ var SelectSeparatorBase = createComponentBase({
1146
2311
  var [SelectProvider, useSelectOwnContext] = createSafeContext("SelectProvider");
1147
2312
 
1148
2313
  // src/components/select/defaults.ts
1149
- var DEFAULT_SIZE7 = "base";
2314
+ var DEFAULT_SIZE9 = "base";
1150
2315
  var DEFAULT_CONTENT_WIDTH = "trigger";
1151
2316
  var Select = (props) => {
1152
2317
  const theme = useComponentTheme("Select");
1153
2318
  const { rootAttrs, rest } = composeRootAttrs(SelectBase, props, theme, {
1154
- stateAttrs: ({ size: size2 = DEFAULT_SIZE7, invalid: invalid2 }) => ({
2319
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE9, invalid: invalid2 }) => ({
1155
2320
  "data-size": size2,
1156
2321
  "data-invalid": invalid2 ? "" : void 0
1157
2322
  })
1158
2323
  });
1159
- const { size = DEFAULT_SIZE7, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH, children, ref, ...sparProps } = rest;
2324
+ const { size = DEFAULT_SIZE9, invalid = false, contentWidth = DEFAULT_CONTENT_WIDTH, children, ref, ...sparProps } = rest;
1160
2325
  return /* @__PURE__ */ jsxRuntime.jsx(SelectProvider, { value: { size, invalid, contentWidth }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Select, { ...sparProps, ref, ...rootAttrs, children }) });
1161
2326
  };
1162
2327
  Select.displayName = "Select";
@@ -1169,10 +2334,44 @@ var SelectTrigger = (props) => {
1169
2334
  "data-invalid": invalid ? "" : void 0
1170
2335
  })
1171
2336
  });
1172
- const { children, ref, ...spar$1 } = rest;
1173
- return /* @__PURE__ */ jsxRuntime.jsx(spar.SelectTrigger, { ...spar$1, ref, ...rootAttrs, children });
2337
+ const { children, indicator, ref, ...spar$1 } = rest;
2338
+ const showIndicator = indicator !== false && indicator !== null;
2339
+ const consumerOwnsLayout = typeof children === "function";
2340
+ if (!showIndicator || consumerOwnsLayout) {
2341
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.SelectTrigger, { ...spar$1, ref, ...rootAttrs, children });
2342
+ }
2343
+ const resolveIndicatorNode = (state) => {
2344
+ if (indicator === void 0 || indicator === true) return state.isOpen ? DEFAULT_DISCLOSURE_COLLAPSE_ICON : DEFAULT_DISCLOSURE_EXPAND_ICON;
2345
+ if (typeof indicator === "function") return indicator(state);
2346
+ return indicator;
2347
+ };
2348
+ const slotLayers = {
2349
+ themeSlotProps: theme?.slotProps,
2350
+ themeClassNames: theme?.classNames,
2351
+ instanceSlotProps: props.slotProps,
2352
+ instanceClassNames: props.classNames
2353
+ };
2354
+ const valueAttrs = buildSlotAttrs(SelectTriggerBase.getSlotProps("value"), "value", slotLayers);
2355
+ const indicatorAttrs = buildSlotAttrs(SelectTriggerBase.getSlotProps("indicator"), "indicator", slotLayers);
2356
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.SelectTrigger, { ...spar$1, ref, ...rootAttrs, children: (state) => {
2357
+ const value = children ?? (state.label || spar$1.placeholder);
2358
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2359
+ /* @__PURE__ */ jsxRuntime.jsx("span", { ...valueAttrs, children: value }),
2360
+ /* @__PURE__ */ jsxRuntime.jsx("span", { ...indicatorAttrs, "aria-hidden": "true", children: resolveIndicatorNode({ isOpen: state.isOpen }) })
2361
+ ] });
2362
+ } });
1174
2363
  };
1175
2364
  SelectTrigger.displayName = "Select.Trigger";
2365
+ var SelectIndicator = (props) => {
2366
+ const theme = useComponentTheme("SelectIndicator");
2367
+ const { isOpen } = spar.useSelectContext();
2368
+ const Component = props.as ?? "span";
2369
+ const { rootAttrs, rest } = composeRootAttrs(SelectIndicatorBase, props, theme);
2370
+ const { as: _as, children, ref, ...rendered } = rest;
2371
+ const resolved = resolveDisclosureIndicator(children, isOpen);
2372
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...rendered, ref, "aria-hidden": "true", ...rootAttrs, children: resolved });
2373
+ };
2374
+ SelectIndicator.displayName = "Select.Indicator";
1176
2375
  var resolveStaticWidth = (mode) => {
1177
2376
  if (mode === "trigger" || mode === "content") return void 0;
1178
2377
  return typeof mode === "number" ? `${mode}px` : mode;
@@ -1243,6 +2442,7 @@ SelectSeparator.displayName = "Select.Separator";
1243
2442
  // src/components/select/index.ts
1244
2443
  var Select2 = Object.assign(Select, {
1245
2444
  Trigger: SelectTrigger,
2445
+ Indicator: SelectIndicator,
1246
2446
  Content: SelectContent,
1247
2447
  Item: SelectItem,
1248
2448
  Group: SelectGroup,
@@ -1250,6 +2450,79 @@ var Select2 = Object.assign(Select, {
1250
2450
  Separator: SelectSeparator
1251
2451
  });
1252
2452
 
2453
+ // src/components/spinner/base.ts
2454
+ var SpinnerBase = createComponentBase({
2455
+ name: "Spinner",
2456
+ slots: ["root", "indicator"],
2457
+ classes: {
2458
+ root: "tk-spinner",
2459
+ indicator: "tk-spinner-indicator"
2460
+ }
2461
+ });
2462
+
2463
+ // src/components/spinner/defaults.ts
2464
+ var DEFAULT_APPEARANCE5 = "rounded";
2465
+ var DEFAULT_SIZE10 = "base";
2466
+ var DEFAULT_VARIANT6 = "neutral";
2467
+ var DEFAULT_ARIA_LABEL = "Loading";
2468
+ var SPINNER_RADIAL_PARTS = 8;
2469
+ var SPINNER_THREE_DOT_PARTS = 3;
2470
+ var renderIndicatorContent = (appearance) => {
2471
+ if (appearance === "rounded") {
2472
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2473
+ /* @__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" }) }),
2474
+ /* @__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" }) })
2475
+ ] });
2476
+ }
2477
+ if (appearance === "loader") {
2478
+ 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" }) });
2479
+ }
2480
+ if (appearance === "dots") {
2481
+ return Array.from({ length: SPINNER_RADIAL_PARTS }, (_, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tk-spinner-dot" }, index));
2482
+ }
2483
+ if (appearance === "lines") {
2484
+ return Array.from({ length: SPINNER_RADIAL_PARTS }, (_, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tk-spinner-line" }, index));
2485
+ }
2486
+ if (appearance === "threeDots") {
2487
+ return Array.from({ length: SPINNER_THREE_DOT_PARTS }, (_, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tk-spinner-dot" }, index));
2488
+ }
2489
+ if (appearance === "logo") {
2490
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", focusable: "false", viewBox: "0 0 48 48", children: /* @__PURE__ */ jsxRuntime.jsx(
2491
+ "path",
2492
+ {
2493
+ clipRule: "evenodd",
2494
+ 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",
2495
+ fillRule: "evenodd"
2496
+ }
2497
+ ) });
2498
+ }
2499
+ return null;
2500
+ };
2501
+ var Spinner = (props) => {
2502
+ const theme = useComponentTheme("Spinner");
2503
+ const { rootAttrs, rest } = composeRootAttrs(SpinnerBase, props, theme, {
2504
+ stateAttrs: ({ variant = DEFAULT_VARIANT6, size = DEFAULT_SIZE10, appearance: appearance2 = DEFAULT_APPEARANCE5 }) => ({
2505
+ "data-variant": variant,
2506
+ "data-size": size,
2507
+ "data-type": appearance2
2508
+ })
2509
+ });
2510
+ const { variant: _variant, size: _size, appearance = DEFAULT_APPEARANCE5, ref, ...nativeProps } = rest;
2511
+ const indicatorSlotAttrs = buildSlotAttrs(SpinnerBase.getSlotProps("indicator"), "indicator", {
2512
+ themeSlotProps: theme?.slotProps,
2513
+ themeClassNames: theme?.classNames,
2514
+ instanceSlotProps: props.slotProps,
2515
+ instanceClassNames: props.classNames
2516
+ });
2517
+ const isDecorative = nativeProps["aria-hidden"] === true || nativeProps["aria-hidden"] === "true";
2518
+ const accessibilityAttrs = isDecorative ? {} : {
2519
+ "role": nativeProps.role ?? "status",
2520
+ "aria-label": nativeProps["aria-label"] ?? (nativeProps["aria-labelledby"] ? void 0 : DEFAULT_ARIA_LABEL)
2521
+ };
2522
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ...accessibilityAttrs, ...nativeProps, ...rootAttrs, ref, children: /* @__PURE__ */ jsxRuntime.jsx("span", { ...indicatorSlotAttrs, "aria-hidden": "true", children: renderIndicatorContent(appearance) }) });
2523
+ };
2524
+ Spinner.displayName = "Spinner";
2525
+
1253
2526
  // src/components/switch/base.ts
1254
2527
  var SwitchBase = createComponentBase({
1255
2528
  name: "Switch",
@@ -1267,12 +2540,12 @@ var SwitchBase = createComponentBase({
1267
2540
  var [SwitchProvider, useSwitchOwnContext] = createSafeContext("SwitchProvider");
1268
2541
 
1269
2542
  // src/components/switch/defaults.ts
1270
- var DEFAULT_SIZE8 = "base";
1271
- var DEFAULT_VARIANT4 = "info";
2543
+ var DEFAULT_SIZE11 = "base";
2544
+ var DEFAULT_VARIANT7 = "info";
1272
2545
  var Switch = (props) => {
1273
2546
  const theme = useComponentTheme("Switch");
1274
2547
  const { rootAttrs, rest } = composeRootAttrs(SwitchBase, props, theme, {
1275
- stateAttrs: ({ size = DEFAULT_SIZE8, variant = DEFAULT_VARIANT4 }) => ({
2548
+ stateAttrs: ({ size = DEFAULT_SIZE11, variant = DEFAULT_VARIANT7 }) => ({
1276
2549
  "data-size": size,
1277
2550
  "data-variant": variant
1278
2551
  })
@@ -1289,28 +2562,19 @@ var Switch = (props) => {
1289
2562
  ref,
1290
2563
  ...sparProps
1291
2564
  } = rest;
1292
- return /* @__PURE__ */ jsxRuntime.jsx(
1293
- spar.Switch,
2565
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.Switch, { ...sparProps, invalid, ref, ...rootAttrs, children: (state) => /* @__PURE__ */ jsxRuntime.jsx(
2566
+ SwitchProvider,
1294
2567
  {
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
- )
2568
+ value: {
2569
+ classNames,
2570
+ slotProps,
2571
+ checked: state.checked,
2572
+ disabled: state.disabled,
2573
+ readOnly: state.readOnly
2574
+ },
2575
+ children: typeof children === "function" ? children(state) : children
1312
2576
  }
1313
- );
2577
+ ) });
1314
2578
  };
1315
2579
  Switch.displayName = "Switch";
1316
2580
  var SwitchIndicator = (props) => {
@@ -1338,6 +2602,870 @@ SwitchIndicator.displayName = "Switch.Indicator";
1338
2602
  var Switch2 = Object.assign(Switch, {
1339
2603
  Indicator: SwitchIndicator
1340
2604
  });
2605
+
2606
+ // src/components/table/base.ts
2607
+ var TableBase = createComponentBase({
2608
+ name: "Table",
2609
+ slots: [
2610
+ "root",
2611
+ "tableViewport",
2612
+ "table",
2613
+ "header",
2614
+ "headerRow",
2615
+ "headerCell",
2616
+ "headerContent",
2617
+ "sortTrigger",
2618
+ "sortIcon",
2619
+ "body",
2620
+ "row",
2621
+ "cell",
2622
+ "selectionCell",
2623
+ "expandCell",
2624
+ "expandButton",
2625
+ "expandedRow",
2626
+ "filterButton",
2627
+ "filterPanel",
2628
+ "pagination",
2629
+ "paginationInfo",
2630
+ "paginationNav",
2631
+ "paginationActions",
2632
+ "paginationSize",
2633
+ "paginationGoToPage",
2634
+ "empty",
2635
+ "loading"
2636
+ ],
2637
+ classes: {
2638
+ root: "tk-table",
2639
+ tableViewport: "tk-table-viewport",
2640
+ table: "tk-table-table",
2641
+ header: "tk-table-header",
2642
+ headerRow: "tk-table-header-row",
2643
+ headerCell: "tk-table-header-cell",
2644
+ headerContent: "tk-table-header-content",
2645
+ sortTrigger: "tk-table-sort-trigger",
2646
+ sortIcon: "tk-table-sort-icon",
2647
+ body: "tk-table-body",
2648
+ row: "tk-table-row",
2649
+ cell: "tk-table-cell",
2650
+ selectionCell: "tk-table-selection-cell",
2651
+ expandCell: "tk-table-expand-cell",
2652
+ expandButton: "tk-table-expand-button",
2653
+ expandedRow: "tk-table-expanded-row",
2654
+ filterButton: "tk-table-filter-button",
2655
+ filterPanel: "tk-table-filter-panel-body",
2656
+ pagination: "tk-table-pagination",
2657
+ paginationInfo: "tk-table-pagination-info",
2658
+ paginationNav: "tk-table-pagination-nav",
2659
+ paginationActions: "tk-table-pagination-actions",
2660
+ paginationSize: "tk-table-pagination-size",
2661
+ paginationGoToPage: "tk-table-pagination-go-to-page",
2662
+ empty: "tk-table-empty",
2663
+ loading: "tk-table-loading"
2664
+ }
2665
+ });
2666
+
2667
+ // src/components/table/context.ts
2668
+ var [TableProvider, useTableContext] = createSafeContext("Table");
2669
+
2670
+ // src/components/table/defaults.ts
2671
+ var DEFAULT_SIZE12 = "base";
2672
+ var DEFAULT_PAGE_SIZE = 10;
2673
+ var DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
2674
+ var DEFAULT_COLUMN_WIDTH = 150;
2675
+ var UTILITY_COLUMN_WIDTH = 48;
2676
+ var SELECTION_COLUMN_KEY = "__tk_selection__";
2677
+ var EXPAND_COLUMN_KEY = "__tk_expand__";
2678
+ var toRenderableValue = (value, columnId) => {
2679
+ if (value == null || typeof value !== "object" || react.isValidElement(value)) return value;
2680
+ if (isDevelopment()) {
2681
+ console.error(
2682
+ `[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.`
2683
+ );
2684
+ }
2685
+ try {
2686
+ return JSON.stringify(value);
2687
+ } catch {
2688
+ return String(value);
2689
+ }
2690
+ };
2691
+ var defaultCell = (ctx) => toRenderableValue(ctx.getValue(), ctx.column.id);
2692
+ var isEmptyFilterValue = (value) => value == null || value === "" || Array.isArray(value) && value.length === 0;
2693
+ var substringFilterFn = (row, columnId, filterValue) => {
2694
+ if (isEmptyFilterValue(filterValue)) return true;
2695
+ return String(row.getValue(columnId)).toLowerCase().includes(String(filterValue).toLowerCase());
2696
+ };
2697
+ substringFilterFn.autoRemove = isEmptyFilterValue;
2698
+ var equalsFilterFn = (row, columnId, filterValue) => {
2699
+ if (isEmptyFilterValue(filterValue)) return true;
2700
+ return String(row.getValue(columnId)) === String(filterValue);
2701
+ };
2702
+ equalsFilterFn.autoRemove = isEmptyFilterValue;
2703
+ var membershipFilterFn = (row, columnId, filterValue) => {
2704
+ if (!Array.isArray(filterValue) || filterValue.length === 0) return true;
2705
+ return filterValue.map(String).includes(String(row.getValue(columnId)));
2706
+ };
2707
+ membershipFilterFn.autoRemove = (value) => !Array.isArray(value) || value.length === 0;
2708
+ var PRESET_FILTER_FN = {
2709
+ "text": substringFilterFn,
2710
+ "select": equalsFilterFn,
2711
+ "radio": equalsFilterFn,
2712
+ "multi-select": membershipFilterFn,
2713
+ "checkbox": membershipFilterFn
2714
+ };
2715
+ var defaultFilterFn = (row, columnId, filterValue) => {
2716
+ if (isEmptyFilterValue(filterValue)) return true;
2717
+ const cell = row.getValue(columnId);
2718
+ if (typeof filterValue === "string") return String(cell).toLowerCase().includes(filterValue.toLowerCase());
2719
+ if (Array.isArray(filterValue)) return filterValue.map(String).includes(String(cell));
2720
+ return String(cell) === String(filterValue);
2721
+ };
2722
+ defaultFilterFn.autoRemove = isEmptyFilterValue;
2723
+ var normalizeColumnFilter = (filter) => {
2724
+ if (filter == null) return void 0;
2725
+ return typeof filter === "string" ? { type: filter } : filter;
2726
+ };
2727
+ var resolveFilterFn = (filter) => {
2728
+ if (filter.filterFn) return filter.filterFn;
2729
+ if (filter.render == null && filter.type) return PRESET_FILTER_FN[filter.type];
2730
+ return defaultFilterFn;
2731
+ };
2732
+ var toTanStackColumns = (columns) => columns.map((col) => {
2733
+ const { id, header, accessor, cell, sortable, filter, sticky, width, align, meta } = col;
2734
+ const normalizedFilter = normalizeColumnFilter(filter);
2735
+ const def = {
2736
+ id,
2737
+ header,
2738
+ enableSorting: sortable ?? false,
2739
+ enableColumnFilter: normalizedFilter != null,
2740
+ meta: {
2741
+ align,
2742
+ sticky,
2743
+ width,
2744
+ className: meta?.className,
2745
+ headerClassName: meta?.headerClassName,
2746
+ headerAlign: meta?.headerAlign,
2747
+ filter: normalizedFilter
2748
+ }
2749
+ };
2750
+ def.cell = cell ?? defaultCell;
2751
+ if (width != null) def.size = width;
2752
+ if (typeof accessor === "function") {
2753
+ def.accessorFn = accessor;
2754
+ } else if (accessor != null) {
2755
+ def.accessorKey = accessor;
2756
+ }
2757
+ if (normalizedFilter) {
2758
+ def.filterFn = resolveFilterFn(normalizedFilter);
2759
+ }
2760
+ return def;
2761
+ });
2762
+ var computeStickyLayout = (ordered) => {
2763
+ const layout = /* @__PURE__ */ new Map();
2764
+ if (isDevelopment()) warnNonContiguousPinning(ordered);
2765
+ let leftOffset = 0;
2766
+ for (const column of ordered) {
2767
+ if (column.side === "left") {
2768
+ layout.set(column.key, { side: "left", offset: leftOffset });
2769
+ leftOffset += column.width;
2770
+ }
2771
+ }
2772
+ let rightOffset = 0;
2773
+ for (let i = ordered.length - 1; i >= 0; i -= 1) {
2774
+ const column = ordered[i];
2775
+ if (column?.side === "right") {
2776
+ layout.set(column.key, { side: "right", offset: rightOffset });
2777
+ rightOffset += column.width;
2778
+ }
2779
+ }
2780
+ return layout;
2781
+ };
2782
+ var warnNonContiguousPinning = (ordered) => {
2783
+ let seenNonLeft = false;
2784
+ for (const column of ordered) {
2785
+ if (column.side === "left") {
2786
+ if (seenNonLeft) return warnPinning("left");
2787
+ } else {
2788
+ seenNonLeft = true;
2789
+ }
2790
+ }
2791
+ let seenNonRight = false;
2792
+ for (let i = ordered.length - 1; i >= 0; i -= 1) {
2793
+ const column = ordered[i];
2794
+ if (column?.side === "right") {
2795
+ if (seenNonRight) return warnPinning("right");
2796
+ } else {
2797
+ seenNonRight = true;
2798
+ }
2799
+ }
2800
+ };
2801
+ var warnPinning = (side) => {
2802
+ console.error(
2803
+ `[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.`
2804
+ );
2805
+ };
2806
+ var buildOrderedColumns = (table, options) => {
2807
+ const leaf = table.getVisibleLeafColumns();
2808
+ const hasLeftPinned = leaf.some((column) => column.columnDef.meta?.sticky === "left");
2809
+ const utilitySide = hasLeftPinned ? "left" : void 0;
2810
+ const ordered = [];
2811
+ if (options.hasSelection) ordered.push({ key: SELECTION_COLUMN_KEY, side: utilitySide, width: UTILITY_COLUMN_WIDTH });
2812
+ if (options.hasExpansion) ordered.push({ key: EXPAND_COLUMN_KEY, side: utilitySide, width: UTILITY_COLUMN_WIDTH });
2813
+ for (const column of leaf) {
2814
+ ordered.push({
2815
+ key: column.id,
2816
+ side: column.columnDef.meta?.sticky,
2817
+ width: column.getSize() || DEFAULT_COLUMN_WIDTH
2818
+ });
2819
+ }
2820
+ return ordered;
2821
+ };
2822
+ var getExportRows = (table) => {
2823
+ if (!table) return [];
2824
+ const columns = table.getAllLeafColumns();
2825
+ return table.getSortedRowModel().rows.map((row) => {
2826
+ const record = {};
2827
+ for (const column of columns) {
2828
+ if (column.accessorFn || column.columnDef.accessorKey != null) {
2829
+ record[column.id] = row.getValue(column.id);
2830
+ }
2831
+ }
2832
+ return record;
2833
+ });
2834
+ };
2835
+ var resolveStickyCell = (layout, key, options) => {
2836
+ const placement = layout.get(key);
2837
+ const isStickyColumn = !!placement;
2838
+ const stickyHeaderActive = options.isHeader && options.stickyHeader;
2839
+ if (!isStickyColumn && !stickyHeaderActive) return {};
2840
+ const style = { position: "sticky" };
2841
+ if (placement) {
2842
+ if (placement.side === "left") style.left = placement.offset;
2843
+ else style.right = placement.offset;
2844
+ }
2845
+ if (stickyHeaderActive) style.top = 0;
2846
+ style.zIndex = isStickyColumn && stickyHeaderActive ? 3 : stickyHeaderActive ? 2 : 1;
2847
+ return { style, dataSticky: placement?.side };
2848
+ };
2849
+ var resolveCellWidth = (column, stickyLayout) => {
2850
+ const hasWidth = column.columnDef.meta?.width != null || stickyLayout.has(column.id);
2851
+ return hasWidth ? { width: column.getSize() } : void 0;
2852
+ };
2853
+ var TableCell = ({ cell }) => {
2854
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.Cell");
2855
+ const column = cell.column;
2856
+ const meta = column.columnDef.meta;
2857
+ const sticky = resolveStickyCell(stickyLayout, column.id, { isHeader: false, stickyHeader });
2858
+ const attrs = slotAttrs("cell", { className: meta?.className });
2859
+ const content = reactTable.flexRender(column.columnDef.cell, cell.getContext());
2860
+ return /* @__PURE__ */ jsxRuntime.jsx("td", { ...attrs, "data-align": meta?.align, "data-sticky": sticky.dataSticky, style: { ...attrs.style, ...sticky.style, ...resolveCellWidth(column, stickyLayout) }, children: content });
2861
+ };
2862
+ TableCell.displayName = "Table.Cell";
2863
+ var mergeStyle = (...styles) => Object.assign({}, ...styles);
2864
+ var SelectionHeaderCell = () => {
2865
+ const { table, slotAttrs, selectionMode, stickyLayout, stickyHeader } = useTableContext("Table.SelectionHeaderCell");
2866
+ const sticky = resolveStickyCell(stickyLayout, SELECTION_COLUMN_KEY, { isHeader: true, stickyHeader });
2867
+ const attrs = slotAttrs("selectionCell");
2868
+ const allSelected = table.getIsAllPageRowsSelected();
2869
+ 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(
2870
+ Checkbox2,
2871
+ {
2872
+ "aria-label": "Select all rows",
2873
+ checked: allSelected,
2874
+ indeterminate: table.getIsSomePageRowsSelected() && !allSelected,
2875
+ onChange: (checked) => table.toggleAllPageRowsSelected(checked),
2876
+ children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox2.Indicator, {})
2877
+ }
2878
+ ) });
2879
+ };
2880
+ SelectionHeaderCell.displayName = "Table.SelectionHeaderCell";
2881
+ var SelectionBodyCell = ({ row }) => {
2882
+ const { slotAttrs, selectionMode, stickyLayout, stickyHeader } = useTableContext("Table.SelectionBodyCell");
2883
+ const sticky = resolveStickyCell(stickyLayout, SELECTION_COLUMN_KEY, { isHeader: false, stickyHeader });
2884
+ const attrs = slotAttrs("selectionCell");
2885
+ 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, {}) }) });
2886
+ };
2887
+ SelectionBodyCell.displayName = "Table.SelectionBodyCell";
2888
+ var ExpandHeaderCell = () => {
2889
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.ExpandHeaderCell");
2890
+ const sticky = resolveStickyCell(stickyLayout, EXPAND_COLUMN_KEY, { isHeader: true, stickyHeader });
2891
+ const attrs = slotAttrs("expandCell");
2892
+ return /* @__PURE__ */ jsxRuntime.jsx("th", { ...attrs, scope: "col", "data-sticky": sticky.dataSticky, style: mergeStyle(attrs.style, sticky.style, { width: UTILITY_COLUMN_WIDTH }) });
2893
+ };
2894
+ ExpandHeaderCell.displayName = "Table.ExpandHeaderCell";
2895
+ var ExpandBodyCell = ({ row }) => {
2896
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.ExpandBodyCell");
2897
+ const sticky = resolveStickyCell(stickyLayout, EXPAND_COLUMN_KEY, { isHeader: false, stickyHeader });
2898
+ const attrs = slotAttrs("expandCell");
2899
+ const expanded = row.getIsExpanded();
2900
+ 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(
2901
+ "button",
2902
+ {
2903
+ ...slotAttrs("expandButton"),
2904
+ type: "button",
2905
+ "aria-label": expanded ? "Collapse row" : "Expand row",
2906
+ "aria-expanded": expanded,
2907
+ onClick: row.getToggleExpandedHandler(),
2908
+ children: expanded ? /* @__PURE__ */ jsxRuntime.jsx(chevronBottom.ChevronBottomIconOutlinedRounded, {}) : /* @__PURE__ */ jsxRuntime.jsx(chevronRight.ChevronRightIconOutlinedRounded, {})
2909
+ }
2910
+ ) });
2911
+ };
2912
+ ExpandBodyCell.displayName = "Table.ExpandBodyCell";
2913
+ var TableRow = ({ row }) => {
2914
+ const { slotAttrs, hasSelection, hasExpansion, treeMode, expansionRender, totalColumnCount } = useTableContext("Table.Row");
2915
+ const selected = row.getIsSelected();
2916
+ const showDetailPanel = hasExpansion && !treeMode && !!expansionRender && row.getIsExpanded();
2917
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
2918
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { ...slotAttrs("row"), "data-selected": selected ? "" : void 0, children: [
2919
+ hasSelection && /* @__PURE__ */ jsxRuntime.jsx(SelectionBodyCell, { row }),
2920
+ hasExpansion && /* @__PURE__ */ jsxRuntime.jsx(ExpandBodyCell, { row }),
2921
+ row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(TableCell, { cell }, cell.id))
2922
+ ] }),
2923
+ showDetailPanel && /* @__PURE__ */ jsxRuntime.jsx("tr", { ...slotAttrs("expandedRow"), children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColumnCount, children: expansionRender(row.original) }) })
2924
+ ] });
2925
+ };
2926
+ TableRow.displayName = "Table.Row";
2927
+ var TableBody = () => {
2928
+ const { table, slotAttrs, totalColumnCount, emptyState, loading } = useTableContext("Table.Body");
2929
+ const rows = table.getRowModel().rows;
2930
+ 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)) });
2931
+ };
2932
+ TableBody.displayName = "Table.Body";
2933
+ var FILTER_BUTTON_CLASS = TableBase.getSlotProps("filterButton").className;
2934
+ var defaultIsActive = (value) => !isEmptyFilterValue(value);
2935
+ var TableColumnFilter = ({ header }) => {
2936
+ const { slotAttrs } = useTableContext("Table.ColumnFilter");
2937
+ const [open, setOpen] = react.useState(false);
2938
+ const column = header.column;
2939
+ const filter = column.columnDef.meta?.filter;
2940
+ if (!filter) return null;
2941
+ const value = column.getFilterValue();
2942
+ const active = (filter.isActive ?? defaultIsActive)(value);
2943
+ const ctx = {
2944
+ value,
2945
+ setValue: (next) => column.setFilterValue(next),
2946
+ clear: () => column.setFilterValue(void 0),
2947
+ column,
2948
+ close: () => setOpen(false)
2949
+ };
2950
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover2, { open, onOpenChange: setOpen, children: [
2951
+ /* @__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" }) }),
2952
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover2.Content, { className: "tk-table-filter-panel", children: [
2953
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...slotAttrs("filterPanel"), children: filter.render ? filter.render(ctx) : /* @__PURE__ */ jsxRuntime.jsx(PresetFilterControl, { filter, ctx }) }),
2954
+ active && /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "small", appearance: "text", onClick: ctx.clear, children: "Clear" })
2955
+ ] })
2956
+ ] });
2957
+ };
2958
+ TableColumnFilter.displayName = "Table.ColumnFilter";
2959
+ var PresetFilterControl = ({ filter, ctx }) => {
2960
+ const { type, options = [], placeholder } = filter;
2961
+ const { value, setValue } = ctx;
2962
+ if (type === "text") {
2963
+ return /* @__PURE__ */ jsxRuntime.jsx(Input2, { children: /* @__PURE__ */ jsxRuntime.jsx(
2964
+ Input2.Field,
2965
+ {
2966
+ type: "search",
2967
+ placeholder,
2968
+ value: typeof value === "string" ? value : "",
2969
+ onChange: (event) => setValue(event.target.value || void 0)
2970
+ }
2971
+ ) });
2972
+ }
2973
+ if (type === "select") {
2974
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectFilter, { options, placeholder, value: typeof value === "string" ? value : "", onChange: (next) => setValue(next || void 0) });
2975
+ }
2976
+ if (type === "radio") {
2977
+ 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)) });
2978
+ }
2979
+ if (type === "checkbox" || type === "multi-select") {
2980
+ return /* @__PURE__ */ jsxRuntime.jsx(CheckboxListFilter, { options, value: Array.isArray(value) ? value : [], onChange: setValue });
2981
+ }
2982
+ return null;
2983
+ };
2984
+ PresetFilterControl.displayName = "Table.PresetFilterControl";
2985
+ var SelectFilter = ({
2986
+ options,
2987
+ placeholder,
2988
+ value,
2989
+ onChange
2990
+ }) => {
2991
+ const selected = options.find((option) => option.value === value);
2992
+ return /* @__PURE__ */ jsxRuntime.jsxs(Select2, { value, onChange, children: [
2993
+ /* @__PURE__ */ jsxRuntime.jsx(Select2.Trigger, { children: selected ? selected.label : placeholder ?? "Select" }),
2994
+ /* @__PURE__ */ jsxRuntime.jsx(Select2.Content, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(Select2.Item, { value: option.value, children: option.label }, option.value)) })
2995
+ ] });
2996
+ };
2997
+ var CheckboxListFilter = ({ options, value, onChange }) => /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map((option) => {
2998
+ const checked = value.includes(option.value);
2999
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3000
+ Checkbox2,
3001
+ {
3002
+ checked,
3003
+ onChange: (next) => {
3004
+ const updated = next ? [...value, option.value] : value.filter((item) => item !== option.value);
3005
+ onChange(updated.length ? updated : void 0);
3006
+ },
3007
+ children: [
3008
+ /* @__PURE__ */ jsxRuntime.jsx(Checkbox2.Indicator, {}),
3009
+ option.label
3010
+ ]
3011
+ },
3012
+ option.value
3013
+ );
3014
+ }) });
3015
+ var TableHeaderCell = ({ header }) => {
3016
+ const { slotAttrs, stickyLayout, stickyHeader } = useTableContext("Table.HeaderCell");
3017
+ const column = header.column;
3018
+ const meta = column.columnDef.meta;
3019
+ const align = meta?.headerAlign ?? meta?.align;
3020
+ const canSort = column.getCanSort();
3021
+ const canFilter = column.getCanFilter() && !!meta?.filter;
3022
+ const sorted = column.getIsSorted();
3023
+ const sticky = resolveStickyCell(stickyLayout, column.id, { isHeader: true, stickyHeader });
3024
+ const attrs = slotAttrs("headerCell", { className: meta?.headerClassName });
3025
+ const ariaSort = canSort ? sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none" : void 0;
3026
+ const content = header.isPlaceholder ? null : reactTable.flexRender(column.columnDef.header, header.getContext());
3027
+ return /* @__PURE__ */ jsxRuntime.jsx(
3028
+ "th",
3029
+ {
3030
+ ...attrs,
3031
+ scope: "col",
3032
+ colSpan: header.colSpan,
3033
+ "aria-sort": ariaSort,
3034
+ "data-align": align,
3035
+ "data-sticky": sticky.dataSticky,
3036
+ "data-sortable": canSort ? "" : void 0,
3037
+ style: { ...attrs.style, ...sticky.style, ...resolveCellWidth(column, stickyLayout) },
3038
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ...slotAttrs("headerContent"), children: [
3039
+ canSort ? /* @__PURE__ */ jsxRuntime.jsxs("button", { ...slotAttrs("sortTrigger"), type: "button", onClick: column.getToggleSortingHandler(), children: [
3040
+ content,
3041
+ /* @__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, {}) })
3042
+ ] }) : content,
3043
+ canFilter && /* @__PURE__ */ jsxRuntime.jsx(TableColumnFilter, { header })
3044
+ ] })
3045
+ }
3046
+ );
3047
+ };
3048
+ TableHeaderCell.displayName = "Table.HeaderCell";
3049
+ var TableHeader = () => {
3050
+ const { table, slotAttrs, hasSelection, hasExpansion } = useTableContext("Table.Header");
3051
+ return /* @__PURE__ */ jsxRuntime.jsx("thead", { ...slotAttrs("header"), children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { ...slotAttrs("headerRow"), children: [
3052
+ hasSelection && /* @__PURE__ */ jsxRuntime.jsx(SelectionHeaderCell, {}),
3053
+ hasExpansion && /* @__PURE__ */ jsxRuntime.jsx(ExpandHeaderCell, {}),
3054
+ headerGroup.headers.map((header) => /* @__PURE__ */ jsxRuntime.jsx(TableHeaderCell, { header }, header.id))
3055
+ ] }, headerGroup.id)) });
3056
+ };
3057
+ TableHeader.displayName = "Table.Header";
3058
+ var getPaginationItems = (pageIndex, pageCount) => {
3059
+ if (pageCount <= 7) return Array.from({ length: pageCount }, (_, index) => index);
3060
+ if (pageIndex <= 3) return [0, 1, 2, 3, 4, "end-ellipsis", pageCount - 1];
3061
+ if (pageIndex >= pageCount - 4) return [0, "start-ellipsis", pageCount - 5, pageCount - 4, pageCount - 3, pageCount - 2, pageCount - 1];
3062
+ return [0, "start-ellipsis", pageIndex - 1, pageIndex, pageIndex + 1, "end-ellipsis", pageCount - 1];
3063
+ };
3064
+ var TablePagination = () => {
3065
+ const { table, slotAttrs, pageSizeOptions } = useTableContext("Table.Pagination");
3066
+ const { pageIndex, pageSize } = table.getState().pagination;
3067
+ const pageCount = table.getPageCount();
3068
+ const paginationItems = getPaginationItems(pageIndex, pageCount);
3069
+ const [pageInput, setPageInput] = react.useState("");
3070
+ const totalRows = table.getRowCount();
3071
+ const startItem = pageIndex * pageSize + 1;
3072
+ const endItem = Math.min((pageIndex + 1) * pageSize, totalRows);
3073
+ const itemsLabel = totalRows === 0 ? "0 items" : `Items ${startItem}-${endItem} of ${totalRows}`;
3074
+ const sizeOptions = pageSizeOptions.includes(pageSize) ? pageSizeOptions : [...pageSizeOptions, pageSize].sort((a, b) => a - b);
3075
+ const goToPage = () => {
3076
+ const requestedPage = Number(pageInput);
3077
+ if (!Number.isFinite(requestedPage) || pageCount <= 0 || pageInput === "") return;
3078
+ const targetPage = Math.min(Math.max(Math.trunc(requestedPage), 1), pageCount);
3079
+ table.setPageIndex(targetPage - 1);
3080
+ setPageInput("");
3081
+ };
3082
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...slotAttrs("pagination"), role: "navigation", "aria-label": "Pagination", children: [
3083
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ...slotAttrs("paginationInfo"), children: [
3084
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", children: pageCount > 0 ? `Page ${pageIndex + 1} of ${pageCount}` : `Page ${pageIndex + 1}` }),
3085
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-live": "polite", children: itemsLabel })
3086
+ ] }),
3087
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ...slotAttrs("paginationNav"), children: [
3088
+ /* @__PURE__ */ jsxRuntime.jsx(
3089
+ Button,
3090
+ {
3091
+ size: "small",
3092
+ variant: "neutral",
3093
+ appearance: "text",
3094
+ "aria-label": "First page",
3095
+ startContent: /* @__PURE__ */ jsxRuntime.jsx(arrowLeft.ArrowLeftIconOutlinedRounded, {}),
3096
+ disabled: !table.getCanPreviousPage(),
3097
+ onClick: () => table.setPageIndex(0)
3098
+ }
3099
+ ),
3100
+ /* @__PURE__ */ jsxRuntime.jsx(
3101
+ Button,
3102
+ {
3103
+ size: "small",
3104
+ variant: "neutral",
3105
+ appearance: "text",
3106
+ "aria-label": "Previous page",
3107
+ startContent: /* @__PURE__ */ jsxRuntime.jsx(chevronLeft.ChevronLeftIconOutlinedRounded, {}),
3108
+ disabled: !table.getCanPreviousPage(),
3109
+ onClick: () => table.previousPage()
3110
+ }
3111
+ ),
3112
+ paginationItems.map((item) => {
3113
+ if (typeof item !== "number") {
3114
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u2026" }, item);
3115
+ }
3116
+ const pageNumber = item + 1;
3117
+ const current = item === pageIndex;
3118
+ return /* @__PURE__ */ jsxRuntime.jsx(
3119
+ Button,
3120
+ {
3121
+ type: "button",
3122
+ size: "small",
3123
+ variant: "neutral",
3124
+ appearance: current ? "outlined" : "text",
3125
+ "aria-label": current ? `Page ${pageNumber}, current page` : `Go to page ${pageNumber}`,
3126
+ "aria-current": current ? "page" : void 0,
3127
+ onClick: () => table.setPageIndex(item),
3128
+ children: pageNumber
3129
+ },
3130
+ item
3131
+ );
3132
+ }),
3133
+ /* @__PURE__ */ jsxRuntime.jsx(
3134
+ Button,
3135
+ {
3136
+ size: "small",
3137
+ variant: "neutral",
3138
+ appearance: "text",
3139
+ "aria-label": "Next page",
3140
+ startContent: /* @__PURE__ */ jsxRuntime.jsx(chevronRight.ChevronRightIconOutlinedRounded, {}),
3141
+ disabled: !table.getCanNextPage() || pageCount <= 0,
3142
+ onClick: () => table.nextPage()
3143
+ }
3144
+ ),
3145
+ /* @__PURE__ */ jsxRuntime.jsx(
3146
+ Button,
3147
+ {
3148
+ size: "small",
3149
+ variant: "neutral",
3150
+ appearance: "text",
3151
+ "aria-label": "Last page",
3152
+ startContent: /* @__PURE__ */ jsxRuntime.jsx(arrowRight.ArrowRightIconOutlinedRounded, {}),
3153
+ disabled: !table.getCanNextPage() || pageCount <= 0,
3154
+ onClick: () => table.setPageIndex(pageCount - 1)
3155
+ }
3156
+ )
3157
+ ] }),
3158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ...slotAttrs("paginationActions"), children: [
3159
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...slotAttrs("paginationSize"), children: /* @__PURE__ */ jsxRuntime.jsxs(Select2, { size: "small", value: String(pageSize), onChange: (value) => table.setPageSize(Number(value)), children: [
3160
+ /* @__PURE__ */ jsxRuntime.jsx(Select2.Trigger, { "aria-label": "Rows per page", children: pageSize }),
3161
+ /* @__PURE__ */ jsxRuntime.jsx(Select2.Content, { children: sizeOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(Select2.Item, { value: String(option), children: option }, option)) })
3162
+ ] }) }),
3163
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...slotAttrs("paginationGoToPage"), children: /* @__PURE__ */ jsxRuntime.jsxs(Input2, { size: "small", children: [
3164
+ /* @__PURE__ */ jsxRuntime.jsx(
3165
+ Input2.Field,
3166
+ {
3167
+ type: "number",
3168
+ min: 1,
3169
+ max: Math.max(pageCount, 1),
3170
+ inputMode: "numeric",
3171
+ "aria-label": "Go to page",
3172
+ placeholder: String(pageIndex + 1),
3173
+ value: pageInput,
3174
+ disabled: pageCount <= 0,
3175
+ onChange: (event) => setPageInput(event.currentTarget.value),
3176
+ onKeyDown: (event) => {
3177
+ if (event.key === "Enter") goToPage();
3178
+ }
3179
+ }
3180
+ ),
3181
+ /* @__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, {}) })
3182
+ ] }) })
3183
+ ] })
3184
+ ] });
3185
+ };
3186
+ TablePagination.displayName = "Table.Pagination";
3187
+ var EMPTY_SORTING = [];
3188
+ var EMPTY_FILTERS = [];
3189
+ var EMPTY_SELECTION = {};
3190
+ var EMPTY_EXPANDED = {};
3191
+ var Table = (props) => {
3192
+ const theme = useComponentTheme("Table");
3193
+ const { rootAttrs, rest } = composeRootAttrs(TableBase, props, theme, {
3194
+ // Visual vocabulary lives on the root so recipes cascade
3195
+ // to the portal-free table descendants. `data-loading` mirrors the
3196
+ // boolean-presence convention (rule 5).
3197
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE12, striped: striped2, bordered: bordered2, stickyHeader: stickyHeader2, loading: loading2 }) => ({
3198
+ "data-size": size2,
3199
+ "data-striped": striped2 ? "" : void 0,
3200
+ "data-bordered": bordered2 ? "" : void 0,
3201
+ "data-sticky-header": stickyHeader2 ? "" : void 0,
3202
+ "data-loading": loading2 ? "" : void 0
3203
+ })
3204
+ });
3205
+ const {
3206
+ data,
3207
+ columns,
3208
+ getRowId,
3209
+ manual = false,
3210
+ loading = false,
3211
+ size = DEFAULT_SIZE12,
3212
+ striped = false,
3213
+ bordered = false,
3214
+ stickyHeader = false,
3215
+ selection,
3216
+ sorting: sortingConfig,
3217
+ filtering,
3218
+ expansion,
3219
+ pagination,
3220
+ onDataRequest,
3221
+ emptyState,
3222
+ getSubRows,
3223
+ tableRef,
3224
+ ref
3225
+ } = rest;
3226
+ const { classNames, slotProps } = props;
3227
+ const tanstackColumns = react.useMemo(() => toTanStackColumns(columns), [columns]);
3228
+ const hasSelection = !!selection;
3229
+ const selectionMode = selection?.mode;
3230
+ const hasExpansion = !!expansion;
3231
+ const treeMode = !!getSubRows;
3232
+ const hasColumnFilters = !!filtering || columns.some((column) => !!column.filter);
3233
+ const hasSortableColumn = columns.some((column) => !!column.sortable);
3234
+ const paginationConfig = typeof pagination === "object" ? pagination : void 0;
3235
+ const paginationEnabled = pagination === true || !!paginationConfig;
3236
+ const pageSizeOptions = paginationConfig?.pageSizeOptions ?? DEFAULT_PAGE_SIZE_OPTIONS;
3237
+ const [tableViewportScrolled, setTableViewportScrolled] = react.useState(false);
3238
+ const [sortingState, setSorting] = useControllableState(sortingConfig?.value, sortingConfig?.defaultValue ?? EMPTY_SORTING, sortingConfig?.onChange);
3239
+ const [filtersState, setFilters] = useControllableState(filtering?.value, filtering?.defaultValue ?? EMPTY_FILTERS, filtering?.onChange);
3240
+ const [selectionState, setSelection] = useControllableState(selection?.value, selection?.defaultValue ?? EMPTY_SELECTION, selection?.onChange);
3241
+ const [expandedState, setExpanded] = useControllableState(expansion?.value, expansion?.defaultValue ?? EMPTY_EXPANDED, expansion?.onChange);
3242
+ const readPaginationSlice = () => ({ pageIndex: paginationConfig?.pageIndex ?? 0, pageSize: paginationConfig?.pageSize ?? DEFAULT_PAGE_SIZE });
3243
+ const initialPagination = react.useMemo(readPaginationSlice, []);
3244
+ const paginationControlled = manual && !!paginationConfig;
3245
+ const controlledPagination = react.useMemo(
3246
+ () => paginationControlled ? readPaginationSlice() : void 0,
3247
+ [paginationControlled, paginationConfig?.pageIndex, paginationConfig?.pageSize]
3248
+ );
3249
+ const [paginationStateRaw, setPagination] = useControllableState(controlledPagination, initialPagination, paginationConfig?.onChange);
3250
+ const sorting = sortingState ?? EMPTY_SORTING;
3251
+ const columnFilters = filtersState ?? EMPTY_FILTERS;
3252
+ const rowSelection = selectionState ?? EMPTY_SELECTION;
3253
+ const expanded = expandedState ?? EMPTY_EXPANDED;
3254
+ const paginationValue = paginationStateRaw ?? initialPagination;
3255
+ const resetPageOnManual = () => {
3256
+ if (manual && paginationValue.pageIndex !== 0) setPagination({ ...paginationValue, pageIndex: 0 });
3257
+ };
3258
+ const onSortingChange = (updater) => {
3259
+ setSorting(reactTable.functionalUpdate(updater, sorting));
3260
+ resetPageOnManual();
3261
+ };
3262
+ const onColumnFiltersChange = (updater) => {
3263
+ setFilters(reactTable.functionalUpdate(updater, columnFilters));
3264
+ resetPageOnManual();
3265
+ };
3266
+ const onRowSelectionChange = (updater) => setSelection(reactTable.functionalUpdate(updater, rowSelection));
3267
+ const onExpandedChange = (updater) => setExpanded(reactTable.functionalUpdate(updater, expanded));
3268
+ const onPaginationChange = (updater) => setPagination(reactTable.functionalUpdate(updater, paginationValue));
3269
+ const table = reactTable.useReactTable({
3270
+ data,
3271
+ columns: tanstackColumns,
3272
+ getRowId: (row, index) => getRowId(row, index),
3273
+ state: {
3274
+ sorting,
3275
+ columnFilters,
3276
+ rowSelection,
3277
+ expanded,
3278
+ pagination: paginationValue
3279
+ },
3280
+ onSortingChange,
3281
+ onColumnFiltersChange,
3282
+ onRowSelectionChange,
3283
+ onExpandedChange,
3284
+ onPaginationChange,
3285
+ // Table-level sort switch. Per-column `sortable` is the real gate
3286
+ // (`column.getCanSort()` ANDs both), so a `sorting` config without any
3287
+ // `sortable` column makes no header interactive — keying off the columns
3288
+ // alone is sufficient and avoids implying otherwise.
3289
+ enableSorting: hasSortableColumn,
3290
+ enableMultiSort: sortingConfig?.multi ?? false,
3291
+ enableRowSelection: hasSelection,
3292
+ enableMultiRowSelection: selectionMode === "multiple",
3293
+ enableColumnFilters: hasColumnFilters,
3294
+ manualSorting: manual,
3295
+ manualFiltering: manual,
3296
+ manualPagination: manual,
3297
+ autoResetPageIndex: !manual,
3298
+ rowCount: manual ? paginationConfig?.rowCount : void 0,
3299
+ getCoreRowModel: reactTable.getCoreRowModel(),
3300
+ getSortedRowModel: manual ? void 0 : reactTable.getSortedRowModel(),
3301
+ getFilteredRowModel: manual ? void 0 : reactTable.getFilteredRowModel(),
3302
+ getExpandedRowModel: hasExpansion ? reactTable.getExpandedRowModel() : void 0,
3303
+ getPaginationRowModel: paginationEnabled && !manual ? reactTable.getPaginationRowModel() : void 0,
3304
+ getSubRows,
3305
+ getRowCanExpand: hasExpansion && !getSubRows ? () => true : void 0
3306
+ });
3307
+ react.useEffect(() => {
3308
+ if (!tableRef) return;
3309
+ if (typeof tableRef === "function") tableRef(table);
3310
+ else tableRef.current = table;
3311
+ return () => {
3312
+ if (typeof tableRef === "function") tableRef(null);
3313
+ else tableRef.current = null;
3314
+ };
3315
+ }, [tableRef, table]);
3316
+ const onDataRequestRef = react.useRef(onDataRequest);
3317
+ onDataRequestRef.current = onDataRequest;
3318
+ const dataRequestKey = react.useMemo(() => JSON.stringify({ pagination: paginationValue, sorting, filters: columnFilters }), [paginationValue, sorting, columnFilters]);
3319
+ react.useEffect(() => {
3320
+ if (!manual) return;
3321
+ onDataRequestRef.current?.({ pagination: paginationValue, sorting, filters: columnFilters });
3322
+ }, [manual, dataRequestKey]);
3323
+ react.useEffect(() => {
3324
+ if (paginationControlled || paginationConfig?.pageSize == null) return;
3325
+ if (table.getState().pagination.pageSize === paginationConfig.pageSize) return;
3326
+ table.setPageSize(paginationConfig.pageSize);
3327
+ }, [paginationControlled, paginationConfig?.pageSize, table]);
3328
+ react.useEffect(() => {
3329
+ if (paginationControlled || paginationConfig?.pageIndex == null) return;
3330
+ if (table.getState().pagination.pageIndex === paginationConfig.pageIndex) return;
3331
+ table.setPageIndex(paginationConfig.pageIndex);
3332
+ }, [paginationControlled, paginationConfig?.pageIndex, table]);
3333
+ const slotAttrs = react.useCallback(
3334
+ (slot, attrs) => buildSlotAttrs(TableBase.getSlotProps(slot, attrs), slot, {
3335
+ themeSlotProps: theme?.slotProps,
3336
+ themeClassNames: theme?.classNames,
3337
+ themeClassName: theme?.className,
3338
+ instanceSlotProps: slotProps,
3339
+ instanceClassNames: classNames
3340
+ }),
3341
+ [theme, slotProps, classNames]
3342
+ );
3343
+ const stickyLayout = react.useMemo(() => computeStickyLayout(buildOrderedColumns(table, { hasSelection, hasExpansion })), [table, tanstackColumns, hasSelection, hasExpansion]);
3344
+ const totalColumnCount = tanstackColumns.length + (hasSelection ? 1 : 0) + (hasExpansion ? 1 : 0);
3345
+ const contextValue = {
3346
+ table,
3347
+ size,
3348
+ striped,
3349
+ bordered,
3350
+ stickyHeader,
3351
+ loading,
3352
+ hasSelection,
3353
+ selectionMode,
3354
+ hasExpansion,
3355
+ treeMode,
3356
+ expansionRender: expansion?.render,
3357
+ hasColumnFilters,
3358
+ stickyLayout,
3359
+ totalColumnCount,
3360
+ emptyState,
3361
+ paginationEnabled,
3362
+ pageSizeOptions,
3363
+ slotAttrs
3364
+ };
3365
+ const tableViewportAttrs = slotAttrs("tableViewport");
3366
+ const handleTableViewportScroll = (event) => {
3367
+ tableViewportAttrs.onScroll?.(event);
3368
+ const nextScrolled = event.currentTarget.scrollTop > 0;
3369
+ setTableViewportScrolled((current) => current === nextScrolled ? current : nextScrolled);
3370
+ };
3371
+ return /* @__PURE__ */ jsxRuntime.jsx(TableProvider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ...rootAttrs, ref, children: [
3372
+ /* @__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: [
3373
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, {}),
3374
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, {})
3375
+ ] }) }),
3376
+ paginationEnabled && /* @__PURE__ */ jsxRuntime.jsx(TablePagination, {}),
3377
+ loading && // No `aria-hidden`: the Spar Spinner ships `role="status"` +
3378
+ // `aria-label="Loading"`, so the overlay politely announces the
3379
+ // loading transition (the table also carries `aria-busy`).
3380
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...slotAttrs("loading"), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) })
3381
+ ] }) });
3382
+ };
3383
+ Table.displayName = "Table";
3384
+
3385
+ // src/components/tabs/base.ts
3386
+ var TabsBase = createComponentBase({
3387
+ name: "Tabs",
3388
+ slots: ["root"],
3389
+ classes: { root: "tk-tabs" }
3390
+ });
3391
+ var TabsListBase = createComponentBase({
3392
+ name: "TabsList",
3393
+ slots: ["root"],
3394
+ classes: { root: "tk-tabs-list" }
3395
+ });
3396
+ var TabsTriggerBase = createComponentBase({
3397
+ name: "TabsTrigger",
3398
+ slots: ["root"],
3399
+ classes: { root: "tk-tabs-trigger" }
3400
+ });
3401
+ var TabsContentBase = createComponentBase({
3402
+ name: "TabsContent",
3403
+ slots: ["root"],
3404
+ classes: { root: "tk-tabs-content" }
3405
+ });
3406
+
3407
+ // src/components/tabs/context.ts
3408
+ var [TabsOwnProvider, useTabsOwnContext] = createSafeContext("Tabs");
3409
+
3410
+ // src/components/tabs/defaults.ts
3411
+ var DEFAULT_SIZE13 = "base";
3412
+ var DEFAULT_VARIANT8 = "primary";
3413
+ var DEFAULT_APPEARANCE6 = "basic";
3414
+ var Tabs = (props) => {
3415
+ const theme = useComponentTheme("Tabs");
3416
+ const { rootAttrs, rest } = composeRootAttrs(TabsBase, props, theme, {
3417
+ stateAttrs: ({ size: size2 = DEFAULT_SIZE13, variant: variant2 = DEFAULT_VARIANT8, appearance: appearance2 = DEFAULT_APPEARANCE6 }) => ({
3418
+ "data-size": size2,
3419
+ "data-variant": variant2,
3420
+ "data-type": appearance2
3421
+ })
3422
+ });
3423
+ const { size = DEFAULT_SIZE13, variant = DEFAULT_VARIANT8, appearance = DEFAULT_APPEARANCE6, children, ref, ...sparProps } = rest;
3424
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsOwnProvider, { value: { size, variant, appearance }, children: /* @__PURE__ */ jsxRuntime.jsx(spar.Tabs, { ...sparProps, ...rootAttrs, ref, children }) });
3425
+ };
3426
+ Tabs.displayName = "Tabs";
3427
+ var TabsList = (props) => {
3428
+ const theme = useComponentTheme("TabsList");
3429
+ const { size, variant, appearance } = useTabsOwnContext("Tabs.List");
3430
+ const { rootAttrs, rest } = composeRootAttrs(TabsListBase, props, theme, {
3431
+ stateAttrs: () => ({
3432
+ "data-size": size,
3433
+ "data-variant": variant,
3434
+ "data-type": appearance
3435
+ })
3436
+ });
3437
+ const { children, ref, ...sparProps } = rest;
3438
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.TabsList, { ...sparProps, ...rootAttrs, ref, children });
3439
+ };
3440
+ TabsList.displayName = "Tabs.List";
3441
+ var TabsTrigger = (props) => {
3442
+ const theme = useComponentTheme("TabsTrigger");
3443
+ const { size, variant, appearance } = useTabsOwnContext("Tabs.Trigger");
3444
+ const { rootAttrs, rest } = composeRootAttrs(TabsTriggerBase, props, theme, {
3445
+ stateAttrs: () => ({
3446
+ "data-size": size,
3447
+ "data-variant": variant,
3448
+ "data-type": appearance
3449
+ })
3450
+ });
3451
+ const { children, ref, ...sparProps } = rest;
3452
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.TabsTrigger, { ...sparProps, ...rootAttrs, ref, children });
3453
+ };
3454
+ TabsTrigger.displayName = "Tabs.Trigger";
3455
+ var TabsContent = (props) => {
3456
+ const theme = useComponentTheme("TabsContent");
3457
+ const { rootAttrs, rest } = composeRootAttrs(TabsContentBase, props, theme);
3458
+ const { children, ref, ...sparProps } = rest;
3459
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.TabsContent, { ...sparProps, ...rootAttrs, ref, children });
3460
+ };
3461
+ TabsContent.displayName = "Tabs.Content";
3462
+
3463
+ // src/components/tabs/index.ts
3464
+ var Tabs2 = Object.assign(Tabs, {
3465
+ List: TabsList,
3466
+ Trigger: TabsTrigger,
3467
+ Content: TabsContent
3468
+ });
1341
3469
  var Tooltip = ({ children, id, open, defaultOpen, onOpenChange, delay, hideDelay, disabled }) => {
1342
3470
  return /* @__PURE__ */ jsxRuntime.jsx(spar.Tooltip, { id, open, defaultOpen, onOpenChange, delay, hideDelay, disabled, children });
1343
3471
  };
@@ -1392,11 +3520,11 @@ var TooltipTrigger = (props) => {
1392
3520
  TooltipTrigger.displayName = "Tooltip.Trigger";
1393
3521
 
1394
3522
  // src/components/tooltip/defaults.ts
1395
- var DEFAULT_VARIANT5 = "dark";
3523
+ var DEFAULT_VARIANT9 = "white";
1396
3524
  var TooltipContent = (props) => {
1397
3525
  const theme = useComponentTheme("TooltipContent");
1398
3526
  const { rootAttrs, rest } = composeRootAttrs(TooltipContentBase, props, theme, {
1399
- stateAttrs: ({ variant = DEFAULT_VARIANT5 }) => ({
3527
+ stateAttrs: ({ variant = DEFAULT_VARIANT9 }) => ({
1400
3528
  "data-variant": variant
1401
3529
  })
1402
3530
  });
@@ -1436,18 +3564,104 @@ var Tooltip2 = Object.assign(Tooltip, {
1436
3564
  Arrow: TooltipArrow
1437
3565
  });
1438
3566
 
3567
+ // src/components/toast/base.ts
3568
+ var ToasterBase = createComponentBase({
3569
+ name: "Toaster",
3570
+ slots: ["root"],
3571
+ classes: {
3572
+ root: "tk-toaster"
3573
+ }
3574
+ });
3575
+ var ToastBase = createComponentBase({
3576
+ name: "Toast",
3577
+ slots: ["root"],
3578
+ classes: {
3579
+ root: "tk-toast"
3580
+ }
3581
+ });
3582
+
3583
+ // src/components/toast/defaults.ts
3584
+ var DEFAULT_TOAST_APPEARANCE = "filled";
3585
+ var DEFAULT_CLOSE_LABEL2 = "Dismiss notification";
3586
+
3587
+ // src/components/toast/utils.ts
3588
+ var toastTypeToVariant = (type) => {
3589
+ switch (type) {
3590
+ case "success":
3591
+ return "success";
3592
+ case "error":
3593
+ return "danger";
3594
+ case "warning":
3595
+ return "warning";
3596
+ case "info":
3597
+ return "info";
3598
+ // 'default' and 'loading' have no dedicated Alert variant.
3599
+ default:
3600
+ return "neutral";
3601
+ }
3602
+ };
3603
+ var Toast = (props) => {
3604
+ const theme = useComponentTheme("Toast");
3605
+ const { rootAttrs, rest } = composeRootAttrs(ToastBase, props, theme);
3606
+ const { as, toast, toaster, appearance = DEFAULT_TOAST_APPEARANCE, closeLabel = DEFAULT_CLOSE_LABEL2, children, ref, ...toastProps } = rest;
3607
+ const Component = as ?? "div";
3608
+ const variant = toastTypeToVariant(toast.type);
3609
+ 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: [
3610
+ /* @__PURE__ */ jsxRuntime.jsxs(Alert2.Content, { children: [
3611
+ toast.title != null && /* @__PURE__ */ jsxRuntime.jsx(spar.Toast.Title, { as: Alert2.Title, children: toast.title }),
3612
+ toast.description != null && /* @__PURE__ */ jsxRuntime.jsx(spar.Toast.Description, { as: Alert2.Description, children: toast.description })
3613
+ ] }),
3614
+ /* @__PURE__ */ jsxRuntime.jsx(spar.Toast.Close, { as: Alert2.Close, "aria-label": closeLabel }),
3615
+ 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" }) })
3616
+ ] }) });
3617
+ };
3618
+ Toast.displayName = "Toast";
3619
+ var Toaster = (props) => {
3620
+ const theme = useComponentTheme("Toaster");
3621
+ const { rootAttrs, rest } = composeRootAttrs(ToasterBase, props, theme, {
3622
+ stateAttrs: ({ toaster: toaster2 }) => ({
3623
+ "data-placement": toaster2.placement
3624
+ })
3625
+ });
3626
+ const { as, toaster, appearance = DEFAULT_TOAST_APPEARANCE, closeLabel = DEFAULT_CLOSE_LABEL2, overlap = false, children, ref, ...toasterProps } = rest;
3627
+ const Component = as ?? "div";
3628
+ return /* @__PURE__ */ jsxRuntime.jsx(spar.Toaster, { ...toasterProps, as: Component, ref, toaster, overlap, ...rootAttrs, children: (toast) => (
3629
+ // Spar renders each item directly into a mapped array, so the key must
3630
+ // live on the element this render prop returns. The default branch keys
3631
+ // <Toast>; a consumer `children` result is keyed via Fragment here.
3632
+ children ? /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: children(toast) }, toast.id) : /* @__PURE__ */ jsxRuntime.jsx(Toast, { toast, toaster, appearance, closeLabel }, toast.id)
3633
+ ) });
3634
+ };
3635
+ Toaster.displayName = "Toaster";
3636
+
3637
+ Object.defineProperty(exports, "createToaster", {
3638
+ enumerable: true,
3639
+ get: function () { return spar.createToaster; }
3640
+ });
1439
3641
  exports.Accordion = Accordion2;
3642
+ exports.Alert = Alert2;
1440
3643
  exports.Badge = Badge;
3644
+ exports.Breadcrumb = Breadcrumb2;
1441
3645
  exports.Button = Button;
3646
+ exports.Card = Card2;
1442
3647
  exports.Checkbox = Checkbox2;
3648
+ exports.Chip = Chip;
3649
+ exports.Dialog = Dialog2;
1443
3650
  exports.Drawer = Drawer2;
1444
3651
  exports.Field = Field2;
1445
3652
  exports.Input = Input2;
3653
+ exports.Label = Label;
1446
3654
  exports.Popover = Popover2;
1447
3655
  exports.Radio = Radio2;
1448
3656
  exports.Select = Select2;
3657
+ exports.Spinner = Spinner;
1449
3658
  exports.Switch = Switch2;
3659
+ exports.Table = Table;
3660
+ exports.Tabs = Tabs2;
1450
3661
  exports.TakeoffSparProvider = TakeoffSparProvider;
3662
+ exports.Toast = Toast;
3663
+ exports.Toaster = Toaster;
1451
3664
  exports.Tooltip = Tooltip2;
3665
+ exports.getExportRows = getExportRows;
1452
3666
  exports.useComponentTheme = useComponentTheme;
1453
3667
  exports.useTheme = useTheme;