@chayns-ui/core 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +9 -3
  2. package/dist/accordion.css +66 -2
  3. package/dist/badge.css +3 -3
  4. package/dist/banner.css +89 -0
  5. package/dist/button.css +16 -2
  6. package/dist/card.css +29 -2
  7. package/dist/checkbox.css +24 -13
  8. package/dist/combo-box.css +20 -2
  9. package/dist/components/accordion/Accordion.d.ts +10 -2
  10. package/dist/components/accordion/Accordion.d.ts.map +1 -1
  11. package/dist/components/accordion/Accordion.js +120 -46
  12. package/dist/components/accordion/Accordion.js.map +1 -1
  13. package/dist/components/accordion/Accordion.types.d.ts +24 -1
  14. package/dist/components/accordion/Accordion.types.d.ts.map +1 -1
  15. package/dist/components/accordion/Accordion.types.js +6 -0
  16. package/dist/components/accordion/Accordion.types.js.map +1 -0
  17. package/dist/components/accordion/AccordionContext.d.ts +9 -0
  18. package/dist/components/accordion/AccordionContext.d.ts.map +1 -1
  19. package/dist/components/accordion/AccordionContext.js +8 -2
  20. package/dist/components/accordion/AccordionContext.js.map +1 -1
  21. package/dist/components/accordion-group/AccordionGroup.d.ts +1 -1
  22. package/dist/components/accordion-group/AccordionGroup.d.ts.map +1 -1
  23. package/dist/components/accordion-group/AccordionGroup.js +3 -3
  24. package/dist/components/accordion-group/AccordionGroup.js.map +1 -1
  25. package/dist/components/avatar/Avatar.js +1 -1
  26. package/dist/components/avatar-group/AvatarGroup.js +1 -1
  27. package/dist/components/badge/Badge.js +1 -1
  28. package/dist/components/banner/Banner.d.ts +3 -0
  29. package/dist/components/banner/Banner.d.ts.map +1 -0
  30. package/dist/components/banner/Banner.js +46 -0
  31. package/dist/components/banner/Banner.js.map +1 -0
  32. package/dist/components/banner/Banner.types.d.ts +24 -0
  33. package/dist/components/banner/Banner.types.d.ts.map +1 -0
  34. package/dist/components/banner/Banner.types.js +11 -0
  35. package/dist/components/banner/Banner.types.js.map +1 -0
  36. package/dist/components/button/Button.d.ts +1 -1
  37. package/dist/components/button/Button.d.ts.map +1 -1
  38. package/dist/components/button/Button.js +8 -3
  39. package/dist/components/button/Button.js.map +1 -1
  40. package/dist/components/button/Button.types.d.ts +15 -11
  41. package/dist/components/button/Button.types.d.ts.map +1 -1
  42. package/dist/components/button/Button.types.js.map +1 -1
  43. package/dist/components/button/button-icon/ButtonIcon.d.ts.map +1 -1
  44. package/dist/components/button/button-icon/ButtonIcon.js +18 -12
  45. package/dist/components/button/button-icon/ButtonIcon.js.map +1 -1
  46. package/dist/components/card/Card.d.ts +4 -2
  47. package/dist/components/card/Card.d.ts.map +1 -1
  48. package/dist/components/card/Card.js +24 -8
  49. package/dist/components/card/Card.js.map +1 -1
  50. package/dist/components/card/Card.types.d.ts +10 -12
  51. package/dist/components/card/Card.types.d.ts.map +1 -1
  52. package/dist/components/checkbox/Checkbox.d.ts +1 -1
  53. package/dist/components/checkbox/Checkbox.d.ts.map +1 -1
  54. package/dist/components/checkbox/Checkbox.js +15 -6
  55. package/dist/components/checkbox/Checkbox.js.map +1 -1
  56. package/dist/components/checkbox/Checkbox.types.d.ts +2 -0
  57. package/dist/components/checkbox/Checkbox.types.d.ts.map +1 -1
  58. package/dist/components/combo-box/ComboBox.d.ts.map +1 -1
  59. package/dist/components/combo-box/ComboBox.js +19 -2
  60. package/dist/components/combo-box/ComboBox.js.map +1 -1
  61. package/dist/components/date-time-picker/DateTimePicker.d.ts +4 -0
  62. package/dist/components/date-time-picker/DateTimePicker.d.ts.map +1 -0
  63. package/dist/components/date-time-picker/DateTimePicker.js +339 -0
  64. package/dist/components/date-time-picker/DateTimePicker.js.map +1 -0
  65. package/dist/components/date-time-picker/DateTimePicker.types.d.ts +26 -0
  66. package/dist/components/date-time-picker/DateTimePicker.types.d.ts.map +1 -0
  67. package/dist/components/date-time-picker/DateTimePicker.types.js +12 -0
  68. package/dist/components/date-time-picker/DateTimePicker.types.js.map +1 -0
  69. package/dist/components/icon-button/IconButton.d.ts +7 -2
  70. package/dist/components/icon-button/IconButton.d.ts.map +1 -1
  71. package/dist/components/icon-button/IconButton.js +8 -3
  72. package/dist/components/icon-button/IconButton.js.map +1 -1
  73. package/dist/components/icon-button/IconButton.types.d.ts +7 -4
  74. package/dist/components/icon-button/IconButton.types.d.ts.map +1 -1
  75. package/dist/components/list/List.js +1 -1
  76. package/dist/components/popup/Popup.js +1 -1
  77. package/dist/components/popup/PopupList.js +1 -1
  78. package/dist/components/radio-group/RadioGroup.d.ts.map +1 -1
  79. package/dist/components/radio-group/RadioGroup.js +17 -8
  80. package/dist/components/radio-group/RadioGroup.js.map +1 -1
  81. package/dist/components/radio-group/RadioGroup.types.d.ts +5 -3
  82. package/dist/components/radio-group/RadioGroup.types.d.ts.map +1 -1
  83. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
  84. package/dist/components/segmented-control/SegmentedControl.js +12 -5
  85. package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
  86. package/dist/components/segmented-control/SegmentedControl.types.d.ts +5 -2
  87. package/dist/components/segmented-control/SegmentedControl.types.d.ts.map +1 -1
  88. package/dist/components/split-button/SplitButton.d.ts +1 -1
  89. package/dist/components/split-button/SplitButton.d.ts.map +1 -1
  90. package/dist/components/split-button/SplitButton.js +9 -17
  91. package/dist/components/split-button/SplitButton.js.map +1 -1
  92. package/dist/components/switch/Switch.d.ts +1 -1
  93. package/dist/components/switch/Switch.d.ts.map +1 -1
  94. package/dist/components/switch/Switch.js +13 -5
  95. package/dist/components/switch/Switch.js.map +1 -1
  96. package/dist/components/switch/Switch.types.d.ts +2 -0
  97. package/dist/components/switch/Switch.types.d.ts.map +1 -1
  98. package/dist/components/text-area/TextArea.d.ts +1 -1
  99. package/dist/components/text-area/TextArea.d.ts.map +1 -1
  100. package/dist/components/text-area/TextArea.js +5 -4
  101. package/dist/components/text-area/TextArea.js.map +1 -1
  102. package/dist/components/text-field/TextField.d.ts +1 -1
  103. package/dist/components/text-field/TextField.d.ts.map +1 -1
  104. package/dist/components/text-field/TextField.js +5 -4
  105. package/dist/components/text-field/TextField.js.map +1 -1
  106. package/dist/date-time-picker.css +121 -0
  107. package/dist/index.d.ts +9 -5
  108. package/dist/index.d.ts.map +1 -1
  109. package/dist/index.js +6 -2
  110. package/dist/list.css +4 -4
  111. package/dist/radio-group.css +13 -1
  112. package/dist/segmented-control.css +24 -7
  113. package/dist/split-button.css +1 -1
  114. package/dist/styles.css +2 -1
  115. package/dist/switch.css +18 -5
  116. package/dist/text-area.css +2 -2
  117. package/dist/text-field.css +1 -1
  118. package/package.json +3 -2
  119. package/dist/components/message-box/MessageBox.d.ts +0 -4
  120. package/dist/components/message-box/MessageBox.d.ts.map +0 -1
  121. package/dist/components/message-box/MessageBox.js +0 -19
  122. package/dist/components/message-box/MessageBox.js.map +0 -1
  123. package/dist/components/message-box/MessageBox.types.d.ts +0 -13
  124. package/dist/components/message-box/MessageBox.types.d.ts.map +0 -1
  125. package/dist/message-box.css +0 -26
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.js","names":[],"sources":["../../../src/components/date-time-picker/DateTimePicker.tsx"],"sourcesContent":["import { forwardRef, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent, PointerEvent as ReactPointerEvent } from 'react';\n\nimport { DATE_TIME_PICKER_MINUTE_STEPS, type DateTimePickerProps } from './DateTimePicker.types.js';\n\nconst WHEEL_LOOP_CYCLES = 11;\nconst WHEEL_CENTER_CYCLE = Math.floor(WHEEL_LOOP_CYCLES / 2);\ntype DatePart = 'date' | 'fullYear' | 'month';\n\ninterface WheelOption {\n label: string;\n value: number;\n}\n\ninterface WheelProps {\n ariaLabel: string;\n onEscape: () => void;\n onSelect: (value: number) => void;\n options: readonly WheelOption[];\n selected: number;\n}\n\nfunction dateAtMidnight(value: Date) {\n return new Date(value.getFullYear(), value.getMonth(), value.getDate());\n}\n\nfunction clampDate(value: Date, minDate?: Date, maxDate?: Date) {\n const date = dateAtMidnight(value);\n if (minDate !== undefined && date < dateAtMidnight(minDate)) return new Date(minDate);\n if (maxDate !== undefined && date > dateAtMidnight(maxDate)) return new Date(maxDate);\n return value;\n}\n\nfunction normalizeMinute(value: Date, minuteStep: number) {\n const normalized = new Date(value);\n normalized.setMinutes(Math.floor(normalized.getMinutes() / minuteStep) * minuteStep);\n return normalized;\n}\n\nfunction Wheel({ ariaLabel, onEscape, onSelect, options, selected }: WheelProps) {\n const wheelRef = useRef<HTMLDivElement>(null);\n const selectedRef = useRef<HTMLButtonElement>(null);\n const dragRef = useRef<{ pointerId: number; scrollTop: number; startY: number } | undefined>(\n undefined,\n );\n const ignoreClickRef = useRef(false);\n\n useEffect(() => {\n if (typeof selectedRef.current?.scrollIntoView === 'function') {\n selectedRef.current.scrollIntoView({ block: 'center' });\n }\n }, []);\n\n function applyPerspective() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const position = wheel.scrollTop / itemHeight;\n for (const option of wheel.querySelectorAll<HTMLButtonElement>(\n '.chayns-date-time-picker__wheel-option',\n )) {\n const index = Number(option.dataset.wheelIndex);\n const distance = Math.max(-2.5, Math.min(2.5, index - position));\n const progress = Math.min(1, Math.abs(distance) / 2.5);\n\n option.style.color = progress < 0.2 ? 'var(--text)' : 'var(--text-3)';\n option.style.fontWeight = progress < 0.2 ? '600' : '400';\n option.style.opacity = String(1 - progress * 0.7);\n option.style.transform = `rotateX(${distance * 22}deg) scale(${1 - progress * 0.24})`;\n }\n }\n\n function selectCenteredValue() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const index = Math.round(wheel.scrollTop / itemHeight);\n const option = options[((index % options.length) + options.length) % options.length];\n if (option !== undefined && option.value !== selected) onSelect(option.value);\n }\n\n function handleScroll() {\n const wheel = wheelRef.current;\n const itemHeight = selectedRef.current?.offsetHeight;\n if (!wheel || !itemHeight) return;\n\n const index = Math.round(wheel.scrollTop / itemHeight);\n const normalizedIndex = ((index % options.length) + options.length) % options.length;\n if (index < options.length * 2 || index >= options.length * (WHEEL_LOOP_CYCLES - 2)) {\n wheel.scrollTop = (WHEEL_CENTER_CYCLE * options.length + normalizedIndex) * itemHeight;\n }\n\n applyPerspective();\n selectCenteredValue();\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'Escape') {\n event.preventDefault();\n onEscape();\n return;\n }\n\n const index = options.findIndex((option) => option.value === selected);\n let nextIndex = index;\n if (event.key === 'ArrowDown') nextIndex = Math.min(index + 1, options.length - 1);\n if (event.key === 'ArrowUp') nextIndex = Math.max(index - 1, 0);\n if (event.key === 'Home') nextIndex = 0;\n if (event.key === 'End') nextIndex = options.length - 1;\n const nextOption = options[nextIndex];\n if (nextIndex !== index && nextOption !== undefined) {\n event.preventDefault();\n onSelect(nextOption.value);\n }\n }\n\n function handlePointerDown(event: ReactPointerEvent<HTMLDivElement>) {\n if (event.button !== 0) return;\n if (typeof event.currentTarget.setPointerCapture === 'function') {\n event.currentTarget.setPointerCapture(event.pointerId);\n }\n dragRef.current = {\n pointerId: event.pointerId,\n scrollTop: event.currentTarget.scrollTop,\n startY: event.clientY,\n };\n ignoreClickRef.current = false;\n }\n\n function handlePointerMove(event: ReactPointerEvent<HTMLDivElement>) {\n const drag = dragRef.current;\n if (drag?.pointerId !== event.pointerId) return;\n const distance = event.clientY - drag.startY;\n if (Math.abs(distance) > 3) {\n ignoreClickRef.current = true;\n event.currentTarget.scrollTop = drag.scrollTop - distance;\n }\n }\n\n function handlePointerUp(event: ReactPointerEvent<HTMLDivElement>) {\n if (dragRef.current?.pointerId !== event.pointerId) return;\n dragRef.current = undefined;\n if (typeof event.currentTarget.releasePointerCapture === 'function') {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n selectCenteredValue();\n }\n\n return (\n <div\n aria-label={ariaLabel}\n className=\"chayns-date-time-picker__wheel\"\n onKeyDown={handleKeyDown}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onScroll={handleScroll}\n ref={wheelRef}\n role=\"listbox\"\n tabIndex={0}\n >\n {Array.from({ length: WHEEL_LOOP_CYCLES }, (_, cycle) =>\n options.map((option, optionIndex) => (\n <button\n aria-selected={option.value === selected}\n className=\"chayns-date-time-picker__wheel-option\"\n data-wheel-index={cycle * options.length + optionIndex}\n key={`${cycle}-${option.value}`}\n onClick={(event) => {\n if (ignoreClickRef.current) {\n event.preventDefault();\n event.stopPropagation();\n ignoreClickRef.current = false;\n return;\n }\n onSelect(option.value);\n }}\n ref={\n cycle === WHEEL_CENTER_CYCLE && option.value === selected ? selectedRef : undefined\n }\n role=\"option\"\n type=\"button\"\n >\n {option.label}\n </button>\n )),\n )}\n </div>\n );\n}\n\nconst DateTimePicker = forwardRef<HTMLButtonElement, DateTimePickerProps>(function DateTimePicker(\n {\n className,\n disabled,\n id,\n label,\n locale,\n maxDate,\n minDate,\n minuteStep = 1,\n mode = 'time',\n onChange,\n onClick,\n onKeyDown,\n placeholder,\n value,\n wheelLabels,\n ...buttonProps\n },\n ref,\n) {\n if (!DATE_TIME_PICKER_MINUTE_STEPS.includes(minuteStep)) {\n throw new Error('DateTimePicker minuteStep must be one of: 1, 5, 15, 30.');\n }\n\n if (\n minDate !== undefined &&\n maxDate !== undefined &&\n dateAtMidnight(minDate) > dateAtMidnight(maxDate)\n ) {\n throw new Error('DateTimePicker requires minDate to be earlier than or equal to maxDate.');\n }\n\n const generatedId = useId();\n const triggerId = id ?? generatedId;\n const popupId = `${triggerId}-popup`;\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const [open, setOpen] = useState(false);\n const displayValue =\n value === null\n ? null\n : mode === 'date'\n ? clampDate(value, minDate, maxDate)\n : normalizeMinute(value, minuteStep);\n const activeValue = displayValue ?? new Date();\n const isTwelveHour =\n new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions().hour12 === true;\n\n useEffect(() => {\n if (!open) return undefined;\n function closeOnOutsidePress(event: PointerEvent) {\n if (event.target instanceof Node && !rootRef.current?.contains(event.target)) close();\n }\n document.addEventListener('pointerdown', closeOnOutsidePress);\n return () => document.removeEventListener('pointerdown', closeOnOutsidePress);\n });\n\n const years = useMemo(() => {\n const today = new Date().getFullYear();\n const first = minDate?.getFullYear() ?? today - 100;\n const last = maxDate?.getFullYear() ?? today + 100;\n return Array.from({ length: last - first + 1 }, (_, index) => first + index);\n }, [maxDate, minDate]);\n\n function close() {\n setOpen(false);\n triggerRef.current?.focus();\n }\n\n function emit(nextValue: Date) {\n onChange(mode === 'date' ? clampDate(nextValue, minDate, maxDate) : nextValue);\n }\n\n function updateTime(part: 'hours' | 'minutes', nextValue: number) {\n const next = new Date(activeValue);\n if (part === 'hours') {\n const hour = isTwelveHour ? (nextValue % 12) + (next.getHours() >= 12 ? 12 : 0) : nextValue;\n next.setHours(hour);\n } else {\n next.setMinutes(nextValue);\n }\n emit(next);\n }\n\n function updatePeriod(period: number) {\n const next = new Date(activeValue);\n next.setHours((next.getHours() % 12) + period * 12);\n emit(next);\n }\n\n function updateDate(part: DatePart, nextValue: number) {\n const next = new Date(activeValue);\n const originalDay = next.getDate();\n next.setDate(1);\n if (part === 'fullYear') next.setFullYear(nextValue);\n if (part === 'month') next.setMonth(nextValue);\n if (part === 'date') next.setDate(nextValue);\n if (part !== 'date') {\n next.setDate(\n Math.min(originalDay, new Date(next.getFullYear(), next.getMonth() + 1, 0).getDate()),\n );\n }\n emit(next);\n }\n\n const formattedValue =\n displayValue === null\n ? placeholder\n : mode === 'time'\n ? `${new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n }).format(displayValue)}${locale.toLowerCase().startsWith('de') ? ' Uhr' : ''}`\n : new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(displayValue);\n const hours = Array.from({ length: isTwelveHour ? 12 : 24 }, (_, index) =>\n isTwelveHour ? index + 1 : index,\n ).map((hour) => ({ label: String(hour).padStart(2, '0'), value: hour }));\n const minutes = Array.from({ length: 60 / minuteStep }, (_, index) => {\n const minute = index * minuteStep;\n return { label: String(minute).padStart(2, '0'), value: minute };\n });\n const months = Array.from({ length: 12 }, (_, month) => ({\n label: new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2026, month, 1)),\n value: month,\n })).filter((month) => {\n const first = new Date(activeValue.getFullYear(), month.value, 1);\n const last = new Date(activeValue.getFullYear(), month.value + 1, 0);\n return (\n (minDate === undefined || last >= dateAtMidnight(minDate)) &&\n (maxDate === undefined || first <= dateAtMidnight(maxDate))\n );\n });\n const days = Array.from(\n { length: new Date(activeValue.getFullYear(), activeValue.getMonth() + 1, 0).getDate() },\n (_, index) => ({ label: String(index + 1).padStart(2, '0'), value: index + 1 }),\n ).filter((day) => {\n const candidate = new Date(activeValue.getFullYear(), activeValue.getMonth(), day.value);\n return (\n (minDate === undefined || candidate >= dateAtMidnight(minDate)) &&\n (maxDate === undefined || candidate <= dateAtMidnight(maxDate))\n );\n });\n const datePartOrder = new Intl.DateTimeFormat(locale, {\n day: 'numeric',\n month: 'numeric',\n year: 'numeric',\n })\n .formatToParts(activeValue)\n .flatMap<DatePart>((part) => {\n if (part.type === 'day') return ['date'];\n if (part.type === 'month') return ['month'];\n if (part.type === 'year') return ['fullYear'];\n return [];\n });\n const yearOptions = years.map((year) => ({ label: String(year), value: year }));\n\n function dateOptions(part: DatePart) {\n if (part === 'date') return days;\n if (part === 'month') return months;\n return yearOptions;\n }\n\n function dateValue(part: DatePart) {\n if (part === 'date') return activeValue.getDate();\n if (part === 'month') return activeValue.getMonth();\n return activeValue.getFullYear();\n }\n const dayPeriods = [0, 1].map((period) => ({\n label:\n new Intl.DateTimeFormat(locale, { hour: 'numeric' })\n .formatToParts(new Date(2026, 0, 1, period === 0 ? 1 : 13))\n .find((part) => part.type === 'dayPeriod')?.value ?? (period === 0 ? 'AM' : 'PM'),\n value: period,\n }));\n const resolvedClassName = [\n 'chayns-date-time-picker',\n `chayns-date-time-picker--${mode}`,\n open ? 'chayns-date-time-picker--open' : '',\n displayValue !== null ? 'chayns-date-time-picker--filled' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className={resolvedClassName} ref={rootRef}>\n <button\n {...buttonProps}\n aria-controls={open ? popupId : undefined}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n className={['chayns-date-time-picker__trigger', className].filter(Boolean).join(' ')}\n disabled={disabled}\n id={triggerId}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((current) => !current);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.key === 'Escape' && open && !event.defaultPrevented) {\n event.preventDefault();\n close();\n }\n }}\n ref={(element) => {\n triggerRef.current = element;\n if (typeof ref === 'function') ref(element);\n else if (ref !== null) ref.current = element;\n }}\n type=\"button\"\n >\n {formattedValue}\n </button>\n <label className=\"chayns-date-time-picker__label\" htmlFor={triggerId}>\n {label}\n </label>\n {open && !disabled ? (\n <div\n aria-label={label}\n className=\"chayns-date-time-picker__popup\"\n id={popupId}\n role=\"dialog\"\n >\n <div className=\"chayns-date-time-picker__selection\" />\n <div className=\"chayns-date-time-picker__wheels\">\n {mode === 'time' ? (\n <>\n <Wheel\n ariaLabel={wheelLabels.hour}\n onEscape={close}\n onSelect={(hour) => updateTime('hours', hour)}\n options={hours}\n selected={\n isTwelveHour ? activeValue.getHours() % 12 || 12 : activeValue.getHours()\n }\n />\n <Wheel\n ariaLabel={wheelLabels.minute}\n onEscape={close}\n onSelect={(minute) => updateTime('minutes', minute)}\n options={minutes}\n selected={activeValue.getMinutes()}\n />\n {isTwelveHour ? (\n <Wheel\n ariaLabel={wheelLabels.dayPeriod}\n onEscape={close}\n onSelect={updatePeriod}\n options={dayPeriods}\n selected={activeValue.getHours() >= 12 ? 1 : 0}\n />\n ) : null}\n </>\n ) : (\n datePartOrder.map((part) => (\n <Wheel\n ariaLabel={\n part === 'date'\n ? wheelLabels.day\n : part === 'month'\n ? wheelLabels.month\n : wheelLabels.year\n }\n key={part}\n onEscape={close}\n onSelect={(nextValue) => updateDate(part, nextValue)}\n options={dateOptions(part)}\n selected={dateValue(part)}\n />\n ))\n )}\n </div>\n </div>\n ) : null}\n </div>\n );\n});\n\nexport default DateTimePicker;\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ComponentPropsWithRef } from 'react';
2
+ export declare const DATE_TIME_PICKER_MODES: readonly ["date", "time"];
3
+ export declare const DATE_TIME_PICKER_MINUTE_STEPS: readonly [1, 5, 15, 30];
4
+ export type DateTimePickerMode = (typeof DATE_TIME_PICKER_MODES)[number];
5
+ export type DateTimePickerMinuteStep = (typeof DATE_TIME_PICKER_MINUTE_STEPS)[number];
6
+ export interface DateTimePickerWheelLabels {
7
+ day: string;
8
+ dayPeriod: string;
9
+ hour: string;
10
+ minute: string;
11
+ month: string;
12
+ year: string;
13
+ }
14
+ export interface DateTimePickerProps extends Omit<ComponentPropsWithRef<'button'>, 'aria-controls' | 'aria-expanded' | 'aria-haspopup' | 'aria-label' | 'aria-labelledby' | 'children' | 'onChange' | 'type' | 'value'> {
15
+ label: string;
16
+ locale: string;
17
+ minDate?: Date;
18
+ maxDate?: Date;
19
+ minuteStep?: DateTimePickerMinuteStep;
20
+ mode?: DateTimePickerMode;
21
+ onChange: (value: Date) => void;
22
+ placeholder: string;
23
+ value: Date | null;
24
+ wheelLabels: DateTimePickerWheelLabels;
25
+ }
26
+ //# sourceMappingURL=DateTimePicker.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.types.d.ts","sourceRoot":"","sources":["../../../src/components/date-time-picker/DateTimePicker.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,eAAO,MAAM,sBAAsB,2BAA4B,CAAC;AAChE,eAAO,MAAM,6BAA6B,yBAA0B,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AACzE,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtF,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,qBAAqB,CAAC,QAAQ,CAAC,EAC7B,eAAe,GACf,eAAe,GACf,eAAe,GACf,YAAY,GACZ,iBAAiB,GACjB,UAAU,GACV,UAAU,GACV,MAAM,GACN,OAAO,CACV;IACC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,yBAAyB,CAAC;CACxC"}
@@ -0,0 +1,12 @@
1
+ //#region src/components/date-time-picker/DateTimePicker.types.ts
2
+ var DATE_TIME_PICKER_MODES = ["date", "time"];
3
+ var DATE_TIME_PICKER_MINUTE_STEPS = [
4
+ 1,
5
+ 5,
6
+ 15,
7
+ 30
8
+ ];
9
+ //#endregion
10
+ export { DATE_TIME_PICKER_MINUTE_STEPS, DATE_TIME_PICKER_MODES };
11
+
12
+ //# sourceMappingURL=DateTimePicker.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.types.js","names":[],"sources":["../../../src/components/date-time-picker/DateTimePicker.types.ts"],"sourcesContent":["import type { ComponentPropsWithRef } from 'react';\n\nexport const DATE_TIME_PICKER_MODES = ['date', 'time'] as const;\nexport const DATE_TIME_PICKER_MINUTE_STEPS = [1, 5, 15, 30] as const;\n\nexport type DateTimePickerMode = (typeof DATE_TIME_PICKER_MODES)[number];\nexport type DateTimePickerMinuteStep = (typeof DATE_TIME_PICKER_MINUTE_STEPS)[number];\n\nexport interface DateTimePickerWheelLabels {\n day: string;\n dayPeriod: string;\n hour: string;\n minute: string;\n month: string;\n year: string;\n}\n\nexport interface DateTimePickerProps extends Omit<\n ComponentPropsWithRef<'button'>,\n | 'aria-controls'\n | 'aria-expanded'\n | 'aria-haspopup'\n | 'aria-label'\n | 'aria-labelledby'\n | 'children'\n | 'onChange'\n | 'type'\n | 'value'\n> {\n label: string;\n locale: string;\n minDate?: Date;\n maxDate?: Date;\n minuteStep?: DateTimePickerMinuteStep;\n mode?: DateTimePickerMode;\n onChange: (value: Date) => void;\n placeholder: string;\n value: Date | null;\n wheelLabels: DateTimePickerWheelLabels;\n}\n"],"mappings":";AAEA,IAAa,yBAAyB,CAAC,QAAQ,MAAM;AACrD,IAAa,gCAAgC;CAAC;CAAG;CAAG;CAAI;AAAE"}
@@ -1,4 +1,9 @@
1
- import type { IconButtonProps } from './IconButton.types.js';
2
- declare function IconButton({ className, icon, type, variant, ...buttonProps }: IconButtonProps): import("react").JSX.Element;
1
+ declare const IconButton: import("react").ForwardRefExoticComponent<(Omit<import("./IconButton.types.js").IconButtonBaseProps & {
2
+ 'aria-label': string;
3
+ 'aria-labelledby'?: never;
4
+ }, "ref"> | Omit<import("./IconButton.types.js").IconButtonBaseProps & {
5
+ 'aria-label'?: never;
6
+ 'aria-labelledby': string;
7
+ }, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
3
8
  export default IconButton;
4
9
  //# sourceMappingURL=IconButton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,IAAI,EACJ,IAAe,EACf,OAAO,EACP,GAAG,WAAW,EACf,EAAE,eAAe,+BAUjB;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAKA,QAAA,MAAM,UAAU;;;;;;8DAkCd,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -1,19 +1,24 @@
1
1
  import ButtonIcon from "../button/button-icon/ButtonIcon.js";
2
+ import { forwardRef } from "react";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  //#region src/components/icon-button/IconButton.tsx
4
- function IconButton({ className, icon, type = "button", variant, ...buttonProps }) {
5
+ var IconButton = forwardRef(function IconButton({ "aria-busy": ariaBusy, className, disabled, icon, loading = false, type = "button", variant, ...buttonProps }, ref) {
5
6
  const resolvedClassName = [
6
7
  "chayns-icon-button",
7
8
  `chayns-icon-button--${variant}`,
9
+ loading ? "chayns-icon-button--loading" : "",
8
10
  className
9
11
  ].filter(Boolean).join(" ");
10
12
  return /* @__PURE__ */ jsx("button", {
11
13
  ...buttonProps,
14
+ "aria-busy": loading ? true : ariaBusy,
12
15
  className: resolvedClassName,
16
+ disabled: loading || disabled,
17
+ ref,
13
18
  type,
14
- children: /* @__PURE__ */ jsx(ButtonIcon, { icon })
19
+ children: /* @__PURE__ */ jsx(ButtonIcon, { icon: loading ? "fa-spinner" : icon })
15
20
  });
16
- }
21
+ });
17
22
  //#endregion
18
23
  export { IconButton as default };
19
24
 
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.js","names":[],"sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import type { IconButtonProps } from './IconButton.types.js';\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\n\nfunction IconButton({\n className,\n icon,\n type = 'button',\n variant,\n ...buttonProps\n}: IconButtonProps) {\n const resolvedClassName = ['chayns-icon-button', `chayns-icon-button--${variant}`, className]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button {...buttonProps} className={resolvedClassName} type={type}>\n <ButtonIcon icon={icon} />\n </button>\n );\n}\n\nexport default IconButton;\n"],"mappings":";;;AAGA,SAAS,WAAW,EAClB,WACA,MACA,OAAO,UACP,SACA,GAAG,eACe;CAClB,MAAM,oBAAoB;EAAC;EAAsB,uBAAuB;EAAW;CAAS,CAAC,CAC1F,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,oBAAC,UAAD;EAAQ,GAAI;EAAa,WAAW;EAAyB;EAC3D,UAAA,oBAAC,YAAD,EAAkB,KAAO,CAAA;CACnB,CAAA;AAEZ"}
1
+ {"version":3,"file":"IconButton.js","names":[],"sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nimport type { IconButtonProps } from './IconButton.types.js';\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\n\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n {\n 'aria-busy': ariaBusy,\n className,\n disabled,\n icon,\n loading = false,\n type = 'button',\n variant,\n ...buttonProps\n },\n ref,\n) {\n const resolvedClassName = [\n 'chayns-icon-button',\n `chayns-icon-button--${variant}`,\n loading ? 'chayns-icon-button--loading' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n {...buttonProps}\n aria-busy={loading ? true : ariaBusy}\n className={resolvedClassName}\n disabled={loading || disabled}\n ref={ref}\n type={type}\n >\n <ButtonIcon icon={loading ? 'fa-spinner' : icon} />\n </button>\n );\n});\n\nexport default IconButton;\n"],"mappings":";;;;AAKA,IAAM,aAAa,WAA+C,SAAS,WACzE,EACE,aAAa,UACb,WACA,UACA,MACA,UAAU,OACV,OAAO,UACP,SACA,GAAG,eAEL,KACA;CACA,MAAM,oBAAoB;EACxB;EACA,uBAAuB;EACvB,UAAU,gCAAgC;EAC1C;CACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,oBAAC,UAAD;EACE,GAAI;EACJ,aAAW,UAAU,OAAO;EAC5B,WAAW;EACX,UAAU,WAAW;EAChB;EACC;EAEN,UAAA,oBAAC,YAAD,EAAY,MAAM,UAAU,eAAe,KAAO,CAAA;CAC5C,CAAA;AAEZ,CAAC"}
@@ -20,18 +20,21 @@ type IconButtonAccessibleName = {
20
20
  */
21
21
  'aria-labelledby': string;
22
22
  };
23
- interface IconButtonBaseProps extends Omit<ComponentPropsWithRef<'button'>, 'aria-label' | 'aria-labelledby' | 'children'> {
23
+ export interface IconButtonBaseProps extends Omit<ComponentPropsWithRef<'button'>, 'aria-label' | 'aria-labelledby' | 'children'> {
24
24
  /**
25
25
  * @description Visual emphasis that communicates the action's role within
26
26
  * its action scope, using the same four values as `Button`.
27
27
  */
28
28
  variant: ButtonVariant;
29
29
  /**
30
- * @description Required FontAwesome Classic icon name rendered Regular at
31
- * rest and Solid on hover/active. `IconButton` has no visible label, so
32
- * this is its only visible content.
30
+ * @description Required FontAwesome Classic or Brands icon name. Classic
31
+ * icons render Regular at rest and Solid on hover/active; Brands icons
32
+ * render without Classic weight classes. `IconButton` has no visible label,
33
+ * so this is its only visible content.
33
34
  */
34
35
  icon: ButtonIcon;
36
+ /** Shows a spinner while preserving the accessible name and disabling the action. */
37
+ loading?: boolean;
35
38
  }
36
39
  /**
37
40
  * @description Props for a compact, icon-only native action button. Does not
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.types.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;GAIG;AACH,KAAK,wBAAwB,GACzB;IACE;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,GACD;IACE,YAAY,CAAC,EAAE,KAAK,CAAC;IAErB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,UAAU,mBAAoB,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,YAAY,GAAG,iBAAiB,GAAG,UAAU,CAC9C;IACC;;;OAGG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;OAIG;IACH,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,wBAAwB,CAAC"}
1
+ {"version":3,"file":"IconButton.types.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;GAIG;AACH,KAAK,wBAAwB,GACzB;IACE;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,GACD;IACE,YAAY,CAAC,EAAE,KAAK,CAAC;IAErB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,YAAY,GAAG,iBAAiB,GAAG,UAAU,CAC9C;IACC;;;OAGG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;;;;OAKG;IACH,IAAI,EAAE,UAAU,CAAC;IAEjB,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,wBAAwB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { ListContext, ListItemContext, useListContext, useListItemContext } from "./ListContext.js";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
2
  import { forwardRef } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/list/List.tsx
5
5
  var Item = forwardRef(function Item({ children, className, ...itemProps }, ref) {
6
6
  useListContext();
@@ -1,5 +1,5 @@
1
- import { jsx } from "react/jsx-runtime";
2
1
  import { cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useRef, useState } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
3
  import { createPortal } from "react-dom";
4
4
  //#region src/components/popup/Popup.tsx
5
5
  var PopupContext = createContext(null);
@@ -1,7 +1,7 @@
1
1
  import ButtonIcon from "../button/button-icon/ButtonIcon.js";
2
2
  import Popup_default from "./Popup.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
3
  import { useRef } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/popup/PopupList.tsx
6
6
  var PopupList = ({ className, items, trigger }) => {
7
7
  const itemRefs = useRef([]);
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/radio-group/RadioGroup.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAoEzE,QAAA,MAAM,UAAU;;CAA2C,CAAC;AAE5D,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/radio-group/RadioGroup.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAgFzE,QAAA,MAAM,UAAU;;CAA2C,CAAC;AAE5D,eAAe,UAAU,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { RadioGroupContext, useRadioGroupContext } from "./RadioGroupContext.js";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
2
  import { forwardRef, useState } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/radio-group/RadioGroup.tsx
5
- var Radio = forwardRef(function Radio({ children, className, disabled, value, ...inputProps }, ref) {
5
+ var Radio = forwardRef(function Radio({ children, className, description, disabled, onChange, value, ...inputProps }, ref) {
6
6
  const group = useRadioGroupContext();
7
7
  const isDisabled = group.disabled || disabled === true;
8
8
  const inputClassName = ["chayns-radio__input", className].filter(Boolean).join(" ");
@@ -15,7 +15,10 @@ var Radio = forwardRef(function Radio({ children, className, disabled, value, ..
15
15
  className: inputClassName,
16
16
  disabled: isDisabled,
17
17
  name: group.name,
18
- onChange: () => group.selectValue(value),
18
+ onChange: (event) => {
19
+ onChange?.(event);
20
+ if (!event.defaultPrevented) group.selectValue(value);
21
+ },
19
22
  ref,
20
23
  type: "radio",
21
24
  value
@@ -24,9 +27,15 @@ var Radio = forwardRef(function Radio({ children, className, disabled, value, ..
24
27
  "aria-hidden": "true",
25
28
  className: "chayns-radio__control"
26
29
  }),
27
- /* @__PURE__ */ jsx("span", {
28
- className: "chayns-radio__label",
29
- children
30
+ /* @__PURE__ */ jsxs("span", {
31
+ className: "chayns-radio__content",
32
+ children: [/* @__PURE__ */ jsx("span", {
33
+ className: "chayns-radio__label",
34
+ children
35
+ }), description !== void 0 ? /* @__PURE__ */ jsx("span", {
36
+ className: "chayns-radio__description",
37
+ children: description
38
+ }) : null]
30
39
  })
31
40
  ]
32
41
  });
@@ -52,10 +61,10 @@ var RadioGroupRoot = forwardRef(function RadioGroupRoot({ children, className, d
52
61
  className: resolvedClassName,
53
62
  disabled,
54
63
  ref,
55
- children: [/* @__PURE__ */ jsx("legend", {
64
+ children: [label !== void 0 ? /* @__PURE__ */ jsx("legend", {
56
65
  className: "chayns-radio-group__legend",
57
66
  children: label
58
- }), /* @__PURE__ */ jsx("div", {
67
+ }) : null, /* @__PURE__ */ jsx("div", {
59
68
  className: "chayns-radio-group__options",
60
69
  children
61
70
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","names":[],"sources":["../../../src/components/radio-group/RadioGroup.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react';\n\nimport { RadioGroupContext, useRadioGroupContext } from './RadioGroupContext.js';\nimport type { RadioGroupProps, RadioProps } from './RadioGroup.types.js';\n\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { children, className, disabled, value, ...inputProps },\n ref,\n) {\n const group = useRadioGroupContext();\n const isDisabled = group.disabled || disabled === true;\n const inputClassName = ['chayns-radio__input', className].filter(Boolean).join(' ');\n\n return (\n <label className=\"chayns-radio\">\n <input\n {...inputProps}\n checked={group.value === value}\n className={inputClassName}\n disabled={isDisabled}\n name={group.name}\n onChange={() => group.selectValue(value)}\n ref={ref}\n type=\"radio\"\n value={value}\n />\n <span aria-hidden=\"true\" className=\"chayns-radio__control\" />\n <span className=\"chayns-radio__label\">{children}</span>\n </label>\n );\n});\n\nconst RadioGroupRoot = forwardRef<HTMLFieldSetElement, RadioGroupProps>(function RadioGroupRoot(\n {\n children,\n className,\n defaultValue,\n disabled,\n label,\n name,\n onValueChange,\n value,\n ...fieldsetProps\n },\n ref,\n) {\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\n const isControlled = value !== undefined;\n const selectedValue = isControlled ? value : uncontrolledValue;\n const resolvedClassName = ['chayns-radio-group', className].filter(Boolean).join(' ');\n\n function selectValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n onValueChange?.(nextValue);\n }\n\n return (\n <RadioGroupContext.Provider\n value={{ disabled: disabled === true, name, selectValue, value: selectedValue }}\n >\n <fieldset {...fieldsetProps} className={resolvedClassName} disabled={disabled} ref={ref}>\n <legend className=\"chayns-radio-group__legend\">{label}</legend>\n <div className=\"chayns-radio-group__options\">{children}</div>\n </fieldset>\n </RadioGroupContext.Provider>\n );\n});\n\nconst RadioGroup = Object.assign(RadioGroupRoot, { Radio });\n\nexport default RadioGroup;\n"],"mappings":";;;;AAKA,IAAM,QAAQ,WAAyC,SAAS,MAC9D,EAAE,UAAU,WAAW,UAAU,OAAO,GAAG,cAC3C,KACA;CACA,MAAM,QAAQ,qBAAqB;CACnC,MAAM,aAAa,MAAM,YAAY,aAAa;CAClD,MAAM,iBAAiB,CAAC,uBAAuB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAElF,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA;GACE,oBAAC,SAAD;IACE,GAAI;IACJ,SAAS,MAAM,UAAU;IACzB,WAAW;IACX,UAAU;IACV,MAAM,MAAM;IACZ,gBAAgB,MAAM,YAAY,KAAK;IAClC;IACL,MAAK;IACE;GACR,CAAA;GACD,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;GAAyB,CAAA;GAC5D,oBAAC,QAAD;IAAM,WAAU;IAAuB;GAAe,CAAA;EACjD;;AAEX,CAAC;AAED,IAAM,iBAAiB,WAAiD,SAAS,eAC/E,EACE,UACA,WACA,cACA,UACA,OACA,MACA,eACA,OACA,GAAG,iBAEL,KACA;CACA,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,YAAY;CACvE,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,gBAAgB,eAAe,QAAQ;CAC7C,MAAM,oBAAoB,CAAC,sBAAsB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpF,SAAS,YAAY,WAAmB;EACtC,IAAI,CAAC,cACH,qBAAqB,SAAS;EAGhC,gBAAgB,SAAS;CAC3B;CAEA,OACE,oBAAC,kBAAkB,UAAnB;EACE,OAAO;GAAE,UAAU,aAAa;GAAM;GAAM;GAAa,OAAO;EAAc;EAE9E,UAAA,qBAAC,YAAD;GAAU,GAAI;GAAe,WAAW;GAA6B;GAAe;GAApF,UAAA,CACE,oBAAC,UAAD;IAAQ,WAAU;IAA8B,UAAA;GAAc,CAAA,GAC9D,oBAAC,OAAD;IAAK,WAAU;IAA+B;GAAc,CAAA,CACpD;;CACgB,CAAA;AAEhC,CAAC;AAED,IAAM,aAAa,OAAO,OAAO,gBAAgB,EAAE,MAAM,CAAC"}
1
+ {"version":3,"file":"RadioGroup.js","names":[],"sources":["../../../src/components/radio-group/RadioGroup.tsx"],"sourcesContent":["import { forwardRef, useState } from 'react';\n\nimport { RadioGroupContext, useRadioGroupContext } from './RadioGroupContext.js';\nimport type { RadioGroupProps, RadioProps } from './RadioGroup.types.js';\n\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { children, className, description, disabled, onChange, value, ...inputProps },\n ref,\n) {\n const group = useRadioGroupContext();\n const isDisabled = group.disabled || disabled === true;\n const inputClassName = ['chayns-radio__input', className].filter(Boolean).join(' ');\n\n return (\n <label className=\"chayns-radio\">\n <input\n {...inputProps}\n checked={group.value === value}\n className={inputClassName}\n disabled={isDisabled}\n name={group.name}\n onChange={(event) => {\n onChange?.(event);\n if (!event.defaultPrevented) {\n group.selectValue(value);\n }\n }}\n ref={ref}\n type=\"radio\"\n value={value}\n />\n <span aria-hidden=\"true\" className=\"chayns-radio__control\" />\n <span className=\"chayns-radio__content\">\n <span className=\"chayns-radio__label\">{children}</span>\n {description !== undefined ? (\n <span className=\"chayns-radio__description\">{description}</span>\n ) : null}\n </span>\n </label>\n );\n});\n\nconst RadioGroupRoot = forwardRef<HTMLFieldSetElement, RadioGroupProps>(function RadioGroupRoot(\n {\n children,\n className,\n defaultValue,\n disabled,\n label,\n name,\n onValueChange,\n value,\n ...fieldsetProps\n },\n ref,\n) {\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\n const isControlled = value !== undefined;\n const selectedValue = isControlled ? value : uncontrolledValue;\n const resolvedClassName = ['chayns-radio-group', className].filter(Boolean).join(' ');\n\n function selectValue(nextValue: string) {\n if (!isControlled) {\n setUncontrolledValue(nextValue);\n }\n\n onValueChange?.(nextValue);\n }\n\n return (\n <RadioGroupContext.Provider\n value={{ disabled: disabled === true, name, selectValue, value: selectedValue }}\n >\n <fieldset {...fieldsetProps} className={resolvedClassName} disabled={disabled} ref={ref}>\n {label !== undefined ? (\n <legend className=\"chayns-radio-group__legend\">{label}</legend>\n ) : null}\n <div className=\"chayns-radio-group__options\">{children}</div>\n </fieldset>\n </RadioGroupContext.Provider>\n );\n});\n\nconst RadioGroup = Object.assign(RadioGroupRoot, { Radio });\n\nexport default RadioGroup;\n"],"mappings":";;;;AAKA,IAAM,QAAQ,WAAyC,SAAS,MAC9D,EAAE,UAAU,WAAW,aAAa,UAAU,UAAU,OAAO,GAAG,cAClE,KACA;CACA,MAAM,QAAQ,qBAAqB;CACnC,MAAM,aAAa,MAAM,YAAY,aAAa;CAClD,MAAM,iBAAiB,CAAC,uBAAuB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAElF,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA;GACE,oBAAC,SAAD;IACE,GAAI;IACJ,SAAS,MAAM,UAAU;IACzB,WAAW;IACX,UAAU;IACV,MAAM,MAAM;IACZ,WAAW,UAAU;KACnB,WAAW,KAAK;KAChB,IAAI,CAAC,MAAM,kBACT,MAAM,YAAY,KAAK;IAE3B;IACK;IACL,MAAK;IACE;GACR,CAAA;GACD,oBAAC,QAAD;IAAM,eAAY;IAAO,WAAU;GAAyB,CAAA;GAC5D,qBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CACE,oBAAC,QAAD;KAAM,WAAU;KAAuB;IAAe,CAAA,GACrD,gBAAgB,KAAA,IACf,oBAAC,QAAD;KAAM,WAAU;KAA6B,UAAA;IAAkB,CAAA,IAC7D,IACA;;EACD;;AAEX,CAAC;AAED,IAAM,iBAAiB,WAAiD,SAAS,eAC/E,EACE,UACA,WACA,cACA,UACA,OACA,MACA,eACA,OACA,GAAG,iBAEL,KACA;CACA,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,YAAY;CACvE,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,gBAAgB,eAAe,QAAQ;CAC7C,MAAM,oBAAoB,CAAC,sBAAsB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpF,SAAS,YAAY,WAAmB;EACtC,IAAI,CAAC,cACH,qBAAqB,SAAS;EAGhC,gBAAgB,SAAS;CAC3B;CAEA,OACE,oBAAC,kBAAkB,UAAnB;EACE,OAAO;GAAE,UAAU,aAAa;GAAM;GAAM;GAAa,OAAO;EAAc;EAE9E,UAAA,qBAAC,YAAD;GAAU,GAAI;GAAe,WAAW;GAA6B;GAAe;GAApF,UAAA,CACG,UAAU,KAAA,IACT,oBAAC,UAAD;IAAQ,WAAU;IAA8B,UAAA;GAAc,CAAA,IAC5D,MACJ,oBAAC,OAAD;IAAK,WAAU;IAA+B;GAAc,CAAA,CACpD;;CACgB,CAAA;AAEhC,CAAC;AAED,IAAM,aAAa,OAAO,OAAO,gBAAgB,EAAE,MAAM,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import type { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  /** Props for a labelled native radio fieldset. */
3
3
  export interface RadioGroupProps extends Omit<ComponentPropsWithRef<'fieldset'>, 'children' | 'name'> {
4
- /** Visible, localized group label rendered as its legend. */
5
- label: Exclude<ReactNode, boolean | null | undefined>;
4
+ /** Optional visible, localized group label rendered as its legend. */
5
+ label?: Exclude<ReactNode, boolean | null | undefined>;
6
6
  /** Shared native name forwarded to every Radio. */
7
7
  name: string;
8
8
  /** Controlled selected option value. */
@@ -20,11 +20,13 @@ export interface RadioProps extends Omit<ComponentPropsWithRef<'input'>, 'childr
20
20
  value: string;
21
21
  /** Visible, localized option label. */
22
22
  children: Exclude<ReactNode, boolean | null | undefined>;
23
+ /** Optional localized supporting text associated with the radio label. */
24
+ description?: ReactNode;
23
25
  /** RadioGroup owns the input type and selection relationship. */
24
26
  type?: never;
25
27
  name?: never;
26
28
  checked?: never;
27
29
  defaultChecked?: never;
28
- onChange?: never;
30
+ onChange?: ComponentPropsWithRef<'input'>['onChange'];
29
31
  }
30
32
  //# sourceMappingURL=RadioGroup.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.types.d.ts","sourceRoot":"","sources":["../../../src/components/radio-group/RadioGroup.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,kDAAkD;AAClD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,qBAAqB,CAAC,UAAU,CAAC,EACjC,UAAU,GAAG,MAAM,CACpB;IACC,6DAA6D;IAC7D,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtD,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,qBAAqB,CAAC,OAAO,CAAC,EAC9B,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,UAAU,CACzE;IACC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAEzD,iEAAiE;IACjE,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB"}
1
+ {"version":3,"file":"RadioGroup.types.d.ts","sourceRoot":"","sources":["../../../src/components/radio-group/RadioGroup.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,kDAAkD;AAClD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,qBAAqB,CAAC,UAAU,CAAC,EACjC,UAAU,GAAG,MAAM,CACpB;IACC,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACvD,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,qBAAqB,CAAC,OAAO,CAAC,EAC9B,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,UAAU,CACzE;IACC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAEzD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB,iEAAiE;IACjE,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;CACvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAyB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAqMvF,QAAA,MAAM,gBAAgB;;;;;;;;;;;;CAAmD,CAAC;AAE1E,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAyB,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAkNvF,QAAA,MAAM,gBAAgB;;;;;;;;;;;;CAAmD,CAAC;AAE1E,eAAe,gBAAgB,CAAC"}
@@ -1,13 +1,14 @@
1
+ import ButtonIcon from "../button/button-icon/ButtonIcon.js";
1
2
  import { SegmentedControlContext, useSegmentedControlContext } from "./SegmentedControlContext.js";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { forwardRef, useId, useLayoutEffect, useRef, useState } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/components/segmented-control/SegmentedControl.tsx
5
6
  function getOrderedSegments(segments) {
6
7
  return [...segments.entries()].filter(([, element]) => !element.disabled).sort(([, first], [, second]) => {
7
8
  return first.compareDocumentPosition(second) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
8
9
  });
9
10
  }
10
- var Segment = forwardRef(function Segment({ children, className, disabled, value, ...buttonProps }, ref) {
11
+ var Segment = forwardRef(function Segment({ children, className, disabled, icon, onClick, onKeyDown, value, ...buttonProps }, ref) {
11
12
  const control = useSegmentedControlContext();
12
13
  const localRef = useRef(null);
13
14
  const isSelected = control.value === value;
@@ -26,6 +27,8 @@ var Segment = forwardRef(function Segment({ children, className, disabled, value
26
27
  else if (ref !== null) ref.current = element;
27
28
  }
28
29
  function handleKeyDown(event) {
30
+ onKeyDown?.(event);
31
+ if (event.defaultPrevented) return;
29
32
  if ([
30
33
  "ArrowDown",
31
34
  "ArrowLeft",
@@ -38,18 +41,22 @@ var Segment = forwardRef(function Segment({ children, className, disabled, value
38
41
  control.moveFocus(value, event.key);
39
42
  }
40
43
  }
41
- return /* @__PURE__ */ jsx("button", {
44
+ function handleClick(event) {
45
+ onClick?.(event);
46
+ if (!event.defaultPrevented) control.selectValue(value);
47
+ }
48
+ return /* @__PURE__ */ jsxs("button", {
42
49
  ...buttonProps,
43
50
  "aria-checked": isSelected,
44
51
  className: resolvedClassName,
45
52
  disabled,
46
- onClick: () => control.selectValue(value),
53
+ onClick: handleClick,
47
54
  onKeyDown: handleKeyDown,
48
55
  ref: setRef,
49
56
  role: "radio",
50
57
  tabIndex: isSelected ? 0 : -1,
51
58
  type: "button",
52
- children
59
+ children: [icon ? /* @__PURE__ */ jsx(ButtonIcon, { icon }) : null, children]
53
60
  });
54
61
  });
55
62
  var SegmentedControlRoot = forwardRef(function SegmentedControlRoot({ children, className, defaultValue, label, onValueChange, value, ...rootProps }, ref) {
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.js","names":[],"sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import { forwardRef, useId, useLayoutEffect, useRef, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\n\nimport { SegmentedControlContext, useSegmentedControlContext } from './SegmentedControlContext.js';\nimport type { SegmentedControlProps, SegmentProps } from './SegmentedControl.types.js';\n\nfunction getOrderedSegments(segments: Map<string, HTMLButtonElement>) {\n return [...segments.entries()]\n .filter(([, element]) => !element.disabled)\n .sort(([, first], [, second]) => {\n const position = first.compareDocumentPosition(second);\n return position & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n });\n}\n\nconst Segment = forwardRef<HTMLButtonElement, SegmentProps>(function Segment(\n { children, className, disabled, value, ...buttonProps },\n ref,\n) {\n const control = useSegmentedControlContext();\n const localRef = useRef<HTMLButtonElement>(null);\n const isSelected = control.value === value;\n const resolvedClassName = [\n 'chayns-segmented-control__segment',\n isSelected ? 'chayns-segmented-control__segment--selected' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n useLayoutEffect(() => {\n if (localRef.current === null) {\n return undefined;\n }\n\n return control.registerSegment(value, localRef.current);\n }, [control, value]);\n\n function setRef(element: HTMLButtonElement | null) {\n localRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLButtonElement>) {\n const keys = ['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home'];\n\n if (keys.includes(event.key)) {\n event.preventDefault();\n control.moveFocus(value, event.key);\n }\n }\n\n return (\n <button\n {...buttonProps}\n aria-checked={isSelected}\n className={resolvedClassName}\n disabled={disabled}\n onClick={() => control.selectValue(value)}\n onKeyDown={handleKeyDown}\n ref={setRef}\n role=\"radio\"\n tabIndex={isSelected ? 0 : -1}\n type=\"button\"\n >\n {children}\n </button>\n );\n});\n\nconst SegmentedControlRoot = forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControlRoot(\n { children, className, defaultValue, label, onValueChange, value, ...rootProps },\n ref,\n ) {\n const labelId = useId();\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\n const segments = useRef(new Map<string, HTMLButtonElement>());\n const segmentsElement = useRef<HTMLDivElement>(null);\n const [indicator, setIndicator] = useState({ offset: 0, width: 0 });\n const selectedValue = value ?? uncontrolledValue ?? '';\n const resolvedClassName = ['chayns-segmented-control', className].filter(Boolean).join(' ');\n\n function selectValue(nextValue: string) {\n if (value === undefined) {\n setUncontrolledValue(nextValue);\n }\n\n onValueChange?.(nextValue);\n }\n\n function registerSegment(segmentValue: string, element: HTMLButtonElement) {\n segments.current.set(segmentValue, element);\n\n return () => {\n segments.current.delete(segmentValue);\n };\n }\n\n function moveFocus(currentValue: string, key: string) {\n const enabledSegments = getOrderedSegments(segments.current);\n const currentIndex = enabledSegments.findIndex(\n ([segmentValue]) => segmentValue === currentValue,\n );\n\n if (currentIndex === -1 || enabledSegments.length === 0) {\n return;\n }\n\n let targetIndex = currentIndex;\n\n if (key === 'Home') {\n targetIndex = 0;\n } else if (key === 'End') {\n targetIndex = enabledSegments.length - 1;\n } else if (key === 'ArrowLeft' || key === 'ArrowUp') {\n targetIndex = (currentIndex - 1 + enabledSegments.length) % enabledSegments.length;\n } else if (key === 'ArrowRight' || key === 'ArrowDown') {\n targetIndex = (currentIndex + 1) % enabledSegments.length;\n }\n\n const nextSegment = enabledSegments[targetIndex];\n\n if (nextSegment === undefined) {\n return;\n }\n\n const [nextValue, nextElement] = nextSegment;\n selectValue(nextValue);\n nextElement.focus();\n }\n\n useLayoutEffect(() => {\n const container = segmentsElement.current;\n const selectedSegment = segments.current.get(selectedValue);\n\n if (container === null || selectedSegment === undefined) {\n return undefined;\n }\n\n const observedContainer = container;\n const observedSegment = selectedSegment;\n\n function updateIndicator() {\n const paddingInlineStart = Number.parseFloat(\n window.getComputedStyle(observedContainer).paddingInlineStart,\n );\n\n setIndicator({\n offset:\n observedSegment.offsetLeft -\n (Number.isNaN(paddingInlineStart) ? 0 : paddingInlineStart),\n width: observedSegment.offsetWidth,\n });\n }\n\n updateIndicator();\n\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(observedContainer);\n\n return () => observer.disconnect();\n }, [selectedValue]);\n\n return (\n <SegmentedControlContext.Provider\n value={{ moveFocus, registerSegment, selectValue, value: selectedValue }}\n >\n <div\n {...rootProps}\n aria-labelledby={labelId}\n className={resolvedClassName}\n ref={ref}\n role=\"radiogroup\"\n >\n <span className=\"chayns-segmented-control__label\" id={labelId}>\n {label}\n </span>\n <div className=\"chayns-segmented-control__segments\" ref={segmentsElement}>\n <span\n aria-hidden=\"true\"\n className=\"chayns-segmented-control__indicator\"\n style={{ transform: `translateX(${indicator.offset}px)`, width: indicator.width }}\n />\n {children}\n </div>\n </div>\n </SegmentedControlContext.Provider>\n );\n },\n);\n\nconst SegmentedControl = Object.assign(SegmentedControlRoot, { Segment });\n\nexport default SegmentedControl;\n"],"mappings":"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"}
1
+ {"version":3,"file":"SegmentedControl.js","names":[],"sources":["../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import { forwardRef, useId, useLayoutEffect, useRef, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\n\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport { SegmentedControlContext, useSegmentedControlContext } from './SegmentedControlContext.js';\nimport type { SegmentedControlProps, SegmentProps } from './SegmentedControl.types.js';\n\nfunction getOrderedSegments(segments: Map<string, HTMLButtonElement>) {\n return [...segments.entries()]\n .filter(([, element]) => !element.disabled)\n .sort(([, first], [, second]) => {\n const position = first.compareDocumentPosition(second);\n return position & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n });\n}\n\nconst Segment = forwardRef<HTMLButtonElement, SegmentProps>(function Segment(\n { children, className, disabled, icon, onClick, onKeyDown, value, ...buttonProps },\n ref,\n) {\n const control = useSegmentedControlContext();\n const localRef = useRef<HTMLButtonElement>(null);\n const isSelected = control.value === value;\n const resolvedClassName = [\n 'chayns-segmented-control__segment',\n isSelected ? 'chayns-segmented-control__segment--selected' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n useLayoutEffect(() => {\n if (localRef.current === null) {\n return undefined;\n }\n\n return control.registerSegment(value, localRef.current);\n }, [control, value]);\n\n function setRef(element: HTMLButtonElement | null) {\n localRef.current = element;\n\n if (typeof ref === 'function') {\n ref(element);\n } else if (ref !== null) {\n ref.current = element;\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLButtonElement>) {\n onKeyDown?.(event);\n if (event.defaultPrevented) {\n return;\n }\n\n const keys = ['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home'];\n\n if (keys.includes(event.key)) {\n event.preventDefault();\n control.moveFocus(value, event.key);\n }\n }\n\n function handleClick(event: React.MouseEvent<HTMLButtonElement>) {\n onClick?.(event);\n if (!event.defaultPrevented) {\n control.selectValue(value);\n }\n }\n\n return (\n <button\n {...buttonProps}\n aria-checked={isSelected}\n className={resolvedClassName}\n disabled={disabled}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n ref={setRef}\n role=\"radio\"\n tabIndex={isSelected ? 0 : -1}\n type=\"button\"\n >\n {icon ? <ButtonIcon icon={icon} /> : null}\n {children}\n </button>\n );\n});\n\nconst SegmentedControlRoot = forwardRef<HTMLDivElement, SegmentedControlProps>(\n function SegmentedControlRoot(\n { children, className, defaultValue, label, onValueChange, value, ...rootProps },\n ref,\n ) {\n const labelId = useId();\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);\n const segments = useRef(new Map<string, HTMLButtonElement>());\n const segmentsElement = useRef<HTMLDivElement>(null);\n const [indicator, setIndicator] = useState({ offset: 0, width: 0 });\n const selectedValue = value ?? uncontrolledValue ?? '';\n const resolvedClassName = ['chayns-segmented-control', className].filter(Boolean).join(' ');\n\n function selectValue(nextValue: string) {\n if (value === undefined) {\n setUncontrolledValue(nextValue);\n }\n\n onValueChange?.(nextValue);\n }\n\n function registerSegment(segmentValue: string, element: HTMLButtonElement) {\n segments.current.set(segmentValue, element);\n\n return () => {\n segments.current.delete(segmentValue);\n };\n }\n\n function moveFocus(currentValue: string, key: string) {\n const enabledSegments = getOrderedSegments(segments.current);\n const currentIndex = enabledSegments.findIndex(\n ([segmentValue]) => segmentValue === currentValue,\n );\n\n if (currentIndex === -1 || enabledSegments.length === 0) {\n return;\n }\n\n let targetIndex = currentIndex;\n\n if (key === 'Home') {\n targetIndex = 0;\n } else if (key === 'End') {\n targetIndex = enabledSegments.length - 1;\n } else if (key === 'ArrowLeft' || key === 'ArrowUp') {\n targetIndex = (currentIndex - 1 + enabledSegments.length) % enabledSegments.length;\n } else if (key === 'ArrowRight' || key === 'ArrowDown') {\n targetIndex = (currentIndex + 1) % enabledSegments.length;\n }\n\n const nextSegment = enabledSegments[targetIndex];\n\n if (nextSegment === undefined) {\n return;\n }\n\n const [nextValue, nextElement] = nextSegment;\n selectValue(nextValue);\n nextElement.focus();\n }\n\n useLayoutEffect(() => {\n const container = segmentsElement.current;\n const selectedSegment = segments.current.get(selectedValue);\n\n if (container === null || selectedSegment === undefined) {\n return undefined;\n }\n\n const observedContainer = container;\n const observedSegment = selectedSegment;\n\n function updateIndicator() {\n const paddingInlineStart = Number.parseFloat(\n window.getComputedStyle(observedContainer).paddingInlineStart,\n );\n\n setIndicator({\n offset:\n observedSegment.offsetLeft -\n (Number.isNaN(paddingInlineStart) ? 0 : paddingInlineStart),\n width: observedSegment.offsetWidth,\n });\n }\n\n updateIndicator();\n\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver(updateIndicator);\n observer.observe(observedContainer);\n\n return () => observer.disconnect();\n }, [selectedValue]);\n\n return (\n <SegmentedControlContext.Provider\n value={{ moveFocus, registerSegment, selectValue, value: selectedValue }}\n >\n <div\n {...rootProps}\n aria-labelledby={labelId}\n className={resolvedClassName}\n ref={ref}\n role=\"radiogroup\"\n >\n <span className=\"chayns-segmented-control__label\" id={labelId}>\n {label}\n </span>\n <div className=\"chayns-segmented-control__segments\" ref={segmentsElement}>\n <span\n aria-hidden=\"true\"\n className=\"chayns-segmented-control__indicator\"\n style={{ transform: `translateX(${indicator.offset}px)`, width: indicator.width }}\n />\n {children}\n </div>\n </div>\n </SegmentedControlContext.Provider>\n );\n },\n);\n\nconst SegmentedControl = Object.assign(SegmentedControlRoot, { Segment });\n\nexport default SegmentedControl;\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import type { ButtonIcon } from '../button/Button.types.js';
2
3
  export interface ControlledSelection {
3
4
  /** Controlled selected segment value. */
4
5
  value: string;
@@ -30,12 +31,14 @@ export interface SegmentProps extends Omit<ComponentPropsWithRef<'button'>, 'ari
30
31
  value: string;
31
32
  /** Visible, localized button label. */
32
33
  children: Exclude<ReactNode, boolean | null | undefined>;
34
+ /** Optional leading FontAwesome icon shown with the segment label. */
35
+ icon?: ButtonIcon;
33
36
  /** SegmentedControl owns the native button semantics and interactions. */
34
37
  type?: never;
35
38
  role?: never;
36
39
  'aria-checked'?: never;
37
40
  tabIndex?: never;
38
- onClick?: never;
39
- onKeyDown?: never;
41
+ onClick?: ComponentPropsWithRef<'button'>['onClick'];
42
+ onKeyDown?: ComponentPropsWithRef<'button'>['onKeyDown'];
40
43
  }
41
44
  //# sourceMappingURL=SegmentedControl.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.types.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gDAAgD;IAChD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,qBAAqB,CAAC,KAAK,CAAC,EAC5B,iBAAiB,GAAG,UAAU,GAAG,MAAM,CACxC,GACC,CAAC,mBAAmB,GAAG,qBAAqB,CAAC,GAAG;IAC9C,sCAAsC;IACtC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtD,yCAAyC;IACzC,QAAQ,EAAE,SAAS,CAAC;IACpB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,CAAC;AAEJ,uDAAuD;AACvD,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CACrF;IACC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD,0EAA0E;IAC1E,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB"}
1
+ {"version":3,"file":"SegmentedControl.types.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/SegmentedControl.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gDAAgD;IAChD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,qBAAqB,CAAC,KAAK,CAAC,EAC5B,iBAAiB,GAAG,UAAU,GAAG,MAAM,CACxC,GACC,CAAC,mBAAmB,GAAG,qBAAqB,CAAC,GAAG;IAC9C,sCAAsC;IACtC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtD,yCAAyC;IACzC,QAAQ,EAAE,SAAS,CAAC;IACpB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,CAAC;AAEJ,uDAAuD;AACvD,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CACrF;IACC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD,sEAAsE;IACtE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,OAAO,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC;IACrD,SAAS,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,CAAC;CAC1D"}
@@ -1,4 +1,4 @@
1
1
  import type { SplitButtonProps } from './SplitButton.types.js';
2
- declare const SplitButton: ({ children, className, disabled, icon, items, onClick, variant, ...containerProps }: SplitButtonProps) => import("react").JSX.Element;
2
+ declare const SplitButton: import("react").ForwardRefExoticComponent<Omit<SplitButtonProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
3
3
  export default SplitButton;
4
4
  //# sourceMappingURL=SplitButton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplitButton.d.ts","sourceRoot":"","sources":["../../../src/components/split-button/SplitButton.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,QAAA,MAAM,WAAW,GAAI,qFASlB,gBAAgB,gCA+ClB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"SplitButton.d.ts","sourceRoot":"","sources":["../../../src/components/split-button/SplitButton.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,QAAA,MAAM,WAAW,0HAwCf,CAAC;AAEH,eAAe,WAAW,CAAC"}
@@ -1,30 +1,21 @@
1
1
  import ButtonIcon from "../button/button-icon/ButtonIcon.js";
2
2
  import Button from "../button/Button.js";
3
3
  import PopupList from "../popup/PopupList.js";
4
+ import { forwardRef, useId } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { useId } from "react";
6
6
  //#region src/components/split-button/SplitButton.tsx
7
- var SplitButton = ({ children, className, disabled, icon, items, onClick, variant, ...containerProps }) => {
7
+ var SplitButton = forwardRef(function SplitButton({ children, className, disabled, icon, items, onClick, variant, ...containerProps }, ref) {
8
8
  const labelId = useId();
9
9
  return /* @__PURE__ */ jsxs("div", {
10
10
  ...containerProps,
11
11
  className: ["chayns-split-button", className].filter(Boolean).join(" "),
12
- children: [icon ? /* @__PURE__ */ jsx(Button, {
12
+ ref,
13
+ children: [/* @__PURE__ */ jsx(Button, {
13
14
  "aria-labelledby": labelId,
14
15
  className: "chayns-split-button__primary",
15
- ...disabled ? { disabled: true } : {},
16
- icon,
17
- ...onClick ? { onClick } : {},
18
- variant,
19
- children: /* @__PURE__ */ jsx("span", {
20
- id: labelId,
21
- children
22
- })
23
- }) : /* @__PURE__ */ jsx(Button, {
24
- "aria-labelledby": labelId,
25
- className: "chayns-split-button__primary",
26
- ...disabled ? { disabled: true } : {},
27
- ...onClick ? { onClick } : {},
16
+ disabled,
17
+ ...icon ? { icon } : {},
18
+ onClick,
28
19
  variant,
29
20
  children: /* @__PURE__ */ jsx("span", {
30
21
  id: labelId,
@@ -34,6 +25,7 @@ var SplitButton = ({ children, className, disabled, icon, items, onClick, varian
34
25
  items,
35
26
  trigger: /* @__PURE__ */ jsx("button", {
36
27
  "aria-labelledby": labelId,
28
+ "aria-haspopup": "menu",
37
29
  className: `chayns-split-button__trigger chayns-button--${variant}`,
38
30
  ...disabled ? { disabled: true } : {},
39
31
  type: "button",
@@ -45,7 +37,7 @@ var SplitButton = ({ children, className, disabled, icon, items, onClick, varian
45
37
  })
46
38
  })]
47
39
  });
48
- };
40
+ });
49
41
  //#endregion
50
42
  export { SplitButton as default };
51
43
 
@@ -1 +1 @@
1
- {"version":3,"file":"SplitButton.js","names":[],"sources":["../../../src/components/split-button/SplitButton.tsx"],"sourcesContent":["import { useId } from 'react';\n\nimport Button from '../button/Button.js';\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport PopupList from '../popup/PopupList.js';\nimport type { SplitButtonProps } from './SplitButton.types.js';\n\nconst SplitButton = ({\n children,\n className,\n disabled,\n icon,\n items,\n onClick,\n variant,\n ...containerProps\n}: SplitButtonProps) => {\n const labelId = useId();\n\n return (\n <div\n {...containerProps}\n className={['chayns-split-button', className].filter(Boolean).join(' ')}\n >\n {icon ? (\n <Button\n aria-labelledby={labelId}\n className=\"chayns-split-button__primary\"\n {...(disabled ? { disabled: true } : {})}\n icon={icon}\n {...(onClick ? { onClick } : {})}\n variant={variant}\n >\n <span id={labelId}>{children}</span>\n </Button>\n ) : (\n <Button\n aria-labelledby={labelId}\n className=\"chayns-split-button__primary\"\n {...(disabled ? { disabled: true } : {})}\n {...(onClick ? { onClick } : {})}\n variant={variant}\n >\n <span id={labelId}>{children}</span>\n </Button>\n )}\n <PopupList\n items={items}\n trigger={\n <button\n aria-labelledby={labelId}\n className={`chayns-split-button__trigger chayns-button--${variant}`}\n {...(disabled ? { disabled: true } : {})}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"chayns-split-button__chevron\">\n <ButtonIcon icon=\"fa-chevron-down\" />\n </span>\n </button>\n }\n />\n </div>\n );\n};\n\nexport default SplitButton;\n"],"mappings":";;;;;;AAOA,IAAM,eAAe,EACnB,UACA,WACA,UACA,MACA,OACA,SACA,SACA,GAAG,qBACmB;CACtB,MAAM,UAAU,MAAM;CAEtB,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,WAAW,CAAC,uBAAuB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAFxE,UAAA,CAIG,OACC,oBAAC,QAAD;GACE,mBAAiB;GACjB,WAAU;GACV,GAAK,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;GAChC;GACN,GAAK,UAAU,EAAE,QAAQ,IAAI,CAAC;GACrB;GAET,UAAA,oBAAC,QAAD;IAAM,IAAI;IAAU;GAAe,CAAA;EAC7B,CAAA,IAER,oBAAC,QAAD;GACE,mBAAiB;GACjB,WAAU;GACV,GAAK,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;GACtC,GAAK,UAAU,EAAE,QAAQ,IAAI,CAAC;GACrB;GAET,UAAA,oBAAC,QAAD;IAAM,IAAI;IAAU;GAAe,CAAA;EAC7B,CAAA,GAEV,oBAAC,WAAD;GACS;GACP,SACE,oBAAC,UAAD;IACE,mBAAiB;IACjB,WAAW,+CAA+C;IAC1D,GAAK,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,MAAK;IAEL,UAAA,oBAAC,QAAD;KAAM,eAAY;KAAO,WAAU;KACjC,UAAA,oBAAC,YAAD,EAAY,MAAK,kBAAmB,CAAA;IAChC,CAAA;GACA,CAAA;EAEX,CAAA,CACE;;AAET"}
1
+ {"version":3,"file":"SplitButton.js","names":[],"sources":["../../../src/components/split-button/SplitButton.tsx"],"sourcesContent":["import { forwardRef, useId } from 'react';\n\nimport Button from '../button/Button.js';\nimport ButtonIcon from '../button/button-icon/ButtonIcon.js';\nimport PopupList from '../popup/PopupList.js';\nimport type { SplitButtonProps } from './SplitButton.types.js';\n\nconst SplitButton = forwardRef<HTMLDivElement, SplitButtonProps>(function SplitButton(\n { children, className, disabled, icon, items, onClick, variant, ...containerProps },\n ref,\n) {\n const labelId = useId();\n\n return (\n <div\n {...containerProps}\n className={['chayns-split-button', className].filter(Boolean).join(' ')}\n ref={ref}\n >\n <Button\n aria-labelledby={labelId}\n className=\"chayns-split-button__primary\"\n disabled={disabled}\n {...(icon ? { icon } : {})}\n onClick={onClick}\n variant={variant}\n >\n <span id={labelId}>{children}</span>\n </Button>\n <PopupList\n items={items}\n trigger={\n <button\n aria-labelledby={labelId}\n aria-haspopup=\"menu\"\n className={`chayns-split-button__trigger chayns-button--${variant}`}\n {...(disabled ? { disabled: true } : {})}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"chayns-split-button__chevron\">\n <ButtonIcon icon=\"fa-chevron-down\" />\n </span>\n </button>\n }\n />\n </div>\n );\n});\n\nexport default SplitButton;\n"],"mappings":";;;;;;AAOA,IAAM,cAAc,WAA6C,SAAS,YACxE,EAAE,UAAU,WAAW,UAAU,MAAM,OAAO,SAAS,SAAS,GAAG,kBACnE,KACA;CACA,MAAM,UAAU,MAAM;CAEtB,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,WAAW,CAAC,uBAAuB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EACjE;EAHP,UAAA,CAKE,oBAAC,QAAD;GACE,mBAAiB;GACjB,WAAU;GACA;GACV,GAAK,OAAO,EAAE,KAAK,IAAI,CAAC;GACf;GACA;GAET,UAAA,oBAAC,QAAD;IAAM,IAAI;IAAU;GAAe,CAAA;EAC7B,CAAA,GACR,oBAAC,WAAD;GACS;GACP,SACE,oBAAC,UAAD;IACE,mBAAiB;IACjB,iBAAc;IACd,WAAW,+CAA+C;IAC1D,GAAK,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,MAAK;IAEL,UAAA,oBAAC,QAAD;KAAM,eAAY;KAAO,WAAU;KACjC,UAAA,oBAAC,YAAD,EAAY,MAAK,kBAAmB,CAAA;IAChC,CAAA;GACA,CAAA;EAEX,CAAA,CACE;;AAET,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import type { SwitchProps } from './Switch.types.js';
2
- declare function Switch({ children, className, ...inputProps }: SwitchProps): import("react").JSX.Element;
2
+ declare const Switch: import("react").ForwardRefExoticComponent<Omit<SwitchProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
3
3
  export default Switch;
4
4
  //# sourceMappingURL=Switch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../src/components/switch/Switch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,EAAE,WAAW,+BAYlE;AAED,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../src/components/switch/Switch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,QAAA,MAAM,MAAM,uHAoBV,CAAC;AAEH,eAAe,MAAM,CAAC"}