@epilot/spark-ui 0.25.1 → 0.26.1

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 (149) hide show
  1. package/dist/components/accordion.cjs.map +1 -1
  2. package/dist/components/accordion.d.cts +1 -1
  3. package/dist/components/accordion.d.ts +1 -1
  4. package/dist/components/accordion.js.map +1 -1
  5. package/dist/components/alert-dialog.cjs +5 -3
  6. package/dist/components/alert-dialog.cjs.map +1 -1
  7. package/dist/components/alert-dialog.d.cts +4 -1
  8. package/dist/components/alert-dialog.d.ts +4 -1
  9. package/dist/components/alert-dialog.js +5 -3
  10. package/dist/components/alert-dialog.js.map +1 -1
  11. package/dist/components/autocomplete.cjs +3 -2
  12. package/dist/components/autocomplete.cjs.map +1 -1
  13. package/dist/components/autocomplete.js +3 -2
  14. package/dist/components/autocomplete.js.map +1 -1
  15. package/dist/components/avatar.js +1 -1
  16. package/dist/components/badge.js +1 -1
  17. package/dist/components/banner.cjs +74 -0
  18. package/dist/components/banner.cjs.map +1 -0
  19. package/dist/components/banner.d.cts +27 -0
  20. package/dist/components/banner.d.ts +27 -0
  21. package/dist/components/banner.js +72 -0
  22. package/dist/components/banner.js.map +1 -0
  23. package/dist/components/box.js +1 -1
  24. package/dist/components/bubble.d.cts +1 -1
  25. package/dist/components/bubble.d.ts +1 -1
  26. package/dist/components/button-group.js +1 -1
  27. package/dist/components/button.d.cts +2 -2
  28. package/dist/components/button.d.ts +2 -2
  29. package/dist/components/button.js +1 -1
  30. package/dist/components/callout.cjs +1 -1
  31. package/dist/components/callout.cjs.map +1 -1
  32. package/dist/components/callout.js +1 -1
  33. package/dist/components/callout.js.map +1 -1
  34. package/dist/components/card.js +1 -1
  35. package/dist/components/checkbox.js +1 -1
  36. package/dist/components/data-list.cjs +39 -0
  37. package/dist/components/data-list.cjs.map +1 -0
  38. package/dist/components/data-list.d.cts +33 -0
  39. package/dist/components/data-list.d.ts +33 -0
  40. package/dist/components/data-list.js +35 -0
  41. package/dist/components/data-list.js.map +1 -0
  42. package/dist/components/dialog.cjs +5 -3
  43. package/dist/components/dialog.cjs.map +1 -1
  44. package/dist/components/dialog.d.cts +4 -1
  45. package/dist/components/dialog.d.ts +4 -1
  46. package/dist/components/dialog.js +5 -3
  47. package/dist/components/dialog.js.map +1 -1
  48. package/dist/components/drawer.cjs +13 -3
  49. package/dist/components/drawer.cjs.map +1 -1
  50. package/dist/components/drawer.d.cts +4 -1
  51. package/dist/components/drawer.d.ts +4 -1
  52. package/dist/components/drawer.js +14 -4
  53. package/dist/components/drawer.js.map +1 -1
  54. package/dist/components/dropdown-menu.cjs +5 -3
  55. package/dist/components/dropdown-menu.cjs.map +1 -1
  56. package/dist/components/dropdown-menu.d.cts +1 -0
  57. package/dist/components/dropdown-menu.d.ts +1 -0
  58. package/dist/components/dropdown-menu.js +5 -3
  59. package/dist/components/dropdown-menu.js.map +1 -1
  60. package/dist/components/empty-state.cjs +97 -25
  61. package/dist/components/empty-state.cjs.map +1 -1
  62. package/dist/components/empty-state.d.cts +28 -11
  63. package/dist/components/empty-state.d.ts +28 -11
  64. package/dist/components/empty-state.js +94 -26
  65. package/dist/components/empty-state.js.map +1 -1
  66. package/dist/components/energy-breakdown.cjs +1 -1
  67. package/dist/components/energy-breakdown.cjs.map +1 -1
  68. package/dist/components/energy-breakdown.js +1 -1
  69. package/dist/components/energy-breakdown.js.map +1 -1
  70. package/dist/components/entity-card.cjs +1 -1
  71. package/dist/components/entity-card.cjs.map +1 -1
  72. package/dist/components/entity-card.js +1 -1
  73. package/dist/components/entity-card.js.map +1 -1
  74. package/dist/components/field.cjs +4 -4
  75. package/dist/components/field.cjs.map +1 -1
  76. package/dist/components/field.js +4 -4
  77. package/dist/components/field.js.map +1 -1
  78. package/dist/components/icon.js +1 -1
  79. package/dist/components/info-block.d.cts +1 -1
  80. package/dist/components/info-block.d.ts +1 -1
  81. package/dist/components/input-otp.cjs +1 -1
  82. package/dist/components/input-otp.js +1 -1
  83. package/dist/components/input.cjs +1 -1
  84. package/dist/components/input.js +1 -1
  85. package/dist/components/kbd.cjs +14 -0
  86. package/dist/components/kbd.cjs.map +1 -0
  87. package/dist/components/kbd.d.cts +13 -0
  88. package/dist/components/kbd.d.ts +13 -0
  89. package/dist/components/kbd.js +13 -0
  90. package/dist/components/kbd.js.map +1 -0
  91. package/dist/components/marker.d.cts +1 -1
  92. package/dist/components/marker.d.ts +1 -1
  93. package/dist/components/message-scroller.cjs +2 -2
  94. package/dist/components/message-scroller.cjs.map +1 -1
  95. package/dist/components/message-scroller.js +2 -2
  96. package/dist/components/message-scroller.js.map +1 -1
  97. package/dist/components/pill.js +1 -1
  98. package/dist/components/popover.cjs +3 -2
  99. package/dist/components/popover.cjs.map +1 -1
  100. package/dist/components/popover.js +3 -2
  101. package/dist/components/popover.js.map +1 -1
  102. package/dist/components/radio.js +1 -1
  103. package/dist/components/schedule-list.cjs +1 -1
  104. package/dist/components/schedule-list.cjs.map +1 -1
  105. package/dist/components/schedule-list.js +1 -1
  106. package/dist/components/schedule-list.js.map +1 -1
  107. package/dist/components/select.cjs +4 -3
  108. package/dist/components/select.cjs.map +1 -1
  109. package/dist/components/select.js +4 -3
  110. package/dist/components/select.js.map +1 -1
  111. package/dist/components/separator.cjs +35 -17
  112. package/dist/components/separator.cjs.map +1 -1
  113. package/dist/components/separator.d.cts +1 -0
  114. package/dist/components/separator.d.ts +1 -0
  115. package/dist/components/separator.js +35 -17
  116. package/dist/components/separator.js.map +1 -1
  117. package/dist/components/sheet.cjs +4 -2
  118. package/dist/components/sheet.cjs.map +1 -1
  119. package/dist/components/sheet.d.cts +4 -1
  120. package/dist/components/sheet.d.ts +4 -1
  121. package/dist/components/sheet.js +4 -2
  122. package/dist/components/sheet.js.map +1 -1
  123. package/dist/components/stat-card.cjs +1 -1
  124. package/dist/components/stat-card.cjs.map +1 -1
  125. package/dist/components/stat-card.js +1 -1
  126. package/dist/components/stat-card.js.map +1 -1
  127. package/dist/components/switch.js +1 -1
  128. package/dist/components/textarea.cjs +1 -1
  129. package/dist/components/textarea.js +1 -1
  130. package/dist/components/theme.cjs +118 -24
  131. package/dist/components/theme.cjs.map +1 -1
  132. package/dist/components/theme.d.cts +7 -1
  133. package/dist/components/theme.d.ts +7 -1
  134. package/dist/components/theme.js +120 -27
  135. package/dist/components/theme.js.map +1 -1
  136. package/dist/components/toast.cjs +4 -3
  137. package/dist/components/toast.cjs.map +1 -1
  138. package/dist/components/toast.js +4 -3
  139. package/dist/components/toast.js.map +1 -1
  140. package/dist/components/toggle-group.js +1 -1
  141. package/dist/components/toggle.cjs +1 -1
  142. package/dist/components/toggle.js +2 -2
  143. package/dist/components/tooltip.cjs +5 -3
  144. package/dist/components/tooltip.cjs.map +1 -1
  145. package/dist/components/tooltip.d.cts +1 -0
  146. package/dist/components/tooltip.d.ts +1 -0
  147. package/dist/components/tooltip.js +5 -3
  148. package/dist/components/tooltip.js.map +1 -1
  149. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"field.cjs","names":["React","useTheme","Skeleton","Separator"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error) =>\n error?.message && <li key={error.message}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"field.cjs","names":["React","useTheme","Skeleton","Separator"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-1 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error) =>\n error?.message && <li key={error.message}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  "use client";
3
3
  import { cn } from "../utils/cn.js";
4
+ import { useTheme } from "./theme.js";
4
5
  import { Separator } from "./separator.js";
5
6
  import { Skeleton } from "./skeleton.js";
6
- import { useTheme } from "./theme.js";
7
7
  import * as React$1 from "react";
8
8
  import { useId } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -188,7 +188,7 @@ function Field({ className, children, labelPosition: labelPositionProp, inputSty
188
188
  function FieldContent({ className, ...props }) {
189
189
  return /* @__PURE__ */ jsx("div", {
190
190
  "data-slot": "field-content",
191
- className: cn("flex min-w-0 flex-1 flex-col gap-0.5 leading-snug", className),
191
+ className: cn("flex min-w-0 flex-1 flex-col gap-1 leading-snug", className),
192
192
  ...props
193
193
  });
194
194
  }
@@ -253,7 +253,7 @@ function FieldDescription({ className, id, ...props }) {
253
253
  return /* @__PURE__ */ jsx("div", {
254
254
  "data-slot": "field-description",
255
255
  id: id ?? field?.descriptionId,
256
- className: cn("mt-0.5 text-sm leading-normal text-gray-light", className),
256
+ className: cn("text-sm leading-normal text-gray-light", className),
257
257
  ...props
258
258
  });
259
259
  }
@@ -299,7 +299,7 @@ function FieldError({ className, children, errors, id, ...props }) {
299
299
  role: "alert",
300
300
  "data-slot": "field-error",
301
301
  id: id ?? field?.errorId,
302
- className: cn("mt-0.5 text-sm font-normal text-error", className),
302
+ className: cn("text-sm font-normal text-error", className),
303
303
  ...props,
304
304
  children: content
305
305
  });
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","names":["React"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error) =>\n error?.message && <li key={error.message}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
1
+ {"version":3,"file":"field.js","names":["React"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-1 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error) =>\n error?.message && <li key={error.message}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { accentByColor } from "../lib/accent-colors.js";
3
2
  import { cn } from "../utils/cn.js";
3
+ import { accentByColor } from "../lib/accent-colors.js";
4
4
  import "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/components/icon.tsx
@@ -5,7 +5,7 @@ import { VariantProps } from "class-variance-authority";
5
5
 
6
6
  //#region src/components/info-block.d.ts
7
7
  declare const InfoBlock: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
8
- variant?: "bare" | "default" | null | undefined;
8
+ variant?: "default" | "bare" | null | undefined;
9
9
  } & import("class-variance-authority/types").ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
10
10
  declare const InfoBlockIcon: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
11
11
  declare const InfoBlockContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
@@ -5,7 +5,7 @@ import { VariantProps } from "class-variance-authority";
5
5
 
6
6
  //#region src/components/info-block.d.ts
7
7
  declare const InfoBlock: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
8
- variant?: "bare" | "default" | null | undefined;
8
+ variant?: "default" | "bare" | null | undefined;
9
9
  } & import("class-variance-authority/types").ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
10
10
  declare const InfoBlockIcon: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
11
11
  declare const InfoBlockContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
4
3
  const require_components_field = require("./field.cjs");
4
+ const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
5
5
  let react_jsx_runtime = require("react/jsx-runtime");
6
6
  let class_variance_authority = require("class-variance-authority");
7
7
  let _base_ui_react_otp_field = require("@base-ui/react/otp-field");
@@ -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 { jsx } from "react/jsx-runtime";
6
6
  import { cva } from "class-variance-authority";
7
7
  import { OTPField } from "@base-ui/react/otp-field";
@@ -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,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";
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ let react_jsx_runtime = require("react/jsx-runtime");
4
+ let cn = require("cn");
5
+ //#region src/components/kbd.tsx
6
+ const Kbd = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("kbd", {
7
+ "data-slot": "kbd",
8
+ className: (0, cn.cn)("inline-flex h-5 min-w-5 items-center justify-center rounded-md border border-gray-a6 bg-gray-a2 px-1.5 font-mono text-xs text-gray-a11", className),
9
+ ...props
10
+ });
11
+ //#endregion
12
+ exports.Kbd = Kbd;
13
+
14
+ //# sourceMappingURL=kbd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd.cjs","names":[],"sources":["../../src/components/kbd.tsx"],"sourcesContent":["import type * as React from 'react'\nimport { cn } from '../utils/cn'\n\ntype KbdProps = React.HTMLAttributes<HTMLElement>\n\nconst Kbd = ({ className, ...props }: KbdProps) => (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex h-5 min-w-5 items-center justify-center rounded-md border border-gray-a6 bg-gray-a2 px-1.5 font-mono text-xs text-gray-a11',\n className,\n )}\n {...props}\n />\n)\n\nexport { Kbd }\nexport type { KbdProps }\n"],"mappings":";;;;;AAKA,MAAM,OAAO,EAAE,WAAW,GAAG,YAC3B,iBAAA,GAAA,kBAAA,KAAC,OAAD;CACE,aAAU;CACV,YAAA,GAAA,GAAA,IACE,0IACA,SACF;CACA,GAAI;AACL,CAAA"}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ import * as React$1 from "react";
4
+
5
+ //#region src/components/kbd.d.ts
6
+ type KbdProps = React$1.HTMLAttributes<HTMLElement>;
7
+ declare const Kbd: ({
8
+ className,
9
+ ...props
10
+ }: KbdProps) => import("react/jsx-runtime").JSX.Element;
11
+ //#endregion
12
+ export { Kbd, type KbdProps };
13
+ //# sourceMappingURL=kbd.d.cts.map
@@ -0,0 +1,13 @@
1
+ "use client";
2
+
3
+ import * as React$1 from "react";
4
+
5
+ //#region src/components/kbd.d.ts
6
+ type KbdProps = React$1.HTMLAttributes<HTMLElement>;
7
+ declare const Kbd: ({
8
+ className,
9
+ ...props
10
+ }: KbdProps) => import("react/jsx-runtime").JSX.Element;
11
+ //#endregion
12
+ export { Kbd, type KbdProps };
13
+ //# sourceMappingURL=kbd.d.ts.map
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { cn } from "../utils/cn.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/kbd.tsx
5
+ const Kbd = ({ className, ...props }) => /* @__PURE__ */ jsx("kbd", {
6
+ "data-slot": "kbd",
7
+ className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded-md border border-gray-a6 bg-gray-a2 px-1.5 font-mono text-xs text-gray-a11", className),
8
+ ...props
9
+ });
10
+ //#endregion
11
+ export { Kbd };
12
+
13
+ //# sourceMappingURL=kbd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd.js","names":[],"sources":["../../src/components/kbd.tsx"],"sourcesContent":["import type * as React from 'react'\nimport { cn } from '../utils/cn'\n\ntype KbdProps = React.HTMLAttributes<HTMLElement>\n\nconst Kbd = ({ className, ...props }: KbdProps) => (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n 'inline-flex h-5 min-w-5 items-center justify-center rounded-md border border-gray-a6 bg-gray-a2 px-1.5 font-mono text-xs text-gray-a11',\n className,\n )}\n {...props}\n />\n)\n\nexport { Kbd }\nexport type { KbdProps }\n"],"mappings":";;;;AAKA,MAAM,OAAO,EAAE,WAAW,GAAG,YAC3B,oBAAC,OAAD;CACE,aAAU;CACV,WAAW,GACT,0IACA,SACF;CACA,GAAI;AACL,CAAA"}
@@ -6,7 +6,7 @@ import { useRender } from "@base-ui/react/use-render";
6
6
 
7
7
  //#region src/components/marker.d.ts
8
8
  declare const markerVariants: (props?: ({
9
- variant?: "border" | "default" | "separator" | null | undefined;
9
+ variant?: "default" | "separator" | "border" | null | undefined;
10
10
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
11
11
  declare function Marker({
12
12
  className,
@@ -6,7 +6,7 @@ import { useRender } from "@base-ui/react/use-render";
6
6
 
7
7
  //#region src/components/marker.d.ts
8
8
  declare const markerVariants: (props?: ({
9
- variant?: "border" | "default" | "separator" | null | undefined;
9
+ variant?: "default" | "separator" | "border" | null | undefined;
10
10
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
11
11
  declare function Marker({
12
12
  className,
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_chunk = require("../chunk-DY84GLCh.cjs");
4
4
  const require_hooks_use_reduced_motion = require("../hooks/use-reduced-motion.cjs");
5
- const require_lib_message_animations = require("../lib/message-animations.cjs");
6
5
  const require_components_button = require("./button.cjs");
6
+ const require_lib_message_animations = require("../lib/message-animations.cjs");
7
7
  let react = require("react");
8
8
  react = require_chunk.__toESM(react);
9
9
  let _epilot_spark_icons = require("@epilot/spark-icons");
@@ -46,7 +46,7 @@ function MessageScrollerViewport({ className, ...props }) {
46
46
  function MessageScrollerContent({ className, ...props }) {
47
47
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_shadcn_react_message_scroller.MessageScroller.Content, {
48
48
  "data-slot": "message-scroller-content",
49
- className: (0, cn.cn)("flex h-max min-h-full flex-col gap-8", className),
49
+ className: (0, cn.cn)("flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]", className),
50
50
  ...props
51
51
  });
52
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-scroller.cjs","names":["React","LazyMotion","domAnimation","MessageScrollerPrimitive","useReducedMotion","MESSAGE_ANIMATIONS","Button","ArrowDownward","ArrowUpward"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn('flex h-max min-h-full flex-col gap-8', className)}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAM,uCAAuCA,MAAM,cAAc,KAAK;AACtE,MAAM,aAAA,GAAA,eAAA,QAAmB,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,KAAK;CAE9C,MAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,YAAD;EAAY,UAAUC,aAAAA;EAAc,QAAA;YAClC,iBAAA,GAAA,kBAAA,KAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,gBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,MAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,UAA1B;EACE,aAAU;EAMV,YAAA,GAAA,GAAA,IACE,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,SAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IAAc,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQH,MAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqBI,iCAAAA,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,iBAAA,GAAA,kBAAA,KAACD,+BAAAA,gBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,YAAA,GAAA,GAAA,IACE,kFACA,SACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,WAAD;GACE,WAAU;GACV,UAAUE,+BAAAA,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,iBAAA,GAAA,kBAAA,KAACF,+BAAAA,gBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,YAAA,GAAA,GAAA,IACE,ypBACA,SACF;EACA,QACE,UACE,iBAAA,GAAA,kBAAA,KAACG,0BAAAA,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,eAAD,CAAgB,CAAA,IAAI,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,aAAD,CAAc,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
1
+ {"version":3,"file":"message-scroller.cjs","names":["React","LazyMotion","domAnimation","MessageScrollerPrimitive","useReducedMotion","MESSAGE_ANIMATIONS","Button","ArrowDownward","ArrowUpward"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn(\n 'flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAM,uCAAuCA,MAAM,cAAc,KAAK;AACtE,MAAM,aAAA,GAAA,eAAA,QAAmB,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,KAAK;CAE9C,MAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,YAAD;EAAY,UAAUC,aAAAA;EAAc,QAAA;YAClC,iBAAA,GAAA,kBAAA,KAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,gBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,MAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,UAA1B;EACE,aAAU;EAMV,YAAA,GAAA,GAAA,IACE,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,SAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,wEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQH,MAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqBI,iCAAAA,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,iBAAA,GAAA,kBAAA,KAACD,+BAAAA,gBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,YAAA,GAAA,GAAA,IACE,kFACA,SACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,WAAD;GACE,WAAU;GACV,UAAUE,+BAAAA,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,iBAAA,GAAA,kBAAA,KAACF,+BAAAA,gBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,YAAA,GAAA,GAAA,IACE,ypBACA,SACF;EACA,QACE,UACE,iBAAA,GAAA,kBAAA,KAACG,0BAAAA,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,eAAD,CAAgB,CAAA,IAAI,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,aAAD,CAAc,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { useReducedMotion } from "../hooks/use-reduced-motion.js";
3
3
  import { cn } from "../utils/cn.js";
4
- import { MESSAGE_ANIMATIONS } from "../lib/message-animations.js";
5
4
  import { Button } from "./button.js";
5
+ import { MESSAGE_ANIMATIONS } from "../lib/message-animations.js";
6
6
  import * as React$1 from "react";
7
7
  import { ArrowDownward, ArrowUpward } from "@epilot/spark-icons";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -43,7 +43,7 @@ function MessageScrollerViewport({ className, ...props }) {
43
43
  function MessageScrollerContent({ className, ...props }) {
44
44
  return /* @__PURE__ */ jsx(MessageScroller$1.Content, {
45
45
  "data-slot": "message-scroller-content",
46
- className: cn("flex h-max min-h-full flex-col gap-8", className),
46
+ className: cn("flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]", className),
47
47
  ...props
48
48
  });
49
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-scroller.js","names":["React","MessageScrollerPrimitive"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn('flex h-max min-h-full flex-col gap-8', className)}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,uCAAuCA,QAAM,cAAc,KAAK;AACtE,MAAM,YAAY,OAAO,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,QAAM,SAAS,KAAK;CAE9C,QAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,YAAD;EAAY,UAAU;EAAc,QAAA;YAClC,oBAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,oBAACC,kBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,oBAACA,kBAAyB,MAA1B;EACE,aAAU;EACV,WAAW,GACT,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,oBAACA,kBAAyB,UAA1B;EACE,aAAU;EAMV,WAAW,GACT,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,kBAAyB,SAA1B;EACE,aAAU;EACV,WAAW,GAAG,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQD,QAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqB,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,oBAACC,kBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,WAAW,GACT,kFACA,SACF;YAEA,oBAAC,WAAD;GACE,WAAU;GACV,UAAU,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,oBAACA,kBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,WAAW,GACT,ypBACA,SACF;EACA,QACE,UACE,oBAAC,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,qBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,oBAAC,eAAD,CAAgB,CAAA,IAAI,oBAAC,aAAD,CAAc,CAAA,GACzD,oBAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
1
+ {"version":3,"file":"message-scroller.js","names":["React","MessageScrollerPrimitive"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn(\n 'flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,uCAAuCA,QAAM,cAAc,KAAK;AACtE,MAAM,YAAY,OAAO,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,QAAM,SAAS,KAAK;CAE9C,QAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,YAAD;EAAY,UAAU;EAAc,QAAA;YAClC,oBAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,oBAACC,kBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,oBAACA,kBAAyB,MAA1B;EACE,aAAU;EACV,WAAW,GACT,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,oBAACA,kBAAyB,UAA1B;EACE,aAAU;EAMV,WAAW,GACT,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,kBAAyB,SAA1B;EACE,aAAU;EACV,WAAW,GACT,wEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQD,QAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqB,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,oBAACC,kBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,WAAW,GACT,kFACA,SACF;YAEA,oBAAC,WAAD;GACE,WAAU;GACV,UAAU,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,oBAACA,kBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,WAAW,GACT,ypBACA,SACF;EACA,QACE,UACE,oBAAC,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,qBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,oBAAC,eAAD,CAAgB,CAAA,IAAI,oBAAC,aAAD,CAAc,CAAA,GACzD,oBAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { accentByColor } from "../lib/accent-colors.js";
3
2
  import { cn } from "../utils/cn.js";
3
+ import { accentByColor } from "../lib/accent-colors.js";
4
4
  import * as React$1 from "react";
5
5
  import { Close } from "@epilot/spark-icons";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -1,6 +1,7 @@
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_components_theme = require("./theme.cjs");
4
5
  let react = require("react");
5
6
  react = require_chunk.__toESM(react);
6
7
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -47,7 +48,7 @@ function PopoverContent({ className, align = "center", sideOffset = 4, side, ali
47
48
  const context = react.useContext(PopoverAnchorContext);
48
49
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_popover.Popover.Portal, {
49
50
  container,
50
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_popover.Popover.Positioner, {
51
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_theme.PortalTheme, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_popover.Popover.Positioner, {
51
52
  align,
52
53
  alignOffset,
53
54
  anchor: anchor ?? context?.anchor ?? void 0,
@@ -60,7 +61,7 @@ function PopoverContent({ className, align = "center", sideOffset = 4, side, ali
60
61
  className: (0, cn.cn)("z-50 w-72 origin-(--transform-origin) rounded-lg border border-gray-a1 bg-gray-1 p-4 text-gray-a12 shadow-md outline-hidden transition-[opacity,scale,translate] duration-100 motion-reduce:transition-none dark:bg-gray-3", "data-starting-style:scale-95 data-starting-style:opacity-0", "data-[side=bottom]:data-starting-style:-translate-y-2 data-[side=left]:data-starting-style:translate-x-2 data-[side=right]:data-starting-style:-translate-x-2 data-[side=top]:data-starting-style:translate-y-2", "data-ending-style:scale-95 data-ending-style:opacity-0", className),
61
62
  ...props
62
63
  })
63
- })
64
+ }) })
64
65
  });
65
66
  }
66
67
  //#endregion