@mitcsutt/kiln-ui 0.2.0 → 0.2.2

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 (220) hide show
  1. package/dist/components/actions/Button/Button.d.ts +8 -0
  2. package/dist/components/actions/Button/Button.js.map +1 -1
  3. package/dist/components/actions/ChipGroup/ChipGroup.d.ts +9 -0
  4. package/dist/components/actions/ChipGroup/ChipGroup.js.map +1 -1
  5. package/dist/components/actions/IconButton/IconButton.d.ts +8 -0
  6. package/dist/components/actions/IconButton/IconButton.js.map +1 -1
  7. package/dist/components/actions/ModeToggle/ModeToggle.d.ts +8 -0
  8. package/dist/components/actions/ModeToggle/ModeToggle.js.map +1 -1
  9. package/dist/components/actions/SegmentedControl/SegmentedControl.d.ts +9 -0
  10. package/dist/components/actions/SegmentedControl/SegmentedControl.js.map +1 -1
  11. package/dist/components/actions/ToggleChip/ToggleChip.d.ts +9 -0
  12. package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
  13. package/dist/components/display/Avatar/Avatar.d.ts +10 -0
  14. package/dist/components/display/Avatar/Avatar.js.map +1 -1
  15. package/dist/components/display/AvatarGroup/AvatarGroup.d.ts +7 -0
  16. package/dist/components/display/AvatarGroup/AvatarGroup.js.map +1 -1
  17. package/dist/components/display/Badge/Badge.d.ts +7 -0
  18. package/dist/components/display/Badge/Badge.js.map +1 -1
  19. package/dist/components/display/Card/Card.js.map +1 -1
  20. package/dist/components/display/CodeBlock/CodeBlock.d.ts +9 -0
  21. package/dist/components/display/CodeBlock/CodeBlock.js.map +1 -1
  22. package/dist/components/display/DataList/DataList.js.map +1 -1
  23. package/dist/components/display/Delta/Delta.d.ts +9 -0
  24. package/dist/components/display/Delta/Delta.js.map +1 -1
  25. package/dist/components/display/EmptyState/EmptyState.d.ts +8 -0
  26. package/dist/components/display/EmptyState/EmptyState.js.map +1 -1
  27. package/dist/components/display/List/List.js.map +1 -1
  28. package/dist/components/display/List/List.module.js.map +1 -1
  29. package/dist/components/display/Marquee/Marquee.d.ts +8 -0
  30. package/dist/components/display/Marquee/Marquee.js.map +1 -1
  31. package/dist/components/display/Media/Media.d.ts +7 -0
  32. package/dist/components/display/Media/Media.js.map +1 -1
  33. package/dist/components/display/Meter/Meter.d.ts +9 -0
  34. package/dist/components/display/Meter/Meter.js.map +1 -1
  35. package/dist/components/display/Progress/Progress.d.ts +8 -0
  36. package/dist/components/display/Progress/Progress.js.map +1 -1
  37. package/dist/components/display/Skeleton/Skeleton.js.map +1 -1
  38. package/dist/components/display/Stamp/Stamp.d.ts +8 -0
  39. package/dist/components/display/Stamp/Stamp.js.map +1 -1
  40. package/dist/components/display/Stat/Stat.d.ts +8 -0
  41. package/dist/components/display/Stat/Stat.js.map +1 -1
  42. package/dist/components/display/Table/Table.js.map +1 -1
  43. package/dist/components/display/Table/Table.module.js.map +1 -1
  44. package/dist/components/display/Tag/Tag.d.ts +7 -0
  45. package/dist/components/display/Tag/Tag.js.map +1 -1
  46. package/dist/components/feedback/Alert/Alert.d.ts +10 -0
  47. package/dist/components/feedback/Alert/Alert.js.map +1 -1
  48. package/dist/components/feedback/LiveIndicator/LiveIndicator.d.ts +7 -0
  49. package/dist/components/feedback/LiveIndicator/LiveIndicator.js.map +1 -1
  50. package/dist/components/feedback/RelativeTime/RelativeTime.d.ts +8 -0
  51. package/dist/components/feedback/RelativeTime/RelativeTime.js.map +1 -1
  52. package/dist/components/feedback/Spinner/Spinner.d.ts +10 -1
  53. package/dist/components/feedback/Spinner/Spinner.js.map +1 -1
  54. package/dist/components/feedback/StatusDot/StatusDot.d.ts +10 -1
  55. package/dist/components/feedback/StatusDot/StatusDot.js.map +1 -1
  56. package/dist/components/inputs/AmountField/AmountField.d.ts +7 -0
  57. package/dist/components/inputs/AmountField/AmountField.js.map +1 -1
  58. package/dist/components/inputs/AmountInput/AmountInput.d.ts +8 -0
  59. package/dist/components/inputs/AmountInput/AmountInput.js.map +1 -1
  60. package/dist/components/inputs/Checkbox/Checkbox.d.ts +8 -0
  61. package/dist/components/inputs/Checkbox/Checkbox.js.map +1 -1
  62. package/dist/components/inputs/CheckboxField/CheckboxField.d.ts +7 -0
  63. package/dist/components/inputs/CheckboxField/CheckboxField.js.map +1 -1
  64. package/dist/components/inputs/CheckboxGroup/CheckboxGroup.d.ts +8 -0
  65. package/dist/components/inputs/CheckboxGroup/CheckboxGroup.js.map +1 -1
  66. package/dist/components/inputs/CheckboxGroupField/CheckboxGroupField.d.ts +7 -0
  67. package/dist/components/inputs/CheckboxGroupField/CheckboxGroupField.js.map +1 -1
  68. package/dist/components/inputs/ChipGroupField/ChipGroupField.d.ts +7 -0
  69. package/dist/components/inputs/ChipGroupField/ChipGroupField.js.map +1 -1
  70. package/dist/components/inputs/ChoiceCards/ChoiceCards.d.ts +9 -0
  71. package/dist/components/inputs/ChoiceCards/ChoiceCards.js.map +1 -1
  72. package/dist/components/inputs/ChoiceCardsField/ChoiceCardsField.d.ts +7 -0
  73. package/dist/components/inputs/ChoiceCardsField/ChoiceCardsField.js.map +1 -1
  74. package/dist/components/inputs/ColorField/ColorField.d.ts +6 -0
  75. package/dist/components/inputs/ColorField/ColorField.js.map +1 -1
  76. package/dist/components/inputs/ColorInput/ColorInput.d.ts +8 -0
  77. package/dist/components/inputs/ColorInput/ColorInput.js.map +1 -1
  78. package/dist/components/inputs/Combobox/Combobox.d.ts +9 -0
  79. package/dist/components/inputs/Combobox/Combobox.js.map +1 -1
  80. package/dist/components/inputs/ComboboxField/ComboboxField.d.ts +7 -0
  81. package/dist/components/inputs/ComboboxField/ComboboxField.js.map +1 -1
  82. package/dist/components/inputs/DateRangeField/DateRangeField.d.ts +7 -0
  83. package/dist/components/inputs/DateRangeField/DateRangeField.js.map +1 -1
  84. package/dist/components/inputs/Field/Field.d.ts +26 -0
  85. package/dist/components/inputs/Field/Field.js.map +1 -1
  86. package/dist/components/inputs/Fieldset/Fieldset.d.ts +8 -0
  87. package/dist/components/inputs/Fieldset/Fieldset.js.map +1 -1
  88. package/dist/components/inputs/FileDrop/FileDrop.d.ts +10 -0
  89. package/dist/components/inputs/FileDrop/FileDrop.js.map +1 -1
  90. package/dist/components/inputs/FileField/FileField.d.ts +7 -0
  91. package/dist/components/inputs/FileField/FileField.js.map +1 -1
  92. package/dist/components/inputs/Input/Input.d.ts +9 -0
  93. package/dist/components/inputs/Input/Input.js.map +1 -1
  94. package/dist/components/inputs/NumberField/NumberField.d.ts +7 -0
  95. package/dist/components/inputs/NumberField/NumberField.js.map +1 -1
  96. package/dist/components/inputs/NumberInput/NumberInput.d.ts +8 -0
  97. package/dist/components/inputs/NumberInput/NumberInput.js.map +1 -1
  98. package/dist/components/inputs/OneTimeCodeField/OneTimeCodeField.d.ts +7 -0
  99. package/dist/components/inputs/OneTimeCodeField/OneTimeCodeField.js.map +1 -1
  100. package/dist/components/inputs/OneTimeCodeInput/OneTimeCodeInput.d.ts +8 -0
  101. package/dist/components/inputs/OneTimeCodeInput/OneTimeCodeInput.js.map +1 -1
  102. package/dist/components/inputs/PasswordField/PasswordField.d.ts +7 -0
  103. package/dist/components/inputs/PasswordField/PasswordField.js.map +1 -1
  104. package/dist/components/inputs/PasswordInput/PasswordInput.d.ts +10 -0
  105. package/dist/components/inputs/PasswordInput/PasswordInput.js.map +1 -1
  106. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +9 -0
  107. package/dist/components/inputs/RadioGroup/RadioGroup.js.map +1 -1
  108. package/dist/components/inputs/RadioGroupField/RadioGroupField.d.ts +8 -0
  109. package/dist/components/inputs/RadioGroupField/RadioGroupField.js.map +1 -1
  110. package/dist/components/inputs/RangeSlider/RangeSlider.d.ts +8 -0
  111. package/dist/components/inputs/RangeSlider/RangeSlider.js.map +1 -1
  112. package/dist/components/inputs/RangeSliderField/RangeSliderField.d.ts +7 -0
  113. package/dist/components/inputs/RangeSliderField/RangeSliderField.js.map +1 -1
  114. package/dist/components/inputs/Rating/Rating.d.ts +8 -0
  115. package/dist/components/inputs/Rating/Rating.js.map +1 -1
  116. package/dist/components/inputs/RatingField/RatingField.d.ts +7 -0
  117. package/dist/components/inputs/RatingField/RatingField.js.map +1 -1
  118. package/dist/components/inputs/SegmentedField/SegmentedField.d.ts +7 -0
  119. package/dist/components/inputs/SegmentedField/SegmentedField.js.map +1 -1
  120. package/dist/components/inputs/Select/Select.d.ts +9 -0
  121. package/dist/components/inputs/Select/Select.js.map +1 -1
  122. package/dist/components/inputs/SelectField/SelectField.d.ts +7 -0
  123. package/dist/components/inputs/SelectField/SelectField.js.map +1 -1
  124. package/dist/components/inputs/Slider/Slider.d.ts +8 -0
  125. package/dist/components/inputs/Slider/Slider.js.map +1 -1
  126. package/dist/components/inputs/SliderField/SliderField.d.ts +7 -0
  127. package/dist/components/inputs/SliderField/SliderField.js.map +1 -1
  128. package/dist/components/inputs/Switch/Switch.d.ts +8 -0
  129. package/dist/components/inputs/Switch/Switch.js.map +1 -1
  130. package/dist/components/inputs/SwitchField/SwitchField.d.ts +8 -0
  131. package/dist/components/inputs/SwitchField/SwitchField.js.map +1 -1
  132. package/dist/components/inputs/TagsField/TagsField.d.ts +6 -0
  133. package/dist/components/inputs/TagsField/TagsField.js.map +1 -1
  134. package/dist/components/inputs/TagsInput/TagsInput.d.ts +8 -0
  135. package/dist/components/inputs/TagsInput/TagsInput.js.map +1 -1
  136. package/dist/components/inputs/TextField/TextField.d.ts +8 -0
  137. package/dist/components/inputs/TextField/TextField.js.map +1 -1
  138. package/dist/components/inputs/Textarea/Textarea.d.ts +8 -0
  139. package/dist/components/inputs/Textarea/Textarea.js.map +1 -1
  140. package/dist/components/inputs/TextareaField/TextareaField.d.ts +7 -0
  141. package/dist/components/inputs/TextareaField/TextareaField.js.map +1 -1
  142. package/dist/components/layout/ActionBar/ActionBar.d.ts +7 -0
  143. package/dist/components/layout/ActionBar/ActionBar.js.map +1 -1
  144. package/dist/components/layout/AppShell/AppShell.js.map +1 -1
  145. package/dist/components/layout/AspectRatio/AspectRatio.d.ts +8 -0
  146. package/dist/components/layout/AspectRatio/AspectRatio.js.map +1 -1
  147. package/dist/components/layout/Box/Box.d.ts +8 -0
  148. package/dist/components/layout/Box/Box.js.map +1 -1
  149. package/dist/components/layout/Container/Container.d.ts +17 -0
  150. package/dist/components/layout/Container/Container.js.map +1 -1
  151. package/dist/components/layout/Divider/Divider.d.ts +7 -0
  152. package/dist/components/layout/Divider/Divider.js.map +1 -1
  153. package/dist/components/layout/Grid/Grid.d.ts +9 -0
  154. package/dist/components/layout/Grid/Grid.js.map +1 -1
  155. package/dist/components/layout/Inline/Inline.d.ts +8 -0
  156. package/dist/components/layout/Inline/Inline.js.map +1 -1
  157. package/dist/components/layout/Section/Section.d.ts +15 -0
  158. package/dist/components/layout/Section/Section.js.map +1 -1
  159. package/dist/components/layout/Split/Split.d.ts +9 -0
  160. package/dist/components/layout/Split/Split.js.map +1 -1
  161. package/dist/components/layout/Stack/Stack.d.ts +12 -0
  162. package/dist/components/layout/Stack/Stack.js.map +1 -1
  163. package/dist/components/layout/VisuallyHidden/VisuallyHidden.d.ts +7 -0
  164. package/dist/components/layout/VisuallyHidden/VisuallyHidden.js.map +1 -1
  165. package/dist/components/navigation/Accordion/Accordion.d.ts +7 -0
  166. package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
  167. package/dist/components/navigation/BottomNav/BottomNav.d.ts +9 -0
  168. package/dist/components/navigation/BottomNav/BottomNav.js.map +1 -1
  169. package/dist/components/navigation/NavLinks/NavLinks.d.ts +9 -0
  170. package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
  171. package/dist/components/navigation/Stepper/Stepper.d.ts +7 -0
  172. package/dist/components/navigation/Stepper/Stepper.js.map +1 -1
  173. package/dist/components/navigation/Tabs/Tabs.d.ts +8 -0
  174. package/dist/components/navigation/Tabs/Tabs.js.map +1 -1
  175. package/dist/components/overlays/Dialog/Dialog.d.ts +13 -0
  176. package/dist/components/overlays/Dialog/Dialog.js.map +1 -1
  177. package/dist/components/overlays/DropdownMenu/DropdownMenu.d.ts +8 -0
  178. package/dist/components/overlays/DropdownMenu/DropdownMenu.js.map +1 -1
  179. package/dist/components/overlays/Popover/Popover.d.ts +7 -0
  180. package/dist/components/overlays/Popover/Popover.js.map +1 -1
  181. package/dist/components/overlays/Sheet/Sheet.d.ts +8 -0
  182. package/dist/components/overlays/Sheet/Sheet.js.map +1 -1
  183. package/dist/components/overlays/Tooltip/Tooltip.d.ts +8 -0
  184. package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
  185. package/dist/components/typography/Amount/Amount.d.ts +8 -0
  186. package/dist/components/typography/Amount/Amount.js.map +1 -1
  187. package/dist/components/typography/Code/Code.d.ts +8 -0
  188. package/dist/components/typography/Code/Code.js.map +1 -1
  189. package/dist/components/typography/Heading/Heading.d.ts +8 -0
  190. package/dist/components/typography/Heading/Heading.js.map +1 -1
  191. package/dist/components/typography/Kbd/Kbd.d.ts +6 -0
  192. package/dist/components/typography/Kbd/Kbd.js.map +1 -1
  193. package/dist/components/typography/Link/Link.d.ts +9 -0
  194. package/dist/components/typography/Link/Link.js.map +1 -1
  195. package/dist/components/typography/Numeral/Numeral.d.ts +8 -0
  196. package/dist/components/typography/Numeral/Numeral.js.map +1 -1
  197. package/dist/components/typography/Prose/Prose.d.ts +9 -0
  198. package/dist/components/typography/Prose/Prose.js.map +1 -1
  199. package/dist/components/typography/Quote/Quote.d.ts +7 -0
  200. package/dist/components/typography/Quote/Quote.js.map +1 -1
  201. package/dist/components/typography/SectionHeader/SectionHeader.d.ts +8 -0
  202. package/dist/components/typography/SectionHeader/SectionHeader.js.map +1 -1
  203. package/dist/components/typography/Text/Text.d.ts +8 -0
  204. package/dist/components/typography/Text/Text.js.map +1 -1
  205. package/dist/styles.css +1 -1
  206. package/package.json +1 -1
  207. package/skills/custom-theme/SKILL.md +1 -1
  208. package/skills/layout-composition/SKILL.md +37 -98
  209. package/skills/layout-composition/references/action-bar.md +4 -4
  210. package/skills/layout-composition/references/app-shell.md +11 -4
  211. package/skills/layout-composition/references/aspect-ratio.md +3 -1
  212. package/skills/layout-composition/references/box.md +7 -7
  213. package/skills/layout-composition/references/checkout.md +1 -1
  214. package/skills/layout-composition/references/container.md +15 -13
  215. package/skills/layout-composition/references/dashboard.md +1 -1
  216. package/skills/layout-composition/references/divider.md +5 -5
  217. package/skills/layout-composition/references/section.md +69 -0
  218. package/skills/layout-composition/references/settings.md +1 -1
  219. package/skills/layout-composition/references/visually-hidden.md +4 -4
  220. package/skills/setup-and-theming/SKILL.md +1 -1
@@ -12,6 +12,16 @@ export interface PasswordInputProps extends Omit<InputProps, 'type' | 'trailing'
12
12
  hideLabel?: string;
13
13
  }
14
14
  /**
15
+ * A password input with a show and hide toggle that says what pressing it does.
16
+ *
17
+ * @remarks
18
+ * `PasswordInput` adds a toggle to the end of the box that shows or hides the password. The toggle
19
+ * is an `IconButton` whose name says what pressing it will do ("Show password"), and submitting or
20
+ * resetting the form hides the password again. `autoComplete` is required (`current-password` or
21
+ * `new-password`), so password managers do the right thing. `onBlur` fires only when focus leaves
22
+ * both the input and its toggle.
23
+ *
24
+ * @privateRemarks
15
25
  * A password input with a show/hide toggle at the end of the box (Radix
16
26
  * PasswordToggleField). The toggle is an IconButton whose name says what pressing it
17
27
  * does; submitting or resetting the form hides the password again. The ref goes to the
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordInput.js","names":["PasswordToggleField","styles","PasswordInput_module_default","PasswordInput","markFieldAware","forwardRef","visibleProp","idProp","disabledProp","rest","field","useResolvedField","autoId","useId","inputId","inputRef","useRef","composedRef","useMergedRefs","ref","internalVisible","setInternalVisible","useState","defaultVisible","visible","setVisible","next","onVisibleChange","setVisibleRef","useEffect","formElement","hide","handleBlur","box","event","onBlur","handleToggleBlur","input","keepFocus","unstable_PasswordToggleField","Input","hideLabel","showLabel","IconButton","jsx","EyeOffIcon","EyeIcon"],"sources":["../../../../src/components/inputs/PasswordInput/PasswordInput.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type MouseEvent,\n} from 'react'\nimport { unstable_PasswordToggleField as PasswordToggleField } from 'radix-ui'\nimport { EyeIcon, EyeOffIcon } from '#icons'\nimport { IconButton } from '#components/actions/IconButton'\nimport { Input, type InputProps } from '#components/inputs/Input'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { useMergedRefs } from '#components/inputs/internal/refs'\nimport styles from './PasswordInput.module.css'\n\nexport interface PasswordInputProps extends Omit<InputProps, 'type' | 'trailing'> {\n /** Required: tells password managers whether to fill a saved password or offer a new one. */\n autoComplete: 'current-password' | 'new-password'\n /** Whether the password shows as text. Controlled; pair with `onVisibleChange`. */\n visible?: boolean\n defaultVisible?: boolean\n onVisibleChange?: (visible: boolean) => void\n /** Accessible name of the toggle while hidden. Default `'Show password'`. */\n showLabel?: string\n /** Accessible name of the toggle while shown. Default `'Hide password'`. */\n hideLabel?: string\n}\n\n/**\n * A password input with a show/hide toggle at the end of the box (Radix\n * PasswordToggleField). The toggle is an IconButton whose name says what pressing it\n * does; submitting or resetting the form hides the password again. The ref goes to the\n * input; `onBlur` fires only when focus leaves the input *and* its toggle.\n *\n * <PasswordInput autoComplete=\"current-password\" />\n */\nexport const PasswordInput = markFieldAware(\n forwardRef<HTMLInputElement, PasswordInputProps>(function PasswordInput(\n {\n autoComplete,\n visible: visibleProp,\n defaultVisible = false,\n onVisibleChange,\n showLabel = 'Show password',\n hideLabel = 'Hide password',\n size = 'md',\n id: idProp,\n disabled: disabledProp,\n onBlur,\n ...rest\n },\n ref,\n ) {\n const field = useResolvedField({ id: idProp, disabled: disabledProp })\n const autoId = useId()\n const inputId = field.id ?? `${autoId}password`\n const inputRef = useRef<HTMLInputElement>(null)\n const composedRef = useMergedRefs(ref, inputRef)\n const [internalVisible, setInternalVisible] = useState(defaultVisible)\n const visible = visibleProp ?? internalVisible\n const setVisible = (next: boolean) => {\n if (visibleProp === undefined) setInternalVisible(next)\n if (next !== visible) onVisibleChange?.(next)\n }\n const setVisibleRef = useRef(setVisible)\n setVisibleRef.current = setVisible\n\n // Submitting or resetting the form hides the password (a shown password shouldn't\n // survive into the next screen or a reset form).\n useEffect(() => {\n const formElement = inputRef.current?.form\n if (!formElement) return\n const hide = () => {\n setVisibleRef.current(false)\n }\n formElement.addEventListener('submit', hide)\n formElement.addEventListener('reset', hide)\n return () => {\n formElement.removeEventListener('submit', hide)\n formElement.removeEventListener('reset', hide)\n }\n }, [])\n\n // Blur counts only when focus leaves the whole box (input + toggle).\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n const box = event.currentTarget.parentElement\n if (box && event.relatedTarget instanceof Node && box.contains(event.relatedTarget)) return\n onBlur?.(event)\n }\n const handleToggleBlur = (event: FocusEvent<HTMLButtonElement>) => {\n const input = inputRef.current\n if (!input || !onBlur) return\n const box = input.parentElement\n if (box && event.relatedTarget instanceof Node && box.contains(event.relatedTarget)) return\n // Same event, typed for the input's handler: the target is the toggle that lost focus.\n onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // A pointer press keeps focus (and the caret) in the input.\n const keepFocus = (event: MouseEvent) => {\n if (document.activeElement === inputRef.current) event.preventDefault()\n }\n\n return (\n <PasswordToggleField.Root visible={visible} onVisibilityChange={setVisible}>\n <Input\n ref={composedRef}\n {...rest}\n id={inputId}\n size={size}\n disabled={disabledProp}\n type={visible ? 'text' : 'password'}\n autoComplete={autoComplete}\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n onBlur={handleBlur}\n trailing={\n <PasswordToggleField.Toggle\n asChild\n id={`${inputId}-toggle`}\n aria-controls={inputId}\n aria-label={visible ? hideLabel : showLabel}\n >\n <IconButton\n className={styles.toggle}\n size=\"sm\"\n label={visible ? hideLabel : showLabel}\n icon={visible ? <EyeOffIcon /> : <EyeIcon />}\n disabled={field.disabled}\n onMouseDown={keepFocus}\n onBlur={handleToggleBlur}\n />\n </PasswordToggleField.Toggle>\n }\n />\n </PasswordToggleField.Root>\n )\n }),\n)\n"],"mappings":";;;;;;;;;;AAsCA,IAAaG,IAAgBC,EAC3BC,EAAiD,SAC/C,EACE,iBACA,SAASC,GACT,oBAAiB,IACjB,oBACA,eAAY,iBACZ,eAAY,iBACZ,UAAO,MACP,IAAIC,GACJ,UAAUC,GACV,WACA,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAiB;EAAE,IAAIJ;EAAQ,UAAUC;CAAa,CAAC,GAC/DI,IAASC,EAAM,GACfC,IAAUJ,EAAM,MAAM,GAAGE,EAAO,WAChCG,IAAWC,EAAyB,IAAI,GACxCC,IAAcC,EAAcC,GAAKJ,CAAQ,GACzC,CAACK,GAAiBC,KAAsBC,EAASC,CAAc,GAC/DC,IAAUlB,KAAec,GACzBK,KAAc,MAAkB;EAEpC,AADInB,MAAgB,KAAA,KAAWe,EAAmBK,CAAI,GAClDA,MAASF,KAASG,IAAkBD,CAAI;CAC9C,GACME,IAAgBZ,EAAOS,CAAU;CAKvC,AAJA,EAAc,UAAUA,GAIxBI,QAAgB;EACd,IAAMC,IAAcf,EAAS,SAAS;EACtC,IAAI,CAACe,GAAa;EAClB,IAAMC,UAAa;GACjB,EAAc,QAAQ,EAAK;EAC7B;EAGA,OAFAD,EAAY,iBAAiB,UAAUC,CAAI,GAC3CD,EAAY,iBAAiB,SAASC,CAAI,SAC7B;GAEX,AADAD,EAAY,oBAAoB,UAAUC,CAAI,GAC9CD,EAAY,oBAAoB,SAASC,CAAI;EAC/C;CACF,GAAG,CAAC,CAAC;CAGL,IAAMC,KAAc,MAAwC;EAC1D,IAAMC,IAAMC,EAAM,cAAc;EAChC,AAAID,KAAOC,EAAM,yBAAyB,QAAQD,EAAI,SAASC,EAAM,aAAa,KAClFC,IAASD,CAAK;CAChB,GACME,KAAoB,MAAyC;EACjE,IAAMC,IAAQtB,EAAS;EACvB,IAAI,CAACsB,KAAS,CAACF,GAAQ;EACvB,IAAMF,IAAMI,EAAM;EAClB,AAAIJ,KAAOC,EAAM,yBAAyB,QAAQD,EAAI,SAASC,EAAM,aAAa,KAElFC,EAAOD,CAAgD;CACzD,GAGMI,KAAa,MAAsB;EACvC,AAAI,SAAS,kBAAkBvB,EAAS,WAASmB,EAAM,eAAe;CACxE;CAEA,OACE,kBAAClC,EAAoB,MAArB;EAAmC;EAAS,oBAAoByB;EAC9D,UAAA,kBAACe,GAAD;GACE,KAAKvB;GACL,GAAIR;GACJ,IAAIK;GACE;GACN,UAAUN;GACV,MAAMgB,IAAU,SAAS;GACX;GACd,gBAAe;GACf,aAAY;GACZ,YAAY;GACZ,QAAQQ;GACR,UACE,kBAAChC,EAAoB,QAArB;IACE,SAAA;IACA,IAAI,GAAGc,EAAQ;IACf,iBAAeA;IACf,cAAYU,IAAUiB,IAAYC;IAElC,UAAA,kBAACC,GAAD;KACE,WAAW1C,EAAO;KAClB,MAAK;KACL,OAAOuB,IAAUiB,IAAYC;KAC7B,MAAgBE,EAAVpB,IAAWqB,IAAiBC,GAAlB,CAAa,CAAc;KAC3C,UAAUpC,EAAM;KAChB,aAAa4B;KACb,QAAQF;IACT,CAAA;GACyB,CAAA;EAE/B,CAAA;CACuB,CAAA;AAE9B,CAAC,CACH"}
1
+ {"version":3,"file":"PasswordInput.js","names":["PasswordToggleField","styles","PasswordInput_module_default","PasswordInput","markFieldAware","forwardRef","visibleProp","idProp","disabledProp","rest","field","useResolvedField","autoId","useId","inputId","inputRef","useRef","composedRef","useMergedRefs","ref","internalVisible","setInternalVisible","useState","defaultVisible","visible","setVisible","next","onVisibleChange","setVisibleRef","useEffect","formElement","hide","handleBlur","box","event","onBlur","handleToggleBlur","input","keepFocus","unstable_PasswordToggleField","Input","hideLabel","showLabel","IconButton","jsx","EyeOffIcon","EyeIcon"],"sources":["../../../../src/components/inputs/PasswordInput/PasswordInput.tsx"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type MouseEvent,\n} from 'react'\nimport { unstable_PasswordToggleField as PasswordToggleField } from 'radix-ui'\nimport { EyeIcon, EyeOffIcon } from '#icons'\nimport { IconButton } from '#components/actions/IconButton'\nimport { Input, type InputProps } from '#components/inputs/Input'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { useMergedRefs } from '#components/inputs/internal/refs'\nimport styles from './PasswordInput.module.css'\n\nexport interface PasswordInputProps extends Omit<InputProps, 'type' | 'trailing'> {\n /** Required: tells password managers whether to fill a saved password or offer a new one. */\n autoComplete: 'current-password' | 'new-password'\n /** Whether the password shows as text. Controlled; pair with `onVisibleChange`. */\n visible?: boolean\n defaultVisible?: boolean\n onVisibleChange?: (visible: boolean) => void\n /** Accessible name of the toggle while hidden. Default `'Show password'`. */\n showLabel?: string\n /** Accessible name of the toggle while shown. Default `'Hide password'`. */\n hideLabel?: string\n}\n\n/**\n * A password input with a show and hide toggle that says what pressing it does.\n *\n * @remarks\n * `PasswordInput` adds a toggle to the end of the box that shows or hides the password. The toggle\n * is an `IconButton` whose name says what pressing it will do (\"Show password\"), and submitting or\n * resetting the form hides the password again. `autoComplete` is required (`current-password` or\n * `new-password`), so password managers do the right thing. `onBlur` fires only when focus leaves\n * both the input and its toggle.\n *\n * @privateRemarks\n * A password input with a show/hide toggle at the end of the box (Radix\n * PasswordToggleField). The toggle is an IconButton whose name says what pressing it\n * does; submitting or resetting the form hides the password again. The ref goes to the\n * input; `onBlur` fires only when focus leaves the input *and* its toggle.\n *\n * <PasswordInput autoComplete=\"current-password\" />\n */\nexport const PasswordInput = markFieldAware(\n forwardRef<HTMLInputElement, PasswordInputProps>(function PasswordInput(\n {\n autoComplete,\n visible: visibleProp,\n defaultVisible = false,\n onVisibleChange,\n showLabel = 'Show password',\n hideLabel = 'Hide password',\n size = 'md',\n id: idProp,\n disabled: disabledProp,\n onBlur,\n ...rest\n },\n ref,\n ) {\n const field = useResolvedField({ id: idProp, disabled: disabledProp })\n const autoId = useId()\n const inputId = field.id ?? `${autoId}password`\n const inputRef = useRef<HTMLInputElement>(null)\n const composedRef = useMergedRefs(ref, inputRef)\n const [internalVisible, setInternalVisible] = useState(defaultVisible)\n const visible = visibleProp ?? internalVisible\n const setVisible = (next: boolean) => {\n if (visibleProp === undefined) setInternalVisible(next)\n if (next !== visible) onVisibleChange?.(next)\n }\n const setVisibleRef = useRef(setVisible)\n setVisibleRef.current = setVisible\n\n // Submitting or resetting the form hides the password (a shown password shouldn't\n // survive into the next screen or a reset form).\n useEffect(() => {\n const formElement = inputRef.current?.form\n if (!formElement) return\n const hide = () => {\n setVisibleRef.current(false)\n }\n formElement.addEventListener('submit', hide)\n formElement.addEventListener('reset', hide)\n return () => {\n formElement.removeEventListener('submit', hide)\n formElement.removeEventListener('reset', hide)\n }\n }, [])\n\n // Blur counts only when focus leaves the whole box (input + toggle).\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n const box = event.currentTarget.parentElement\n if (box && event.relatedTarget instanceof Node && box.contains(event.relatedTarget)) return\n onBlur?.(event)\n }\n const handleToggleBlur = (event: FocusEvent<HTMLButtonElement>) => {\n const input = inputRef.current\n if (!input || !onBlur) return\n const box = input.parentElement\n if (box && event.relatedTarget instanceof Node && box.contains(event.relatedTarget)) return\n // Same event, typed for the input's handler: the target is the toggle that lost focus.\n onBlur(event as unknown as FocusEvent<HTMLInputElement>)\n }\n\n // A pointer press keeps focus (and the caret) in the input.\n const keepFocus = (event: MouseEvent) => {\n if (document.activeElement === inputRef.current) event.preventDefault()\n }\n\n return (\n <PasswordToggleField.Root visible={visible} onVisibilityChange={setVisible}>\n <Input\n ref={composedRef}\n {...rest}\n id={inputId}\n size={size}\n disabled={disabledProp}\n type={visible ? 'text' : 'password'}\n autoComplete={autoComplete}\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n onBlur={handleBlur}\n trailing={\n <PasswordToggleField.Toggle\n asChild\n id={`${inputId}-toggle`}\n aria-controls={inputId}\n aria-label={visible ? hideLabel : showLabel}\n >\n <IconButton\n className={styles.toggle}\n size=\"sm\"\n label={visible ? hideLabel : showLabel}\n icon={visible ? <EyeOffIcon /> : <EyeIcon />}\n disabled={field.disabled}\n onMouseDown={keepFocus}\n onBlur={handleToggleBlur}\n />\n </PasswordToggleField.Toggle>\n }\n />\n </PasswordToggleField.Root>\n )\n }),\n)\n"],"mappings":";;;;;;;;;;AAgDA,IAAaG,IAAgBC,EAC3BC,EAAiD,SAC/C,EACE,iBACA,SAASC,GACT,oBAAiB,IACjB,oBACA,eAAY,iBACZ,eAAY,iBACZ,UAAO,MACP,IAAIC,GACJ,UAAUC,GACV,WACA,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAiB;EAAE,IAAIJ;EAAQ,UAAUC;CAAa,CAAC,GAC/DI,IAASC,EAAM,GACfC,IAAUJ,EAAM,MAAM,GAAGE,EAAO,WAChCG,IAAWC,EAAyB,IAAI,GACxCC,IAAcC,EAAcC,GAAKJ,CAAQ,GACzC,CAACK,GAAiBC,KAAsBC,EAASC,CAAc,GAC/DC,IAAUlB,KAAec,GACzBK,KAAc,MAAkB;EAEpC,AADInB,MAAgB,KAAA,KAAWe,EAAmBK,CAAI,GAClDA,MAASF,KAASG,IAAkBD,CAAI;CAC9C,GACME,IAAgBZ,EAAOS,CAAU;CAKvC,AAJA,EAAc,UAAUA,GAIxBI,QAAgB;EACd,IAAMC,IAAcf,EAAS,SAAS;EACtC,IAAI,CAACe,GAAa;EAClB,IAAMC,UAAa;GACjB,EAAc,QAAQ,EAAK;EAC7B;EAGA,OAFAD,EAAY,iBAAiB,UAAUC,CAAI,GAC3CD,EAAY,iBAAiB,SAASC,CAAI,SAC7B;GAEX,AADAD,EAAY,oBAAoB,UAAUC,CAAI,GAC9CD,EAAY,oBAAoB,SAASC,CAAI;EAC/C;CACF,GAAG,CAAC,CAAC;CAGL,IAAMC,KAAc,MAAwC;EAC1D,IAAMC,IAAMC,EAAM,cAAc;EAChC,AAAID,KAAOC,EAAM,yBAAyB,QAAQD,EAAI,SAASC,EAAM,aAAa,KAClFC,IAASD,CAAK;CAChB,GACME,KAAoB,MAAyC;EACjE,IAAMC,IAAQtB,EAAS;EACvB,IAAI,CAACsB,KAAS,CAACF,GAAQ;EACvB,IAAMF,IAAMI,EAAM;EAClB,AAAIJ,KAAOC,EAAM,yBAAyB,QAAQD,EAAI,SAASC,EAAM,aAAa,KAElFC,EAAOD,CAAgD;CACzD,GAGMI,KAAa,MAAsB;EACvC,AAAI,SAAS,kBAAkBvB,EAAS,WAASmB,EAAM,eAAe;CACxE;CAEA,OACE,kBAAClC,EAAoB,MAArB;EAAmC;EAAS,oBAAoByB;EAC9D,UAAA,kBAACe,GAAD;GACE,KAAKvB;GACL,GAAIR;GACJ,IAAIK;GACE;GACN,UAAUN;GACV,MAAMgB,IAAU,SAAS;GACX;GACd,gBAAe;GACf,aAAY;GACZ,YAAY;GACZ,QAAQQ;GACR,UACE,kBAAChC,EAAoB,QAArB;IACE,SAAA;IACA,IAAI,GAAGc,EAAQ;IACf,iBAAeA;IACf,cAAYU,IAAUiB,IAAYC;IAElC,UAAA,kBAACC,GAAD;KACE,WAAW1C,EAAO;KAClB,MAAK;KACL,OAAOuB,IAAUiB,IAAYC;KAC7B,MAAgBE,EAAVpB,IAAWqB,IAAiBC,GAAlB,CAAa,CAAc;KAC3C,UAAUpC,EAAM;KAChB,aAAa4B;KACb,QAAQF;IACT,CAAA;GACyB,CAAA;EAE/B,CAAA;CACuB,CAAA;AAE9B,CAAC,CACH"}
@@ -14,6 +14,15 @@ export interface RadioGroupItemProps extends Omit<ComponentPropsWithoutRef<typeo
14
14
  /** Secondary line under the label, linked with `aria-describedby`. */
15
15
  description?: ReactNode;
16
16
  }
17
+ /**
18
+ * One choice from a short list. One tab stop, with arrow keys to move and choose.
19
+ *
20
+ * @remarks
21
+ * `RadioGroup` is Radix RadioGroup with Kiln's look. The group is one tab stop, and arrow keys
22
+ * move between options and select them. Compose `RadioGroup.Item`s with your own labels, or use
23
+ * {@link RadioGroupField | RadioGroupField}, which lays the options out with labels and
24
+ * descriptions under a legend.
25
+ */
17
26
  export declare const RadioGroup: import("react").ForwardRefExoticComponent<RadioGroupProps & import("react").RefAttributes<HTMLDivElement>> & {
18
27
  Item: import("react").ForwardRefExoticComponent<RadioGroupItemProps & import("react").RefAttributes<HTMLButtonElement>>;
19
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","names":["RadioGroup","RadixRadioGroup","styles","messageStyles","messages_module_default","RadioGroup_module_default","RadioGroupRoot","forwardRef","invalidProp","disabledProp","readOnlyProp","describedByProp","ariaInvalid","labelledByProp","rest","field","useResolvedField","RadioGroup","cx","className","orientation","size","onValueChange","RadioGroupItem","idProp","autoId","useId","id","descriptionId","radio","joinIds","description","label","RadioGroup$1","markFieldAware"],"sources":["../../../../src/components/inputs/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { forwardRef, useId, type ComponentPropsWithoutRef, type ReactNode } from 'react'\nimport { RadioGroup as RadixRadioGroup } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { joinIds } from '#components/inputs/internal/refs'\nimport messageStyles from '#components/inputs/internal/messages.module.css'\nimport styles from './RadioGroup.module.css'\n\nexport interface RadioGroupProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixRadioGroup.Root>,\n 'asChild'\n> {\n size?: Size\n /** Critical border on every radio + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores selection changes. */\n readOnly?: boolean\n}\n\n/**\n * One choice from a short list (Radix RadioGroup: arrow keys move, one tab stop).\n * Label the group with a `<Fieldset legend>`, a `<Field label>` or `aria-label`.\n *\n * <RadioGroup defaultValue=\"20\" orientation=\"horizontal\">\n * <RadioGroup.Item value=\"10\" label=\"$10\" />\n * <RadioGroup.Item value=\"20\" label=\"$20\" />\n * </RadioGroup>\n */\nconst RadioGroupRoot = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n {\n size = 'md',\n invalid: invalidProp,\n orientation = 'vertical',\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onValueChange,\n className,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n 'aria-labelledby': labelledByProp,\n ...rest\n },\n ref,\n) {\n // A group is labelled by reference, so it takes the Field's label id rather than its id.\n const field = useResolvedField({\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n return (\n <RadixRadioGroup.Root\n ref={ref}\n className={cx(styles.group, className)}\n orientation={orientation}\n data-orientation={orientation}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-readonly={field.readOnly || undefined}\n disabled={field.disabled}\n aria-labelledby={labelledByProp ?? field.groupLabelId}\n aria-readonly={field.readOnly || undefined}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-busy={field.busy || undefined}\n onValueChange={field.readOnly ? undefined : onValueChange}\n {...rest}\n />\n )\n})\n\nexport interface RadioGroupItemProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixRadioGroup.Item>,\n 'asChild'\n> {\n /** Visible label beside the radio. Omit only if you supply `aria-label`. */\n label?: ReactNode\n /** Secondary line under the label, linked with `aria-describedby`. */\n description?: ReactNode\n}\n\n/** One option. The ref and `className` go to the radio button itself. */\nconst RadioGroupItem = forwardRef<HTMLButtonElement, RadioGroupItemProps>(function RadioGroupItem(\n { label, description, id: idProp, className, 'aria-describedby': describedByProp, ...rest },\n ref,\n) {\n const autoId = useId()\n const id = idProp ?? `${autoId}radio`\n const descriptionId = `${id}-description`\n const radio = (\n <RadixRadioGroup.Item\n ref={ref}\n id={id}\n className={cx(styles.radio, className)}\n aria-describedby={joinIds(describedByProp, description != null && descriptionId)}\n {...rest}\n >\n <RadixRadioGroup.Indicator className={styles.dot} />\n </RadixRadioGroup.Item>\n )\n if (label == null) return radio\n return (\n <div className={styles.item} data-disabled={rest.disabled ? true : undefined}>\n <span className={styles.slot}>{radio}</span>\n <span className={styles.text}>\n <label htmlFor={id} className={styles.label}>\n {label}\n </label>\n {description != null ? (\n <span id={descriptionId} className={messageStyles.description}>\n {description}\n </span>\n ) : null}\n </span>\n </div>\n )\n})\n\nexport const RadioGroup = markFieldAware(Object.assign(RadioGroupRoot, { Item: RadioGroupItem }))\n"],"mappings":";;;;;;;;;AA6BA,IAAMM,IAAiBC,EAA4C,SACjE,EACE,UAAO,MACP,SAASC,GACT,iBAAc,YACd,UAAUC,GACV,UAAUC,GACV,kBACA,cACA,oBAAoBC,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGC,KAEL,GACA;CAEA,IAAMC,IAAQC,EAAiB;EAC7B,aAAaL;EACb,SAASH;EACT;EACA,UAAUC;EACV,UAAUC;CACZ,CAAC;CACD,OACE,kBAACT,EAAgB,MAAjB;EACO;EACL,WAAWiB,EAAGhB,EAAO,OAAOiB,CAAS;EACxB;EACb,oBAAkBC;EAClB,aAAWC;EACX,gBAAcN,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,UAAUA,EAAM;EAChB,mBAAiBF,KAAkBE,EAAM;EACzC,iBAAeA,EAAM,YAAY,KAAA;EACjC,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,aAAWA,EAAM,QAAQ,KAAA;EACzB,eAAeA,EAAM,WAAW,KAAA,IAAYO;EAC5C,GAAIR;CACL,CAAA;AAEL,CAAC,GAaKS,IAAiBhB,EAAmD,SACxE,EAAE,UAAO,gBAAa,IAAIiB,GAAQ,cAAW,oBAAoBb,GAAiB,GAAGG,KACrF,GACA;CACA,IAAMW,IAASC,EAAM,GACfC,IAAKH,KAAU,GAAGC,EAAO,QACzBG,IAAgB,GAAGD,EAAG,eACtBE,IACJ,kBAAC5B,EAAgB,MAAjB;EACO;EACD;EACJ,WAAWiB,EAAGhB,EAAO,OAAOiB,CAAS;EACrC,oBAAkBW,EAAQnB,GAAiBoB,KAAe,QAAQH,CAAa;EAC/E,GAAId;EAEJ,UAAA,kBAACb,EAAgB,WAAjB,EAA2B,WAAWC,EAAO,IAAM,CAAA;CAC/B,CAAA;CAGxB,OADI8B,KAAS,OAAaH,IAExB,kBAAC,OAAD;EAAK,WAAW3B,EAAO;EAAM,iBAAeY,EAAK,WAAW,KAAO,KAAA;EAAnE,UAAA,CACE,kBAAC,QAAD;GAAM,WAAWZ,EAAO;GAAO,UAAA2B;EAAY,CAAA,GAC3C,kBAAC,QAAD;GAAM,WAAW3B,EAAO;GAAxB,UAAA,CACE,kBAAC,SAAD;IAAO,SAASyB;IAAI,WAAWzB,EAAO;IACnC,UAAA8B;GACI,CAAA,GACND,KAAe,OAIZ,OAHF,kBAAC,QAAD;IAAM,IAAIH;IAAe,WAAWzB,EAAc;IAC/C,UAAA4B;GACG,CAAA,CAEJ;EACH,CAAA,CAAA;;AAET,CAAC,GAEY/B,IAAakC,EAAe,OAAO,OAAO5B,GAAgB,EAAE,MAAMiB,EAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"RadioGroup.js","names":["RadioGroup","RadixRadioGroup","styles","messageStyles","messages_module_default","RadioGroup_module_default","RadioGroupRoot","forwardRef","invalidProp","disabledProp","readOnlyProp","describedByProp","ariaInvalid","labelledByProp","rest","field","useResolvedField","RadioGroup","cx","className","orientation","size","onValueChange","RadioGroupItem","idProp","autoId","useId","id","descriptionId","radio","joinIds","description","label","RadioGroup$1","markFieldAware"],"sources":["../../../../src/components/inputs/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { forwardRef, useId, type ComponentPropsWithoutRef, type ReactNode } from 'react'\nimport { RadioGroup as RadixRadioGroup } from 'radix-ui'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { joinIds } from '#components/inputs/internal/refs'\nimport messageStyles from '#components/inputs/internal/messages.module.css'\nimport styles from './RadioGroup.module.css'\n\nexport interface RadioGroupProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixRadioGroup.Root>,\n 'asChild'\n> {\n size?: Size\n /** Critical border on every radio + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores selection changes. */\n readOnly?: boolean\n}\n\n/**\n * One choice from a short list (Radix RadioGroup: arrow keys move, one tab stop).\n * Label the group with a `<Fieldset legend>`, a `<Field label>` or `aria-label`.\n *\n * <RadioGroup defaultValue=\"20\" orientation=\"horizontal\">\n * <RadioGroup.Item value=\"10\" label=\"$10\" />\n * <RadioGroup.Item value=\"20\" label=\"$20\" />\n * </RadioGroup>\n */\nconst RadioGroupRoot = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n {\n size = 'md',\n invalid: invalidProp,\n orientation = 'vertical',\n disabled: disabledProp,\n readOnly: readOnlyProp,\n onValueChange,\n className,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n 'aria-labelledby': labelledByProp,\n ...rest\n },\n ref,\n) {\n // A group is labelled by reference, so it takes the Field's label id rather than its id.\n const field = useResolvedField({\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n return (\n <RadixRadioGroup.Root\n ref={ref}\n className={cx(styles.group, className)}\n orientation={orientation}\n data-orientation={orientation}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-readonly={field.readOnly || undefined}\n disabled={field.disabled}\n aria-labelledby={labelledByProp ?? field.groupLabelId}\n aria-readonly={field.readOnly || undefined}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-busy={field.busy || undefined}\n onValueChange={field.readOnly ? undefined : onValueChange}\n {...rest}\n />\n )\n})\n\nexport interface RadioGroupItemProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixRadioGroup.Item>,\n 'asChild'\n> {\n /** Visible label beside the radio. Omit only if you supply `aria-label`. */\n label?: ReactNode\n /** Secondary line under the label, linked with `aria-describedby`. */\n description?: ReactNode\n}\n\n/** One option. The ref and `className` go to the radio button itself. */\nconst RadioGroupItem = forwardRef<HTMLButtonElement, RadioGroupItemProps>(function RadioGroupItem(\n { label, description, id: idProp, className, 'aria-describedby': describedByProp, ...rest },\n ref,\n) {\n const autoId = useId()\n const id = idProp ?? `${autoId}radio`\n const descriptionId = `${id}-description`\n const radio = (\n <RadixRadioGroup.Item\n ref={ref}\n id={id}\n className={cx(styles.radio, className)}\n aria-describedby={joinIds(describedByProp, description != null && descriptionId)}\n {...rest}\n >\n <RadixRadioGroup.Indicator className={styles.dot} />\n </RadixRadioGroup.Item>\n )\n if (label == null) return radio\n return (\n <div className={styles.item} data-disabled={rest.disabled ? true : undefined}>\n <span className={styles.slot}>{radio}</span>\n <span className={styles.text}>\n <label htmlFor={id} className={styles.label}>\n {label}\n </label>\n {description != null ? (\n <span id={descriptionId} className={messageStyles.description}>\n {description}\n </span>\n ) : null}\n </span>\n </div>\n )\n})\n\n/**\n * One choice from a short list. One tab stop, with arrow keys to move and choose.\n *\n * @remarks\n * `RadioGroup` is Radix RadioGroup with Kiln's look. The group is one tab stop, and arrow keys\n * move between options and select them. Compose `RadioGroup.Item`s with your own labels, or use\n * {@link RadioGroupField | RadioGroupField}, which lays the options out with labels and\n * descriptions under a legend.\n */\nexport const RadioGroup = markFieldAware(Object.assign(RadioGroupRoot, { Item: RadioGroupItem }))\n"],"mappings":";;;;;;;;;AA6BA,IAAMM,IAAiBC,EAA4C,SACjE,EACE,UAAO,MACP,SAASC,GACT,iBAAc,YACd,UAAUC,GACV,UAAUC,GACV,kBACA,cACA,oBAAoBC,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGC,KAEL,GACA;CAEA,IAAMC,IAAQC,EAAiB;EAC7B,aAAaL;EACb,SAASH;EACT;EACA,UAAUC;EACV,UAAUC;CACZ,CAAC;CACD,OACE,kBAACT,EAAgB,MAAjB;EACO;EACL,WAAWiB,EAAGhB,EAAO,OAAOiB,CAAS;EACxB;EACb,oBAAkBC;EAClB,aAAWC;EACX,gBAAcN,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,UAAUA,EAAM;EAChB,mBAAiBF,KAAkBE,EAAM;EACzC,iBAAeA,EAAM,YAAY,KAAA;EACjC,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,aAAWA,EAAM,QAAQ,KAAA;EACzB,eAAeA,EAAM,WAAW,KAAA,IAAYO;EAC5C,GAAIR;CACL,CAAA;AAEL,CAAC,GAaKS,IAAiBhB,EAAmD,SACxE,EAAE,UAAO,gBAAa,IAAIiB,GAAQ,cAAW,oBAAoBb,GAAiB,GAAGG,KACrF,GACA;CACA,IAAMW,IAASC,EAAM,GACfC,IAAKH,KAAU,GAAGC,EAAO,QACzBG,IAAgB,GAAGD,EAAG,eACtBE,IACJ,kBAAC5B,EAAgB,MAAjB;EACO;EACD;EACJ,WAAWiB,EAAGhB,EAAO,OAAOiB,CAAS;EACrC,oBAAkBW,EAAQnB,GAAiBoB,KAAe,QAAQH,CAAa;EAC/E,GAAId;EAEJ,UAAA,kBAACb,EAAgB,WAAjB,EAA2B,WAAWC,EAAO,IAAM,CAAA;CAC/B,CAAA;CAGxB,OADI8B,KAAS,OAAaH,IAExB,kBAAC,OAAD;EAAK,WAAW3B,EAAO;EAAM,iBAAeY,EAAK,WAAW,KAAO,KAAA;EAAnE,UAAA,CACE,kBAAC,QAAD;GAAM,WAAWZ,EAAO;GAAO,UAAA2B;EAAY,CAAA,GAC3C,kBAAC,QAAD;GAAM,WAAW3B,EAAO;GAAxB,UAAA,CACE,kBAAC,SAAD;IAAO,SAASyB;IAAI,WAAWzB,EAAO;IACnC,UAAA8B;GACI,CAAA,GACND,KAAe,OAIZ,OAHF,kBAAC,QAAD;IAAM,IAAIH;IAAe,WAAWzB,EAAc;IAC/C,UAAA4B;GACG,CAAA,CAEJ;EACH,CAAA,CAAA;;AAET,CAAC,GAWY/B,IAAakC,EAAe,OAAO,OAAO5B,GAAgB,EAAE,MAAMiB,EAAe,CAAC,CAAC"}
@@ -7,6 +7,14 @@ export interface RadioGroupFieldProps extends FieldLabelProps, Omit<RadioGroupPr
7
7
  orientation?: 'vertical' | 'horizontal';
8
8
  }
9
9
  /**
10
+ * One choice from a short list, with labels, descriptions and a legend for the set.
11
+ *
12
+ * @remarks
13
+ * `RadioGroupField` lays out a {@link RadioGroup | RadioGroup} from `options` under a {@link
14
+ * Fieldset | Fieldset} legend, each option with a label and an optional description. Arrow keys
15
+ * move and select.
16
+ *
17
+ * @privateRemarks
10
18
  * One choice from a short list, under a `<Fieldset>` legend. Arrow keys move and select;
11
19
  * the group is one tab stop. `className`/`style` go to the fieldset; `ref`, `id`, `name`
12
20
  * and the rest go to the radio group (`name` submits the checked value natively).
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroupField.js","names":["RadioGroupField","forwardRef","fieldProps","rest","splitFieldLabelProps","props","groupProps","current","setCurrent","useControllableValue","value","defaultValue","onValueChange","handleBlur","useFocusLeave","onBlur","Fieldset","toFieldsetProps","RadioGroup","options","o"],"sources":["../../../../src/components/inputs/RadioGroupField/RadioGroupField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport {\n useControllableValue,\n useFocusLeave,\n toFieldsetProps,\n type ChoiceOption,\n} from '#components/inputs/CheckboxGroup/choice'\nimport type { FieldLabelProps } from '#components/inputs/Field'\nimport { Fieldset } from '#components/inputs/Fieldset'\nimport { RadioGroup, type RadioGroupProps } from '#components/inputs/RadioGroup'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport interface RadioGroupFieldProps\n extends FieldLabelProps, Omit<RadioGroupProps, 'invalid' | 'children' | keyof FieldLabelProps> {\n options: readonly ChoiceOption[]\n /** `vertical` (default) stacks the options; `horizontal` runs them in a wrapping row. */\n orientation?: 'vertical' | 'horizontal'\n}\n\n/**\n * One choice from a short list, under a `<Fieldset>` legend. Arrow keys move and select;\n * the group is one tab stop. `className`/`style` go to the fieldset; `ref`, `id`, `name`\n * and the rest go to the radio group (`name` submits the checked value natively).\n *\n * <RadioGroupField label=\"Billing period\" name=\"period\" options={periods} defaultValue=\"monthly\" />\n */\nexport const RadioGroupField = forwardRef<HTMLDivElement, RadioGroupFieldProps>(\n function RadioGroupField(props, ref) {\n const [fieldProps, rest] = splitFieldLabelProps(props)\n const {\n options,\n value,\n defaultValue,\n onValueChange,\n onBlur,\n className,\n style,\n disabled,\n ...groupProps\n } = rest\n // Hold the value here so read-only also holds for an uncontrolled group.\n const [current, setCurrent] = useControllableValue(\n value === null ? '' : value,\n defaultValue ?? '',\n onValueChange,\n fieldProps.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n return (\n <Fieldset\n {...toFieldsetProps(fieldProps)}\n disabled={disabled}\n className={className}\n style={style}\n >\n <RadioGroup\n ref={ref}\n value={current}\n onValueChange={setCurrent}\n onBlur={handleBlur}\n {...groupProps}\n >\n {options.map((o) => (\n <RadioGroup.Item\n key={o.value}\n value={o.value}\n label={o.label}\n description={o.description}\n disabled={o.disabled}\n />\n ))}\n </RadioGroup>\n </Fieldset>\n )\n },\n)\n"],"mappings":";;;;;;;AA0BA,IAAaA,IAAkBC,EAC7B,SAAyB,GAAO,GAAK;CACnC,IAAM,CAACC,GAAYC,KAAQC,EAAqBC,CAAK,GAC/C,EACJ,YACA,UACA,iBACA,kBACA,WACA,cACA,UACA,aACA,GAAGC,MACDH,GAEE,CAACI,GAASC,KAAcC,EAC5BC,MAAU,OAAO,KAAKA,GACtBC,KAAgB,IAChBC,GACAV,EAAW,QACb,GACMW,IAAaC,EAAcC,CAAM;CACvC,OACE,kBAACC,GAAD;EACE,GAAIC,EAAgBf,CAAU;EACpB;EACC;EACJ;EAEP,UAAA,kBAACgB,GAAD;GACO;GACL,OAAOX;GACP,eAAeC;GACf,QAAQK;GACR,GAAIP;GAEH,UAAAa,EAAQ,KAAK,MACZ,kBAACD,EAAW,MAAZ;IAEE,OAAOE,EAAE;IACT,OAAOA,EAAE;IACT,aAAaA,EAAE;IACf,UAAUA,EAAE;GACb,GALMA,EAAE,KAKR,CACF;EACS,CAAA;CACJ,CAAA;AAEd,CACF"}
1
+ {"version":3,"file":"RadioGroupField.js","names":["RadioGroupField","forwardRef","fieldProps","rest","splitFieldLabelProps","props","groupProps","current","setCurrent","useControllableValue","value","defaultValue","onValueChange","handleBlur","useFocusLeave","onBlur","Fieldset","toFieldsetProps","RadioGroup","options","o"],"sources":["../../../../src/components/inputs/RadioGroupField/RadioGroupField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport {\n useControllableValue,\n useFocusLeave,\n toFieldsetProps,\n type ChoiceOption,\n} from '#components/inputs/CheckboxGroup/choice'\nimport type { FieldLabelProps } from '#components/inputs/Field'\nimport { Fieldset } from '#components/inputs/Fieldset'\nimport { RadioGroup, type RadioGroupProps } from '#components/inputs/RadioGroup'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport interface RadioGroupFieldProps\n extends FieldLabelProps, Omit<RadioGroupProps, 'invalid' | 'children' | keyof FieldLabelProps> {\n options: readonly ChoiceOption[]\n /** `vertical` (default) stacks the options; `horizontal` runs them in a wrapping row. */\n orientation?: 'vertical' | 'horizontal'\n}\n\n/**\n * One choice from a short list, with labels, descriptions and a legend for the set.\n *\n * @remarks\n * `RadioGroupField` lays out a {@link RadioGroup | RadioGroup} from `options` under a {@link\n * Fieldset | Fieldset} legend, each option with a label and an optional description. Arrow keys\n * move and select.\n *\n * @privateRemarks\n * One choice from a short list, under a `<Fieldset>` legend. Arrow keys move and select;\n * the group is one tab stop. `className`/`style` go to the fieldset; `ref`, `id`, `name`\n * and the rest go to the radio group (`name` submits the checked value natively).\n *\n * <RadioGroupField label=\"Billing period\" name=\"period\" options={periods} defaultValue=\"monthly\" />\n */\nexport const RadioGroupField = forwardRef<HTMLDivElement, RadioGroupFieldProps>(\n function RadioGroupField(props, ref) {\n const [fieldProps, rest] = splitFieldLabelProps(props)\n const {\n options,\n value,\n defaultValue,\n onValueChange,\n onBlur,\n className,\n style,\n disabled,\n ...groupProps\n } = rest\n // Hold the value here so read-only also holds for an uncontrolled group.\n const [current, setCurrent] = useControllableValue(\n value === null ? '' : value,\n defaultValue ?? '',\n onValueChange,\n fieldProps.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n return (\n <Fieldset\n {...toFieldsetProps(fieldProps)}\n disabled={disabled}\n className={className}\n style={style}\n >\n <RadioGroup\n ref={ref}\n value={current}\n onValueChange={setCurrent}\n onBlur={handleBlur}\n {...groupProps}\n >\n {options.map((o) => (\n <RadioGroup.Item\n key={o.value}\n value={o.value}\n label={o.label}\n description={o.description}\n disabled={o.disabled}\n />\n ))}\n </RadioGroup>\n </Fieldset>\n )\n },\n)\n"],"mappings":";;;;;;;AAkCA,IAAaA,IAAkBC,EAC7B,SAAyB,GAAO,GAAK;CACnC,IAAM,CAACC,GAAYC,KAAQC,EAAqBC,CAAK,GAC/C,EACJ,YACA,UACA,iBACA,kBACA,WACA,cACA,UACA,aACA,GAAGC,MACDH,GAEE,CAACI,GAASC,KAAcC,EAC5BC,MAAU,OAAO,KAAKA,GACtBC,KAAgB,IAChBC,GACAV,EAAW,QACb,GACMW,IAAaC,EAAcC,CAAM;CACvC,OACE,kBAACC,GAAD;EACE,GAAIC,EAAgBf,CAAU;EACpB;EACC;EACJ;EAEP,UAAA,kBAACgB,GAAD;GACO;GACL,OAAOX;GACP,eAAeC;GACf,QAAQK;GACR,GAAIP;GAEH,UAAAa,EAAQ,KAAK,MACZ,kBAACD,EAAW,MAAZ;IAEE,OAAOE,EAAE;IACT,OAAOA,EAAE;IACT,aAAaA,EAAE;IACf,UAAUA,EAAE;GACb,GALMA,EAAE,KAKR,CACF;EACS,CAAA;CACJ,CAAA;AAEd,CACF"}
@@ -12,6 +12,14 @@ export interface RangeSliderProps extends Omit<SliderProps, 'value' | 'defaultVa
12
12
  thumbLabels?: readonly [string, string];
13
13
  }
14
14
  /**
15
+ * A low and high value on one track, each thumb with its own name.
16
+ *
17
+ * @remarks
18
+ * `RangeSlider` picks a range: a departure window, a price band. The wrapper is a group, labelled
19
+ * by its Field or `aria-label`, and each thumb is a slider named by `thumbLabels`.
20
+ * `minStepsBetweenThumbs` keeps the thumbs apart.
21
+ *
22
+ * @privateRemarks
15
23
  * A low–high range on one track ("Price range": £500–£5,000). The wrapper is a
16
24
  * `role="group"` labelled by the surrounding `<Field>` (see `RangeSliderField`) or
17
25
  * `aria-label`; each thumb is a `role="slider"` named by `thumbLabels`. The ref and `id`
@@ -1 +1 @@
1
- {"version":3,"file":"RangeSlider.js","names":["DEFAULT_THUMB_LABELS","RangeSlider","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","labelledByProp","describedByProp","ariaInvalid","rest","autoId","useId","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","min","max","onValueChange","next","handleBlur","useFocusLeave","onBlur","toTuple","thumbState","SliderBase","onValueCommit","thumbLabels"],"sources":["../../../../src/components/inputs/RangeSlider/RangeSlider.tsx"],"sourcesContent":["import { forwardRef, useId } from 'react'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport type { SliderProps } from '#components/inputs/Slider'\nimport { SliderBase } from '#components/inputs/Slider/SliderBase'\n\nexport interface RangeSliderProps extends Omit<\n SliderProps,\n 'value' | 'defaultValue' | 'onValueChange' | 'onValueCommit'\n> {\n /** Controlled `[low, high]`. */\n value?: readonly [number, number]\n /** Initial `[low, high]` when uncontrolled. Defaults to `[min, max]`. */\n defaultValue?: readonly [number, number]\n onValueChange?: (value: [number, number]) => void\n onValueCommit?: (value: [number, number]) => void\n /** How many steps the thumbs must stay apart. Default 0 (they may meet). */\n minStepsBetweenThumbs?: number\n /** Accessible names of the two thumbs. Default `['Minimum', 'Maximum']`. */\n thumbLabels?: readonly [string, string]\n}\n\nconst DEFAULT_THUMB_LABELS = ['Minimum', 'Maximum'] as const\n\n/**\n * A low–high range on one track (\"Price range\": £500–£5,000). The wrapper is a\n * `role=\"group\"` labelled by the surrounding `<Field>` (see `RangeSliderField`) or\n * `aria-label`; each thumb is a `role=\"slider\"` named by `thumbLabels`. The ref and `id`\n * go to the group. `onBlur` fires once, when focus leaves both thumbs.\n *\n * <RangeSlider aria-label=\"Price range\" min={500} max={5000} step={100} defaultValue={[1000, 2500]} showValue\n * formatOptions={{ style: 'currency', currency: 'GBP', maximumFractionDigits: 0 }} />\n */\nexport const RangeSlider = markFieldAware(\n forwardRef<HTMLSpanElement, RangeSliderProps>(function RangeSlider(\n {\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n min = 0,\n max = 100,\n step = 1,\n minStepsBetweenThumbs = 0,\n thumbLabels = DEFAULT_THUMB_LABELS,\n marks,\n showValue = false,\n formatOptions,\n locale,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n onBlur,\n 'aria-labelledby': labelledByProp,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const autoId = useId()\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue<readonly [number, number]>(\n value,\n defaultValue ?? [min, max],\n onValueChange &&\n ((next) => {\n onValueChange([next[0], next[1]])\n }),\n field.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n const toTuple = (next: number[]): [number, number] => [next[0] ?? min, next[1] ?? max]\n\n const thumbState = {\n 'aria-invalid': field.invalid || undefined,\n 'aria-readonly': field.readOnly || undefined,\n 'aria-busy': field.busy || undefined,\n } as const\n\n return (\n // aria-invalid on the group as well as each thumb, like CheckboxGroup: the error belongs to the range.\n // eslint-disable-next-line jsx-a11y/role-supports-aria-props\n <SliderBase\n ref={ref}\n id={field.id}\n role=\"group\"\n aria-labelledby={labelledByProp ?? (rest['aria-label'] ? undefined : field.labelId)}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n {...rest}\n onBlur={handleBlur}\n values={current}\n onValuesChange={(next) => {\n setCurrent(toTuple(next))\n }}\n onValuesCommit={(next) => onValueCommit?.(toTuple(next))}\n min={min}\n max={max}\n step={step}\n minStepsBetweenThumbs={minStepsBetweenThumbs}\n marks={marks}\n showValue={showValue}\n formatOptions={formatOptions}\n locale={locale}\n name={name}\n disabled={field.disabled}\n readOnly={field.readOnly}\n invalid={field.invalid}\n size={size}\n thumbs={[\n { id: `${autoId}min`, 'aria-label': thumbLabels[0], ...thumbState },\n { id: `${autoId}max`, 'aria-label': thumbLabels[1], ...thumbState },\n ]}\n />\n )\n }),\n)\n"],"mappings":";;;;;;AAsBA,IAAMA,IAAuB,CAAC,WAAW,SAAS,GAWrCC,IAAcC,EACzBC,EAA8C,SAC5C,EACE,UACA,iBACA,kBACA,kBACA,SAAM,GACN,SAAM,KACN,UAAO,GACP,2BAAwB,GACxB,iBAAcH,GACd,UACA,eAAY,IACZ,kBACA,WACA,SACA,UAAUI,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,WACA,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,GAAGC,KAEL,GACA;CACA,IAAMC,IAASC,EAAM,GACfC,IAAQC,EAAiB;EAC7B,IAAIR;EACJ,aAAaE;EACb,SAASH;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACW,GAASC,KAAcC,EAC5BC,GACAC,KAAgB,CAACC,GAAKC,CAAG,GACzBC,OACI,MAAS;EACT,EAAc,CAACC,EAAK,IAAIA,EAAK,EAAE,CAAC;CAClC,IACFV,EAAM,QACR,GACMW,IAAaC,EAAcC,CAAM,GACjCC,KAAW,MAAqC,CAACJ,EAAK,MAAMH,GAAKG,EAAK,MAAMF,CAAG,GAE/EO,IAAa;EACjB,gBAAgBf,EAAM,WAAW,KAAA;EACjC,iBAAiBA,EAAM,YAAY,KAAA;EACnC,aAAaA,EAAM,QAAQ,KAAA;CAC7B;CAEA,OAGE,kBAACgB,GAAD;EACO;EACL,IAAIhB,EAAM;EACV,MAAK;EACL,mBAAiBN,MAAmBG,EAAK,gBAAgB,KAAA,IAAYG,EAAM;EAC3E,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,GAAIH;EACJ,QAAQc;EACR,QAAQT;EACR,iBAAiB,MAAS;GACxB,EAAWY,EAAQJ,CAAI,CAAC;EAC1B;EACA,iBAAiB,MAASO,IAAgBH,EAAQJ,CAAI,CAAC;EAClD;EACA;EACC;EACiB;EAChB;EACI;EACI;EACP;EACF;EACN,UAAUV,EAAM;EAChB,UAAUA,EAAM;EAChB,SAASA,EAAM;EACT;EACN,QAAQ,CACN;GAAE,IAAI,GAAGF,EAAO;GAAM,cAAcoB,EAAY;GAAI,GAAGH;EAAW,GAClE;GAAE,IAAI,GAAGjB,EAAO;GAAM,cAAcoB,EAAY;GAAI,GAAGH;EAAW,CACpE;CACD,CAAA;AAEL,CAAC,CACH"}
1
+ {"version":3,"file":"RangeSlider.js","names":["DEFAULT_THUMB_LABELS","RangeSlider","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","labelledByProp","describedByProp","ariaInvalid","rest","autoId","useId","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","min","max","onValueChange","next","handleBlur","useFocusLeave","onBlur","toTuple","thumbState","SliderBase","onValueCommit","thumbLabels"],"sources":["../../../../src/components/inputs/RangeSlider/RangeSlider.tsx"],"sourcesContent":["import { forwardRef, useId } from 'react'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport type { SliderProps } from '#components/inputs/Slider'\nimport { SliderBase } from '#components/inputs/Slider/SliderBase'\n\nexport interface RangeSliderProps extends Omit<\n SliderProps,\n 'value' | 'defaultValue' | 'onValueChange' | 'onValueCommit'\n> {\n /** Controlled `[low, high]`. */\n value?: readonly [number, number]\n /** Initial `[low, high]` when uncontrolled. Defaults to `[min, max]`. */\n defaultValue?: readonly [number, number]\n onValueChange?: (value: [number, number]) => void\n onValueCommit?: (value: [number, number]) => void\n /** How many steps the thumbs must stay apart. Default 0 (they may meet). */\n minStepsBetweenThumbs?: number\n /** Accessible names of the two thumbs. Default `['Minimum', 'Maximum']`. */\n thumbLabels?: readonly [string, string]\n}\n\nconst DEFAULT_THUMB_LABELS = ['Minimum', 'Maximum'] as const\n\n/**\n * A low and high value on one track, each thumb with its own name.\n *\n * @remarks\n * `RangeSlider` picks a range: a departure window, a price band. The wrapper is a group, labelled\n * by its Field or `aria-label`, and each thumb is a slider named by `thumbLabels`.\n * `minStepsBetweenThumbs` keeps the thumbs apart.\n *\n * @privateRemarks\n * A low–high range on one track (\"Price range\": £500–£5,000). The wrapper is a\n * `role=\"group\"` labelled by the surrounding `<Field>` (see `RangeSliderField`) or\n * `aria-label`; each thumb is a `role=\"slider\"` named by `thumbLabels`. The ref and `id`\n * go to the group. `onBlur` fires once, when focus leaves both thumbs.\n *\n * <RangeSlider aria-label=\"Price range\" min={500} max={5000} step={100} defaultValue={[1000, 2500]} showValue\n * formatOptions={{ style: 'currency', currency: 'GBP', maximumFractionDigits: 0 }} />\n */\nexport const RangeSlider = markFieldAware(\n forwardRef<HTMLSpanElement, RangeSliderProps>(function RangeSlider(\n {\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n min = 0,\n max = 100,\n step = 1,\n minStepsBetweenThumbs = 0,\n thumbLabels = DEFAULT_THUMB_LABELS,\n marks,\n showValue = false,\n formatOptions,\n locale,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n onBlur,\n 'aria-labelledby': labelledByProp,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const autoId = useId()\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue<readonly [number, number]>(\n value,\n defaultValue ?? [min, max],\n onValueChange &&\n ((next) => {\n onValueChange([next[0], next[1]])\n }),\n field.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n const toTuple = (next: number[]): [number, number] => [next[0] ?? min, next[1] ?? max]\n\n const thumbState = {\n 'aria-invalid': field.invalid || undefined,\n 'aria-readonly': field.readOnly || undefined,\n 'aria-busy': field.busy || undefined,\n } as const\n\n return (\n // aria-invalid on the group as well as each thumb, like CheckboxGroup: the error belongs to the range.\n // eslint-disable-next-line jsx-a11y/role-supports-aria-props\n <SliderBase\n ref={ref}\n id={field.id}\n role=\"group\"\n aria-labelledby={labelledByProp ?? (rest['aria-label'] ? undefined : field.labelId)}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n {...rest}\n onBlur={handleBlur}\n values={current}\n onValuesChange={(next) => {\n setCurrent(toTuple(next))\n }}\n onValuesCommit={(next) => onValueCommit?.(toTuple(next))}\n min={min}\n max={max}\n step={step}\n minStepsBetweenThumbs={minStepsBetweenThumbs}\n marks={marks}\n showValue={showValue}\n formatOptions={formatOptions}\n locale={locale}\n name={name}\n disabled={field.disabled}\n readOnly={field.readOnly}\n invalid={field.invalid}\n size={size}\n thumbs={[\n { id: `${autoId}min`, 'aria-label': thumbLabels[0], ...thumbState },\n { id: `${autoId}max`, 'aria-label': thumbLabels[1], ...thumbState },\n ]}\n />\n )\n }),\n)\n"],"mappings":";;;;;;AAsBA,IAAMA,IAAuB,CAAC,WAAW,SAAS,GAmBrCC,IAAcC,EACzBC,EAA8C,SAC5C,EACE,UACA,iBACA,kBACA,kBACA,SAAM,GACN,SAAM,KACN,UAAO,GACP,2BAAwB,GACxB,iBAAcH,GACd,UACA,eAAY,IACZ,kBACA,WACA,SACA,UAAUI,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,WACA,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,GAAGC,KAEL,GACA;CACA,IAAMC,IAASC,EAAM,GACfC,IAAQC,EAAiB;EAC7B,IAAIR;EACJ,aAAaE;EACb,SAASH;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACW,GAASC,KAAcC,EAC5BC,GACAC,KAAgB,CAACC,GAAKC,CAAG,GACzBC,OACI,MAAS;EACT,EAAc,CAACC,EAAK,IAAIA,EAAK,EAAE,CAAC;CAClC,IACFV,EAAM,QACR,GACMW,IAAaC,EAAcC,CAAM,GACjCC,KAAW,MAAqC,CAACJ,EAAK,MAAMH,GAAKG,EAAK,MAAMF,CAAG,GAE/EO,IAAa;EACjB,gBAAgBf,EAAM,WAAW,KAAA;EACjC,iBAAiBA,EAAM,YAAY,KAAA;EACnC,aAAaA,EAAM,QAAQ,KAAA;CAC7B;CAEA,OAGE,kBAACgB,GAAD;EACO;EACL,IAAIhB,EAAM;EACV,MAAK;EACL,mBAAiBN,MAAmBG,EAAK,gBAAgB,KAAA,IAAYG,EAAM;EAC3E,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,GAAIH;EACJ,QAAQc;EACR,QAAQT;EACR,iBAAiB,MAAS;GACxB,EAAWY,EAAQJ,CAAI,CAAC;EAC1B;EACA,iBAAiB,MAASO,IAAgBH,EAAQJ,CAAI,CAAC;EAClD;EACA;EACC;EACiB;EAChB;EACI;EACI;EACP;EACF;EACN,UAAUV,EAAM;EAChB,UAAUA,EAAM;EAChB,SAASA,EAAM;EACT;EACN,QAAQ,CACN;GAAE,IAAI,GAAGF,EAAO;GAAM,cAAcoB,EAAY;GAAI,GAAGH;EAAW,GAClE;GAAE,IAAI,GAAGjB,EAAO;GAAM,cAAcoB,EAAY;GAAI,GAAGH;EAAW,CACpE;CACD,CAAA;AAEL,CAAC,CACH"}
@@ -3,6 +3,13 @@ import { type RangeSliderProps } from '../RangeSlider/index.js';
3
3
  export interface RangeSliderFieldProps extends FieldLabelProps, Omit<RangeSliderProps, 'invalid' | keyof FieldLabelProps> {
4
4
  }
5
5
  /**
6
+ * A labelled range slider, the label naming the group and thumbLabels naming each thumb.
7
+ *
8
+ * @remarks
9
+ * `RangeSliderField` is a {@link Field | Field} around a {@link RangeSlider | RangeSlider}. The
10
+ * label names the group, and `thumbLabels` name the two thumbs.
11
+ *
12
+ * @privateRemarks
6
13
  * A labelled `RangeSlider`: the Field's label names the group, `thumbLabels` name the two
7
14
  * thumbs. `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the
8
15
  * range slider's group.
@@ -1 +1 @@
1
- {"version":3,"file":"RangeSliderField.js","names":["RangeSliderField","forwardRef","fieldProps","sliderProps","splitFieldLabelProps","props","Field","id","RangeSlider"],"sources":["../../../../src/components/inputs/RangeSliderField/RangeSliderField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { RangeSlider, type RangeSliderProps } from '#components/inputs/RangeSlider'\n\nexport interface RangeSliderFieldProps\n extends FieldLabelProps, Omit<RangeSliderProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled `RangeSlider`: the Field's label names the group, `thumbLabels` name the two\n * thumbs. `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the\n * range slider's group.\n *\n * <RangeSliderField label=\"Price range\" name=\"price\" min={500} max={5000} step={100} showValue />\n */\nexport const RangeSliderField = forwardRef<HTMLSpanElement, RangeSliderFieldProps>(\n function RangeSliderField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...sliderProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <RangeSlider ref={ref} {...sliderProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAeA,IAAaA,IAAmBC,EAC9B,SAA0B,GAAO,GAAK;CACpC,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAkB;GAAK,GAAIL;EAAc,CAAA;CACpC,CAAA;AAEX,CACF"}
1
+ {"version":3,"file":"RangeSliderField.js","names":["RangeSliderField","forwardRef","fieldProps","sliderProps","splitFieldLabelProps","props","Field","id","RangeSlider"],"sources":["../../../../src/components/inputs/RangeSliderField/RangeSliderField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { RangeSlider, type RangeSliderProps } from '#components/inputs/RangeSlider'\n\nexport interface RangeSliderFieldProps\n extends FieldLabelProps, Omit<RangeSliderProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled range slider, the label naming the group and thumbLabels naming each thumb.\n *\n * @remarks\n * `RangeSliderField` is a {@link Field | Field} around a {@link RangeSlider | RangeSlider}. The\n * label names the group, and `thumbLabels` name the two thumbs.\n *\n * @privateRemarks\n * A labelled `RangeSlider`: the Field's label names the group, `thumbLabels` name the two\n * thumbs. `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the\n * range slider's group.\n *\n * <RangeSliderField label=\"Price range\" name=\"price\" min={500} max={5000} step={100} showValue />\n */\nexport const RangeSliderField = forwardRef<HTMLSpanElement, RangeSliderFieldProps>(\n function RangeSliderField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...sliderProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <RangeSlider ref={ref} {...sliderProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAsBA,IAAaA,IAAmBC,EAC9B,SAA0B,GAAO,GAAK;CACpC,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAkB;GAAK,GAAIL;EAAc,CAAA;CACpC,CAAA;AAEX,CACF"}
@@ -21,6 +21,14 @@ export interface RatingProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onCha
21
21
  size?: Size;
22
22
  }
23
23
  /**
24
+ * A star rating that's one tab stop, with arrow keys to choose and a preview on hover.
25
+ *
26
+ * @remarks
27
+ * `Rating` is a radio group whose radios are stars, so it's one tab stop and the arrow keys move
28
+ * and choose. Stars up to the rating fill with the accent, and hovering previews a rating before
29
+ * you choose. `clearable` lets pressing the chosen star again clear it.
30
+ *
31
+ * @privateRemarks
24
32
  * A star rating — a Radix RadioGroup whose radios are stars, so it's one tab stop and the
25
33
  * arrow keys move and choose. Stars up to the rating fill with the accent; hovering
26
34
  * previews a rating before you choose it. Label it with a `<Field>` (see `RatingField`) or
@@ -1 +1 @@
1
- {"version":3,"file":"Rating.js","names":["RadixRadioGroup","styles","Rating_module_default","defaultItemLabel","n","max","Rating","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","describedByProp","ariaInvalid","labelledByProp","rest","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","onValueChange","preview","setPreview","useState","handleBlur","useFocusLeave","onBlur","interactive","shown","stars","i","RadioGroup","cx","className","v","size","onPointerLeave","event","itemLabel","clearable","StarIcon","name"],"sources":["../../../../src/components/inputs/Rating/Rating.tsx"],"sourcesContent":["import { forwardRef, useState, type HTMLAttributes } from 'react'\nimport { RadioGroup as RadixRadioGroup } from 'radix-ui'\nimport { StarIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport styles from './Rating.module.css'\n\nexport interface RatingProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n /** Controlled rating, `null` for none. */\n value?: number | null\n defaultValue?: number | null\n onValueChange?: (value: number | null) => void\n /** Number of stars. Default 5. */\n max?: number\n /** Choosing the current rating again clears it (`null`). */\n clearable?: boolean\n /** Each star's accessible name. Default `${n} of ${max}`. */\n itemLabel?: (n: number, max: number) => string\n /** Emits a hidden input with the rating (none when `null`), for native form submission. */\n name?: string\n disabled?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores changes. */\n readOnly?: boolean\n /** Critical edge on the empty stars + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n size?: Size\n}\n\nconst defaultItemLabel = (n: number, max: number) => `${String(n)} of ${String(max)}`\n\n/**\n * A star rating — a Radix RadioGroup whose radios are stars, so it's one tab stop and the\n * arrow keys move and choose. Stars up to the rating fill with the accent; hovering\n * previews a rating before you choose it. Label it with a `<Field>` (see `RatingField`) or\n * `aria-label`. `onBlur` fires once, when focus leaves the stars.\n *\n * <Rating aria-label=\"Rate this release\" defaultValue={4} clearable />\n */\nexport const Rating = markFieldAware(\n forwardRef<HTMLDivElement, RatingProps>(function Rating(\n {\n value,\n defaultValue = null,\n onValueChange,\n max = 5,\n clearable = false,\n itemLabel = defaultItemLabel,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n className,\n onBlur,\n onPointerLeave,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n 'aria-labelledby': labelledByProp,\n ...rest\n },\n ref,\n ) {\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue<number | null>(\n value,\n defaultValue,\n onValueChange,\n field.readOnly,\n )\n const [preview, setPreview] = useState<number | null>(null)\n const handleBlur = useFocusLeave(onBlur)\n const interactive = !field.disabled && !field.readOnly\n const shown = preview ?? current ?? 0\n const stars = Array.from({ length: Math.max(0, Math.floor(max)) }, (_, i) => i + 1)\n\n return (\n <RadixRadioGroup.Root\n ref={ref}\n id={field.id}\n className={cx(styles.rating, className)}\n value={current === null ? '' : String(current)}\n onValueChange={(v) => {\n setCurrent(v === '' ? null : Number(v))\n }}\n disabled={field.disabled}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-readonly={field.readOnly || undefined}\n data-previewing={preview !== null || undefined}\n aria-labelledby={labelledByProp ?? (rest['aria-label'] ? undefined : field.labelId)}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-readonly={field.readOnly || undefined}\n aria-busy={field.busy || undefined}\n onBlur={handleBlur}\n onPointerLeave={(event) => {\n setPreview(null)\n onPointerLeave?.(event)\n }}\n {...rest}\n >\n {stars.map((n) => (\n <RadixRadioGroup.Item\n key={n}\n value={String(n)}\n className={styles.star}\n aria-label={itemLabel(n, max)}\n data-filled={n <= shown || undefined}\n onPointerEnter={\n interactive\n ? () => {\n setPreview(n)\n }\n : undefined\n }\n onClick={\n clearable\n ? () => {\n // Radix ignores a click on the checked radio; clearable turns it into \"none\".\n if (current === n) setCurrent(null)\n }\n : undefined\n }\n >\n <StarIcon className={styles.glyph} />\n </RadixRadioGroup.Item>\n ))}\n {name && current !== null ? (\n <input type=\"hidden\" name={name} value={current} disabled={field.disabled || undefined} />\n ) : null}\n </RadixRadioGroup.Root>\n )\n }),\n)\n"],"mappings":";;;;;;;;;AAiCA,IAAMG,KAAoB,GAAW,MAAgB,GAAG,OAAOC,CAAC,EAAE,MAAM,OAAOC,CAAG,KAUrEC,IAASC,EACpBC,EAAwC,SACtC,EACE,UACA,kBAAe,MACf,kBACA,SAAM,GACN,eAAY,IACZ,eAAYL,GACZ,SACA,UAAUM,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,cACA,WACA,mBACA,oBAAoBC,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAiB;EAC7B,IAAIN;EACJ,aAAaC;EACb,SAASF;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACS,GAASC,KAAcC,EAC5BC,GACAC,GACAC,GACAP,EAAM,QACR,GACM,CAACQ,GAASC,KAAcC,EAAwB,IAAI,GACpDC,IAAaC,EAAcC,CAAM,GACjCC,IAAc,CAACd,EAAM,YAAY,CAACA,EAAM,UACxCe,IAAQP,KAAWN,KAAW,GAC9Bc,IAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM5B,CAAG,CAAC,EAAE,IAAI,GAAG,MAAM6B,IAAI,CAAC;CAElF,OACE,kBAAClC,EAAgB,MAAjB;EACO;EACL,IAAIiB,EAAM;EACV,WAAWmB,EAAGnC,EAAO,QAAQoC,CAAS;EACtC,OAAOlB,MAAY,OAAO,KAAK,OAAOA,CAAO;EAC7C,gBAAgB,MAAM;GACpB,EAAWmB,MAAM,KAAK,OAAO,OAAOA,CAAC,CAAC;EACxC;EACA,UAAUrB,EAAM;EAChB,aAAWsB;EACX,gBAActB,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,mBAAiBQ,MAAY,QAAQ,KAAA;EACrC,mBAAiBV,MAAmBC,EAAK,gBAAgB,KAAA,IAAYC,EAAM;EAC3E,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,iBAAeA,EAAM,YAAY,KAAA;EACjC,aAAWA,EAAM,QAAQ,KAAA;EACzB,QAAQW;EACR,iBAAiB,MAAU;GAEzB,AADAF,EAAW,IAAI,GACfc,IAAiBC,CAAK;EACxB;EACA,GAAIzB;EAxBN,UAAA,CA0BGiB,EAAM,KAAK,MACV,kBAACjC,EAAgB,MAAjB;GAEE,OAAO,OAAOI,CAAC;GACf,WAAWH,EAAO;GAClB,cAAYyC,EAAUtC,GAAGC,CAAG;GAC5B,eAAaD,KAAK4B,KAAS,KAAA;GAC3B,gBACED,UACU;IACJ,EAAW3B,CAAC;GACd,IACA,KAAA;GAEN,SACEuC,UACU;IAEJ,AAAIxB,MAAYf,KAAGgB,EAAW,IAAI;GACpC,IACA,KAAA;GAGN,UAAA,kBAACwB,GAAD,EAAU,WAAW3C,EAAO,MAAQ,CAAA;EAChB,GAtBfG,CAsBe,CACvB,GACAyC,KAAQ1B,MAAY,OACnB,kBAAC,SAAD;GAAO,MAAK;GAAe;GAAM,OAAOA;GAAS,UAAUF,EAAM,YAAY,KAAA;EAAY,CAAA,IACvF,IACgB;;AAE1B,CAAC,CACH"}
1
+ {"version":3,"file":"Rating.js","names":["RadixRadioGroup","styles","Rating_module_default","defaultItemLabel","n","max","Rating","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","describedByProp","ariaInvalid","labelledByProp","rest","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","onValueChange","preview","setPreview","useState","handleBlur","useFocusLeave","onBlur","interactive","shown","stars","i","RadioGroup","cx","className","v","size","onPointerLeave","event","itemLabel","clearable","StarIcon","name"],"sources":["../../../../src/components/inputs/Rating/Rating.tsx"],"sourcesContent":["import { forwardRef, useState, type HTMLAttributes } from 'react'\nimport { RadioGroup as RadixRadioGroup } from 'radix-ui'\nimport { StarIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport styles from './Rating.module.css'\n\nexport interface RatingProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n /** Controlled rating, `null` for none. */\n value?: number | null\n defaultValue?: number | null\n onValueChange?: (value: number | null) => void\n /** Number of stars. Default 5. */\n max?: number\n /** Choosing the current rating again clears it (`null`). */\n clearable?: boolean\n /** Each star's accessible name. Default `${n} of ${max}`. */\n itemLabel?: (n: number, max: number) => string\n /** Emits a hidden input with the rating (none when `null`), for native form submission. */\n name?: string\n disabled?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores changes. */\n readOnly?: boolean\n /** Critical edge on the empty stars + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n size?: Size\n}\n\nconst defaultItemLabel = (n: number, max: number) => `${String(n)} of ${String(max)}`\n\n/**\n * A star rating that's one tab stop, with arrow keys to choose and a preview on hover.\n *\n * @remarks\n * `Rating` is a radio group whose radios are stars, so it's one tab stop and the arrow keys move\n * and choose. Stars up to the rating fill with the accent, and hovering previews a rating before\n * you choose. `clearable` lets pressing the chosen star again clear it.\n *\n * @privateRemarks\n * A star rating — a Radix RadioGroup whose radios are stars, so it's one tab stop and the\n * arrow keys move and choose. Stars up to the rating fill with the accent; hovering\n * previews a rating before you choose it. Label it with a `<Field>` (see `RatingField`) or\n * `aria-label`. `onBlur` fires once, when focus leaves the stars.\n *\n * <Rating aria-label=\"Rate this release\" defaultValue={4} clearable />\n */\nexport const Rating = markFieldAware(\n forwardRef<HTMLDivElement, RatingProps>(function Rating(\n {\n value,\n defaultValue = null,\n onValueChange,\n max = 5,\n clearable = false,\n itemLabel = defaultItemLabel,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n className,\n onBlur,\n onPointerLeave,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n 'aria-labelledby': labelledByProp,\n ...rest\n },\n ref,\n ) {\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue<number | null>(\n value,\n defaultValue,\n onValueChange,\n field.readOnly,\n )\n const [preview, setPreview] = useState<number | null>(null)\n const handleBlur = useFocusLeave(onBlur)\n const interactive = !field.disabled && !field.readOnly\n const shown = preview ?? current ?? 0\n const stars = Array.from({ length: Math.max(0, Math.floor(max)) }, (_, i) => i + 1)\n\n return (\n <RadixRadioGroup.Root\n ref={ref}\n id={field.id}\n className={cx(styles.rating, className)}\n value={current === null ? '' : String(current)}\n onValueChange={(v) => {\n setCurrent(v === '' ? null : Number(v))\n }}\n disabled={field.disabled}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-readonly={field.readOnly || undefined}\n data-previewing={preview !== null || undefined}\n aria-labelledby={labelledByProp ?? (rest['aria-label'] ? undefined : field.labelId)}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-readonly={field.readOnly || undefined}\n aria-busy={field.busy || undefined}\n onBlur={handleBlur}\n onPointerLeave={(event) => {\n setPreview(null)\n onPointerLeave?.(event)\n }}\n {...rest}\n >\n {stars.map((n) => (\n <RadixRadioGroup.Item\n key={n}\n value={String(n)}\n className={styles.star}\n aria-label={itemLabel(n, max)}\n data-filled={n <= shown || undefined}\n onPointerEnter={\n interactive\n ? () => {\n setPreview(n)\n }\n : undefined\n }\n onClick={\n clearable\n ? () => {\n // Radix ignores a click on the checked radio; clearable turns it into \"none\".\n if (current === n) setCurrent(null)\n }\n : undefined\n }\n >\n <StarIcon className={styles.glyph} />\n </RadixRadioGroup.Item>\n ))}\n {name && current !== null ? (\n <input type=\"hidden\" name={name} value={current} disabled={field.disabled || undefined} />\n ) : null}\n </RadixRadioGroup.Root>\n )\n }),\n)\n"],"mappings":";;;;;;;;;AAiCA,IAAMG,KAAoB,GAAW,MAAgB,GAAG,OAAOC,CAAC,EAAE,MAAM,OAAOC,CAAG,KAkBrEC,IAASC,EACpBC,EAAwC,SACtC,EACE,UACA,kBAAe,MACf,kBACA,SAAM,GACN,eAAY,IACZ,eAAYL,GACZ,SACA,UAAUM,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,cACA,WACA,mBACA,oBAAoBC,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAiB;EAC7B,IAAIN;EACJ,aAAaC;EACb,SAASF;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACS,GAASC,KAAcC,EAC5BC,GACAC,GACAC,GACAP,EAAM,QACR,GACM,CAACQ,GAASC,KAAcC,EAAwB,IAAI,GACpDC,IAAaC,EAAcC,CAAM,GACjCC,IAAc,CAACd,EAAM,YAAY,CAACA,EAAM,UACxCe,IAAQP,KAAWN,KAAW,GAC9Bc,IAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM5B,CAAG,CAAC,EAAE,IAAI,GAAG,MAAM6B,IAAI,CAAC;CAElF,OACE,kBAAClC,EAAgB,MAAjB;EACO;EACL,IAAIiB,EAAM;EACV,WAAWmB,EAAGnC,EAAO,QAAQoC,CAAS;EACtC,OAAOlB,MAAY,OAAO,KAAK,OAAOA,CAAO;EAC7C,gBAAgB,MAAM;GACpB,EAAWmB,MAAM,KAAK,OAAO,OAAOA,CAAC,CAAC;EACxC;EACA,UAAUrB,EAAM;EAChB,aAAWsB;EACX,gBAActB,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,mBAAiBQ,MAAY,QAAQ,KAAA;EACrC,mBAAiBV,MAAmBC,EAAK,gBAAgB,KAAA,IAAYC,EAAM;EAC3E,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,iBAAeA,EAAM,YAAY,KAAA;EACjC,aAAWA,EAAM,QAAQ,KAAA;EACzB,QAAQW;EACR,iBAAiB,MAAU;GAEzB,AADAF,EAAW,IAAI,GACfc,IAAiBC,CAAK;EACxB;EACA,GAAIzB;EAxBN,UAAA,CA0BGiB,EAAM,KAAK,MACV,kBAACjC,EAAgB,MAAjB;GAEE,OAAO,OAAOI,CAAC;GACf,WAAWH,EAAO;GAClB,cAAYyC,EAAUtC,GAAGC,CAAG;GAC5B,eAAaD,KAAK4B,KAAS,KAAA;GAC3B,gBACED,UACU;IACJ,EAAW3B,CAAC;GACd,IACA,KAAA;GAEN,SACEuC,UACU;IAEJ,AAAIxB,MAAYf,KAAGgB,EAAW,IAAI;GACpC,IACA,KAAA;GAGN,UAAA,kBAACwB,GAAD,EAAU,WAAW3C,EAAO,MAAQ,CAAA;EAChB,GAtBfG,CAsBe,CACvB,GACAyC,KAAQ1B,MAAY,OACnB,kBAAC,SAAD;GAAO,MAAK;GAAe;GAAM,OAAOA;GAAS,UAAUF,EAAM,YAAY,KAAA;EAAY,CAAA,IACvF,IACgB;;AAE1B,CAAC,CACH"}
@@ -3,6 +3,13 @@ import { type RatingProps } from '../Rating/index.js';
3
3
  export interface RatingFieldProps extends FieldLabelProps, Omit<RatingProps, 'invalid' | keyof FieldLabelProps> {
4
4
  }
5
5
  /**
6
+ * A labelled star rating.
7
+ *
8
+ * @remarks
9
+ * `RatingField` is a {@link Field | Field} around a {@link Rating | Rating}. The stars' radio
10
+ * group is labelled by the field's label and described by its help.
11
+ *
12
+ * @privateRemarks
6
13
  * A labelled `Rating`. The stars' radiogroup is labelled by the Field's label and described
7
14
  * by its help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name`
8
15
  * and the rest go to the radiogroup.
@@ -1 +1 @@
1
- {"version":3,"file":"RatingField.js","names":["RatingField","forwardRef","fieldProps","ratingProps","splitFieldLabelProps","props","Field","id","Rating"],"sources":["../../../../src/components/inputs/RatingField/RatingField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { Rating, type RatingProps } from '#components/inputs/Rating'\n\nexport interface RatingFieldProps\n extends FieldLabelProps, Omit<RatingProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled `Rating`. The stars' radiogroup is labelled by the Field's label and described\n * by its help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name`\n * and the rest go to the radiogroup.\n *\n * <RatingField label=\"Rate this release\" name=\"rating\" clearable />\n */\nexport const RatingField = forwardRef<HTMLDivElement, RatingFieldProps>(\n function RatingField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...ratingProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Rating ref={ref} {...ratingProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAeA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAK,GAAIL;EAAc,CAAA;CAC/B,CAAA;AAEX,CACF"}
1
+ {"version":3,"file":"RatingField.js","names":["RatingField","forwardRef","fieldProps","ratingProps","splitFieldLabelProps","props","Field","id","Rating"],"sources":["../../../../src/components/inputs/RatingField/RatingField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { Rating, type RatingProps } from '#components/inputs/Rating'\n\nexport interface RatingFieldProps\n extends FieldLabelProps, Omit<RatingProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled star rating.\n *\n * @remarks\n * `RatingField` is a {@link Field | Field} around a {@link Rating | Rating}. The stars' radio\n * group is labelled by the field's label and described by its help.\n *\n * @privateRemarks\n * A labelled `Rating`. The stars' radiogroup is labelled by the Field's label and described\n * by its help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name`\n * and the rest go to the radiogroup.\n *\n * <RatingField label=\"Rate this release\" name=\"rating\" clearable />\n */\nexport const RatingField = forwardRef<HTMLDivElement, RatingFieldProps>(\n function RatingField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...ratingProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Rating ref={ref} {...ratingProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAsBA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAK,GAAIL;EAAc,CAAA;CAC/B,CAAA;AAEX,CACF"}
@@ -3,6 +3,13 @@ import { type FieldLabelProps } from '../Field/index.js';
3
3
  export interface SegmentedFieldProps extends FieldLabelProps, Omit<SegmentedControlProps, 'children' | 'invalid' | keyof FieldLabelProps> {
4
4
  }
5
5
  /**
6
+ * A labelled segmented control for one of two to five peers, always one selected.
7
+ *
8
+ * @remarks
9
+ * `SegmentedField` is a {@link SegmentedControl | SegmentedControl} with a label, description and
10
+ * error. It always has one segment selected, so it suits choices with a sensible default.
11
+ *
12
+ * @privateRemarks
6
13
  * A labelled `SegmentedControl` — one of 2–5 peers, always one selected. The control is
7
14
  * labelled by the Field's label and described by its help, warning and error.
8
15
  * `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the control.
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedField.js","names":["SegmentedField","forwardRef","fieldProps","controlProps","splitFieldLabelProps","props","Field","id","SegmentedControl"],"sources":["../../../../src/components/inputs/SegmentedField/SegmentedField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { SegmentedControl, type SegmentedControlProps } from '#components/actions/SegmentedControl'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport interface SegmentedFieldProps\n extends\n FieldLabelProps,\n Omit<SegmentedControlProps, 'children' | 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled `SegmentedControl` — one of 2–5 peers, always one selected. The control is\n * labelled by the Field's label and described by its help, warning and error.\n * `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the control.\n *\n * <SegmentedField label=\"Billing period\" name=\"period\" options={periods} layout=\"horizontal\" />\n */\nexport const SegmentedField = forwardRef<HTMLDivElement, SegmentedFieldProps>(\n function SegmentedField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...controlProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <SegmentedControl ref={ref} {...controlProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAiBA,IAAaA,IAAiBC,EAC5B,SAAwB,GAAO,GAAK;CAClC,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAuB;GAAK,GAAIL;EAAe,CAAA;CAC1C,CAAA;AAEX,CACF"}
1
+ {"version":3,"file":"SegmentedField.js","names":["SegmentedField","forwardRef","fieldProps","controlProps","splitFieldLabelProps","props","Field","id","SegmentedControl"],"sources":["../../../../src/components/inputs/SegmentedField/SegmentedField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { SegmentedControl, type SegmentedControlProps } from '#components/actions/SegmentedControl'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport interface SegmentedFieldProps\n extends\n FieldLabelProps,\n Omit<SegmentedControlProps, 'children' | 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled segmented control for one of two to five peers, always one selected.\n *\n * @remarks\n * `SegmentedField` is a {@link SegmentedControl | SegmentedControl} with a label, description and\n * error. It always has one segment selected, so it suits choices with a sensible default.\n *\n * @privateRemarks\n * A labelled `SegmentedControl` — one of 2–5 peers, always one selected. The control is\n * labelled by the Field's label and described by its help, warning and error.\n * `className`/`style` go to the Field; `ref`, `id`, `name` and the rest go to the control.\n *\n * <SegmentedField label=\"Billing period\" name=\"period\" options={periods} layout=\"horizontal\" />\n */\nexport const SegmentedField = forwardRef<HTMLDivElement, SegmentedFieldProps>(\n function SegmentedField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...controlProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <SegmentedControl ref={ref} {...controlProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAwBA,IAAaA,IAAiBC,EAC5B,SAAwB,GAAO,GAAK;CAClC,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAuB;GAAK,GAAIL;EAAe,CAAA;CAC1C,CAAA;AAEX,CACF"}
@@ -54,6 +54,15 @@ export interface SelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement
54
54
  required?: boolean;
55
55
  autoComplete?: string;
56
56
  }
57
+ /**
58
+ * Pick one option from a list. A styled listbox with keyboard support and native form submission.
59
+ *
60
+ * @remarks
61
+ * `Select` is Radix Select with Kiln's look: a button that opens a listbox, with typeahead, arrow
62
+ * keys and grouped options. Pass `options`, or `groups` for labelled sections. `name` adds a
63
+ * hidden input so it submits with a native form. For a labelled select, use {@link SelectField |
64
+ * SelectField}.
65
+ */
57
66
  export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLButtonElement>> & {
58
67
  Root: typeof SelectRoot;
59
68
  Trigger: import("react").ForwardRefExoticComponent<SelectTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["RadixSelect","control","styles","Select","control_module_default","Select_module_default","TriggerNodeContext","createContext","SelectRoot","node","setNode","useState","scope","useMemo","Select","props","SelectTrigger","markFieldAware","forwardRef","invalidProp","readOnlyProp","idProp","disabledProp","describedByProp","ariaInvalid","rest","triggerNode","useContext","composedRef","useMergedRefs","ref","field","useResolvedField","cx","className","size","children","ChevronDownIcon","themeScopeOf","SelectContent","container","position","sideOffset","ChevronUpIcon","SelectItem","CheckIcon","SelectGroupPart","SelectLabel","SelectSeparator","SelectBase","onValueChange","options","option","groups","index","group","Select$1"],"sources":["../../../../src/components/inputs/Select/Select.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n useMemo,\n useState,\n type ButtonHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport { Select as RadixSelect } from 'radix-ui'\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { useMergedRefs } from '#components/inputs/internal/refs'\nimport control from '#components/inputs/internal/control.module.css'\nimport styles from './Select.module.css'\n\nexport interface SelectOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface SelectGroup {\n label: string\n options: SelectOption[]\n}\n\n/* ─── Compound parts (the escape hatch) ───────────────────────────────────── */\n\n// The trigger's element, so the popover can portal into the same theme scope.\nconst TriggerNodeContext = createContext<{\n node: HTMLElement | null\n setNode: (node: HTMLElement | null) => void\n} | null>(null)\n\nexport type SelectRootProps = ComponentPropsWithoutRef<typeof RadixSelect.Root>\n\n/** State owner. Radix naming: `value` / `defaultValue` / `onValueChange`, `open` / `onOpenChange`. */\nfunction SelectRoot(props: SelectRootProps) {\n const [node, setNode] = useState<HTMLElement | null>(null)\n const scope = useMemo(() => ({ node, setNode }), [node])\n return (\n <TriggerNodeContext.Provider value={scope}>\n <RadixSelect.Root {...props} />\n </TriggerNodeContext.Provider>\n )\n}\n\nexport interface SelectTriggerProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Trigger>,\n 'asChild'\n> {\n size?: Size\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly`. Gate `onValueChange` at the `Root`. */\n readOnly?: boolean\n /** Shown while no value is chosen. */\n placeholder?: ReactNode\n}\n\n/** The field-styled button. Picks up id / describedby / invalid from a surrounding `<Field>`. */\nconst SelectTrigger = markFieldAware(\n forwardRef<HTMLButtonElement, SelectTriggerProps>(function SelectTrigger(\n {\n size = 'md',\n invalid: invalidProp,\n readOnly: readOnlyProp,\n placeholder,\n id: idProp,\n disabled: disabledProp,\n className,\n children,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const triggerNode = useContext(TriggerNodeContext)\n const composedRef = useMergedRefs(ref, triggerNode?.setNode)\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n return (\n <RadixSelect.Trigger\n ref={composedRef}\n id={field.id}\n className={cx(control.box, styles.trigger, className)}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readOnly || undefined}\n disabled={field.disabled || undefined}\n aria-readonly={field.readOnly || undefined}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-busy={field.busy || undefined}\n {...rest}\n >\n <span className={styles.value}>\n {children ?? <RadixSelect.Value placeholder={placeholder} />}\n </span>\n <RadixSelect.Icon className={styles.chevron}>\n <ChevronDownIcon />\n </RadixSelect.Icon>\n </RadixSelect.Trigger>\n )\n }),\n)\n\nexport interface SelectContentProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Content>,\n 'asChild'\n> {\n /**\n * Where to portal the list. Defaults to the trigger's nearest `[data-theme]` scope, so a\n * select inside a `<ThemeScope>` opens in that theme; falls back to `document.body`.\n */\n container?: HTMLElement | null\n}\n\nfunction themeScopeOf(node: HTMLElement | null): HTMLElement | undefined {\n const scope = node?.closest<HTMLElement>('[data-theme]')\n return scope && scope !== node?.ownerDocument.documentElement ? scope : undefined\n}\n\n/** The floating list. Anchored under the trigger, at least as wide as it. */\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(function SelectContent(\n {\n container,\n position = 'popper',\n sideOffset = 6,\n collisionPadding = 8,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const triggerNode = useContext(TriggerNodeContext)\n return (\n <RadixSelect.Portal container={container ?? themeScopeOf(triggerNode?.node ?? null)}>\n <RadixSelect.Content\n ref={ref}\n position={position}\n sideOffset={position === 'popper' ? sideOffset : undefined}\n collisionPadding={collisionPadding}\n className={cx(styles.content, className)}\n {...rest}\n >\n <RadixSelect.ScrollUpButton className={styles.scroll}>\n <ChevronUpIcon />\n </RadixSelect.ScrollUpButton>\n <RadixSelect.Viewport className={styles.viewport}>{children}</RadixSelect.Viewport>\n <RadixSelect.ScrollDownButton className={styles.scroll}>\n <ChevronDownIcon />\n </RadixSelect.ScrollDownButton>\n </RadixSelect.Content>\n </RadixSelect.Portal>\n )\n})\n\nexport type SelectItemProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Item>, 'asChild'>\n\n/** One option. The chosen one carries a check. */\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(function SelectItem(\n { className, children, ...rest },\n ref,\n) {\n return (\n <RadixSelect.Item ref={ref} className={cx(styles.item, className)} {...rest}>\n <RadixSelect.ItemText>{children}</RadixSelect.ItemText>\n <RadixSelect.ItemIndicator className={styles.indicator}>\n <CheckIcon />\n </RadixSelect.ItemIndicator>\n </RadixSelect.Item>\n )\n})\n\nexport type SelectGroupProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Group>, 'asChild'>\n\nconst SelectGroupPart = forwardRef<HTMLDivElement, SelectGroupProps>(function SelectGroup(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Group ref={ref} className={cx(styles.group, className)} {...rest} />\n})\n\nexport type SelectLabelProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Label>, 'asChild'>\n\n/** A group heading inside the list. */\nconst SelectLabel = forwardRef<HTMLDivElement, SelectLabelProps>(function SelectLabel(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Label ref={ref} className={cx(styles.label, className)} {...rest} />\n})\n\nexport type SelectSeparatorProps = Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Separator>,\n 'asChild'\n>\n\nconst SelectSeparator = forwardRef<HTMLDivElement, SelectSeparatorProps>(function SelectSeparator(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Separator ref={ref} className={cx(styles.separator, className)} {...rest} />\n})\n\n/* ─── Simple API ──────────────────────────────────────────────────────────── */\n\nexport interface SelectProps extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'value' | 'defaultValue' | 'onChange' | 'dir' | 'placeholder'\n> {\n /** Flat list of options. */\n options?: SelectOption[]\n /** Or headed groups (rendered after `options` if both are given). */\n groups?: SelectGroup[]\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n placeholder?: ReactNode\n size?: Size\n /** Critical border + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores value changes. */\n readOnly?: boolean\n /** Submitted with a native `<form>` under this name. */\n name?: string\n required?: boolean\n autoComplete?: string\n}\n\n/**\n * A single-choice dropdown. Pass `options` (or `groups`) for the common case; compose\n * `Select.Root` / `Trigger` / `Content` / `Item` / `Group` / `Label` for anything custom.\n * The ref and native button props go to the trigger.\n *\n * <Select options={categories} placeholder=\"Choose a category\" onValueChange={setCategory} />\n */\nconst SelectBase = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n groups,\n value,\n defaultValue,\n onValueChange,\n open,\n defaultOpen,\n onOpenChange,\n placeholder,\n size,\n invalid,\n readOnly,\n name,\n required,\n disabled,\n autoComplete,\n form,\n ...rest\n },\n ref,\n) {\n const field = useResolvedField({ disabled, required, readOnly })\n return (\n <SelectRoot\n value={value}\n defaultValue={defaultValue}\n onValueChange={field.readOnly ? undefined : onValueChange}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n name={name}\n required={required}\n disabled={field.disabled}\n autoComplete={autoComplete}\n form={form}\n >\n <SelectTrigger\n ref={ref}\n size={size}\n invalid={invalid}\n readOnly={field.readOnly}\n placeholder={placeholder}\n {...rest}\n />\n <SelectContent>\n {options?.map((option) => (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </SelectItem>\n ))}\n {groups?.map((group, index) => (\n <SelectGroupPart key={group.label}>\n {index > 0 || (options && options.length > 0) ? <SelectSeparator /> : null}\n <SelectLabel>{group.label}</SelectLabel>\n {group.options.map((option) => (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </SelectItem>\n ))}\n </SelectGroupPart>\n ))}\n </SelectContent>\n </SelectRoot>\n )\n})\n\nexport const Select = markFieldAware(\n Object.assign(SelectBase, {\n Root: SelectRoot,\n Trigger: SelectTrigger,\n Content: SelectContent,\n Item: SelectItem,\n Group: SelectGroupPart,\n Label: SelectLabel,\n Separator: SelectSeparator,\n }),\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"Select.js","names":["RadixSelect","control","styles","Select","control_module_default","Select_module_default","TriggerNodeContext","createContext","SelectRoot","node","setNode","useState","scope","useMemo","Select","props","SelectTrigger","markFieldAware","forwardRef","invalidProp","readOnlyProp","idProp","disabledProp","describedByProp","ariaInvalid","rest","triggerNode","useContext","composedRef","useMergedRefs","ref","field","useResolvedField","cx","className","size","children","ChevronDownIcon","themeScopeOf","SelectContent","container","position","sideOffset","ChevronUpIcon","SelectItem","CheckIcon","SelectGroupPart","SelectLabel","SelectSeparator","SelectBase","onValueChange","options","option","groups","index","group","Select$1"],"sources":["../../../../src/components/inputs/Select/Select.tsx"],"sourcesContent":["import {\n createContext,\n forwardRef,\n useContext,\n useMemo,\n useState,\n type ButtonHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport { Select as RadixSelect } from 'radix-ui'\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '#icons'\nimport { cx } from '#utils/cx'\nimport type { Size } from '#utils/tokens'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { useMergedRefs } from '#components/inputs/internal/refs'\nimport control from '#components/inputs/internal/control.module.css'\nimport styles from './Select.module.css'\n\nexport interface SelectOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface SelectGroup {\n label: string\n options: SelectOption[]\n}\n\n/* ─── Compound parts (the escape hatch) ───────────────────────────────────── */\n\n// The trigger's element, so the popover can portal into the same theme scope.\nconst TriggerNodeContext = createContext<{\n node: HTMLElement | null\n setNode: (node: HTMLElement | null) => void\n} | null>(null)\n\nexport type SelectRootProps = ComponentPropsWithoutRef<typeof RadixSelect.Root>\n\n/** State owner. Radix naming: `value` / `defaultValue` / `onValueChange`, `open` / `onOpenChange`. */\nfunction SelectRoot(props: SelectRootProps) {\n const [node, setNode] = useState<HTMLElement | null>(null)\n const scope = useMemo(() => ({ node, setNode }), [node])\n return (\n <TriggerNodeContext.Provider value={scope}>\n <RadixSelect.Root {...props} />\n </TriggerNodeContext.Provider>\n )\n}\n\nexport interface SelectTriggerProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Trigger>,\n 'asChild'\n> {\n size?: Size\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly`. Gate `onValueChange` at the `Root`. */\n readOnly?: boolean\n /** Shown while no value is chosen. */\n placeholder?: ReactNode\n}\n\n/** The field-styled button. Picks up id / describedby / invalid from a surrounding `<Field>`. */\nconst SelectTrigger = markFieldAware(\n forwardRef<HTMLButtonElement, SelectTriggerProps>(function SelectTrigger(\n {\n size = 'md',\n invalid: invalidProp,\n readOnly: readOnlyProp,\n placeholder,\n id: idProp,\n disabled: disabledProp,\n className,\n children,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const triggerNode = useContext(TriggerNodeContext)\n const composedRef = useMergedRefs(ref, triggerNode?.setNode)\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n return (\n <RadixSelect.Trigger\n ref={composedRef}\n id={field.id}\n className={cx(control.box, styles.trigger, className)}\n data-size={size}\n data-invalid={field.invalid || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readOnly || undefined}\n disabled={field.disabled || undefined}\n aria-readonly={field.readOnly || undefined}\n aria-describedby={field.describedBy}\n aria-invalid={field.invalid || undefined}\n aria-required={field.required || undefined}\n aria-busy={field.busy || undefined}\n {...rest}\n >\n <span className={styles.value}>\n {children ?? <RadixSelect.Value placeholder={placeholder} />}\n </span>\n <RadixSelect.Icon className={styles.chevron}>\n <ChevronDownIcon />\n </RadixSelect.Icon>\n </RadixSelect.Trigger>\n )\n }),\n)\n\nexport interface SelectContentProps extends Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Content>,\n 'asChild'\n> {\n /**\n * Where to portal the list. Defaults to the trigger's nearest `[data-theme]` scope, so a\n * select inside a `<ThemeScope>` opens in that theme; falls back to `document.body`.\n */\n container?: HTMLElement | null\n}\n\nfunction themeScopeOf(node: HTMLElement | null): HTMLElement | undefined {\n const scope = node?.closest<HTMLElement>('[data-theme]')\n return scope && scope !== node?.ownerDocument.documentElement ? scope : undefined\n}\n\n/** The floating list. Anchored under the trigger, at least as wide as it. */\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(function SelectContent(\n {\n container,\n position = 'popper',\n sideOffset = 6,\n collisionPadding = 8,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const triggerNode = useContext(TriggerNodeContext)\n return (\n <RadixSelect.Portal container={container ?? themeScopeOf(triggerNode?.node ?? null)}>\n <RadixSelect.Content\n ref={ref}\n position={position}\n sideOffset={position === 'popper' ? sideOffset : undefined}\n collisionPadding={collisionPadding}\n className={cx(styles.content, className)}\n {...rest}\n >\n <RadixSelect.ScrollUpButton className={styles.scroll}>\n <ChevronUpIcon />\n </RadixSelect.ScrollUpButton>\n <RadixSelect.Viewport className={styles.viewport}>{children}</RadixSelect.Viewport>\n <RadixSelect.ScrollDownButton className={styles.scroll}>\n <ChevronDownIcon />\n </RadixSelect.ScrollDownButton>\n </RadixSelect.Content>\n </RadixSelect.Portal>\n )\n})\n\nexport type SelectItemProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Item>, 'asChild'>\n\n/** One option. The chosen one carries a check. */\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(function SelectItem(\n { className, children, ...rest },\n ref,\n) {\n return (\n <RadixSelect.Item ref={ref} className={cx(styles.item, className)} {...rest}>\n <RadixSelect.ItemText>{children}</RadixSelect.ItemText>\n <RadixSelect.ItemIndicator className={styles.indicator}>\n <CheckIcon />\n </RadixSelect.ItemIndicator>\n </RadixSelect.Item>\n )\n})\n\nexport type SelectGroupProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Group>, 'asChild'>\n\nconst SelectGroupPart = forwardRef<HTMLDivElement, SelectGroupProps>(function SelectGroup(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Group ref={ref} className={cx(styles.group, className)} {...rest} />\n})\n\nexport type SelectLabelProps = Omit<ComponentPropsWithoutRef<typeof RadixSelect.Label>, 'asChild'>\n\n/** A group heading inside the list. */\nconst SelectLabel = forwardRef<HTMLDivElement, SelectLabelProps>(function SelectLabel(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Label ref={ref} className={cx(styles.label, className)} {...rest} />\n})\n\nexport type SelectSeparatorProps = Omit<\n ComponentPropsWithoutRef<typeof RadixSelect.Separator>,\n 'asChild'\n>\n\nconst SelectSeparator = forwardRef<HTMLDivElement, SelectSeparatorProps>(function SelectSeparator(\n { className, ...rest },\n ref,\n) {\n return <RadixSelect.Separator ref={ref} className={cx(styles.separator, className)} {...rest} />\n})\n\n/* ─── Simple API ──────────────────────────────────────────────────────────── */\n\nexport interface SelectProps extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'value' | 'defaultValue' | 'onChange' | 'dir' | 'placeholder'\n> {\n /** Flat list of options. */\n options?: SelectOption[]\n /** Or headed groups (rendered after `options` if both are given). */\n groups?: SelectGroup[]\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n placeholder?: ReactNode\n size?: Size\n /** Critical border + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores value changes. */\n readOnly?: boolean\n /** Submitted with a native `<form>` under this name. */\n name?: string\n required?: boolean\n autoComplete?: string\n}\n\n/**\n * A single-choice dropdown. Pass `options` (or `groups`) for the common case; compose\n * `Select.Root` / `Trigger` / `Content` / `Item` / `Group` / `Label` for anything custom.\n * The ref and native button props go to the trigger.\n *\n * <Select options={categories} placeholder=\"Choose a category\" onValueChange={setCategory} />\n */\nconst SelectBase = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n groups,\n value,\n defaultValue,\n onValueChange,\n open,\n defaultOpen,\n onOpenChange,\n placeholder,\n size,\n invalid,\n readOnly,\n name,\n required,\n disabled,\n autoComplete,\n form,\n ...rest\n },\n ref,\n) {\n const field = useResolvedField({ disabled, required, readOnly })\n return (\n <SelectRoot\n value={value}\n defaultValue={defaultValue}\n onValueChange={field.readOnly ? undefined : onValueChange}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n name={name}\n required={required}\n disabled={field.disabled}\n autoComplete={autoComplete}\n form={form}\n >\n <SelectTrigger\n ref={ref}\n size={size}\n invalid={invalid}\n readOnly={field.readOnly}\n placeholder={placeholder}\n {...rest}\n />\n <SelectContent>\n {options?.map((option) => (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </SelectItem>\n ))}\n {groups?.map((group, index) => (\n <SelectGroupPart key={group.label}>\n {index > 0 || (options && options.length > 0) ? <SelectSeparator /> : null}\n <SelectLabel>{group.label}</SelectLabel>\n {group.options.map((option) => (\n <SelectItem key={option.value} value={option.value} disabled={option.disabled}>\n {option.label}\n </SelectItem>\n ))}\n </SelectGroupPart>\n ))}\n </SelectContent>\n </SelectRoot>\n )\n})\n\n/**\n * Pick one option from a list. A styled listbox with keyboard support and native form submission.\n *\n * @remarks\n * `Select` is Radix Select with Kiln's look: a button that opens a listbox, with typeahead, arrow\n * keys and grouped options. Pass `options`, or `groups` for labelled sections. `name` adds a\n * hidden input so it submits with a native form. For a labelled select, use {@link SelectField |\n * SelectField}.\n */\nexport const Select = markFieldAware(\n Object.assign(SelectBase, {\n Root: SelectRoot,\n Trigger: SelectTrigger,\n Content: SelectContent,\n Item: SelectItem,\n Group: SelectGroupPart,\n Label: SelectLabel,\n Separator: SelectSeparator,\n }),\n)\n"],"mappings":";;;;;;;;;;AAiCA,IAAMM,IAAqBC,EAGjB,IAAI;AAKd,SAASC,EAAW,GAAwB;CAC1C,IAAM,CAACC,GAAMC,KAAWC,EAA6B,IAAI,GACnDC,IAAQC,SAAe;EAAE;EAAM;CAAQ,IAAI,CAACJ,CAAI,CAAC;CACvD,OACE,kBAACH,EAAmB,UAApB;EAA6B,OAAOM;EAClC,UAAA,kBAACZ,EAAY,MAAb,EAAkB,GAAIe,EAAQ,CAAA;CACH,CAAA;AAEjC;AAeA,IAAMC,IAAgBC,EACpBC,EAAkD,SAChD,EACE,UAAO,MACP,SAASC,GACT,UAAUC,GACV,gBACA,IAAIC,GACJ,UAAUC,GACV,cACA,aACA,oBAAoBC,GACpB,gBAAgBC,GAChB,GAAGC,KAEL,GACA;CACA,IAAMC,IAAcC,EAAWrB,CAAkB,GAC3CsB,IAAcC,EAAcC,GAAKJ,GAAa,OAAO,GACrDK,IAAQC,EAAiB;EAC7B,IAAIX;EACJ,aAAaE;EACb,SAASJ;EACT;EACA,UAAUG;EACV,UAAUF;CACZ,CAAC;CACD,OACE,kBAACpB,EAAY,SAAb;EACE,KAAK4B;EACL,IAAIG,EAAM;EACV,WAAWE,EAAGhC,EAAQ,KAAKC,EAAO,SAASgC,CAAS;EACpD,aAAWC;EACX,gBAAcJ,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,iBAAeA,EAAM,YAAY,KAAA;EACjC,UAAUA,EAAM,YAAY,KAAA;EAC5B,iBAAeA,EAAM,YAAY,KAAA;EACjC,oBAAkBA,EAAM;EACxB,gBAAcA,EAAM,WAAW,KAAA;EAC/B,iBAAeA,EAAM,YAAY,KAAA;EACjC,aAAWA,EAAM,QAAQ,KAAA;EACzB,GAAIN;EAdN,UAAA,CAgBE,kBAAC,QAAD;GAAM,WAAWvB,EAAO;GACrB,UAAAkC,KAAY,kBAACpC,EAAY,OAAb,EAAgC,eAAc,CAAA;EACvD,CAAA,GACN,kBAACA,EAAY,MAAb;GAAkB,WAAWE,EAAO;GAClC,UAAA,kBAACmC,GAAD,CAAkB,CAAA;EACF,CAAA,CACC;;AAEzB,CAAC,CACH;AAaA,SAASC,EAAa,GAAmD;CACvE,IAAM1B,IAAQH,GAAM,QAAqB,cAAc;CACvD,OAAOG,KAASA,MAAUH,GAAM,cAAc,kBAAkBG,IAAQ,KAAA;AAC1E;AAGA,IAAM2B,IAAgBrB,EAA+C,SACnE,EACE,cACA,cAAW,UACX,gBAAa,GACb,sBAAmB,GACnB,cACA,aACA,GAAGO,KAEL,GACA;CACA,IAAMC,IAAcC,EAAWrB,CAAkB;CACjD,OACE,kBAACN,EAAY,QAAb;EAAoB,WAAWwC,KAAaF,EAAaZ,GAAa,QAAQ,IAAI;EAChF,UAAA,kBAAC1B,EAAY,SAAb;GACO;GACK;GACV,YAAYyC,MAAa,WAAWC,IAAa,KAAA;GAC/B;GAClB,WAAWT,EAAG/B,EAAO,SAASgC,CAAS;GACvC,GAAIT;GANN,UAAA;IAQE,kBAACzB,EAAY,gBAAb;KAA4B,WAAWE,EAAO;KAC5C,UAAA,kBAACyC,GAAD,CAAgB,CAAA;IACU,CAAA;IAC5B,kBAAC3C,EAAY,UAAb;KAAsB,WAAWE,EAAO;KAAW;IAA+B,CAAA;IAClF,kBAACF,EAAY,kBAAb;KAA8B,WAAWE,EAAO;KAC9C,UAAA,kBAACmC,GAAD,CAAkB,CAAA;IACU,CAAA;GACX;;CACH,CAAA;AAExB,CAAC,GAKKO,IAAa1B,EAA4C,SAC7D,EAAE,cAAW,aAAU,GAAGO,KAC1B,GACA;CACA,OACE,kBAACzB,EAAY,MAAb;EAAuB;EAAK,WAAWiC,EAAG/B,EAAO,MAAMgC,CAAS;EAAG,GAAIT;EAAvE,UAAA,CACE,kBAACzB,EAAY,UAAb,EAAuB,YAA+B,CAAA,GACtD,kBAACA,EAAY,eAAb;GAA2B,WAAWE,EAAO;GAC3C,UAAA,kBAAC2C,GAAD,CAAY,CAAA;EACa,CAAA,CACX;;AAEtB,CAAC,GAIKC,IAAkB5B,EAA6C,SACnE,EAAE,cAAW,GAAGO,KAChB,GACA;CACA,OAAO,kBAACzB,EAAY,OAAb;EAAwB;EAAK,WAAWiC,EAAG/B,EAAO,OAAOgC,CAAS;EAAG,GAAIT;CAAO,CAAA;AACzF,CAAC,GAKKsB,IAAc7B,EAA6C,SAC/D,EAAE,cAAW,GAAGO,KAChB,GACA;CACA,OAAO,kBAACzB,EAAY,OAAb;EAAwB;EAAK,WAAWiC,EAAG/B,EAAO,OAAOgC,CAAS;EAAG,GAAIT;CAAO,CAAA;AACzF,CAAC,GAOKuB,IAAkB9B,EAAiD,SACvE,EAAE,cAAW,GAAGO,KAChB,GACA;CACA,OAAO,kBAACzB,EAAY,WAAb;EAA4B;EAAK,WAAWiC,EAAG/B,EAAO,WAAWgC,CAAS;EAAG,GAAIT;CAAO,CAAA;AACjG,CAAC,GAqCKwB,IAAa/B,EAA2C,SAC5D,EACE,YACA,WACA,UACA,iBACA,kBACA,SACA,gBACA,iBACA,gBACA,SACA,YACA,aACA,SACA,aACA,aACA,iBACA,SACA,GAAGO,KAEL,GACA;CACA,IAAMM,IAAQC,EAAiB;EAAE;EAAU;EAAU;CAAS,CAAC;CAC/D,OACE,kBAACxB,GAAD;EACS;EACO;EACd,eAAeuB,EAAM,WAAW,KAAA,IAAYmB;EACtC;EACO;EACC;EACR;EACI;EACV,UAAUnB,EAAM;EACF;EACR;EAXR,UAAA,CAaE,kBAACf,GAAD;GACO;GACC;GACG;GACT,UAAUe,EAAM;GACH;GACb,GAAIN;EACL,CAAA,GACD,kBAACc,GAAD,EAAA,UAAA,CACGY,GAAS,KAAK,MACb,kBAACP,GAAD;GAA+B,OAAOQ,EAAO;GAAO,UAAUA,EAAO;GAClE,UAAAA,EAAO;EACE,GAFKA,EAAO,KAEZ,CACb,GACAC,GAAQ,KAAK,GAAO,MACnB,kBAACP,GAAD,EAAA,UAAA;GACGQ,IAAQ,KAAMH,KAAWA,EAAQ,SAAS,IAAK,kBAACH,GAAD,CAAkB,CAAA,IAAI;GACtE,kBAACD,GAAD,EAAA,UAAcQ,EAAM,MAAmB,CAAA;GACtCA,EAAM,QAAQ,KAAK,MAClB,kBAACX,GAAD;IAA+B,OAAOQ,EAAO;IAAO,UAAUA,EAAO;IAClE,UAAAA,EAAO;GACE,GAFKA,EAAO,KAEZ,CACb;EACc,EAAA,GARKG,EAAM,KAQX,CAClB,CACY,EAAA,CAAA,CACL;;AAEhB,CAAC,GAWYpD,IAASc,EACpB,OAAO,OAAOgC,GAAY;CACxB,MAAMzC;CACN,SAASQ;CACT,SAASuB;CACT,MAAMK;CACN,OAAOE;CACP,OAAOC;CACP,WAAWC;AACb,CAAC,CACH"}
@@ -4,6 +4,13 @@ export type { SelectOption, SelectGroup } from '../Select/index.js';
4
4
  export interface SelectFieldProps extends FieldLabelProps, Omit<SelectProps, 'invalid'> {
5
5
  }
6
6
  /**
7
+ * A labelled select with description, error and warning.
8
+ *
9
+ * @remarks
10
+ * `SelectField` is a {@link Field | Field} around a {@link Select | Select}. Select props
11
+ * (`options`, `groups`, `value`, `placeholder`) go to the select.
12
+ *
13
+ * @privateRemarks
7
14
  * Label + Select + description + error. Select props (`options`, `value`,
8
15
  * `onValueChange`, `placeholder`…) and the ref go to the trigger; `className`/`style` go
9
16
  * to the field wrapper.
@@ -1 +1 @@
1
- {"version":3,"file":"SelectField.js","names":["SelectField","forwardRef","fieldProps","rest","splitFieldLabelProps","props","selectRest","Field","id","Select"],"sources":["../../../../src/components/inputs/SelectField/SelectField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { Select, type SelectProps } from '#components/inputs/Select'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport type { SelectOption, SelectGroup } from '#components/inputs/Select'\n\nexport interface SelectFieldProps extends FieldLabelProps, Omit<SelectProps, 'invalid'> {}\n\n/**\n * Label + Select + description + error. Select props (`options`, `value`,\n * `onValueChange`, `placeholder`…) and the ref go to the trigger; `className`/`style` go\n * to the field wrapper.\n *\n * <SelectField label=\"Category\" options={categories} placeholder=\"Choose one\" required />\n */\nexport const SelectField = forwardRef<HTMLButtonElement, SelectFieldProps>(\n function SelectField(props, ref) {\n const [fieldProps, rest] = splitFieldLabelProps(props)\n const { id, disabled, className, style, ...selectRest } = rest\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Select ref={ref} id={id} disabled={disabled} {...selectRest} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAgBA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAYC,KAAQC,EAAqBC,CAAK,GAC/C,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,MAAeH;CAC1D,OACE,kBAACI,GAAD;EAAO,GAAIL;EAAY,SAASM;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAS;GAAc;GAAU,GAAIH;EAAa,CAAA;CAC1D,CAAA;AAEX,CACF"}
1
+ {"version":3,"file":"SelectField.js","names":["SelectField","forwardRef","fieldProps","rest","splitFieldLabelProps","props","selectRest","Field","id","Select"],"sources":["../../../../src/components/inputs/SelectField/SelectField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { Select, type SelectProps } from '#components/inputs/Select'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\n\nexport type { SelectOption, SelectGroup } from '#components/inputs/Select'\n\nexport interface SelectFieldProps extends FieldLabelProps, Omit<SelectProps, 'invalid'> {}\n\n/**\n * A labelled select with description, error and warning.\n *\n * @remarks\n * `SelectField` is a {@link Field | Field} around a {@link Select | Select}. Select props\n * (`options`, `groups`, `value`, `placeholder`) go to the select.\n *\n * @privateRemarks\n * Label + Select + description + error. Select props (`options`, `value`,\n * `onValueChange`, `placeholder`…) and the ref go to the trigger; `className`/`style` go\n * to the field wrapper.\n *\n * <SelectField label=\"Category\" options={categories} placeholder=\"Choose one\" required />\n */\nexport const SelectField = forwardRef<HTMLButtonElement, SelectFieldProps>(\n function SelectField(props, ref) {\n const [fieldProps, rest] = splitFieldLabelProps(props)\n const { id, disabled, className, style, ...selectRest } = rest\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Select ref={ref} id={id} disabled={disabled} {...selectRest} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAuBA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAYC,KAAQC,EAAqBC,CAAK,GAC/C,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,MAAeH;CAC1D,OACE,kBAACI,GAAD;EAAO,GAAIL;EAAY,SAASM;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAS;GAAc;GAAU,GAAIH;EAAa,CAAA;CAC1D,CAAA;AAEX,CACF"}
@@ -30,6 +30,14 @@ export interface SliderProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'onCh
30
30
  size?: SliderSize;
31
31
  }
32
32
  /**
33
+ * One number from a continuous range, by dragging or with the arrow keys.
34
+ *
35
+ * @remarks
36
+ * `Slider` is Radix Slider with Kiln's look. Arrow keys step, Page Up and Page Down step by ten,
37
+ * and Home and End jump to the ends. Label it with a Field (see {@link SliderField | SliderField})
38
+ * or an `aria-label`.
39
+ *
40
+ * @privateRemarks
33
41
  * One number from a continuous range (Radix Slider). Arrow keys step, Page Up/Down step
34
42
  * by ten, Home/End jump to the ends. Label it with a `<Field>` (see `SliderField`) or
35
43
  * `aria-label`. The ref and `id` go to the thumb — the focusable `role="slider"`;
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","names":["Slider","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","ariaLabel","labelledByProp","describedByProp","ariaInvalid","rest","autoId","useId","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","min","onValueChange","handleBlur","useFocusLeave","onBlur","SliderBase","next","onValueCommit"],"sources":["../../../../src/components/inputs/Slider/Slider.tsx"],"sourcesContent":["import { forwardRef, useId, type HTMLAttributes } from 'react'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { SliderBase, type SliderMark, type SliderSize } from './SliderBase'\n\nexport type { SliderMark, SliderSize } from './SliderBase'\n\nexport interface SliderProps extends Omit<\n HTMLAttributes<HTMLSpanElement>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n /** Controlled value. */\n value?: number\n /** Initial value when uncontrolled. Defaults to `min`. */\n defaultValue?: number\n /** Every change while dragging or stepping. */\n onValueChange?: (value: number) => void\n /** Once, when the user lets go (or after each key press). */\n onValueCommit?: (value: number) => void\n min?: number\n max?: number\n step?: number\n /** Labelled stops under the track. A thumb on a mark reads the mark's label. */\n marks?: readonly SliderMark[]\n /** Shows the formatted value beside the track, in tabular figures. */\n showValue?: boolean\n /** Formats the shown value and the thumb's `aria-valuetext` (\"£2,500\"). */\n formatOptions?: Intl.NumberFormatOptions\n locale?: string\n /** Emits a hidden input with the value, for native form submission. */\n name?: string\n disabled?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores changes. */\n readOnly?: boolean\n /** Critical edge on the thumb + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n size?: SliderSize\n}\n\n/**\n * One number from a continuous range (Radix Slider). Arrow keys step, Page Up/Down step\n * by ten, Home/End jump to the ends. Label it with a `<Field>` (see `SliderField`) or\n * `aria-label`. The ref and `id` go to the thumb — the focusable `role=\"slider\"`;\n * `className`/`style` and other props go to the wrapper. `onBlur` fires when focus leaves.\n *\n * <Slider aria-label=\"Discount rate\" defaultValue={20} step={5} showValue formatOptions={{ style: 'unit', unit: 'percent' }} />\n */\nexport const Slider = markFieldAware(\n forwardRef<HTMLSpanElement, SliderProps>(function Slider(\n {\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n min = 0,\n max = 100,\n step = 1,\n marks,\n showValue = false,\n formatOptions,\n locale,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n onBlur,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelledByProp,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const autoId = useId()\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue(\n value,\n defaultValue ?? min,\n onValueChange,\n field.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n\n return (\n <SliderBase\n {...rest}\n onBlur={handleBlur}\n values={[current]}\n onValuesChange={(next) => {\n setCurrent(next[0] ?? min)\n }}\n onValuesCommit={(next) => onValueCommit?.(next[0] ?? min)}\n min={min}\n max={max}\n step={step}\n marks={marks}\n showValue={showValue}\n formatOptions={formatOptions}\n locale={locale}\n name={name}\n disabled={field.disabled}\n readOnly={field.readOnly}\n invalid={field.invalid}\n size={size}\n thumbs={[\n {\n id: field.id ?? `${autoId}thumb`,\n ref,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelledByProp ?? (ariaLabel ? undefined : field.labelId),\n 'aria-describedby': field.describedBy,\n 'aria-invalid': field.invalid || undefined,\n 'aria-readonly': field.readOnly || undefined,\n 'aria-busy': field.busy || undefined,\n },\n ]}\n />\n )\n }),\n)\n"],"mappings":";;;;;;AA+CA,IAAaA,IAASC,EACpBC,EAAyC,SACvC,EACE,UACA,iBACA,kBACA,kBACA,SAAM,GACN,SAAM,KACN,UAAO,GACP,UACA,eAAY,IACZ,kBACA,WACA,SACA,UAAUC,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,WACA,cAAcC,GACd,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,GAAGC,KAEL,GACA;CACA,IAAMC,IAASC,EAAM,GACfC,IAAQC,EAAiB;EAC7B,IAAIT;EACJ,aAAaG;EACb,SAASJ;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACY,GAASC,KAAcC,EAC5BC,GACAC,KAAgBC,GAChBC,GACAR,EAAM,QACR,GACMS,IAAaC,EAAcC,CAAM;CAEvC,OACE,kBAACC,GAAD;EACE,GAAIf;EACJ,QAAQY;EACR,QAAQ,CAACP,CAAO;EAChB,iBAAiB,MAAS;GACxB,EAAWW,EAAK,MAAMN,CAAG;EAC3B;EACA,iBAAiB,MAASO,IAAgBD,EAAK,MAAMN,CAAG;EACnD;EACA;EACC;EACC;EACI;EACI;EACP;EACF;EACN,UAAUP,EAAM;EAChB,UAAUA,EAAM;EAChB,SAASA,EAAM;EACT;EACN,QAAQ,CACN;GACE,IAAIA,EAAM,MAAM,GAAGF,EAAO;GAC1B;GACA,cAAcL;GACd,mBAAmBC,MAAmBD,IAAY,KAAA,IAAYO,EAAM;GACpE,oBAAoBA,EAAM;GAC1B,gBAAgBA,EAAM,WAAW,KAAA;GACjC,iBAAiBA,EAAM,YAAY,KAAA;GACnC,aAAaA,EAAM,QAAQ,KAAA;EAC7B,CACF;CACD,CAAA;AAEL,CAAC,CACH"}
1
+ {"version":3,"file":"Slider.js","names":["Slider","markFieldAware","forwardRef","disabledProp","readOnlyProp","invalidProp","idProp","ariaLabel","labelledByProp","describedByProp","ariaInvalid","rest","autoId","useId","field","useResolvedField","current","setCurrent","useControllableValue","value","defaultValue","min","onValueChange","handleBlur","useFocusLeave","onBlur","SliderBase","next","onValueCommit"],"sources":["../../../../src/components/inputs/Slider/Slider.tsx"],"sourcesContent":["import { forwardRef, useId, type HTMLAttributes } from 'react'\nimport { useControllableValue, useFocusLeave } from '#components/inputs/CheckboxGroup/choice'\nimport { markFieldAware, useResolvedField } from '#components/inputs/internal/FieldContext'\nimport { SliderBase, type SliderMark, type SliderSize } from './SliderBase'\n\nexport type { SliderMark, SliderSize } from './SliderBase'\n\nexport interface SliderProps extends Omit<\n HTMLAttributes<HTMLSpanElement>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n /** Controlled value. */\n value?: number\n /** Initial value when uncontrolled. Defaults to `min`. */\n defaultValue?: number\n /** Every change while dragging or stepping. */\n onValueChange?: (value: number) => void\n /** Once, when the user lets go (or after each key press). */\n onValueCommit?: (value: number) => void\n min?: number\n max?: number\n step?: number\n /** Labelled stops under the track. A thumb on a mark reads the mark's label. */\n marks?: readonly SliderMark[]\n /** Shows the formatted value beside the track, in tabular figures. */\n showValue?: boolean\n /** Formats the shown value and the thumb's `aria-valuetext` (\"£2,500\"). */\n formatOptions?: Intl.NumberFormatOptions\n locale?: string\n /** Emits a hidden input with the value, for native form submission. */\n name?: string\n disabled?: boolean\n /** Focusable but not editable: sets `aria-readonly` and ignores changes. */\n readOnly?: boolean\n /** Critical edge on the thumb + `aria-invalid`. Inside a `<Field error>` this is set for you. */\n invalid?: boolean\n size?: SliderSize\n}\n\n/**\n * One number from a continuous range, by dragging or with the arrow keys.\n *\n * @remarks\n * `Slider` is Radix Slider with Kiln's look. Arrow keys step, Page Up and Page Down step by ten,\n * and Home and End jump to the ends. Label it with a Field (see {@link SliderField | SliderField})\n * or an `aria-label`.\n *\n * @privateRemarks\n * One number from a continuous range (Radix Slider). Arrow keys step, Page Up/Down step\n * by ten, Home/End jump to the ends. Label it with a `<Field>` (see `SliderField`) or\n * `aria-label`. The ref and `id` go to the thumb — the focusable `role=\"slider\"`;\n * `className`/`style` and other props go to the wrapper. `onBlur` fires when focus leaves.\n *\n * <Slider aria-label=\"Discount rate\" defaultValue={20} step={5} showValue formatOptions={{ style: 'unit', unit: 'percent' }} />\n */\nexport const Slider = markFieldAware(\n forwardRef<HTMLSpanElement, SliderProps>(function Slider(\n {\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n min = 0,\n max = 100,\n step = 1,\n marks,\n showValue = false,\n formatOptions,\n locale,\n name,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n invalid: invalidProp,\n size = 'md',\n id: idProp,\n onBlur,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelledByProp,\n 'aria-describedby': describedByProp,\n 'aria-invalid': ariaInvalid,\n ...rest\n },\n ref,\n ) {\n const autoId = useId()\n const field = useResolvedField({\n id: idProp,\n describedBy: describedByProp,\n invalid: invalidProp,\n ariaInvalid,\n disabled: disabledProp,\n readOnly: readOnlyProp,\n })\n const [current, setCurrent] = useControllableValue(\n value,\n defaultValue ?? min,\n onValueChange,\n field.readOnly,\n )\n const handleBlur = useFocusLeave(onBlur)\n\n return (\n <SliderBase\n {...rest}\n onBlur={handleBlur}\n values={[current]}\n onValuesChange={(next) => {\n setCurrent(next[0] ?? min)\n }}\n onValuesCommit={(next) => onValueCommit?.(next[0] ?? min)}\n min={min}\n max={max}\n step={step}\n marks={marks}\n showValue={showValue}\n formatOptions={formatOptions}\n locale={locale}\n name={name}\n disabled={field.disabled}\n readOnly={field.readOnly}\n invalid={field.invalid}\n size={size}\n thumbs={[\n {\n id: field.id ?? `${autoId}thumb`,\n ref,\n 'aria-label': ariaLabel,\n 'aria-labelledby': labelledByProp ?? (ariaLabel ? undefined : field.labelId),\n 'aria-describedby': field.describedBy,\n 'aria-invalid': field.invalid || undefined,\n 'aria-readonly': field.readOnly || undefined,\n 'aria-busy': field.busy || undefined,\n },\n ]}\n />\n )\n }),\n)\n"],"mappings":";;;;;;AAuDA,IAAaA,IAASC,EACpBC,EAAyC,SACvC,EACE,UACA,iBACA,kBACA,kBACA,SAAM,GACN,SAAM,KACN,UAAO,GACP,UACA,eAAY,IACZ,kBACA,WACA,SACA,UAAUC,GACV,UAAUC,GACV,SAASC,GACT,UAAO,MACP,IAAIC,GACJ,WACA,cAAcC,GACd,mBAAmBC,GACnB,oBAAoBC,GACpB,gBAAgBC,GAChB,GAAGC,KAEL,GACA;CACA,IAAMC,IAASC,EAAM,GACfC,IAAQC,EAAiB;EAC7B,IAAIT;EACJ,aAAaG;EACb,SAASJ;EACT;EACA,UAAUF;EACV,UAAUC;CACZ,CAAC,GACK,CAACY,GAASC,KAAcC,EAC5BC,GACAC,KAAgBC,GAChBC,GACAR,EAAM,QACR,GACMS,IAAaC,EAAcC,CAAM;CAEvC,OACE,kBAACC,GAAD;EACE,GAAIf;EACJ,QAAQY;EACR,QAAQ,CAACP,CAAO;EAChB,iBAAiB,MAAS;GACxB,EAAWW,EAAK,MAAMN,CAAG;EAC3B;EACA,iBAAiB,MAASO,IAAgBD,EAAK,MAAMN,CAAG;EACnD;EACA;EACC;EACC;EACI;EACI;EACP;EACF;EACN,UAAUP,EAAM;EAChB,UAAUA,EAAM;EAChB,SAASA,EAAM;EACT;EACN,QAAQ,CACN;GACE,IAAIA,EAAM,MAAM,GAAGF,EAAO;GAC1B;GACA,cAAcL;GACd,mBAAmBC,MAAmBD,IAAY,KAAA,IAAYO,EAAM;GACpE,oBAAoBA,EAAM;GAC1B,gBAAgBA,EAAM,WAAW,KAAA;GACjC,iBAAiBA,EAAM,YAAY,KAAA;GACnC,aAAaA,EAAM,QAAQ,KAAA;EAC7B,CACF;CACD,CAAA;AAEL,CAAC,CACH"}
@@ -3,6 +3,13 @@ import { type SliderProps } from '../Slider/index.js';
3
3
  export interface SliderFieldProps extends FieldLabelProps, Omit<SliderProps, 'invalid' | keyof FieldLabelProps> {
4
4
  }
5
5
  /**
6
+ * A labelled slider, its thumb named by the label and described by the help text.
7
+ *
8
+ * @remarks
9
+ * `SliderField` is a {@link Field | Field} around a {@link Slider | Slider}. The thumb is labelled
10
+ * by the field's label and described by its description and error.
11
+ *
12
+ * @privateRemarks
6
13
  * A labelled `Slider`. The thumb is labelled by the Field's label and described by its
7
14
  * help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name` and the
8
15
  * rest go to the slider (the ref to its thumb).
@@ -1 +1 @@
1
- {"version":3,"file":"SliderField.js","names":["SliderField","forwardRef","fieldProps","sliderProps","splitFieldLabelProps","props","Field","id","Slider"],"sources":["../../../../src/components/inputs/SliderField/SliderField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { Slider, type SliderProps } from '#components/inputs/Slider'\n\nexport interface SliderFieldProps\n extends FieldLabelProps, Omit<SliderProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled `Slider`. The thumb is labelled by the Field's label and described by its\n * help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name` and the\n * rest go to the slider (the ref to its thumb).\n *\n * <SliderField label=\"Discount rate\" name=\"discountRate\" step={5} showValue formatOptions={{ style: 'unit', unit: 'percent' }} />\n */\nexport const SliderField = forwardRef<HTMLSpanElement, SliderFieldProps>(\n function SliderField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...sliderProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Slider ref={ref} {...sliderProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAeA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAK,GAAIL;EAAc,CAAA;CAC/B,CAAA;AAEX,CACF"}
1
+ {"version":3,"file":"SliderField.js","names":["SliderField","forwardRef","fieldProps","sliderProps","splitFieldLabelProps","props","Field","id","Slider"],"sources":["../../../../src/components/inputs/SliderField/SliderField.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport { Field, type FieldLabelProps } from '#components/inputs/Field'\nimport { splitFieldLabelProps } from '#components/inputs/internal/fieldProps'\nimport { Slider, type SliderProps } from '#components/inputs/Slider'\n\nexport interface SliderFieldProps\n extends FieldLabelProps, Omit<SliderProps, 'invalid' | keyof FieldLabelProps> {}\n\n/**\n * A labelled slider, its thumb named by the label and described by the help text.\n *\n * @remarks\n * `SliderField` is a {@link Field | Field} around a {@link Slider | Slider}. The thumb is labelled\n * by the field's label and described by its description and error.\n *\n * @privateRemarks\n * A labelled `Slider`. The thumb is labelled by the Field's label and described by its\n * help, warning and error. `className`/`style` go to the Field; `ref`, `id`, `name` and the\n * rest go to the slider (the ref to its thumb).\n *\n * <SliderField label=\"Discount rate\" name=\"discountRate\" step={5} showValue formatOptions={{ style: 'unit', unit: 'percent' }} />\n */\nexport const SliderField = forwardRef<HTMLSpanElement, SliderFieldProps>(\n function SliderField(props, ref) {\n const [fieldProps, { id, disabled, className, style, ...sliderProps }] =\n splitFieldLabelProps(props)\n return (\n <Field {...fieldProps} htmlFor={id} disabled={disabled} className={className} style={style}>\n <Slider ref={ref} {...sliderProps} />\n </Field>\n )\n },\n)\n"],"mappings":";;;;;;AAsBA,IAAaA,IAAcC,EACzB,SAAqB,GAAO,GAAK;CAC/B,IAAM,CAACC,GAAY,EAAE,OAAI,aAAU,cAAW,UAAO,GAAGC,OACtDC,EAAqBC,CAAK;CAC5B,OACE,kBAACC,GAAD;EAAO,GAAIJ;EAAY,SAASK;EAAc;EAAqB;EAAkB;EACnF,UAAA,kBAACC,GAAD;GAAa;GAAK,GAAIL;EAAc,CAAA;CAC/B,CAAA;AAEX,CACF"}
@@ -10,6 +10,14 @@ export interface SwitchProps extends Omit<ComponentPropsWithoutRef<typeof RadixS
10
10
  readOnly?: boolean;
11
11
  }
12
12
  /**
13
+ * An on-off setting that takes effect at once.
14
+ *
15
+ * @remarks
16
+ * `Switch` is for a setting that applies immediately, like turning alerts on. For a choice that's
17
+ * submitted with a form, a checkbox says more clearly that nothing happens until you submit.
18
+ * `label` puts a label beside it; inside a settings list, use {@link SwitchField | SwitchField}.
19
+ *
20
+ * @privateRemarks
13
21
  * An on/off setting that applies immediately (Radix Switch). For a choice that's
14
22
  * submitted with a form, prefer a checkbox. The ref and `className` go to the switch.
15
23
  *