@epilot/spark-ui 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/components/accordion.cjs +1 -1
  2. package/dist/components/accordion.js +1 -1
  3. package/dist/components/attachment.d.cts +1 -1
  4. package/dist/components/attachment.d.ts +1 -1
  5. package/dist/components/avatar.d.cts +1 -1
  6. package/dist/components/avatar.d.ts +1 -1
  7. package/dist/components/badge.d.cts +1 -1
  8. package/dist/components/badge.d.ts +1 -1
  9. package/dist/components/bar-chart.js +1 -1
  10. package/dist/components/box.cjs +3 -2
  11. package/dist/components/box.cjs.map +1 -1
  12. package/dist/components/box.d.cts +8 -1
  13. package/dist/components/box.d.ts +8 -1
  14. package/dist/components/box.js +3 -2
  15. package/dist/components/box.js.map +1 -1
  16. package/dist/components/bubble.d.cts +1 -1
  17. package/dist/components/bubble.d.ts +1 -1
  18. package/dist/components/button-group.d.cts +1 -1
  19. package/dist/components/button-group.d.ts +1 -1
  20. package/dist/components/button.d.cts +3 -3
  21. package/dist/components/button.d.ts +3 -3
  22. package/dist/components/calendar.cjs +2 -2
  23. package/dist/components/calendar.cjs.map +1 -1
  24. package/dist/components/calendar.js +2 -2
  25. package/dist/components/calendar.js.map +1 -1
  26. package/dist/components/callout.cjs +1 -1
  27. package/dist/components/callout.cjs.map +1 -1
  28. package/dist/components/callout.d.cts +2 -2
  29. package/dist/components/callout.d.ts +2 -2
  30. package/dist/components/callout.js +1 -1
  31. package/dist/components/callout.js.map +1 -1
  32. package/dist/components/card.cjs +3 -2
  33. package/dist/components/card.cjs.map +1 -1
  34. package/dist/components/card.d.cts +7 -1
  35. package/dist/components/card.d.ts +7 -1
  36. package/dist/components/card.js +3 -2
  37. package/dist/components/card.js.map +1 -1
  38. package/dist/components/checkbox.d.cts +1 -1
  39. package/dist/components/checkbox.d.ts +1 -1
  40. package/dist/components/field.d.cts +1 -1
  41. package/dist/components/field.d.ts +1 -1
  42. package/dist/components/icon.cjs +1 -1
  43. package/dist/components/icon.js +1 -1
  44. package/dist/components/info-block.d.cts +1 -1
  45. package/dist/components/info-block.d.ts +1 -1
  46. package/dist/components/input-group.cjs +1 -1
  47. package/dist/components/input-group.cjs.map +1 -1
  48. package/dist/components/input-group.js +1 -1
  49. package/dist/components/input-group.js.map +1 -1
  50. package/dist/components/input-otp.cjs +1 -1
  51. package/dist/components/input-otp.js +1 -1
  52. package/dist/components/input.cjs +1 -1
  53. package/dist/components/input.d.cts +1 -1
  54. package/dist/components/input.d.ts +1 -1
  55. package/dist/components/input.js +1 -1
  56. package/dist/components/line-chart.cjs +1 -1
  57. package/dist/components/line-chart.js +2 -2
  58. package/dist/components/list.d.cts +1 -1
  59. package/dist/components/list.d.ts +1 -1
  60. package/dist/components/page-header.d.cts +1 -1
  61. package/dist/components/page-header.d.ts +1 -1
  62. package/dist/components/pill.cjs +20 -13
  63. package/dist/components/pill.cjs.map +1 -1
  64. package/dist/components/pill.d.cts +1 -1
  65. package/dist/components/pill.d.ts +1 -1
  66. package/dist/components/pill.js +20 -13
  67. package/dist/components/pill.js.map +1 -1
  68. package/dist/components/power-history-chart.cjs +1 -1
  69. package/dist/components/power-history-chart.js +2 -2
  70. package/dist/components/progress.cjs +1 -1
  71. package/dist/components/progress.cjs.map +1 -1
  72. package/dist/components/progress.js +1 -1
  73. package/dist/components/progress.js.map +1 -1
  74. package/dist/components/radio-card-group.cjs.map +1 -1
  75. package/dist/components/radio-card-group.js.map +1 -1
  76. package/dist/components/radio.d.cts +1 -1
  77. package/dist/components/radio.d.ts +1 -1
  78. package/dist/components/schedule-list.cjs +10 -7
  79. package/dist/components/schedule-list.cjs.map +1 -1
  80. package/dist/components/schedule-list.js +10 -7
  81. package/dist/components/schedule-list.js.map +1 -1
  82. package/dist/components/segmented-control.d.cts +1 -1
  83. package/dist/components/segmented-control.d.ts +1 -1
  84. package/dist/components/select.cjs +1 -1
  85. package/dist/components/select.d.cts +1 -1
  86. package/dist/components/select.d.ts +1 -1
  87. package/dist/components/select.js +1 -1
  88. package/dist/components/solar-forecast-chart.cjs +1 -1
  89. package/dist/components/solar-forecast-chart.js +2 -2
  90. package/dist/components/switch.d.cts +1 -1
  91. package/dist/components/switch.d.ts +1 -1
  92. package/dist/components/textarea.cjs +1 -1
  93. package/dist/components/textarea.d.cts +1 -1
  94. package/dist/components/textarea.d.ts +1 -1
  95. package/dist/components/textarea.js +1 -1
  96. package/dist/components/theme.cjs +18 -6
  97. package/dist/components/theme.cjs.map +1 -1
  98. package/dist/components/theme.d.cts +16 -2
  99. package/dist/components/theme.d.ts +16 -2
  100. package/dist/components/theme.js +19 -7
  101. package/dist/components/theme.js.map +1 -1
  102. package/dist/{generate-radix-colors-Bw-RYaV4.d.ts → generate-radix-colors-BY4Wjsm7.d.cts} +4 -2
  103. package/dist/{generate-radix-colors-Bw-RYaV4.d.cts → generate-radix-colors-BY4Wjsm7.d.ts} +4 -2
  104. package/dist/icons/material-symbol.cjs +1 -1
  105. package/dist/icons/material-symbol.cjs.map +1 -1
  106. package/dist/icons/material-symbol.js +1 -1
  107. package/dist/icons/material-symbol.js.map +1 -1
  108. package/dist/lib/accent-theme.cjs +367 -16
  109. package/dist/lib/accent-theme.cjs.map +1 -1
  110. package/dist/lib/accent-theme.d.cts +75 -6
  111. package/dist/lib/accent-theme.d.ts +75 -6
  112. package/dist/lib/accent-theme.js +365 -18
  113. package/dist/lib/accent-theme.js.map +1 -1
  114. package/dist/lib/container-chrome.cjs +9 -7
  115. package/dist/lib/container-chrome.cjs.map +1 -1
  116. package/dist/lib/container-chrome.d.cts +4 -3
  117. package/dist/lib/container-chrome.d.ts +4 -3
  118. package/dist/lib/container-chrome.js +9 -8
  119. package/dist/lib/container-chrome.js.map +1 -1
  120. package/dist/lib/generate-radix-colors.cjs +7 -0
  121. package/dist/lib/generate-radix-colors.cjs.map +1 -1
  122. package/dist/lib/generate-radix-colors.d.cts +2 -2
  123. package/dist/lib/generate-radix-colors.d.ts +2 -2
  124. package/dist/lib/generate-radix-colors.js +6 -1
  125. package/dist/lib/generate-radix-colors.js.map +1 -1
  126. package/dist/lib/input-box-variants.d.cts +1 -1
  127. package/dist/lib/input-box-variants.d.ts +1 -1
  128. package/dist/lib/theme-types.cjs +19 -0
  129. package/dist/lib/theme-types.cjs.map +1 -0
  130. package/dist/lib/theme-types.d.cts +2 -2
  131. package/dist/lib/theme-types.d.ts +2 -2
  132. package/dist/lib/theme-types.js +17 -1
  133. package/dist/lib/theme-types.js.map +1 -0
  134. package/dist/styles/material-symbol.css +3 -0
  135. package/dist/styles/spark-default.css +148 -0
  136. package/dist/styles/utilities.css +9 -8
  137. package/dist/{theme-types-1yB0d8mp.d.ts → theme-types-Bn5E15-P.d.cts} +12 -3
  138. package/dist/{theme-types-1yB0d8mp.d.cts → theme-types-Bn5E15-P.d.ts} +12 -3
  139. package/package.json +113 -55
@@ -1 +1 @@
1
- {"version":3,"file":"pill.js","names":["React"],"sources":["../../src/components/pill.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkAccentColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\ntype PillRemoveProps =\n | { onRemove?: undefined; removeLabel?: string }\n | {\n /** Fires on a pointer click of the (decorative) glyph, or Delete/Backspace while the pill has focus. */\n onRemove: (event: React.SyntheticEvent) => void\n /** Visually-hidden text folded into the pill's accessible name -- the glyph itself is `aria-hidden`. */\n removeLabel: string\n }\n\ntype PillProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'onClick'> &\n PillRemoveProps & {\n styleVariant?: SparkStyle\n color?: SparkAccentColor\n disabled?: boolean\n onClick?: (event: React.SyntheticEvent<HTMLSpanElement>) => void\n }\n\n/**\n * Like Badge, but interactive: `onClick` makes the whole pill a button\n * (Enter/Space), `onRemove` adds a Delete/Backspace-and-click affordance.\n * Both are optional -- with neither, it's a static label.\n */\nconst Pill = React.forwardRef<HTMLSpanElement, PillProps>(function Pill(\n {\n className,\n children,\n styleVariant,\n color,\n disabled = false,\n onClick,\n onRemove,\n removeLabel,\n onKeyDown,\n ...props\n },\n ref,\n) {\n const clickable = !disabled && onClick !== undefined\n const removable = !disabled && onRemove !== undefined\n const focusable = clickable || removable\n const hasLook = styleVariant !== undefined || color !== undefined\n\n return (\n <span\n aria-disabled={disabled || undefined}\n aria-keyshortcuts={removable ? 'Delete' : undefined}\n data-slot=\"pill\"\n data-style={hasLook ? (styleVariant ?? 'soft') : undefined}\n data-accent-color={color ? accentByColor[color] : undefined}\n onClick={clickable ? onClick : undefined}\n onKeyDown={(event) => {\n onKeyDown?.(event)\n if (clickable && (event.key === 'Enter' || event.key === ' ')) {\n if (event.key === ' ') event.preventDefault()\n onClick?.(event)\n }\n if (\n removable &&\n (event.key === 'Delete' || event.key === 'Backspace')\n ) {\n onRemove?.(event)\n }\n }}\n ref={ref}\n role={clickable ? 'button' : undefined}\n tabIndex={focusable ? 0 : undefined}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none',\n 'bg-(--spark-style-bg,var(--neutral-a3)) text-(--spark-style-fg,var(--neutral-a11))',\n focusable &&\n 'transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden motion-reduce:transition-none',\n clickable && 'cursor-pointer hover:bg-(--spark-style-bg-hover)',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n {removable ? (\n <>\n {/* aria-hidden hides the glyph itself; this carries removeLabel into the pill's own accessible name */}\n <span className=\"sr-only\">{removeLabel}</span>\n <span\n aria-hidden=\"true\"\n data-slot=\"pill-remove\"\n onClick={(event) => {\n event.stopPropagation()\n onRemove?.(event)\n }}\n className=\"-mr-1 inline-flex size-4 shrink-0 items-center justify-center rounded-full transition-colors hover:bg-(--spark-style-bg-hover) motion-reduce:transition-none\"\n >\n <MaterialSymbol className=\"[--spark-icon-size:14px]\" name=\"close\" />\n </span>\n </>\n ) : null}\n </span>\n )\n})\n\nPill.displayName = 'Pill'\n\nexport { Pill }\nexport type { PillProps }\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAM,OAAOA,QAAM,WAAuC,SAAS,KACjE,EACE,WACA,UACA,cACA,OACA,WAAW,OACX,SACA,UACA,aACA,WACA,GAAG,SAEL,KACA;CACA,MAAM,YAAY,CAAC,YAAY,YAAY,KAAA;CAC3C,MAAM,YAAY,CAAC,YAAY,aAAa,KAAA;CAC5C,MAAM,YAAY,aAAa;CAG/B,OACE,qBAAC,QAAD;EACE,iBAAe,YAAY,KAAA;EAC3B,qBAAmB,YAAY,WAAW,KAAA;EAC1C,aAAU;EACV,cAPY,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAO7B,gBAAgB,SAAU,KAAA;EACjD,qBAAmB,QAAQ,cAAc,SAAS,KAAA;EAClD,SAAS,YAAY,UAAU,KAAA;EAC/B,YAAY,UAAU;GACpB,YAAY,KAAK;GACjB,IAAI,cAAc,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;IAC7D,IAAI,MAAM,QAAQ,KAAK,MAAM,eAAe;IAC5C,UAAU,KAAK;GACjB;GACA,IACE,cACC,MAAM,QAAQ,YAAY,MAAM,QAAQ,cAEzC,WAAW,KAAK;EAEpB;EACK;EACL,MAAM,YAAY,WAAW,KAAA;EAC7B,UAAU,YAAY,IAAI,KAAA;EAC1B,WAAW,GACT,0FACA,sFACA,aACE,iIACF,aAAa,oDACb,YAAY,kCACZ,SACF;EACA,GAAI;YAhCN,CAkCG,UACA,YACC,qBAAA,UAAA,EAAA,UAAA,CAEE,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAkB,CAAA,GAC7C,oBAAC,QAAD;GACE,eAAY;GACZ,aAAU;GACV,UAAU,UAAU;IAClB,MAAM,gBAAgB;IACtB,WAAW,KAAK;GAClB;GACA,WAAU;aAEV,oBAAC,gBAAD;IAAgB,WAAU;IAA2B,MAAK;GAAS,CAAA;EAC/D,CAAA,CACN,EAAA,CAAA,IACA,IACA;;AAEV,CAAC;AAED,KAAK,cAAc"}
1
+ {"version":3,"file":"pill.js","names":["React"],"sources":["../../src/components/pill.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkAccentColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\ntype PillRemoveProps =\n | { onRemove?: undefined; removeLabel?: string }\n | {\n /** Fires on a pointer click of the (decorative) glyph, or Delete/Backspace while the pill has focus. */\n onRemove: (event: React.SyntheticEvent) => void\n /** Visually-hidden text folded into the pill's accessible name -- the glyph itself is `aria-hidden`. */\n removeLabel: string\n }\n\ntype PillProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'onClick'> &\n PillRemoveProps & {\n styleVariant?: SparkStyle\n color?: SparkAccentColor\n disabled?: boolean\n onClick?: (event: React.SyntheticEvent<HTMLSpanElement>) => void\n }\n\n/**\n * Like Badge, but interactive: `onClick` makes the whole pill a button\n * (Enter/Space), `onRemove` adds a Delete/Backspace-and-click affordance.\n * Both are optional -- with neither, it's a static label.\n */\nconst Pill = React.forwardRef<HTMLSpanElement, PillProps>(function Pill(\n {\n className,\n children,\n styleVariant,\n color,\n disabled = false,\n onClick,\n onRemove,\n removeLabel,\n onKeyDown,\n ...props\n },\n ref,\n) {\n const clickable = !disabled && onClick !== undefined\n const removable = !disabled && onRemove !== undefined\n const focusable = clickable || removable\n const hasLook = styleVariant !== undefined || color !== undefined\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLSpanElement>) => {\n onKeyDown?.(event)\n if (clickable && (event.key === 'Enter' || event.key === ' ')) {\n if (event.key === ' ') event.preventDefault()\n onClick?.(event)\n }\n if (removable && (event.key === 'Delete' || event.key === 'Backspace')) {\n onRemove?.(event)\n }\n }\n\n // button role and click handler travel together, so a clickable pill always\n // answers Enter/Space; a removable-only pill stays generic and answers Delete\n const interaction = {\n onKeyDown: handleKeyDown,\n ...(clickable && { role: 'button' as const, onClick }),\n ...(focusable && { tabIndex: 0 }),\n }\n\n return (\n <span\n aria-disabled={disabled || undefined}\n aria-keyshortcuts={removable ? 'Delete' : undefined}\n data-slot=\"pill\"\n data-style={hasLook ? (styleVariant ?? 'soft') : undefined}\n data-accent-color={color ? accentByColor[color] : undefined}\n {...interaction}\n ref={ref}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-full px-2.5 text-xs font-medium select-none',\n 'bg-(--spark-style-bg,var(--neutral-a3)) text-(--spark-style-fg,var(--neutral-a11))',\n focusable &&\n 'transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden motion-reduce:transition-none',\n clickable && 'cursor-pointer hover:bg-(--spark-style-bg-hover)',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n {removable ? (\n <>\n {/* aria-hidden hides the glyph itself; this carries removeLabel into the pill's own accessible name */}\n <span className=\"sr-only\">{removeLabel}</span>\n <span\n aria-hidden=\"true\"\n data-slot=\"pill-remove\"\n onClick={(event) => {\n event.stopPropagation()\n onRemove?.(event)\n }}\n className=\"-mr-1 inline-flex size-4 shrink-0 items-center justify-center rounded-full transition-colors hover:bg-(--spark-style-bg-hover) motion-reduce:transition-none\"\n >\n <MaterialSymbol className=\"[--spark-icon-size:14px]\" name=\"close\" />\n </span>\n </>\n ) : null}\n </span>\n )\n})\n\nPill.displayName = 'Pill'\n\nexport { Pill }\nexport type { PillProps }\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAM,OAAOA,QAAM,WAAuC,SAAS,KACjE,EACE,WACA,UACA,cACA,OACA,WAAW,OACX,SACA,UACA,aACA,WACA,GAAG,SAEL,KACA;CACA,MAAM,YAAY,CAAC,YAAY,YAAY,KAAA;CAC3C,MAAM,YAAY,CAAC,YAAY,aAAa,KAAA;CAC5C,MAAM,YAAY,aAAa;CAC/B,MAAM,UAAU,iBAAiB,KAAA,KAAa,UAAU,KAAA;CAExD,MAAM,iBAAiB,UAAgD;EACrE,YAAY,KAAK;EACjB,IAAI,cAAc,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;GAC7D,IAAI,MAAM,QAAQ,KAAK,MAAM,eAAe;GAC5C,UAAU,KAAK;EACjB;EACA,IAAI,cAAc,MAAM,QAAQ,YAAY,MAAM,QAAQ,cACxD,WAAW,KAAK;CAEpB;CAIA,MAAM,cAAc;EAClB,WAAW;EACX,GAAI,aAAa;GAAE,MAAM;GAAmB;EAAQ;EACpD,GAAI,aAAa,EAAE,UAAU,EAAE;CACjC;CAEA,OACE,qBAAC,QAAD;EACE,iBAAe,YAAY,KAAA;EAC3B,qBAAmB,YAAY,WAAW,KAAA;EAC1C,aAAU;EACV,cAAY,UAAW,gBAAgB,SAAU,KAAA;EACjD,qBAAmB,QAAQ,cAAc,SAAS,KAAA;EAClD,GAAI;EACC;EACL,WAAW,GACT,0FACA,sFACA,aACE,iIACF,aAAa,oDACb,YAAY,kCACZ,SACF;EACA,GAAI;YAjBN,CAmBG,UACA,YACC,qBAAA,UAAA,EAAA,UAAA,CAEE,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAkB,CAAA,GAC7C,oBAAC,QAAD;GACE,eAAY;GACZ,aAAU;GACV,UAAU,UAAU;IAClB,MAAM,gBAAgB;IACtB,WAAW,KAAK;GAClB;GACA,WAAU;aAEV,oBAAC,gBAAD;IAAgB,WAAU;IAA2B,MAAK;GAAS,CAAA;EAC/D,CAAA,CACN,EAAA,CAAA,IACA,IACA;;AAEV,CAAC;AAED,KAAK,cAAc"}
@@ -6,10 +6,10 @@ const require_hooks_use_reduced_motion = require("../hooks/use-reduced-motion.cj
6
6
  require("../utils/chars.cjs");
7
7
  const require_utils_format = require("../utils/format.cjs");
8
8
  const require_utils_chart_scale = require("../utils/chart-scale.cjs");
9
- const require_utils_chart_time_ticks = require("../utils/chart-time-ticks.cjs");
10
9
  const require_components_chart = require("./chart.cjs");
11
10
  const require_components_series_legend = require("./series-legend.cjs");
12
11
  const require_components_typography = require("./typography.cjs");
12
+ const require_utils_chart_time_ticks = require("../utils/chart-time-ticks.cjs");
13
13
  let react = require("react");
14
14
  react = require_chunk.__toESM(react);
15
15
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { useAnimatedChartDomain, useChartZoom } from "../hooks/use-chart-zoom.js";
3
3
  import { useReducedMotion } from "../hooks/use-reduced-motion.js";
4
+ import { cn } from "../utils/cn.js";
4
5
  import "../utils/chars.js";
5
6
  import { twoDecimalFormat } from "../utils/format.js";
6
7
  import { buildYAxisScale, formatYAxisTick, measureYAxisGutter } from "../utils/chart-scale.js";
7
- import { buildTimeTicks } from "../utils/chart-time-ticks.js";
8
- import { cn } from "../utils/cn.js";
9
8
  import { ChartTooltipCard, ChartZoomResetButton, clampTooltipPosition, useMeasuredSize } from "./chart.js";
10
9
  import { SeriesLegend } from "./series-legend.js";
11
10
  import { SectionTitle } from "./typography.js";
11
+ import { buildTimeTicks } from "../utils/chart-time-ticks.js";
12
12
  import * as React$1 from "react";
13
13
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -22,7 +22,7 @@ const Progress = react.forwardRef(({ className, value, max = 100, size = "defaul
22
22
  role: "progressbar",
23
23
  ...props,
24
24
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
25
- className: "h-full rounded-full bg-spark-9 transition-all duration-300",
25
+ className: "h-full rounded-full bg-(--spark-style-bg,var(--spark-9)) transition-all duration-300",
26
26
  style: { width: `${percentage}%` }
27
27
  })
28
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"progress.cjs","names":["React"],"sources":["../../src/components/progress.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Current value */\n value: number\n /** Maximum value. Default: 100 */\n max?: number\n /** Height variant */\n size?: 'sm' | 'default' | 'lg'\n}\n\nconst sizeClasses = {\n sm: 'h-1',\n default: 'h-2',\n lg: 'h-3',\n} as const\n\nconst Progress = React.forwardRef<HTMLDivElement, ProgressProps>(\n ({ className, value, max = 100, size = 'default', ...props }, ref) => {\n const percentage = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div\n aria-valuemax={max}\n aria-valuemin={0}\n aria-valuenow={value}\n className={cn(\n 'w-full overflow-hidden rounded-full bg-gray-a4',\n sizeClasses[size],\n className,\n )}\n ref={ref}\n role=\"progressbar\"\n {...props}\n >\n <div\n className=\"h-full rounded-full bg-spark-9 transition-all duration-300\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n )\n },\n)\n\nProgress.displayName = 'Progress'\n\nexport { Progress }\n"],"mappings":";;;;;;;;AAYA,MAAM,cAAc;CAClB,IAAI;CACJ,SAAS;CACT,IAAI;AACN;AAEA,MAAM,WAAWA,MAAM,YACpB,EAAE,WAAW,OAAO,MAAM,KAAK,OAAO,WAAW,GAAG,SAAS,QAAQ;CACpE,MAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,QAAQ,MAAO,GAAG,CAAC;CAEjE,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,YAAA,GAAA,OAAA,IACE,kDACA,YAAY,OACZ,SACF;EACK;EACL,MAAK;EACL,GAAI;YAEJ,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG;EAClC,CAAA;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc"}
1
+ {"version":3,"file":"progress.cjs","names":["React"],"sources":["../../src/components/progress.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Current value */\n value: number\n /** Maximum value. Default: 100 */\n max?: number\n /** Height variant */\n size?: 'sm' | 'default' | 'lg'\n}\n\nconst sizeClasses = {\n sm: 'h-1',\n default: 'h-2',\n lg: 'h-3',\n} as const\n\nconst Progress = React.forwardRef<HTMLDivElement, ProgressProps>(\n ({ className, value, max = 100, size = 'default', ...props }, ref) => {\n const percentage = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div\n aria-valuemax={max}\n aria-valuemin={0}\n aria-valuenow={value}\n className={cn(\n 'w-full overflow-hidden rounded-full bg-gray-a4',\n sizeClasses[size],\n className,\n )}\n ref={ref}\n role=\"progressbar\"\n {...props}\n >\n <div\n className=\"h-full rounded-full bg-(--spark-style-bg,var(--spark-9)) transition-all duration-300\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n )\n },\n)\n\nProgress.displayName = 'Progress'\n\nexport { Progress }\n"],"mappings":";;;;;;;;AAYA,MAAM,cAAc;CAClB,IAAI;CACJ,SAAS;CACT,IAAI;AACN;AAEA,MAAM,WAAWA,MAAM,YACpB,EAAE,WAAW,OAAO,MAAM,KAAK,OAAO,WAAW,GAAG,SAAS,QAAQ;CACpE,MAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,QAAQ,MAAO,GAAG,CAAC;CAEjE,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,YAAA,GAAA,OAAA,IACE,kDACA,YAAY,OACZ,SACF;EACK;EACL,MAAK;EACL,GAAI;YAEJ,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG;EAClC,CAAA;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc"}
@@ -19,7 +19,7 @@ const Progress = React$1.forwardRef(({ className, value, max = 100, size = "defa
19
19
  role: "progressbar",
20
20
  ...props,
21
21
  children: /* @__PURE__ */ jsx("div", {
22
- className: "h-full rounded-full bg-spark-9 transition-all duration-300",
22
+ className: "h-full rounded-full bg-(--spark-style-bg,var(--spark-9)) transition-all duration-300",
23
23
  style: { width: `${percentage}%` }
24
24
  })
25
25
  });
@@ -1 +1 @@
1
- {"version":3,"file":"progress.js","names":["React"],"sources":["../../src/components/progress.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Current value */\n value: number\n /** Maximum value. Default: 100 */\n max?: number\n /** Height variant */\n size?: 'sm' | 'default' | 'lg'\n}\n\nconst sizeClasses = {\n sm: 'h-1',\n default: 'h-2',\n lg: 'h-3',\n} as const\n\nconst Progress = React.forwardRef<HTMLDivElement, ProgressProps>(\n ({ className, value, max = 100, size = 'default', ...props }, ref) => {\n const percentage = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div\n aria-valuemax={max}\n aria-valuemin={0}\n aria-valuenow={value}\n className={cn(\n 'w-full overflow-hidden rounded-full bg-gray-a4',\n sizeClasses[size],\n className,\n )}\n ref={ref}\n role=\"progressbar\"\n {...props}\n >\n <div\n className=\"h-full rounded-full bg-spark-9 transition-all duration-300\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n )\n },\n)\n\nProgress.displayName = 'Progress'\n\nexport { Progress }\n"],"mappings":";;;;;AAYA,MAAM,cAAc;CAClB,IAAI;CACJ,SAAS;CACT,IAAI;AACN;AAEA,MAAM,WAAWA,QAAM,YACpB,EAAE,WAAW,OAAO,MAAM,KAAK,OAAO,WAAW,GAAG,SAAS,QAAQ;CACpE,MAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,QAAQ,MAAO,GAAG,CAAC;CAEjE,OACE,oBAAC,OAAD;EACE,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,WAAW,GACT,kDACA,YAAY,OACZ,SACF;EACK;EACL,MAAK;EACL,GAAI;YAEJ,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG;EAClC,CAAA;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc"}
1
+ {"version":3,"file":"progress.js","names":["React"],"sources":["../../src/components/progress.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\nexport interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Current value */\n value: number\n /** Maximum value. Default: 100 */\n max?: number\n /** Height variant */\n size?: 'sm' | 'default' | 'lg'\n}\n\nconst sizeClasses = {\n sm: 'h-1',\n default: 'h-2',\n lg: 'h-3',\n} as const\n\nconst Progress = React.forwardRef<HTMLDivElement, ProgressProps>(\n ({ className, value, max = 100, size = 'default', ...props }, ref) => {\n const percentage = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div\n aria-valuemax={max}\n aria-valuemin={0}\n aria-valuenow={value}\n className={cn(\n 'w-full overflow-hidden rounded-full bg-gray-a4',\n sizeClasses[size],\n className,\n )}\n ref={ref}\n role=\"progressbar\"\n {...props}\n >\n <div\n className=\"h-full rounded-full bg-(--spark-style-bg,var(--spark-9)) transition-all duration-300\"\n style={{ width: `${percentage}%` }}\n />\n </div>\n )\n },\n)\n\nProgress.displayName = 'Progress'\n\nexport { Progress }\n"],"mappings":";;;;;AAYA,MAAM,cAAc;CAClB,IAAI;CACJ,SAAS;CACT,IAAI;AACN;AAEA,MAAM,WAAWA,QAAM,YACpB,EAAE,WAAW,OAAO,MAAM,KAAK,OAAO,WAAW,GAAG,SAAS,QAAQ;CACpE,MAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,GAAI,QAAQ,MAAO,GAAG,CAAC;CAEjE,OACE,oBAAC,OAAD;EACE,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,WAAW,GACT,kDACA,YAAY,OACZ,SACF;EACK;EACL,MAAK;EACL,GAAI;YAEJ,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG;EAClC,CAAA;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-card-group.cjs","names":["React"],"sources":["../../src/components/radio-card-group.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface RadioCardGroupContextValue {\n value: string | undefined\n onValueChange: (value: string) => void\n disabled?: boolean\n name: string\n}\n\nconst RadioCardGroupContext = React.createContext<\n RadioCardGroupContextValue | undefined\n>(undefined)\n\nconst ARROW_STEP: Record<string, 1 | -1> = {\n ArrowDown: 1,\n ArrowRight: 1,\n ArrowUp: -1,\n ArrowLeft: -1,\n}\n\ninterface RadioCardGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n disabled?: boolean\n /** Optional name used for ARIA grouping. Defaults to a generated id. */\n name?: string\n /** How many `--spark-layout-gap` units apart each card sits. */\n gap?: number\n}\n\nconst RadioCardGroup = React.forwardRef<HTMLDivElement, RadioCardGroupProps>(\n (\n {\n value: valueProp,\n defaultValue,\n onValueChange,\n disabled,\n name,\n gap = 2,\n className,\n style,\n children,\n ...props\n },\n ref,\n ) => {\n const generatedName = React.useId()\n const [internalValue, setInternalValue] = React.useState<\n string | undefined\n >(defaultValue)\n const isControlled = valueProp !== undefined\n const value = isControlled ? valueProp : internalValue\n\n const handleValueChange = React.useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange],\n )\n\n const ctx = React.useMemo<RadioCardGroupContextValue>(\n () => ({\n value,\n onValueChange: handleValueChange,\n disabled,\n name: name ?? generatedName,\n }),\n [value, handleValueChange, disabled, name, generatedName],\n )\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const step = ARROW_STEP[event.key]\n if (step === undefined && event.key !== 'Home' && event.key !== 'End')\n return\n const radios = [\n ...event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]:not(:disabled)',\n ),\n ]\n if (radios.length === 0) return\n event.preventDefault()\n\n let next = 0\n if (event.key === 'End') {\n next = radios.length - 1\n } else if (step !== undefined) {\n const current = radios.indexOf(\n document.activeElement as HTMLButtonElement,\n )\n if (current !== -1) {\n next = (current + step + radios.length) % radios.length\n }\n }\n const target = radios[next]\n if (!target) return\n target.focus()\n target.click()\n }\n\n return (\n <RadioCardGroupContext.Provider value={ctx}>\n <div\n ref={ref}\n role=\"radiogroup\"\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*var(--radio-card-group-gap-steps,2))]',\n className,\n )}\n style={\n {\n '--radio-card-group-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...props}\n >\n {children}\n </div>\n </RadioCardGroupContext.Provider>\n )\n },\n)\n\nRadioCardGroup.displayName = 'RadioCardGroup'\n\ninterface RadioCardGroupItemProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'value'\n> {\n value: string\n}\n\nconst RadioCardGroupItem = React.forwardRef<\n HTMLButtonElement,\n RadioCardGroupItemProps\n>(({ value, className, children, disabled, onClick, ...props }, ref) => {\n const ctx = React.useContext(RadioCardGroupContext)\n if (!ctx) {\n throw new Error('RadioCardGroupItem must be used within a RadioCardGroup')\n }\n\n const checked = ctx.value === value\n const isDisabled = disabled ?? ctx.disabled\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n data-state={checked ? 'checked' : 'unchecked'}\n tabIndex={checked || ctx.value === undefined ? 0 : -1}\n disabled={isDisabled}\n onClick={(event) => {\n onClick?.(event)\n if (!event.defaultPrevented && !isDisabled) {\n ctx.onValueChange(value)\n }\n }}\n className={cn(\n 'h-12 w-full rounded-lg px-4 text-base font-medium transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n checked\n ? 'border border-accent bg-base-accent-soft text-accent'\n : 'border border-transparent bg-base-gray-soft text-gray hover:bg-gray-a3',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n})\n\nRadioCardGroupItem.displayName = 'RadioCardGroupItem'\n\nexport { RadioCardGroup, RadioCardGroupItem }\nexport type { RadioCardGroupProps, RadioCardGroupItemProps }\n"],"mappings":";;;;;;;;AAUA,MAAM,wBAAwBA,MAAM,cAElC,KAAA,CAAS;AAEX,MAAM,aAAqC;CACzC,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;AACb;AAaA,MAAM,iBAAiBA,MAAM,YAEzB,EACE,OAAO,WACP,cACA,eACA,UACA,MACA,MAAM,GACN,WACA,OACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,gBAAgBA,MAAM,MAAM;CAClC,MAAM,CAAC,eAAe,oBAAoBA,MAAM,SAE9C,YAAY;CACd,MAAM,eAAe,cAAc,KAAA;CACnC,MAAM,QAAQ,eAAe,YAAY;CAEzC,MAAM,oBAAoBA,MAAM,aAC7B,SAAiB;EAChB,IAAI,CAAC,cAAc,iBAAiB,IAAI;EACxC,gBAAgB,IAAI;CACtB,GACA,CAAC,cAAc,aAAa,CAC9B;CAEA,MAAM,MAAMA,MAAM,eACT;EACL;EACA,eAAe;EACf;EACA,MAAM,QAAQ;CAChB,IACA;EAAC;EAAO;EAAmB;EAAU;EAAM;CAAa,CAC1D;CAEA,MAAM,iBAAiB,UAA+C;EACpE,MAAM,OAAO,WAAW,MAAM;EAC9B,IAAI,SAAS,KAAA,KAAa,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAC9D;EACF,MAAM,SAAS,CACb,GAAG,MAAM,cAAc,iBACrB,iCACF,CACF;EACA,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,eAAe;EAErB,IAAI,OAAO;EACX,IAAI,MAAM,QAAQ,OAChB,OAAO,OAAO,SAAS;OAClB,IAAI,SAAS,KAAA,GAAW;GAC7B,MAAM,UAAU,OAAO,QACrB,SAAS,aACX;GACA,IAAI,YAAY,IACd,QAAQ,UAAU,OAAO,OAAO,UAAU,OAAO;EAErD;EACA,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,QAAQ;EACb,OAAO,MAAM;EACb,OAAO,MAAM;CACf;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAC,sBAAsB,UAAvB;EAAgC,OAAO;YACrC,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACO;GACL,MAAK;GACL,WAAW;GACX,YAAA,GAAA,OAAA,IACE,yFACA,SACF;GACA,OACE;IACE,gCAAgC;IAChC,GAAG;GACL;GAEF,GAAI;GAEH;EACE,CAAA;CACyB,CAAA;AAEpC,CACF;AAEA,eAAe,cAAc;AAS7B,MAAM,qBAAqBA,MAAM,YAG9B,EAAE,OAAO,WAAW,UAAU,UAAU,SAAS,GAAG,SAAS,QAAQ;CACtE,MAAM,MAAMA,MAAM,WAAW,qBAAqB;CAClD,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,yDAAyD;CAG3E,MAAM,UAAU,IAAI,UAAU;CAC9B,MAAM,aAAa,YAAY,IAAI;CAEnC,OACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;EACO;EACL,MAAK;EACL,MAAK;EACL,gBAAc;EACd,cAAY,UAAU,YAAY;EAClC,UAAU,WAAW,IAAI,UAAU,KAAA,IAAY,IAAI;EACnD,UAAU;EACV,UAAU,UAAU;GAClB,UAAU,KAAK;GACf,IAAI,CAAC,MAAM,oBAAoB,CAAC,YAC9B,IAAI,cAAc,KAAK;EAE3B;EACA,YAAA,GAAA,OAAA,IACE,qMACA,UACI,yDACA,0EACJ,SACF;EACA,GAAI;EAEH;CACK,CAAA;AAEZ,CAAC;AAED,mBAAmB,cAAc"}
1
+ {"version":3,"file":"radio-card-group.cjs","names":["React"],"sources":["../../src/components/radio-card-group.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface RadioCardGroupContextValue {\n value: string | undefined\n onValueChange: (value: string) => void\n disabled?: boolean\n name: string\n}\n\nconst RadioCardGroupContext = React.createContext<\n RadioCardGroupContextValue | undefined\n>(undefined)\n\nconst ARROW_STEP: Record<string, 1 | -1> = {\n ArrowDown: 1,\n ArrowRight: 1,\n ArrowUp: -1,\n ArrowLeft: -1,\n}\n\ninterface RadioCardGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n disabled?: boolean\n /** Optional name used for ARIA grouping. Defaults to a generated id. */\n name?: string\n /** How many `--spark-layout-gap` units apart each card sits. */\n gap?: number\n}\n\nconst RadioCardGroup = React.forwardRef<HTMLDivElement, RadioCardGroupProps>(\n (\n {\n value: valueProp,\n defaultValue,\n onValueChange,\n disabled,\n name,\n gap = 2,\n className,\n style,\n children,\n ...props\n },\n ref,\n ) => {\n const generatedName = React.useId()\n const [internalValue, setInternalValue] = React.useState<\n string | undefined\n >(defaultValue)\n const isControlled = valueProp !== undefined\n const value = isControlled ? valueProp : internalValue\n\n const handleValueChange = React.useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange],\n )\n\n const ctx = React.useMemo<RadioCardGroupContextValue>(\n () => ({\n value,\n onValueChange: handleValueChange,\n disabled,\n name: name ?? generatedName,\n }),\n [value, handleValueChange, disabled, name, generatedName],\n )\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const step = ARROW_STEP[event.key]\n if (step === undefined && event.key !== 'Home' && event.key !== 'End')\n return\n const radios = [\n ...event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]:not(:disabled)',\n ),\n ]\n if (radios.length === 0) return\n event.preventDefault()\n\n let next = 0\n if (event.key === 'End') {\n next = radios.length - 1\n } else if (step !== undefined) {\n const current = radios.indexOf(\n document.activeElement as HTMLButtonElement,\n )\n if (current !== -1) {\n next = (current + step + radios.length) % radios.length\n }\n }\n const target = radios[next]\n if (!target) return\n target.focus()\n target.click()\n }\n\n return (\n <RadioCardGroupContext.Provider value={ctx}>\n {/* oxlint-disable-next-line jsx-a11y/interactive-supports-focus -- radiogroup is a composite: the tab stop belongs on the roving radios, not the container */}\n <div\n ref={ref}\n role=\"radiogroup\"\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*var(--radio-card-group-gap-steps,2))]',\n className,\n )}\n style={\n {\n '--radio-card-group-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...props}\n >\n {children}\n </div>\n </RadioCardGroupContext.Provider>\n )\n },\n)\n\nRadioCardGroup.displayName = 'RadioCardGroup'\n\ninterface RadioCardGroupItemProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'value'\n> {\n value: string\n}\n\nconst RadioCardGroupItem = React.forwardRef<\n HTMLButtonElement,\n RadioCardGroupItemProps\n>(({ value, className, children, disabled, onClick, ...props }, ref) => {\n const ctx = React.useContext(RadioCardGroupContext)\n if (!ctx) {\n throw new Error('RadioCardGroupItem must be used within a RadioCardGroup')\n }\n\n const checked = ctx.value === value\n const isDisabled = disabled ?? ctx.disabled\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n data-state={checked ? 'checked' : 'unchecked'}\n tabIndex={checked || ctx.value === undefined ? 0 : -1}\n disabled={isDisabled}\n onClick={(event) => {\n onClick?.(event)\n if (!event.defaultPrevented && !isDisabled) {\n ctx.onValueChange(value)\n }\n }}\n className={cn(\n 'h-12 w-full rounded-lg px-4 text-base font-medium transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n checked\n ? 'border border-accent bg-base-accent-soft text-accent'\n : 'border border-transparent bg-base-gray-soft text-gray hover:bg-gray-a3',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n})\n\nRadioCardGroupItem.displayName = 'RadioCardGroupItem'\n\nexport { RadioCardGroup, RadioCardGroupItem }\nexport type { RadioCardGroupProps, RadioCardGroupItemProps }\n"],"mappings":";;;;;;;;AAUA,MAAM,wBAAwBA,MAAM,cAElC,KAAA,CAAS;AAEX,MAAM,aAAqC;CACzC,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;AACb;AAaA,MAAM,iBAAiBA,MAAM,YAEzB,EACE,OAAO,WACP,cACA,eACA,UACA,MACA,MAAM,GACN,WACA,OACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,gBAAgBA,MAAM,MAAM;CAClC,MAAM,CAAC,eAAe,oBAAoBA,MAAM,SAE9C,YAAY;CACd,MAAM,eAAe,cAAc,KAAA;CACnC,MAAM,QAAQ,eAAe,YAAY;CAEzC,MAAM,oBAAoBA,MAAM,aAC7B,SAAiB;EAChB,IAAI,CAAC,cAAc,iBAAiB,IAAI;EACxC,gBAAgB,IAAI;CACtB,GACA,CAAC,cAAc,aAAa,CAC9B;CAEA,MAAM,MAAMA,MAAM,eACT;EACL;EACA,eAAe;EACf;EACA,MAAM,QAAQ;CAChB,IACA;EAAC;EAAO;EAAmB;EAAU;EAAM;CAAa,CAC1D;CAEA,MAAM,iBAAiB,UAA+C;EACpE,MAAM,OAAO,WAAW,MAAM;EAC9B,IAAI,SAAS,KAAA,KAAa,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAC9D;EACF,MAAM,SAAS,CACb,GAAG,MAAM,cAAc,iBACrB,iCACF,CACF;EACA,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,eAAe;EAErB,IAAI,OAAO;EACX,IAAI,MAAM,QAAQ,OAChB,OAAO,OAAO,SAAS;OAClB,IAAI,SAAS,KAAA,GAAW;GAC7B,MAAM,UAAU,OAAO,QACrB,SAAS,aACX;GACA,IAAI,YAAY,IACd,QAAQ,UAAU,OAAO,OAAO,UAAU,OAAO;EAErD;EACA,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,QAAQ;EACb,OAAO,MAAM;EACb,OAAO,MAAM;CACf;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAC,sBAAsB,UAAvB;EAAgC,OAAO;YAErC,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACO;GACL,MAAK;GACL,WAAW;GACX,YAAA,GAAA,OAAA,IACE,yFACA,SACF;GACA,OACE;IACE,gCAAgC;IAChC,GAAG;GACL;GAEF,GAAI;GAEH;EACE,CAAA;CACyB,CAAA;AAEpC,CACF;AAEA,eAAe,cAAc;AAS7B,MAAM,qBAAqBA,MAAM,YAG9B,EAAE,OAAO,WAAW,UAAU,UAAU,SAAS,GAAG,SAAS,QAAQ;CACtE,MAAM,MAAMA,MAAM,WAAW,qBAAqB;CAClD,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,yDAAyD;CAG3E,MAAM,UAAU,IAAI,UAAU;CAC9B,MAAM,aAAa,YAAY,IAAI;CAEnC,OACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;EACO;EACL,MAAK;EACL,MAAK;EACL,gBAAc;EACd,cAAY,UAAU,YAAY;EAClC,UAAU,WAAW,IAAI,UAAU,KAAA,IAAY,IAAI;EACnD,UAAU;EACV,UAAU,UAAU;GAClB,UAAU,KAAK;GACf,IAAI,CAAC,MAAM,oBAAoB,CAAC,YAC9B,IAAI,cAAc,KAAK;EAE3B;EACA,YAAA,GAAA,OAAA,IACE,qMACA,UACI,yDACA,0EACJ,SACF;EACA,GAAI;EAEH;CACK,CAAA;AAEZ,CAAC;AAED,mBAAmB,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-card-group.js","names":["React"],"sources":["../../src/components/radio-card-group.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface RadioCardGroupContextValue {\n value: string | undefined\n onValueChange: (value: string) => void\n disabled?: boolean\n name: string\n}\n\nconst RadioCardGroupContext = React.createContext<\n RadioCardGroupContextValue | undefined\n>(undefined)\n\nconst ARROW_STEP: Record<string, 1 | -1> = {\n ArrowDown: 1,\n ArrowRight: 1,\n ArrowUp: -1,\n ArrowLeft: -1,\n}\n\ninterface RadioCardGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n disabled?: boolean\n /** Optional name used for ARIA grouping. Defaults to a generated id. */\n name?: string\n /** How many `--spark-layout-gap` units apart each card sits. */\n gap?: number\n}\n\nconst RadioCardGroup = React.forwardRef<HTMLDivElement, RadioCardGroupProps>(\n (\n {\n value: valueProp,\n defaultValue,\n onValueChange,\n disabled,\n name,\n gap = 2,\n className,\n style,\n children,\n ...props\n },\n ref,\n ) => {\n const generatedName = React.useId()\n const [internalValue, setInternalValue] = React.useState<\n string | undefined\n >(defaultValue)\n const isControlled = valueProp !== undefined\n const value = isControlled ? valueProp : internalValue\n\n const handleValueChange = React.useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange],\n )\n\n const ctx = React.useMemo<RadioCardGroupContextValue>(\n () => ({\n value,\n onValueChange: handleValueChange,\n disabled,\n name: name ?? generatedName,\n }),\n [value, handleValueChange, disabled, name, generatedName],\n )\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const step = ARROW_STEP[event.key]\n if (step === undefined && event.key !== 'Home' && event.key !== 'End')\n return\n const radios = [\n ...event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]:not(:disabled)',\n ),\n ]\n if (radios.length === 0) return\n event.preventDefault()\n\n let next = 0\n if (event.key === 'End') {\n next = radios.length - 1\n } else if (step !== undefined) {\n const current = radios.indexOf(\n document.activeElement as HTMLButtonElement,\n )\n if (current !== -1) {\n next = (current + step + radios.length) % radios.length\n }\n }\n const target = radios[next]\n if (!target) return\n target.focus()\n target.click()\n }\n\n return (\n <RadioCardGroupContext.Provider value={ctx}>\n <div\n ref={ref}\n role=\"radiogroup\"\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*var(--radio-card-group-gap-steps,2))]',\n className,\n )}\n style={\n {\n '--radio-card-group-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...props}\n >\n {children}\n </div>\n </RadioCardGroupContext.Provider>\n )\n },\n)\n\nRadioCardGroup.displayName = 'RadioCardGroup'\n\ninterface RadioCardGroupItemProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'value'\n> {\n value: string\n}\n\nconst RadioCardGroupItem = React.forwardRef<\n HTMLButtonElement,\n RadioCardGroupItemProps\n>(({ value, className, children, disabled, onClick, ...props }, ref) => {\n const ctx = React.useContext(RadioCardGroupContext)\n if (!ctx) {\n throw new Error('RadioCardGroupItem must be used within a RadioCardGroup')\n }\n\n const checked = ctx.value === value\n const isDisabled = disabled ?? ctx.disabled\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n data-state={checked ? 'checked' : 'unchecked'}\n tabIndex={checked || ctx.value === undefined ? 0 : -1}\n disabled={isDisabled}\n onClick={(event) => {\n onClick?.(event)\n if (!event.defaultPrevented && !isDisabled) {\n ctx.onValueChange(value)\n }\n }}\n className={cn(\n 'h-12 w-full rounded-lg px-4 text-base font-medium transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n checked\n ? 'border border-accent bg-base-accent-soft text-accent'\n : 'border border-transparent bg-base-gray-soft text-gray hover:bg-gray-a3',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n})\n\nRadioCardGroupItem.displayName = 'RadioCardGroupItem'\n\nexport { RadioCardGroup, RadioCardGroupItem }\nexport type { RadioCardGroupProps, RadioCardGroupItemProps }\n"],"mappings":";;;;;AAUA,MAAM,wBAAwBA,QAAM,cAElC,KAAA,CAAS;AAEX,MAAM,aAAqC;CACzC,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;AACb;AAaA,MAAM,iBAAiBA,QAAM,YAEzB,EACE,OAAO,WACP,cACA,eACA,UACA,MACA,MAAM,GACN,WACA,OACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,gBAAgBA,QAAM,MAAM;CAClC,MAAM,CAAC,eAAe,oBAAoBA,QAAM,SAE9C,YAAY;CACd,MAAM,eAAe,cAAc,KAAA;CACnC,MAAM,QAAQ,eAAe,YAAY;CAEzC,MAAM,oBAAoBA,QAAM,aAC7B,SAAiB;EAChB,IAAI,CAAC,cAAc,iBAAiB,IAAI;EACxC,gBAAgB,IAAI;CACtB,GACA,CAAC,cAAc,aAAa,CAC9B;CAEA,MAAM,MAAMA,QAAM,eACT;EACL;EACA,eAAe;EACf;EACA,MAAM,QAAQ;CAChB,IACA;EAAC;EAAO;EAAmB;EAAU;EAAM;CAAa,CAC1D;CAEA,MAAM,iBAAiB,UAA+C;EACpE,MAAM,OAAO,WAAW,MAAM;EAC9B,IAAI,SAAS,KAAA,KAAa,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAC9D;EACF,MAAM,SAAS,CACb,GAAG,MAAM,cAAc,iBACrB,iCACF,CACF;EACA,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,eAAe;EAErB,IAAI,OAAO;EACX,IAAI,MAAM,QAAQ,OAChB,OAAO,OAAO,SAAS;OAClB,IAAI,SAAS,KAAA,GAAW;GAC7B,MAAM,UAAU,OAAO,QACrB,SAAS,aACX;GACA,IAAI,YAAY,IACd,QAAQ,UAAU,OAAO,OAAO,UAAU,OAAO;EAErD;EACA,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,QAAQ;EACb,OAAO,MAAM;EACb,OAAO,MAAM;CACf;CAEA,OACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;YACrC,oBAAC,OAAD;GACO;GACL,MAAK;GACL,WAAW;GACX,WAAW,GACT,yFACA,SACF;GACA,OACE;IACE,gCAAgC;IAChC,GAAG;GACL;GAEF,GAAI;GAEH;EACE,CAAA;CACyB,CAAA;AAEpC,CACF;AAEA,eAAe,cAAc;AAS7B,MAAM,qBAAqBA,QAAM,YAG9B,EAAE,OAAO,WAAW,UAAU,UAAU,SAAS,GAAG,SAAS,QAAQ;CACtE,MAAM,MAAMA,QAAM,WAAW,qBAAqB;CAClD,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,yDAAyD;CAG3E,MAAM,UAAU,IAAI,UAAU;CAC9B,MAAM,aAAa,YAAY,IAAI;CAEnC,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,MAAK;EACL,gBAAc;EACd,cAAY,UAAU,YAAY;EAClC,UAAU,WAAW,IAAI,UAAU,KAAA,IAAY,IAAI;EACnD,UAAU;EACV,UAAU,UAAU;GAClB,UAAU,KAAK;GACf,IAAI,CAAC,MAAM,oBAAoB,CAAC,YAC9B,IAAI,cAAc,KAAK;EAE3B;EACA,WAAW,GACT,qMACA,UACI,yDACA,0EACJ,SACF;EACA,GAAI;EAEH;CACK,CAAA;AAEZ,CAAC;AAED,mBAAmB,cAAc"}
1
+ {"version":3,"file":"radio-card-group.js","names":["React"],"sources":["../../src/components/radio-card-group.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface RadioCardGroupContextValue {\n value: string | undefined\n onValueChange: (value: string) => void\n disabled?: boolean\n name: string\n}\n\nconst RadioCardGroupContext = React.createContext<\n RadioCardGroupContextValue | undefined\n>(undefined)\n\nconst ARROW_STEP: Record<string, 1 | -1> = {\n ArrowDown: 1,\n ArrowRight: 1,\n ArrowUp: -1,\n ArrowLeft: -1,\n}\n\ninterface RadioCardGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n disabled?: boolean\n /** Optional name used for ARIA grouping. Defaults to a generated id. */\n name?: string\n /** How many `--spark-layout-gap` units apart each card sits. */\n gap?: number\n}\n\nconst RadioCardGroup = React.forwardRef<HTMLDivElement, RadioCardGroupProps>(\n (\n {\n value: valueProp,\n defaultValue,\n onValueChange,\n disabled,\n name,\n gap = 2,\n className,\n style,\n children,\n ...props\n },\n ref,\n ) => {\n const generatedName = React.useId()\n const [internalValue, setInternalValue] = React.useState<\n string | undefined\n >(defaultValue)\n const isControlled = valueProp !== undefined\n const value = isControlled ? valueProp : internalValue\n\n const handleValueChange = React.useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next)\n onValueChange?.(next)\n },\n [isControlled, onValueChange],\n )\n\n const ctx = React.useMemo<RadioCardGroupContextValue>(\n () => ({\n value,\n onValueChange: handleValueChange,\n disabled,\n name: name ?? generatedName,\n }),\n [value, handleValueChange, disabled, name, generatedName],\n )\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n const step = ARROW_STEP[event.key]\n if (step === undefined && event.key !== 'Home' && event.key !== 'End')\n return\n const radios = [\n ...event.currentTarget.querySelectorAll<HTMLButtonElement>(\n '[role=\"radio\"]:not(:disabled)',\n ),\n ]\n if (radios.length === 0) return\n event.preventDefault()\n\n let next = 0\n if (event.key === 'End') {\n next = radios.length - 1\n } else if (step !== undefined) {\n const current = radios.indexOf(\n document.activeElement as HTMLButtonElement,\n )\n if (current !== -1) {\n next = (current + step + radios.length) % radios.length\n }\n }\n const target = radios[next]\n if (!target) return\n target.focus()\n target.click()\n }\n\n return (\n <RadioCardGroupContext.Provider value={ctx}>\n {/* oxlint-disable-next-line jsx-a11y/interactive-supports-focus -- radiogroup is a composite: the tab stop belongs on the roving radios, not the container */}\n <div\n ref={ref}\n role=\"radiogroup\"\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*var(--radio-card-group-gap-steps,2))]',\n className,\n )}\n style={\n {\n '--radio-card-group-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...props}\n >\n {children}\n </div>\n </RadioCardGroupContext.Provider>\n )\n },\n)\n\nRadioCardGroup.displayName = 'RadioCardGroup'\n\ninterface RadioCardGroupItemProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'value'\n> {\n value: string\n}\n\nconst RadioCardGroupItem = React.forwardRef<\n HTMLButtonElement,\n RadioCardGroupItemProps\n>(({ value, className, children, disabled, onClick, ...props }, ref) => {\n const ctx = React.useContext(RadioCardGroupContext)\n if (!ctx) {\n throw new Error('RadioCardGroupItem must be used within a RadioCardGroup')\n }\n\n const checked = ctx.value === value\n const isDisabled = disabled ?? ctx.disabled\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"radio\"\n aria-checked={checked}\n data-state={checked ? 'checked' : 'unchecked'}\n tabIndex={checked || ctx.value === undefined ? 0 : -1}\n disabled={isDisabled}\n onClick={(event) => {\n onClick?.(event)\n if (!event.defaultPrevented && !isDisabled) {\n ctx.onValueChange(value)\n }\n }}\n className={cn(\n 'h-12 w-full rounded-lg px-4 text-base font-medium transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n checked\n ? 'border border-accent bg-base-accent-soft text-accent'\n : 'border border-transparent bg-base-gray-soft text-gray hover:bg-gray-a3',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n})\n\nRadioCardGroupItem.displayName = 'RadioCardGroupItem'\n\nexport { RadioCardGroup, RadioCardGroupItem }\nexport type { RadioCardGroupProps, RadioCardGroupItemProps }\n"],"mappings":";;;;;AAUA,MAAM,wBAAwBA,QAAM,cAElC,KAAA,CAAS;AAEX,MAAM,aAAqC;CACzC,WAAW;CACX,YAAY;CACZ,SAAS;CACT,WAAW;AACb;AAaA,MAAM,iBAAiBA,QAAM,YAEzB,EACE,OAAO,WACP,cACA,eACA,UACA,MACA,MAAM,GACN,WACA,OACA,UACA,GAAG,SAEL,QACG;CACH,MAAM,gBAAgBA,QAAM,MAAM;CAClC,MAAM,CAAC,eAAe,oBAAoBA,QAAM,SAE9C,YAAY;CACd,MAAM,eAAe,cAAc,KAAA;CACnC,MAAM,QAAQ,eAAe,YAAY;CAEzC,MAAM,oBAAoBA,QAAM,aAC7B,SAAiB;EAChB,IAAI,CAAC,cAAc,iBAAiB,IAAI;EACxC,gBAAgB,IAAI;CACtB,GACA,CAAC,cAAc,aAAa,CAC9B;CAEA,MAAM,MAAMA,QAAM,eACT;EACL;EACA,eAAe;EACf;EACA,MAAM,QAAQ;CAChB,IACA;EAAC;EAAO;EAAmB;EAAU;EAAM;CAAa,CAC1D;CAEA,MAAM,iBAAiB,UAA+C;EACpE,MAAM,OAAO,WAAW,MAAM;EAC9B,IAAI,SAAS,KAAA,KAAa,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAC9D;EACF,MAAM,SAAS,CACb,GAAG,MAAM,cAAc,iBACrB,iCACF,CACF;EACA,IAAI,OAAO,WAAW,GAAG;EACzB,MAAM,eAAe;EAErB,IAAI,OAAO;EACX,IAAI,MAAM,QAAQ,OAChB,OAAO,OAAO,SAAS;OAClB,IAAI,SAAS,KAAA,GAAW;GAC7B,MAAM,UAAU,OAAO,QACrB,SAAS,aACX;GACA,IAAI,YAAY,IACd,QAAQ,UAAU,OAAO,OAAO,UAAU,OAAO;EAErD;EACA,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,QAAQ;EACb,OAAO,MAAM;EACb,OAAO,MAAM;CACf;CAEA,OACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;YAErC,oBAAC,OAAD;GACO;GACL,MAAK;GACL,WAAW;GACX,WAAW,GACT,yFACA,SACF;GACA,OACE;IACE,gCAAgC;IAChC,GAAG;GACL;GAEF,GAAI;GAEH;EACE,CAAA;CACyB,CAAA;AAEpC,CACF;AAEA,eAAe,cAAc;AAS7B,MAAM,qBAAqBA,QAAM,YAG9B,EAAE,OAAO,WAAW,UAAU,UAAU,SAAS,GAAG,SAAS,QAAQ;CACtE,MAAM,MAAMA,QAAM,WAAW,qBAAqB;CAClD,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,yDAAyD;CAG3E,MAAM,UAAU,IAAI,UAAU;CAC9B,MAAM,aAAa,YAAY,IAAI;CAEnC,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,MAAK;EACL,gBAAc;EACd,cAAY,UAAU,YAAY;EAClC,UAAU,WAAW,IAAI,UAAU,KAAA,IAAY,IAAI;EACnD,UAAU;EACV,UAAU,UAAU;GAClB,UAAU,KAAK;GACf,IAAI,CAAC,MAAM,oBAAoB,CAAC,YAC9B,IAAI,cAAc,KAAK;EAE3B;EACA,WAAW,GACT,qMACA,UACI,yDACA,0EACJ,SACF;EACA,GAAI;EAEH;CACK,CAAA;AAEZ,CAAC;AAED,mBAAmB,cAAc"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.cjs";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.cjs";
4
4
  import * as React$1 from "react";
5
5
  import { Radio as Radio$1 } from "@base-ui/react/radio";
6
6
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.js";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.js";
4
4
  import * as React$1 from "react";
5
5
  import { Radio as Radio$1 } from "@base-ui/react/radio";
6
6
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
@@ -34,13 +34,15 @@ const ScheduleEntry = react.forwardRef(({ children, className, disabled, onClick
34
34
  const interactive = onClick !== void 0 && !disabled;
35
35
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
36
36
  ref,
37
- role: interactive ? "button" : void 0,
38
- tabIndex: interactive ? 0 : void 0,
39
- onClick: interactive ? onClick : void 0,
40
- onKeyDown: interactive ? (event) => {
41
- if (event.key === "Enter" || event.key === " ") {
42
- event.preventDefault();
43
- onClick();
37
+ ...interactive ? {
38
+ role: "button",
39
+ tabIndex: 0,
40
+ onClick,
41
+ onKeyDown: (event) => {
42
+ if (event.key === "Enter" || event.key === " ") {
43
+ event.preventDefault();
44
+ onClick();
45
+ }
44
46
  }
45
47
  } : void 0,
46
48
  "aria-disabled": disabled || void 0,
@@ -72,6 +74,7 @@ ScheduleEntrySubtitle.displayName = "ScheduleEntrySubtitle";
72
74
  * don't fire the parent `ScheduleEntry`'s `onClick`. */
73
75
  const ScheduleEntryActions = react.forwardRef(({ className, onClick, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
74
76
  ref,
77
+ role: "presentation",
75
78
  onClick: (event) => {
76
79
  event.stopPropagation();
77
80
  onClick?.(event);
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-list.cjs","names":["React","MaterialSymbol"],"sources":["../../src/components/schedule-list.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst ScheduleList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*2)]',\n className,\n )}\n {...props}\n />\n))\n\nScheduleList.displayName = 'ScheduleList'\n\nconst ScheduleListEmpty = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('px-3 py-2 text-sm text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleListEmpty.displayName = 'ScheduleListEmpty'\n\ninterface ScheduleListAddProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon override; defaults to a `+`. */\n icon?: React.ReactNode\n}\n\nconst ScheduleListAdd = React.forwardRef<\n HTMLButtonElement,\n ScheduleListAddProps\n>(({ children, className, icon, type = 'button', ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n 'inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-2xl border border-dashed border-gray text-sm font-medium text-gray-light transition-colors hover:border-spark-a8 hover:bg-base-accent-soft hover:text-accent focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {icon ?? <MaterialSymbol className=\"text-[14px]\" name=\"add\" />}\n {children}\n </button>\n))\n\nScheduleListAdd.displayName = 'ScheduleListAdd'\n\ninterface ScheduleEntryProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Make the row interactive — enables hover, role=button, keyboard activation. */\n onClick?: () => void\n disabled?: boolean\n}\n\nconst ScheduleEntry = React.forwardRef<HTMLDivElement, ScheduleEntryProps>(\n ({ children, className, disabled, onClick, ...props }, ref) => {\n const interactive = onClick !== undefined && !disabled\n return (\n <div\n ref={ref}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive ? 0 : undefined}\n onClick={interactive ? onClick : undefined}\n onKeyDown={\n interactive\n ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n }\n : undefined\n }\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex items-center gap-3 rounded-2xl bg-base-gray-soft px-3 py-2.5 transition-colors',\n interactive &&\n 'cursor-pointer hover:bg-gray-a3 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n },\n)\n\nScheduleEntry.displayName = 'ScheduleEntry'\n\nconst ScheduleEntryContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col gap-0.5', className)}\n {...props}\n />\n))\n\nScheduleEntryContent.displayName = 'ScheduleEntryContent'\n\nconst ScheduleEntryTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex min-w-0 items-center gap-2 truncate text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n))\n\nScheduleEntryTitle.displayName = 'ScheduleEntryTitle'\n\nconst ScheduleEntrySubtitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n className={cn('truncate text-xs text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleEntrySubtitle.displayName = 'ScheduleEntrySubtitle'\n\n/** Right-aligned action area. Stops click propagation so inner controls\n * don't fire the parent `ScheduleEntry`'s `onClick`. */\nconst ScheduleEntryActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, onClick, ...props }, ref) => (\n <div\n ref={ref}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn('flex shrink-0 items-center gap-1.5', className)}\n {...props}\n />\n))\n\nScheduleEntryActions.displayName = 'ScheduleEntryActions'\n\ninterface ScheduleEntryDeleteProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nconst ScheduleEntryDelete = React.forwardRef<\n HTMLButtonElement,\n ScheduleEntryDeleteProps\n>(\n (\n {\n 'aria-label': ariaLabel = 'Delete schedule entry',\n children,\n className,\n onClick,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn(\n 'inline-flex size-8 shrink-0 items-center justify-center rounded-circle text-gray-light transition-colors hover:bg-base-error-soft hover:text-error focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children ?? <MaterialSymbol className=\"text-[14px]\" name=\"delete\" />}\n </button>\n ),\n)\n\nScheduleEntryDelete.displayName = 'ScheduleEntryDelete'\n\nexport {\n ScheduleEntry,\n ScheduleEntryActions,\n ScheduleEntryContent,\n ScheduleEntryDelete,\n ScheduleEntrySubtitle,\n ScheduleEntryTitle,\n ScheduleList,\n ScheduleListAdd,\n ScheduleListEmpty,\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schedule-list.cjs","names":["React","MaterialSymbol"],"sources":["../../src/components/schedule-list.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst ScheduleList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*2)]',\n className,\n )}\n {...props}\n />\n))\n\nScheduleList.displayName = 'ScheduleList'\n\nconst ScheduleListEmpty = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('px-3 py-2 text-sm text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleListEmpty.displayName = 'ScheduleListEmpty'\n\ninterface ScheduleListAddProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon override; defaults to a `+`. */\n icon?: React.ReactNode\n}\n\nconst ScheduleListAdd = React.forwardRef<\n HTMLButtonElement,\n ScheduleListAddProps\n>(({ children, className, icon, type = 'button', ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n 'inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-2xl border border-dashed border-gray text-sm font-medium text-gray-light transition-colors hover:border-spark-a8 hover:bg-base-accent-soft hover:text-accent focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {icon ?? <MaterialSymbol className=\"text-[14px]\" name=\"add\" />}\n {children}\n </button>\n))\n\nScheduleListAdd.displayName = 'ScheduleListAdd'\n\ninterface ScheduleEntryProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Make the row interactive — enables hover, role=button, keyboard activation. */\n onClick?: () => void\n disabled?: boolean\n}\n\nconst ScheduleEntry = React.forwardRef<HTMLDivElement, ScheduleEntryProps>(\n ({ children, className, disabled, onClick, ...props }, ref) => {\n const interactive = onClick !== undefined && !disabled\n // role, tab stop and key handler travel together -- the row is never\n // clickable without Enter/Space, and never focusable without a role\n const interaction = interactive\n ? {\n role: 'button' as const,\n tabIndex: 0,\n onClick,\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n },\n }\n : undefined\n return (\n <div\n ref={ref}\n {...interaction}\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex items-center gap-3 rounded-2xl bg-base-gray-soft px-3 py-2.5 transition-colors',\n interactive &&\n 'cursor-pointer hover:bg-gray-a3 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n },\n)\n\nScheduleEntry.displayName = 'ScheduleEntry'\n\nconst ScheduleEntryContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col gap-0.5', className)}\n {...props}\n />\n))\n\nScheduleEntryContent.displayName = 'ScheduleEntryContent'\n\nconst ScheduleEntryTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex min-w-0 items-center gap-2 truncate text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n))\n\nScheduleEntryTitle.displayName = 'ScheduleEntryTitle'\n\nconst ScheduleEntrySubtitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n className={cn('truncate text-xs text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleEntrySubtitle.displayName = 'ScheduleEntrySubtitle'\n\n/** Right-aligned action area. Stops click propagation so inner controls\n * don't fire the parent `ScheduleEntry`'s `onClick`. */\nconst ScheduleEntryActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, onClick, ...props }, ref) => (\n <div\n ref={ref}\n // a layout wrapper, not a control: the handler only shields the inner\n // buttons' clicks (keyboard activation included) from the parent row\n role=\"presentation\"\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn('flex shrink-0 items-center gap-1.5', className)}\n {...props}\n />\n))\n\nScheduleEntryActions.displayName = 'ScheduleEntryActions'\n\ninterface ScheduleEntryDeleteProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nconst ScheduleEntryDelete = React.forwardRef<\n HTMLButtonElement,\n ScheduleEntryDeleteProps\n>(\n (\n {\n 'aria-label': ariaLabel = 'Delete schedule entry',\n children,\n className,\n onClick,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn(\n 'inline-flex size-8 shrink-0 items-center justify-center rounded-circle text-gray-light transition-colors hover:bg-base-error-soft hover:text-error focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children ?? <MaterialSymbol className=\"text-[14px]\" name=\"delete\" />}\n </button>\n ),\n)\n\nScheduleEntryDelete.displayName = 'ScheduleEntryDelete'\n\nexport {\n ScheduleEntry,\n ScheduleEntryActions,\n ScheduleEntryContent,\n ScheduleEntryDelete,\n ScheduleEntrySubtitle,\n ScheduleEntryTitle,\n ScheduleList,\n ScheduleListAdd,\n ScheduleListEmpty,\n}\n"],"mappings":"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"}
@@ -31,13 +31,15 @@ const ScheduleEntry = React$1.forwardRef(({ children, className, disabled, onCli
31
31
  const interactive = onClick !== void 0 && !disabled;
32
32
  return /* @__PURE__ */ jsx("div", {
33
33
  ref,
34
- role: interactive ? "button" : void 0,
35
- tabIndex: interactive ? 0 : void 0,
36
- onClick: interactive ? onClick : void 0,
37
- onKeyDown: interactive ? (event) => {
38
- if (event.key === "Enter" || event.key === " ") {
39
- event.preventDefault();
40
- onClick();
34
+ ...interactive ? {
35
+ role: "button",
36
+ tabIndex: 0,
37
+ onClick,
38
+ onKeyDown: (event) => {
39
+ if (event.key === "Enter" || event.key === " ") {
40
+ event.preventDefault();
41
+ onClick();
42
+ }
41
43
  }
42
44
  } : void 0,
43
45
  "aria-disabled": disabled || void 0,
@@ -69,6 +71,7 @@ ScheduleEntrySubtitle.displayName = "ScheduleEntrySubtitle";
69
71
  * don't fire the parent `ScheduleEntry`'s `onClick`. */
70
72
  const ScheduleEntryActions = React$1.forwardRef(({ className, onClick, ...props }, ref) => /* @__PURE__ */ jsx("div", {
71
73
  ref,
74
+ role: "presentation",
72
75
  onClick: (event) => {
73
76
  event.stopPropagation();
74
77
  onClick?.(event);
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-list.js","names":["React"],"sources":["../../src/components/schedule-list.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst ScheduleList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*2)]',\n className,\n )}\n {...props}\n />\n))\n\nScheduleList.displayName = 'ScheduleList'\n\nconst ScheduleListEmpty = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('px-3 py-2 text-sm text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleListEmpty.displayName = 'ScheduleListEmpty'\n\ninterface ScheduleListAddProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon override; defaults to a `+`. */\n icon?: React.ReactNode\n}\n\nconst ScheduleListAdd = React.forwardRef<\n HTMLButtonElement,\n ScheduleListAddProps\n>(({ children, className, icon, type = 'button', ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n 'inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-2xl border border-dashed border-gray text-sm font-medium text-gray-light transition-colors hover:border-spark-a8 hover:bg-base-accent-soft hover:text-accent focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {icon ?? <MaterialSymbol className=\"text-[14px]\" name=\"add\" />}\n {children}\n </button>\n))\n\nScheduleListAdd.displayName = 'ScheduleListAdd'\n\ninterface ScheduleEntryProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Make the row interactive — enables hover, role=button, keyboard activation. */\n onClick?: () => void\n disabled?: boolean\n}\n\nconst ScheduleEntry = React.forwardRef<HTMLDivElement, ScheduleEntryProps>(\n ({ children, className, disabled, onClick, ...props }, ref) => {\n const interactive = onClick !== undefined && !disabled\n return (\n <div\n ref={ref}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive ? 0 : undefined}\n onClick={interactive ? onClick : undefined}\n onKeyDown={\n interactive\n ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n }\n : undefined\n }\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex items-center gap-3 rounded-2xl bg-base-gray-soft px-3 py-2.5 transition-colors',\n interactive &&\n 'cursor-pointer hover:bg-gray-a3 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n },\n)\n\nScheduleEntry.displayName = 'ScheduleEntry'\n\nconst ScheduleEntryContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col gap-0.5', className)}\n {...props}\n />\n))\n\nScheduleEntryContent.displayName = 'ScheduleEntryContent'\n\nconst ScheduleEntryTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex min-w-0 items-center gap-2 truncate text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n))\n\nScheduleEntryTitle.displayName = 'ScheduleEntryTitle'\n\nconst ScheduleEntrySubtitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n className={cn('truncate text-xs text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleEntrySubtitle.displayName = 'ScheduleEntrySubtitle'\n\n/** Right-aligned action area. Stops click propagation so inner controls\n * don't fire the parent `ScheduleEntry`'s `onClick`. */\nconst ScheduleEntryActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, onClick, ...props }, ref) => (\n <div\n ref={ref}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn('flex shrink-0 items-center gap-1.5', className)}\n {...props}\n />\n))\n\nScheduleEntryActions.displayName = 'ScheduleEntryActions'\n\ninterface ScheduleEntryDeleteProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nconst ScheduleEntryDelete = React.forwardRef<\n HTMLButtonElement,\n ScheduleEntryDeleteProps\n>(\n (\n {\n 'aria-label': ariaLabel = 'Delete schedule entry',\n children,\n className,\n onClick,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn(\n 'inline-flex size-8 shrink-0 items-center justify-center rounded-circle text-gray-light transition-colors hover:bg-base-error-soft hover:text-error focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children ?? <MaterialSymbol className=\"text-[14px]\" name=\"delete\" />}\n </button>\n ),\n)\n\nScheduleEntryDelete.displayName = 'ScheduleEntryDelete'\n\nexport {\n ScheduleEntry,\n ScheduleEntryActions,\n ScheduleEntryContent,\n ScheduleEntryDelete,\n ScheduleEntrySubtitle,\n ScheduleEntryTitle,\n ScheduleList,\n ScheduleListAdd,\n ScheduleListEmpty,\n}\n"],"mappings":";;;;;;AAIA,MAAM,eAAeA,QAAM,YAGxB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GACT,uDACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc;AAE3B,MAAM,oBAAoBA,QAAM,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,KAAD;CACO;CACL,WAAW,GAAG,qCAAqC,SAAS;CAC5D,GAAI;AACL,CAAA,CACF;AAED,kBAAkB,cAAc;AAOhC,MAAM,kBAAkBA,QAAM,YAG3B,EAAE,UAAU,WAAW,MAAM,OAAO,UAAU,GAAG,SAAS,QAC3D,qBAAC,UAAD;CACO;CACC;CACN,WAAW,GACT,kWACA,SACF;CACA,GAAI;WAPN,CASG,QAAQ,oBAAC,gBAAD;EAAgB,WAAU;EAAc,MAAK;CAAO,CAAA,GAC5D,QACK;EACT;AAED,gBAAgB,cAAc;AAQ9B,MAAM,gBAAgBA,QAAM,YACzB,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,SAAS,QAAQ;CAC7D,MAAM,cAAc,YAAY,KAAA,KAAa,CAAC;CAC9C,OACE,oBAAC,OAAD;EACO;EACL,MAAM,cAAc,WAAW,KAAA;EAC/B,UAAU,cAAc,IAAI,KAAA;EAC5B,SAAS,cAAc,UAAU,KAAA;EACjC,WACE,eACK,UAAU;GACT,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;IAC9C,MAAM,eAAe;IACrB,QAAQ;GACV;EACF,IACA,KAAA;EAEN,iBAAe,YAAY,KAAA;EAC3B,WAAW,GACT,uFACA,eACE,iHACF,YAAY,iCACZ,SACF;EACA,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,cAAc,cAAc;AAE5B,MAAM,uBAAuBA,QAAM,YAGhC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,wCAAwC,SAAS;CAC/D,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAEnC,MAAM,qBAAqBA,QAAM,YAG9B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GACT,0EACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,mBAAmB,cAAc;AAEjC,MAAM,wBAAwBA,QAAM,YAGjC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACO;CACL,WAAW,GAAG,oCAAoC,SAAS;CAC3D,GAAI;AACL,CAAA,CACF;AAED,sBAAsB,cAAc;;;AAIpC,MAAM,uBAAuBA,QAAM,YAGhC,EAAE,WAAW,SAAS,GAAG,SAAS,QACnC,oBAAC,OAAD;CACO;CACL,UAAU,UAAU;EAClB,MAAM,gBAAgB;EACtB,UAAU,KAAK;CACjB;CACA,WAAW,GAAG,sCAAsC,SAAS;CAC7D,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAInC,MAAM,sBAAsBA,QAAM,YAK9B,EACE,cAAc,YAAY,yBAC1B,UACA,WACA,SACA,OAAO,UACP,GAAG,SAEL,QAEA,oBAAC,UAAD;CACO;CACC;CACN,cAAY;CACZ,UAAU,UAAU;EAClB,MAAM,gBAAgB;EACtB,UAAU,KAAK;CACjB;CACA,WAAW,GACT,oRACA,SACF;CACA,GAAI;WAEH,YAAY,oBAAC,gBAAD;EAAgB,WAAU;EAAc,MAAK;CAAU,CAAA;AAC9D,CAAA,CAEZ;AAEA,oBAAoB,cAAc"}
1
+ {"version":3,"file":"schedule-list.js","names":["React"],"sources":["../../src/components/schedule-list.tsx"],"sourcesContent":["import * as React from 'react'\nimport { MaterialSymbol } from '../icons/material-symbol'\nimport { cn } from '../utils/cn'\n\nconst ScheduleList = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*2)]',\n className,\n )}\n {...props}\n />\n))\n\nScheduleList.displayName = 'ScheduleList'\n\nconst ScheduleListEmpty = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('px-3 py-2 text-sm text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleListEmpty.displayName = 'ScheduleListEmpty'\n\ninterface ScheduleListAddProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon override; defaults to a `+`. */\n icon?: React.ReactNode\n}\n\nconst ScheduleListAdd = React.forwardRef<\n HTMLButtonElement,\n ScheduleListAddProps\n>(({ children, className, icon, type = 'button', ...props }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n 'inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-2xl border border-dashed border-gray text-sm font-medium text-gray-light transition-colors hover:border-spark-a8 hover:bg-base-accent-soft hover:text-accent focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {icon ?? <MaterialSymbol className=\"text-[14px]\" name=\"add\" />}\n {children}\n </button>\n))\n\nScheduleListAdd.displayName = 'ScheduleListAdd'\n\ninterface ScheduleEntryProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Make the row interactive — enables hover, role=button, keyboard activation. */\n onClick?: () => void\n disabled?: boolean\n}\n\nconst ScheduleEntry = React.forwardRef<HTMLDivElement, ScheduleEntryProps>(\n ({ children, className, disabled, onClick, ...props }, ref) => {\n const interactive = onClick !== undefined && !disabled\n // role, tab stop and key handler travel together -- the row is never\n // clickable without Enter/Space, and never focusable without a role\n const interaction = interactive\n ? {\n role: 'button' as const,\n tabIndex: 0,\n onClick,\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n onClick()\n }\n },\n }\n : undefined\n return (\n <div\n ref={ref}\n {...interaction}\n aria-disabled={disabled || undefined}\n className={cn(\n 'flex items-center gap-3 rounded-2xl bg-base-gray-soft px-3 py-2.5 transition-colors',\n interactive &&\n 'cursor-pointer hover:bg-gray-a3 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n },\n)\n\nScheduleEntry.displayName = 'ScheduleEntry'\n\nconst ScheduleEntryContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col gap-0.5', className)}\n {...props}\n />\n))\n\nScheduleEntryContent.displayName = 'ScheduleEntryContent'\n\nconst ScheduleEntryTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex min-w-0 items-center gap-2 truncate text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n))\n\nScheduleEntryTitle.displayName = 'ScheduleEntryTitle'\n\nconst ScheduleEntrySubtitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n className={cn('truncate text-xs text-gray-light', className)}\n {...props}\n />\n))\n\nScheduleEntrySubtitle.displayName = 'ScheduleEntrySubtitle'\n\n/** Right-aligned action area. Stops click propagation so inner controls\n * don't fire the parent `ScheduleEntry`'s `onClick`. */\nconst ScheduleEntryActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, onClick, ...props }, ref) => (\n <div\n ref={ref}\n // a layout wrapper, not a control: the handler only shields the inner\n // buttons' clicks (keyboard activation included) from the parent row\n role=\"presentation\"\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn('flex shrink-0 items-center gap-1.5', className)}\n {...props}\n />\n))\n\nScheduleEntryActions.displayName = 'ScheduleEntryActions'\n\ninterface ScheduleEntryDeleteProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}\n\nconst ScheduleEntryDelete = React.forwardRef<\n HTMLButtonElement,\n ScheduleEntryDeleteProps\n>(\n (\n {\n 'aria-label': ariaLabel = 'Delete schedule entry',\n children,\n className,\n onClick,\n type = 'button',\n ...props\n },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation()\n onClick?.(event)\n }}\n className={cn(\n 'inline-flex size-8 shrink-0 items-center justify-center rounded-circle text-gray-light transition-colors hover:bg-base-error-soft hover:text-error focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children ?? <MaterialSymbol className=\"text-[14px]\" name=\"delete\" />}\n </button>\n ),\n)\n\nScheduleEntryDelete.displayName = 'ScheduleEntryDelete'\n\nexport {\n ScheduleEntry,\n ScheduleEntryActions,\n ScheduleEntryContent,\n ScheduleEntryDelete,\n ScheduleEntrySubtitle,\n ScheduleEntryTitle,\n ScheduleList,\n ScheduleListAdd,\n ScheduleListEmpty,\n}\n"],"mappings":";;;;;;AAIA,MAAM,eAAeA,QAAM,YAGxB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GACT,uDACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,aAAa,cAAc;AAE3B,MAAM,oBAAoBA,QAAM,YAG7B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,KAAD;CACO;CACL,WAAW,GAAG,qCAAqC,SAAS;CAC5D,GAAI;AACL,CAAA,CACF;AAED,kBAAkB,cAAc;AAOhC,MAAM,kBAAkBA,QAAM,YAG3B,EAAE,UAAU,WAAW,MAAM,OAAO,UAAU,GAAG,SAAS,QAC3D,qBAAC,UAAD;CACO;CACC;CACN,WAAW,GACT,kWACA,SACF;CACA,GAAI;WAPN,CASG,QAAQ,oBAAC,gBAAD;EAAgB,WAAU;EAAc,MAAK;CAAO,CAAA,GAC5D,QACK;EACT;AAED,gBAAgB,cAAc;AAQ9B,MAAM,gBAAgBA,QAAM,YACzB,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,SAAS,QAAQ;CAC7D,MAAM,cAAc,YAAY,KAAA,KAAa,CAAC;CAgB9C,OACE,oBAAC,OAAD;EACO;EACL,GAhBgB,cAChB;GACE,MAAM;GACN,UAAU;GACV;GACA,YAAY,UAA+C;IACzD,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;KAC9C,MAAM,eAAe;KACrB,QAAQ;IACV;GACF;EACF,IACA,KAAA;EAKA,iBAAe,YAAY,KAAA;EAC3B,WAAW,GACT,uFACA,eACE,iHACF,YAAY,iCACZ,SACF;EACA,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,cAAc,cAAc;AAE5B,MAAM,uBAAuBA,QAAM,YAGhC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GAAG,wCAAwC,SAAS;CAC/D,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAEnC,MAAM,qBAAqBA,QAAM,YAG9B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACO;CACL,WAAW,GACT,0EACA,SACF;CACA,GAAI;AACL,CAAA,CACF;AAED,mBAAmB,cAAc;AAEjC,MAAM,wBAAwBA,QAAM,YAGjC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACO;CACL,WAAW,GAAG,oCAAoC,SAAS;CAC3D,GAAI;AACL,CAAA,CACF;AAED,sBAAsB,cAAc;;;AAIpC,MAAM,uBAAuBA,QAAM,YAGhC,EAAE,WAAW,SAAS,GAAG,SAAS,QACnC,oBAAC,OAAD;CACO;CAGL,MAAK;CACL,UAAU,UAAU;EAClB,MAAM,gBAAgB;EACtB,UAAU,KAAK;CACjB;CACA,WAAW,GAAG,sCAAsC,SAAS;CAC7D,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAInC,MAAM,sBAAsBA,QAAM,YAK9B,EACE,cAAc,YAAY,yBAC1B,UACA,WACA,SACA,OAAO,UACP,GAAG,SAEL,QAEA,oBAAC,UAAD;CACO;CACC;CACN,cAAY;CACZ,UAAU,UAAU;EAClB,MAAM,gBAAgB;EACtB,UAAU,KAAK;CACjB;CACA,WAAW,GACT,oRACA,SACF;CACA,GAAI;WAEH,YAAY,oBAAC,gBAAD;EAAgB,WAAU;EAAc,MAAK;CAAU,CAAA;AAC9D,CAAA,CAEZ;AAEA,oBAAoB,cAAc"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.cjs";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.cjs";
4
4
  import * as React$1 from "react";
5
5
  import { Tabs } from "@base-ui/react/tabs";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.js";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.js";
4
4
  import * as React$1 from "react";
5
5
  import { Tabs } from "@base-ui/react/tabs";
6
6
 
@@ -2,9 +2,9 @@
2
2
  "use client";
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  const require_chunk = require("../chunk-DY84GLCh.cjs");
5
- const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
6
5
  const require_icons_material_symbol = require("../icons/material-symbol.cjs");
7
6
  const require_components_field = require("./field.cjs");
7
+ const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
8
8
  let react = require("react");
9
9
  react = require_chunk.__toESM(react);
10
10
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { i as SparkInputStyle } from "../theme-types-1yB0d8mp.cjs";
3
+ import { a as SparkInputStyle } from "../theme-types-Bn5E15-P.cjs";
4
4
  import * as React$1 from "react";
5
5
  import { Select as Select$1 } from "@base-ui/react/select";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { i as SparkInputStyle } from "../theme-types-1yB0d8mp.js";
3
+ import { a as SparkInputStyle } from "../theme-types-Bn5E15-P.js";
4
4
  import * as React$1 from "react";
5
5
  import { Select as Select$1 } from "@base-ui/react/select";
6
6
 
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  "use client";
3
3
  import { cn } from "../utils/cn.js";
4
- import { boxChrome } from "../lib/input-box-variants.js";
5
4
  import { MaterialSymbol } from "../icons/material-symbol.js";
6
5
  import { useFieldControl } from "./field.js";
6
+ import { boxChrome } from "../lib/input-box-variants.js";
7
7
  import "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Select as Select$1 } from "@base-ui/react/select";
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  __esModule: { value: true },
4
4
  [Symbol.toStringTag]: { value: "Module" }
5
5
  });
6
+ const require_icons_material_symbol = require("../icons/material-symbol.cjs");
6
7
  require("../utils/chars.cjs");
7
8
  const require_utils_format = require("../utils/format.cjs");
8
- const require_icons_material_symbol = require("../icons/material-symbol.cjs");
9
9
  const require_components_line_chart = require("./line-chart.cjs");
10
10
  let react = require("react");
11
11
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import "../utils/chars.js";
3
- import { oneDecimalFormat } from "../utils/format.js";
4
2
  import { cn } from "../utils/cn.js";
5
3
  import { MaterialSymbol } from "../icons/material-symbol.js";
4
+ import "../utils/chars.js";
5
+ import { oneDecimalFormat } from "../utils/format.js";
6
6
  import { LineChart } from "./line-chart.js";
7
7
  import { useEffect, useRef, useState } from "react";
8
8
  import { jsx } from "react/jsx-runtime";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.cjs";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.cjs";
4
4
  import { Switch as Switch$1 } from "@base-ui/react/switch";
5
5
 
6
6
  //#region src/components/switch.d.ts
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { u as SparkStyle } from "../theme-types-1yB0d8mp.js";
3
+ import { f as SparkStyle } from "../theme-types-Bn5E15-P.js";
4
4
  import { Switch as Switch$1 } from "@base-ui/react/switch";
5
5
 
6
6
  //#region src/components/switch.d.ts
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_chunk = require("../chunk-DY84GLCh.cjs");
4
- const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
5
4
  const require_components_field = require("./field.cjs");
5
+ const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
6
6
  let react = require("react");
7
7
  react = require_chunk.__toESM(react);
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { i as SparkInputStyle } from "../theme-types-1yB0d8mp.cjs";
3
+ import { a as SparkInputStyle } from "../theme-types-Bn5E15-P.cjs";
4
4
  import * as React$1 from "react";
5
5
 
6
6
  //#region src/components/textarea.d.ts
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { i as SparkInputStyle } from "../theme-types-1yB0d8mp.js";
3
+ import { a as SparkInputStyle } from "../theme-types-Bn5E15-P.js";
4
4
  import * as React$1 from "react";
5
5
 
6
6
  //#region src/components/textarea.d.ts
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../utils/cn.js";
3
- import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
4
3
  import { useFieldControl } from "./field.js";
4
+ import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
5
5
  import * as React$1 from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { cva } from "class-variance-authority";
@@ -2,6 +2,7 @@
2
2
  "use client";
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  const require_chunk = require("../chunk-DY84GLCh.cjs");
5
+ const require_lib_theme_types = require("../lib/theme-types.cjs");
5
6
  const require_lib_accent_theme = require("../lib/accent-theme.cjs");
6
7
  let react = require("react");
7
8
  react = require_chunk.__toESM(react);
@@ -18,7 +19,7 @@ function useTheme() {
18
19
  return react.useContext(ThemeContext);
19
20
  }
20
21
  /** Optional sugar: writes the theming `data-*` attrs + accent `--spark-*` vars onto a wrapper. */
21
- const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, neutralColor, radius, scaling, spacing, styleVariant, highContrast, labelPosition, inputStyle, inputColor, cardVariant, cardColor, appearance, fontHeading, fontBody, render, className, style, children, ...rest }, ref) {
22
+ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, neutralColor, radius, scaling, spacing, styleVariant, highContrast, inverted, labelPosition, inputStyle, inputColor, cardVariant, cardColor, appearance, fontHeading, fontBody, render, className, style, children, ...rest }, ref) {
22
23
  const parent = useTheme();
23
24
  const value = react.useMemo(() => ({
24
25
  accentColor: accentColor ?? parent.accentColor,
@@ -29,6 +30,7 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
29
30
  spacing: spacing ?? parent.spacing,
30
31
  styleVariant: styleVariant ?? parent.styleVariant,
31
32
  highContrast: highContrast ?? parent.highContrast,
33
+ inverted: inverted ?? parent.inverted,
32
34
  labelPosition: labelPosition ?? parent.labelPosition,
33
35
  inputStyle: inputStyle ?? parent.inputStyle,
34
36
  inputColor: inputColor ?? parent.inputColor,
@@ -46,6 +48,7 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
46
48
  spacing,
47
49
  styleVariant,
48
50
  highContrast,
51
+ inverted,
49
52
  labelPosition,
50
53
  inputStyle,
51
54
  inputColor,
@@ -57,7 +60,11 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
57
60
  parent
58
61
  ]);
59
62
  const scopeId = react.useId();
60
- const resolvedNeutralColor = neutralColor === "auto" ? require_lib_accent_theme.getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT) : neutralColor;
63
+ const rawNeutralColor = neutralColor === "auto" ? require_lib_accent_theme.resolveAutoNeutral(value.accentColor ?? DEFAULT_ACCENT, backgroundColor) : neutralColor;
64
+ const neutralColorIsValid = rawNeutralColor === void 0 || require_lib_theme_types.isSparkNeutralFamily(rawNeutralColor) || require_lib_accent_theme.isParsableColor(rawNeutralColor);
65
+ if (!neutralColorIsValid) console.warn(`[Theme] Ignoring invalid neutralColor "${rawNeutralColor}" — falling back to the accent-matched family.`);
66
+ const resolvedNeutralColor = neutralColorIsValid ? rawNeutralColor : require_lib_accent_theme.getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT);
67
+ const neutralColorAttr = resolvedNeutralColor === void 0 ? void 0 : require_lib_theme_types.isSparkNeutralFamily(resolvedNeutralColor) ? resolvedNeutralColor : require_lib_accent_theme.getMatchingNeutral(value.accentColor ?? DEFAULT_ACCENT);
61
68
  const accent = react.useMemo(() => {
62
69
  const empty = {
63
70
  inlineVars: {},
@@ -81,15 +88,18 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
81
88
  const emit = (scale, custom) => custom ? [...require_lib_accent_theme.accentSparkVars(scale), ...require_lib_accent_theme.neutralSparkVars(scale)] : require_lib_accent_theme.accentSparkVars(scale);
82
89
  const build = (appearance) => {
83
90
  const opts = optsFor(appearance);
84
- return emit(require_lib_accent_theme.generateAccentScale(hex, appearance, opts), opts != null);
91
+ const scale = require_lib_accent_theme.generateAccentScale(hex, appearance, opts);
92
+ return emit(inverted ? require_lib_accent_theme.invertAccentScale(scale) : scale, opts != null);
85
93
  };
86
94
  if (value.appearance) return {
87
95
  inlineVars: toVars(build(value.appearance)),
88
96
  css: "",
89
97
  scoped: false
90
98
  };
91
- const light = build("light");
92
- const dark = build("dark");
99
+ const offCanvasNeutrals = backgroundColor ? require_lib_accent_theme.neutralFamilyVars(resolvedNeutralColor ?? "slate") : [];
100
+ const scaleFor = (appearance) => bgAppearance === appearance ? build(appearance) : [...build(appearance), ...offCanvasNeutrals];
101
+ const light = scaleFor("light");
102
+ const dark = scaleFor("dark");
93
103
  const sel = `[data-spark-scope="${scopeId}"]`;
94
104
  return {
95
105
  inlineVars: {},
@@ -103,6 +113,7 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
103
113
  }, [
104
114
  accentColor,
105
115
  backgroundColor,
116
+ inverted,
106
117
  resolvedNeutralColor,
107
118
  value.accentColor,
108
119
  value.appearance,
@@ -114,12 +125,13 @@ const Theme = react.forwardRef(function Theme({ accentColor, backgroundColor, ne
114
125
  ref,
115
126
  props: (0, _base_ui_react_merge_props.mergeProps)({
116
127
  className: (0, cnfast.cn)("spark-theme", appearance, className),
117
- "data-neutral-color": resolvedNeutralColor,
128
+ "data-neutral-color": neutralColorAttr,
118
129
  "data-radius": radius,
119
130
  "data-scaling": scaling,
120
131
  "data-spacing": spacing,
121
132
  "data-style": styleVariant,
122
133
  "data-high-contrast": highContrast ? "" : void 0,
134
+ "data-inverted": inverted ? "" : void 0,
123
135
  "data-label-position": labelPosition,
124
136
  "data-input-style": inputStyle,
125
137
  "data-input-color": inputColor,