@sixthshift/design-system 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -12
- package/dist/components/Badge/Badge.d.ts +64 -9
- package/dist/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/Badge.js +54 -46
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/Badge/index.d.ts.map +1 -1
- package/dist/components/Badge/index.js +1 -1
- package/dist/components/Badge/index.js.map +1 -1
- package/dist/components/BarChart/BarChart.d.ts +12 -0
- package/dist/components/BarChart/BarChart.d.ts.map +1 -1
- package/dist/components/BarChart/BarChart.js +12 -0
- package/dist/components/BarChart/BarChart.js.map +1 -1
- package/dist/components/Button/Button.d.ts +85 -6
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +97 -106
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts +18 -4
- package/dist/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/components/Calendar/Calendar.js +19 -5
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/CalendarView.d.ts.map +1 -1
- package/dist/components/Calendar/CalendarView.js +10 -2
- package/dist/components/Calendar/CalendarView.js.map +1 -1
- package/dist/components/Calendar/calendar.types.d.ts +9 -0
- package/dist/components/Calendar/calendar.types.d.ts.map +1 -1
- package/dist/components/Card/Card.d.ts +61 -2
- package/dist/components/Card/Card.d.ts.map +1 -1
- package/dist/components/Card/Card.js +99 -3
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Card/index.d.ts +1 -1
- package/dist/components/Card/index.d.ts.map +1 -1
- package/dist/components/Card/index.js +1 -1
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +21 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +22 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +22 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.js +22 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
- package/dist/components/Code/Editor/Editor.js +2 -2
- package/dist/components/Code/Editor/Editor.js.map +1 -1
- package/dist/components/Code/Editor/themes.d.ts +2 -2
- package/dist/components/Code/Editor/themes.d.ts.map +1 -1
- package/dist/components/Code/Editor/themes.js +50 -32
- package/dist/components/Code/Editor/themes.js.map +1 -1
- package/dist/components/Code/ValidationStatus/ValidationStatus.d.ts.map +1 -1
- package/dist/components/Code/ValidationStatus/ValidationStatus.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +43 -0
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.js +166 -4
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DatePicker/DateSegments.d.ts +60 -0
- package/dist/components/DatePicker/DateSegments.d.ts.map +1 -0
- package/dist/components/DatePicker/DateSegments.js +80 -0
- package/dist/components/DatePicker/DateSegments.js.map +1 -0
- package/dist/components/DatePicker/datepicker.types.d.ts +19 -1
- package/dist/components/DatePicker/datepicker.types.d.ts.map +1 -1
- package/dist/components/DatePicker/index.d.ts +1 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +20 -2
- package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js +22 -4
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/DateRangePicker/daterangepicker.types.d.ts +6 -1
- package/dist/components/DateRangePicker/daterangepicker.types.d.ts.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +30 -2
- package/dist/components/DateTimePicker/DateTimePicker.d.ts.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.js +105 -32
- package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
- package/dist/components/DateTimePicker/DateTimeSegments.d.ts +41 -0
- package/dist/components/DateTimePicker/DateTimeSegments.d.ts.map +1 -0
- package/dist/components/DateTimePicker/DateTimeSegments.js +67 -0
- package/dist/components/DateTimePicker/DateTimeSegments.js.map +1 -0
- package/dist/components/DateTimePicker/datetimepicker.types.d.ts +6 -1
- package/dist/components/DateTimePicker/datetimepicker.types.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.d.ts +28 -2
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js +136 -58
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js.map +1 -1
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.d.ts +6 -1
- package/dist/components/DateTimeRangePicker/datetimerangepicker.types.d.ts.map +1 -1
- package/dist/components/Field/Field.d.ts +15 -17
- package/dist/components/Field/Field.d.ts.map +1 -1
- package/dist/components/Field/Field.js +18 -3
- package/dist/components/Field/Field.js.map +1 -1
- package/dist/components/FormField/FormField.d.ts +15 -0
- package/dist/components/FormField/FormField.d.ts.map +1 -1
- package/dist/components/FormField/FormField.js +15 -0
- package/dist/components/FormField/FormField.js.map +1 -1
- package/dist/components/HoverCard/HoverCard.d.ts +6 -0
- package/dist/components/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/components/HoverCard/HoverCard.js +6 -0
- package/dist/components/HoverCard/HoverCard.js.map +1 -1
- package/dist/components/Input/Input.d.ts +15 -0
- package/dist/components/Input/Input.d.ts.map +1 -1
- package/dist/components/Input/Input.js +18 -3
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/LineChart/LineChart.d.ts +17 -0
- package/dist/components/LineChart/LineChart.d.ts.map +1 -1
- package/dist/components/LineChart/LineChart.js +17 -0
- package/dist/components/LineChart/LineChart.js.map +1 -1
- package/dist/components/Markdown/Markdown.d.ts +17 -0
- package/dist/components/Markdown/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown/Markdown.js +17 -0
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Message/Message.d.ts +49 -4
- package/dist/components/Message/Message.d.ts.map +1 -1
- package/dist/components/Message/Message.js +53 -17
- package/dist/components/Message/Message.js.map +1 -1
- package/dist/components/Message/index.d.ts +1 -1
- package/dist/components/Message/index.d.ts.map +1 -1
- package/dist/components/Modal/Modal.d.ts +36 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -1
- package/dist/components/Modal/Modal.js +37 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Modal/components/ModalHeader.js +1 -1
- package/dist/components/Modal/components/ModalHeader.js.map +1 -1
- package/dist/components/Popover/Popover.d.ts +29 -0
- package/dist/components/Popover/Popover.d.ts.map +1 -1
- package/dist/components/Popover/Popover.js +29 -0
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.d.ts +14 -0
- package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.js +14 -0
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
- package/dist/components/RadioButton/RadioButton.d.ts +26 -0
- package/dist/components/RadioButton/RadioButton.d.ts.map +1 -1
- package/dist/components/RadioButton/RadioButton.js +35 -1
- package/dist/components/RadioButton/RadioButton.js.map +1 -1
- package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts +26 -0
- package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts.map +1 -1
- package/dist/components/RadioButtonGroup/RadioButtonGroup.js +33 -0
- package/dist/components/RadioButtonGroup/RadioButtonGroup.js.map +1 -1
- package/dist/components/SearchInput/SearchInput.d.ts +10 -0
- package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/components/SearchInput/SearchInput.js +12 -1
- package/dist/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/components/Select/Select.d.ts +4 -5
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +4 -5
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/SelectDropdown.d.ts.map +1 -1
- package/dist/components/Select/SelectDropdown.js +4 -3
- package/dist/components/Select/SelectDropdown.js.map +1 -1
- package/dist/components/Select/SelectTrigger.js +2 -2
- package/dist/components/Select/SelectTrigger.js.map +1 -1
- package/dist/components/Separator/Separator.d.ts +10 -0
- package/dist/components/Separator/Separator.d.ts.map +1 -1
- package/dist/components/Separator/Separator.js +10 -0
- package/dist/components/Separator/Separator.js.map +1 -1
- package/dist/components/Sheet/Sheet.d.ts +6 -0
- package/dist/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/components/Sheet/Sheet.js +7 -1
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Sheet/components/SheetFooter.js +1 -1
- package/dist/components/Sheet/components/SheetFooter.js.map +1 -1
- package/dist/components/Sheet/components/SheetHeader.js +1 -1
- package/dist/components/Sheet/components/SheetHeader.js.map +1 -1
- package/dist/components/Sparkline/Sparkline.d.ts +11 -0
- package/dist/components/Sparkline/Sparkline.d.ts.map +1 -1
- package/dist/components/Sparkline/Sparkline.js +11 -0
- package/dist/components/Sparkline/Sparkline.js.map +1 -1
- package/dist/components/Spinner/Spinner.d.ts +27 -2
- package/dist/components/Spinner/Spinner.d.ts.map +1 -1
- package/dist/components/Spinner/Spinner.js +28 -3
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/Switch/Switch.d.ts +18 -0
- package/dist/components/Switch/Switch.d.ts.map +1 -1
- package/dist/components/Switch/Switch.js +19 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Tabs/Tabs.d.ts +6 -0
- package/dist/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/Tabs/Tabs.js +6 -0
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tabs/components/TabsTrigger.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsTrigger.js +22 -6
- package/dist/components/Tabs/components/TabsTrigger.js.map +1 -1
- package/dist/components/TagChip/TagChip.d.ts +14 -12
- package/dist/components/TagChip/TagChip.d.ts.map +1 -1
- package/dist/components/TagChip/TagChip.js +14 -1
- package/dist/components/TagChip/TagChip.js.map +1 -1
- package/dist/components/TagInput/TagInput.d.ts +11 -8
- package/dist/components/TagInput/TagInput.d.ts.map +1 -1
- package/dist/components/TagInput/TagInput.js +11 -0
- package/dist/components/TagInput/TagInput.js.map +1 -1
- package/dist/components/Text/Text.d.ts +9 -0
- package/dist/components/Text/Text.d.ts.map +1 -1
- package/dist/components/Text/Text.js +9 -0
- package/dist/components/Text/Text.js.map +1 -1
- package/dist/components/TextInline/TextInline.d.ts +15 -4
- package/dist/components/TextInline/TextInline.d.ts.map +1 -1
- package/dist/components/TextInline/TextInline.js +11 -0
- package/dist/components/TextInline/TextInline.js.map +1 -1
- package/dist/components/Textarea/Textarea.d.ts +12 -0
- package/dist/components/Textarea/Textarea.d.ts.map +1 -1
- package/dist/components/Textarea/Textarea.js +13 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/TimePicker/TimeColumn.d.ts +10 -1
- package/dist/components/TimePicker/TimeColumn.d.ts.map +1 -1
- package/dist/components/TimePicker/TimeColumn.js +8 -1
- package/dist/components/TimePicker/TimeColumn.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.d.ts +32 -0
- package/dist/components/TimePicker/TimePicker.d.ts.map +1 -1
- package/dist/components/TimePicker/TimePicker.js +93 -6
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/TimePicker/TimeSegments.d.ts +50 -0
- package/dist/components/TimePicker/TimeSegments.d.ts.map +1 -0
- package/dist/components/TimePicker/TimeSegments.js +93 -0
- package/dist/components/TimePicker/TimeSegments.js.map +1 -0
- package/dist/components/TimePicker/timepicker.hooks.d.ts +0 -4
- package/dist/components/TimePicker/timepicker.hooks.d.ts.map +1 -1
- package/dist/components/TimePicker/timepicker.hooks.js +1 -23
- package/dist/components/TimePicker/timepicker.hooks.js.map +1 -1
- package/dist/components/TimePicker/timepicker.types.d.ts +0 -2
- package/dist/components/TimePicker/timepicker.types.d.ts.map +1 -1
- package/dist/components/Toast/Toast.d.ts +27 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/components/Toast/Toast.js +28 -1
- package/dist/components/Toast/Toast.js.map +1 -1
- package/dist/components/Toggle/Toggle.d.ts +31 -12
- package/dist/components/Toggle/Toggle.d.ts.map +1 -1
- package/dist/components/Toggle/Toggle.js +19 -31
- package/dist/components/Toggle/Toggle.js.map +1 -1
- package/dist/components/Toggle/index.d.ts +1 -1
- package/dist/components/Toggle/index.d.ts.map +1 -1
- package/dist/components/Toggle/index.js +1 -1
- package/dist/components/Toggle/index.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.d.ts +17 -0
- package/dist/components/ToggleGroup/ToggleGroup.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.js +17 -0
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.d.ts +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.js +7 -6
- package/dist/components/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts +4 -3
- package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupMultiple.js +2 -2
- package/dist/components/ToggleGroup/ToggleGroupMultiple.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts +4 -3
- package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupSingle.js +2 -2
- package/dist/components/ToggleGroup/ToggleGroupSingle.js.map +1 -1
- package/dist/components/ToggleGroup/toggleGroup.types.d.ts +12 -3
- package/dist/components/ToggleGroup/toggleGroup.types.d.ts.map +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +6 -0
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +6 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/date-time/index.d.ts.map +1 -1
- package/dist/date-time/index.js +0 -1
- package/dist/date-time/index.js.map +1 -1
- package/dist/internal/PickerField.d.ts +45 -0
- package/dist/internal/PickerField.d.ts.map +1 -0
- package/dist/internal/PickerField.js +24 -0
- package/dist/internal/PickerField.js.map +1 -0
- package/dist/internal/SegmentedField.d.ts +98 -0
- package/dist/internal/SegmentedField.d.ts.map +1 -0
- package/dist/internal/SegmentedField.js +315 -0
- package/dist/internal/SegmentedField.js.map +1 -0
- package/dist/internal/index.d.ts +2 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +2 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/OverlayContext.d.ts +2 -2
- package/dist/lib/contexts/OverlayContext/OverlayContext.d.ts.map +1 -1
- package/dist/lib/contexts/OverlayContext/OverlayContext.js +17 -6
- package/dist/lib/contexts/OverlayContext/OverlayContext.js.map +1 -1
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/schema.d.ts +0 -22
- package/dist/theme/schema.d.ts.map +1 -1
- package/dist/theme/schema.js +0 -9
- package/dist/theme/schema.js.map +1 -1
- package/package.json +7 -48
- package/src/components/Badge/Badge.tsx +85 -48
- package/src/components/Badge/index.ts +10 -1
- package/src/components/BarChart/BarChart.tsx +12 -0
- package/src/components/Button/Button.tsx +129 -106
- package/src/components/Button/index.ts +10 -1
- package/src/components/Calendar/Calendar.tsx +29 -16
- package/src/components/Calendar/CalendarView.tsx +10 -1
- package/src/components/Calendar/calendar.types.ts +10 -0
- package/src/components/Card/Card.tsx +114 -15
- package/src/components/Card/index.ts +1 -1
- package/src/components/Checkbox/Checkbox.tsx +22 -2
- package/src/components/CheckboxGroup/CheckboxGroup.tsx +22 -0
- package/src/components/Code/Editor/Editor.tsx +2 -2
- package/src/components/Code/Editor/themes.ts +50 -32
- package/src/components/Code/ValidationStatus/ValidationStatus.tsx +6 -3
- package/src/components/DatePicker/DatePicker.tsx +279 -28
- package/src/components/DatePicker/DateSegments.tsx +125 -0
- package/src/components/DatePicker/datepicker.types.ts +21 -1
- package/src/components/DatePicker/index.ts +8 -1
- package/src/components/DateRangePicker/DateRangePicker.tsx +22 -4
- package/src/components/DateRangePicker/daterangepicker.types.ts +7 -1
- package/src/components/DateTimePicker/DateTimePicker.tsx +143 -70
- package/src/components/DateTimePicker/DateTimeSegments.tsx +113 -0
- package/src/components/DateTimePicker/datetimepicker.types.ts +7 -1
- package/src/components/DateTimeRangePicker/DateTimeRangePicker.tsx +195 -104
- package/src/components/DateTimeRangePicker/datetimerangepicker.types.ts +7 -1
- package/src/components/Field/Field.tsx +20 -22
- package/src/components/FormField/FormField.tsx +15 -0
- package/src/components/HoverCard/HoverCard.tsx +6 -0
- package/src/components/Input/Input.tsx +19 -4
- package/src/components/LineChart/LineChart.tsx +17 -0
- package/src/components/Markdown/Markdown.tsx +17 -0
- package/src/components/Message/Message.tsx +73 -23
- package/src/components/Message/index.ts +1 -1
- package/src/components/Modal/Modal.tsx +42 -3
- package/src/components/Modal/components/ModalHeader.tsx +1 -1
- package/src/components/Popover/Popover.tsx +29 -0
- package/src/components/ProgressBar/ProgressBar.tsx +14 -0
- package/src/components/RadioButton/RadioButton.tsx +34 -3
- package/src/components/RadioButtonGroup/RadioButtonGroup.tsx +32 -0
- package/src/components/SearchInput/SearchInput.tsx +13 -2
- package/src/components/Select/Select.tsx +4 -5
- package/src/components/Select/SelectDropdown.tsx +13 -9
- package/src/components/Select/SelectTrigger.tsx +7 -7
- package/src/components/Separator/Separator.tsx +10 -0
- package/src/components/Sheet/Sheet.tsx +8 -2
- package/src/components/Sheet/components/SheetFooter.tsx +1 -1
- package/src/components/Sheet/components/SheetHeader.tsx +2 -2
- package/src/components/Sparkline/Sparkline.tsx +11 -0
- package/src/components/Spinner/Spinner.tsx +28 -3
- package/src/components/Switch/Switch.tsx +27 -4
- package/src/components/Tabs/Tabs.tsx +6 -0
- package/src/components/Tabs/components/TabsTrigger.tsx +22 -5
- package/src/components/TagChip/TagChip.tsx +18 -16
- package/src/components/TagInput/TagInput.tsx +11 -8
- package/src/components/Text/Text.tsx +9 -0
- package/src/components/TextInline/TextInline.tsx +11 -0
- package/src/components/Textarea/Textarea.tsx +13 -1
- package/src/components/TimePicker/TimeColumn.tsx +24 -1
- package/src/components/TimePicker/TimePicker.tsx +127 -39
- package/src/components/TimePicker/TimeSegments.tsx +131 -0
- package/src/components/TimePicker/timepicker.hooks.ts +1 -24
- package/src/components/TimePicker/timepicker.types.ts +0 -3
- package/src/components/Toast/Toast.tsx +28 -1
- package/src/components/Toggle/Toggle.tsx +34 -32
- package/src/components/Toggle/index.ts +1 -1
- package/src/components/ToggleGroup/ToggleGroup.tsx +17 -0
- package/src/components/ToggleGroup/ToggleGroupItem.tsx +13 -8
- package/src/components/ToggleGroup/ToggleGroupMultiple.tsx +3 -1
- package/src/components/ToggleGroup/ToggleGroupSingle.tsx +3 -1
- package/src/components/ToggleGroup/toggleGroup.types.ts +12 -3
- package/src/components/Tooltip/Tooltip.tsx +6 -0
- package/src/date-time/index.ts +0 -1
- package/src/internal/PickerField.tsx +90 -0
- package/src/internal/SegmentedField.tsx +445 -0
- package/src/internal/index.ts +2 -0
- package/src/lib/contexts/OverlayContext/OverlayContext.tsx +21 -10
- package/src/theme/index.ts +0 -6
- package/src/theme/recipes/badge.css +140 -0
- package/src/theme/recipes/button.css +167 -0
- package/src/theme/recipes/card.css +31 -0
- package/src/theme/recipes/checkbox.css +44 -0
- package/src/theme/recipes/field.css +14 -0
- package/src/theme/recipes/index.css +28 -0
- package/src/theme/recipes/input.css +29 -0
- package/src/theme/recipes/message.css +47 -0
- package/src/theme/recipes/modal.css +31 -0
- package/src/theme/recipes/radio-button.css +42 -0
- package/src/theme/recipes/search-input.css +16 -0
- package/src/theme/recipes/select.css +105 -0
- package/src/theme/recipes/sheet.css +34 -0
- package/src/theme/recipes/spinner.css +17 -0
- package/src/theme/recipes/switch.css +39 -0
- package/src/theme/recipes/tabs.css +41 -0
- package/src/theme/recipes/tag-chip.css +27 -0
- package/src/theme/recipes/textarea.css +20 -0
- package/src/theme/recipes/toggle.css +92 -0
- package/src/theme/schema.ts +0 -27
- package/src/theme/tokens.css +26 -9
- package/dist/components/Avatar/Avatar.d.ts +0 -6
- package/dist/components/Avatar/Avatar.d.ts.map +0 -1
- package/dist/components/Avatar/Avatar.js +0 -11
- package/dist/components/Avatar/Avatar.js.map +0 -1
- package/dist/components/Avatar/index.d.ts +0 -2
- package/dist/components/Avatar/index.d.ts.map +0 -1
- package/dist/components/Avatar/index.js +0 -2
- package/dist/components/Avatar/index.js.map +0 -1
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +0 -12
- package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +0 -1
- package/dist/components/Breadcrumb/Breadcrumb.js +0 -19
- package/dist/components/Breadcrumb/Breadcrumb.js.map +0 -1
- package/dist/components/Breadcrumb/index.d.ts +0 -2
- package/dist/components/Breadcrumb/index.d.ts.map +0 -1
- package/dist/components/Breadcrumb/index.js +0 -2
- package/dist/components/Breadcrumb/index.js.map +0 -1
- package/dist/components/ColorDot/ColorDot.d.ts +0 -19
- package/dist/components/ColorDot/ColorDot.d.ts.map +0 -1
- package/dist/components/ColorDot/ColorDot.js +0 -36
- package/dist/components/ColorDot/ColorDot.js.map +0 -1
- package/dist/components/ColorDot/index.d.ts +0 -2
- package/dist/components/ColorDot/index.d.ts.map +0 -1
- package/dist/components/ColorDot/index.js +0 -2
- package/dist/components/ColorDot/index.js.map +0 -1
- package/dist/components/EmptyState/EmptyState.d.ts +0 -26
- package/dist/components/EmptyState/EmptyState.d.ts.map +0 -1
- package/dist/components/EmptyState/EmptyState.js +0 -9
- package/dist/components/EmptyState/EmptyState.js.map +0 -1
- package/dist/components/EmptyState/index.d.ts +0 -2
- package/dist/components/EmptyState/index.d.ts.map +0 -1
- package/dist/components/EmptyState/index.js +0 -2
- package/dist/components/EmptyState/index.js.map +0 -1
- package/dist/components/HeatMap/HeatMapCalendar.d.ts +0 -11
- package/dist/components/HeatMap/HeatMapCalendar.d.ts.map +0 -1
- package/dist/components/HeatMap/HeatMapCalendar.js +0 -68
- package/dist/components/HeatMap/HeatMapCalendar.js.map +0 -1
- package/dist/components/HeatMap/HeatMapMatrix.d.ts +0 -12
- package/dist/components/HeatMap/HeatMapMatrix.d.ts.map +0 -1
- package/dist/components/HeatMap/HeatMapMatrix.js +0 -35
- package/dist/components/HeatMap/HeatMapMatrix.js.map +0 -1
- package/dist/components/HeatMap/heat-map.utils.d.ts +0 -10
- package/dist/components/HeatMap/heat-map.utils.d.ts.map +0 -1
- package/dist/components/HeatMap/heat-map.utils.js +0 -10
- package/dist/components/HeatMap/heat-map.utils.js.map +0 -1
- package/dist/components/HeatMap/index.d.ts +0 -4
- package/dist/components/HeatMap/index.d.ts.map +0 -1
- package/dist/components/HeatMap/index.js +0 -3
- package/dist/components/HeatMap/index.js.map +0 -1
- package/dist/components/MetricList/MetricList.d.ts +0 -9
- package/dist/components/MetricList/MetricList.d.ts.map +0 -1
- package/dist/components/MetricList/MetricList.js +0 -8
- package/dist/components/MetricList/MetricList.js.map +0 -1
- package/dist/components/MetricList/MetricRow.d.ts +0 -13
- package/dist/components/MetricList/MetricRow.d.ts.map +0 -1
- package/dist/components/MetricList/MetricRow.js +0 -13
- package/dist/components/MetricList/MetricRow.js.map +0 -1
- package/dist/components/MetricList/index.d.ts +0 -3
- package/dist/components/MetricList/index.d.ts.map +0 -1
- package/dist/components/MetricList/index.js +0 -3
- package/dist/components/MetricList/index.js.map +0 -1
- package/dist/components/NavBottom/NavBottom.d.ts +0 -16
- package/dist/components/NavBottom/NavBottom.d.ts.map +0 -1
- package/dist/components/NavBottom/NavBottom.js +0 -21
- package/dist/components/NavBottom/NavBottom.js.map +0 -1
- package/dist/components/NavBottom/index.d.ts +0 -3
- package/dist/components/NavBottom/index.d.ts.map +0 -1
- package/dist/components/NavBottom/index.js +0 -2
- package/dist/components/NavBottom/index.js.map +0 -1
- package/dist/components/NavSide/NavItem.d.ts +0 -9
- package/dist/components/NavSide/NavItem.d.ts.map +0 -1
- package/dist/components/NavSide/NavItem.js +0 -13
- package/dist/components/NavSide/NavItem.js.map +0 -1
- package/dist/components/NavSide/NavSide.d.ts +0 -16
- package/dist/components/NavSide/NavSide.d.ts.map +0 -1
- package/dist/components/NavSide/NavSide.js +0 -12
- package/dist/components/NavSide/NavSide.js.map +0 -1
- package/dist/components/NavSide/index.d.ts +0 -3
- package/dist/components/NavSide/index.d.ts.map +0 -1
- package/dist/components/NavSide/index.js +0 -2
- package/dist/components/NavSide/index.js.map +0 -1
- package/dist/components/NavSide/types.d.ts +0 -38
- package/dist/components/NavSide/types.d.ts.map +0 -1
- package/dist/components/NavSide/types.js +0 -2
- package/dist/components/NavSide/types.js.map +0 -1
- package/dist/components/Pagination/Pagination.d.ts +0 -35
- package/dist/components/Pagination/Pagination.d.ts.map +0 -1
- package/dist/components/Pagination/Pagination.js +0 -26
- package/dist/components/Pagination/Pagination.js.map +0 -1
- package/dist/components/Pagination/index.d.ts +0 -3
- package/dist/components/Pagination/index.d.ts.map +0 -1
- package/dist/components/Pagination/index.js +0 -2
- package/dist/components/Pagination/index.js.map +0 -1
- package/dist/components/Skeleton/Skeleton.d.ts +0 -4
- package/dist/components/Skeleton/Skeleton.d.ts.map +0 -1
- package/dist/components/Skeleton/Skeleton.js +0 -9
- package/dist/components/Skeleton/Skeleton.js.map +0 -1
- package/dist/components/Skeleton/index.d.ts +0 -2
- package/dist/components/Skeleton/index.d.ts.map +0 -1
- package/dist/components/Skeleton/index.js +0 -2
- package/dist/components/Skeleton/index.js.map +0 -1
- package/dist/components/StatsCard/StatsCard.d.ts +0 -17
- package/dist/components/StatsCard/StatsCard.d.ts.map +0 -1
- package/dist/components/StatsCard/StatsCard.js +0 -15
- package/dist/components/StatsCard/StatsCard.js.map +0 -1
- package/dist/components/StatsCard/index.d.ts +0 -2
- package/dist/components/StatsCard/index.d.ts.map +0 -1
- package/dist/components/StatsCard/index.js +0 -2
- package/dist/components/StatsCard/index.js.map +0 -1
- package/src/components/Avatar/Avatar.tsx +0 -19
- package/src/components/Avatar/index.ts +0 -1
- package/src/components/Breadcrumb/Breadcrumb.tsx +0 -47
- package/src/components/Breadcrumb/index.ts +0 -5
- package/src/components/ColorDot/ColorDot.tsx +0 -52
- package/src/components/ColorDot/index.ts +0 -1
- package/src/components/EmptyState/EmptyState.tsx +0 -30
- package/src/components/EmptyState/index.ts +0 -1
- package/src/components/HeatMap/HeatMapCalendar.tsx +0 -127
- package/src/components/HeatMap/HeatMapMatrix.tsx +0 -75
- package/src/components/HeatMap/heat-map.utils.ts +0 -15
- package/src/components/HeatMap/index.ts +0 -3
- package/src/components/MetricList/MetricList.tsx +0 -18
- package/src/components/MetricList/MetricRow.tsx +0 -30
- package/src/components/MetricList/index.ts +0 -2
- package/src/components/NavBottom/NavBottom.tsx +0 -55
- package/src/components/NavBottom/index.ts +0 -3
- package/src/components/NavSide/NavItem.tsx +0 -39
- package/src/components/NavSide/NavSide.tsx +0 -42
- package/src/components/NavSide/index.ts +0 -2
- package/src/components/NavSide/types.ts +0 -36
- package/src/components/Pagination/Pagination.tsx +0 -86
- package/src/components/Pagination/index.ts +0 -2
- package/src/components/Skeleton/Skeleton.tsx +0 -9
- package/src/components/Skeleton/index.ts +0 -1
- package/src/components/StatsCard/StatsCard.tsx +0 -41
- package/src/components/StatsCard/index.ts +0 -1
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { cn } from "@sixthshift/design-system/utils";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { useRef, useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One segment of a segmented field.
|
|
7
|
+
*
|
|
8
|
+
* `numeric` covers everything that is typed as digits — a month, an hour, a
|
|
9
|
+
* year. `choice` covers a segment with a fixed vocabulary, which in practice
|
|
10
|
+
* means AM/PM: it holds the index of an option, is typed by first letter, and
|
|
11
|
+
* announces the word rather than the number.
|
|
12
|
+
*/
|
|
13
|
+
export type SegmentSpec =
|
|
14
|
+
| {
|
|
15
|
+
kind?: "numeric";
|
|
16
|
+
/** Key in the values record. */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Accessible name, e.g. `"Month"`. */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Shown when empty, e.g. `"mm"`. */
|
|
21
|
+
placeholder: string;
|
|
22
|
+
/** Width in digits: 2 for a month, 4 for a year. */
|
|
23
|
+
digits: number;
|
|
24
|
+
min: number;
|
|
25
|
+
max: number;
|
|
26
|
+
/** Rendered before this segment, e.g. `"/"` or `":"`. */
|
|
27
|
+
separatorBefore?: string | undefined;
|
|
28
|
+
/** Where an arrow key starts from when the segment is empty. */
|
|
29
|
+
stepFrom?: number | undefined;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
kind: "choice";
|
|
33
|
+
name: string;
|
|
34
|
+
label: string;
|
|
35
|
+
placeholder: string;
|
|
36
|
+
/** Ordered vocabulary; the segment's value is an index into it. */
|
|
37
|
+
options: string[];
|
|
38
|
+
separatorBefore?: string | undefined;
|
|
39
|
+
stepFrom?: number | undefined;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Segment values by name. `null` is "nothing typed yet". */
|
|
43
|
+
export type SegmentValues = Record<string, number | null>;
|
|
44
|
+
|
|
45
|
+
export type SegmentedFieldProps<T> = {
|
|
46
|
+
spec: SegmentSpec[];
|
|
47
|
+
/** The value the segments display. `undefined` leaves them empty. */
|
|
48
|
+
value: T | undefined;
|
|
49
|
+
/** Split a value into segments. */
|
|
50
|
+
toSegments: (value: T | undefined) => SegmentValues;
|
|
51
|
+
/** Build a value from a complete set of segments. May normalise (clamp a day). */
|
|
52
|
+
fromSegments: (values: Record<string, number>) => T;
|
|
53
|
+
/** Stable identity for a value — how an echo is told from a real change. */
|
|
54
|
+
keyOf: (value: T) => string;
|
|
55
|
+
/**
|
|
56
|
+
* Fires with a whole value, or `undefined` the moment the segments stop
|
|
57
|
+
* describing one. Never fires a partial value, and never mid-number.
|
|
58
|
+
*/
|
|
59
|
+
onChange: (value: T | undefined) => void;
|
|
60
|
+
/** Read a pasted string into segments. Omit to ignore pastes. */
|
|
61
|
+
parsePaste?: ((text: string) => SegmentValues | null) | undefined;
|
|
62
|
+
/** Accessible name for the group. */
|
|
63
|
+
label: string;
|
|
64
|
+
isDisabled?: boolean | undefined;
|
|
65
|
+
isInvalid?: boolean | undefined;
|
|
66
|
+
/** `Alt+ArrowDown` — the combobox convention for "open the popup". */
|
|
67
|
+
onOpenRequest?: (() => void) | undefined;
|
|
68
|
+
/** `Enter` — the caller decides whether that commits, submits or nothing. */
|
|
69
|
+
onSubmit?: (() => void) | undefined;
|
|
70
|
+
id?: string | undefined;
|
|
71
|
+
className?: string | undefined;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
type Limits = { min: number; max: number; digits: number };
|
|
75
|
+
|
|
76
|
+
function limitsOf(segment: SegmentSpec): Limits {
|
|
77
|
+
if (segment.kind === "choice") {
|
|
78
|
+
// `digits: 0` is what makes a digit roll straight past AM/PM instead of
|
|
79
|
+
// being swallowed by it.
|
|
80
|
+
return { min: 0, max: segment.options.length - 1, digits: 0 };
|
|
81
|
+
}
|
|
82
|
+
return { min: segment.min, max: segment.max, digits: segment.digits };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const pad = (value: number, digits: number) => String(value).padStart(digits, "0");
|
|
86
|
+
|
|
87
|
+
function displayOf(segment: SegmentSpec, current: number | null, typed: string): string {
|
|
88
|
+
if (typed !== "") return typed;
|
|
89
|
+
if (current === null) return segment.placeholder;
|
|
90
|
+
if (segment.kind === "choice") return segment.options[current] ?? segment.placeholder;
|
|
91
|
+
return pad(current, segment.digits);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A typeable field made of spinbutton segments — the shared keyboard model
|
|
96
|
+
* behind every picker's trigger.
|
|
97
|
+
*
|
|
98
|
+
* Segments rather than a text box and a parser: `08/09` cannot be read without
|
|
99
|
+
* knowing the order, and a parser that guesses is wrong for half the world. A
|
|
100
|
+
* labelled `Month` spinbutton cannot be misread, and it displays in exactly the
|
|
101
|
+
* format it accepts, so there is no reformat-on-blur surprise.
|
|
102
|
+
*
|
|
103
|
+
* The behaviour that makes it typeable rather than merely focusable:
|
|
104
|
+
*
|
|
105
|
+
* - **A digit that cannot extend the current segment rolls into the next one.**
|
|
106
|
+
* `152026` in an `mdy` field is January the 5th 2026. Restarting the segment
|
|
107
|
+
* instead — the obvious implementation — silently turns January into May and
|
|
108
|
+
* eats the day, which is what makes a segmented field feel broken.
|
|
109
|
+
* - **Separators advance.** `1/5/2026` typed literally works, because `/` is how
|
|
110
|
+
* a person says "done with this one".
|
|
111
|
+
* - **`Backspace` takes back one digit**, then clears the segment, then steps
|
|
112
|
+
* back to the previous one — the only keyboard route to a segment the digits
|
|
113
|
+
* have already advanced past.
|
|
114
|
+
* - **A click anywhere in the field focuses a segment**, the way clicking a text
|
|
115
|
+
* input anywhere gives it a caret.
|
|
116
|
+
* - **`onChange` is held while a number is still being typed.** A year arrives
|
|
117
|
+
* one digit at a time, and `2` is the start of 2026, not the year 2. Deferred
|
|
118
|
+
* edits flush on blur.
|
|
119
|
+
*
|
|
120
|
+
* Values are the caller's own type; `toSegments`/`fromSegments` are the codec
|
|
121
|
+
* and `keyOf` supplies identity, which Temporal objects do not have.
|
|
122
|
+
*
|
|
123
|
+
* Internal. Not exported from the package.
|
|
124
|
+
*/
|
|
125
|
+
export function SegmentedField<T>({
|
|
126
|
+
spec,
|
|
127
|
+
value,
|
|
128
|
+
toSegments,
|
|
129
|
+
fromSegments,
|
|
130
|
+
keyOf,
|
|
131
|
+
onChange,
|
|
132
|
+
parsePaste,
|
|
133
|
+
label,
|
|
134
|
+
isDisabled = false,
|
|
135
|
+
isInvalid = false,
|
|
136
|
+
onOpenRequest,
|
|
137
|
+
onSubmit,
|
|
138
|
+
id,
|
|
139
|
+
className,
|
|
140
|
+
}: SegmentedFieldProps<T>) {
|
|
141
|
+
const names = spec.map((segment) => segment.name);
|
|
142
|
+
const bySpec = (name: string) => spec.find((segment) => segment.name === name)!;
|
|
143
|
+
// `!= null` rather than `!== null`: a key the codec forgot to set would be
|
|
144
|
+
// `undefined`, which a `!== null` test would count as filled — and hand
|
|
145
|
+
// `fromSegments` a NaN.
|
|
146
|
+
const isComplete = (values: SegmentValues) => names.every((name) => values[name] != null);
|
|
147
|
+
|
|
148
|
+
const [segments, setSegments] = useState<SegmentValues>(() => toSegments(value));
|
|
149
|
+
|
|
150
|
+
// Props win, except over the value this field just emitted. Comparing a caller
|
|
151
|
+
// supplied key rather than the value itself matters twice: Temporal has no
|
|
152
|
+
// value identity, and an echoed-back value must not restart the user's edit.
|
|
153
|
+
const valueKey = value === undefined ? "" : keyOf(value);
|
|
154
|
+
const syncedKey = useRef(valueKey);
|
|
155
|
+
if (valueKey !== syncedKey.current) {
|
|
156
|
+
syncedKey.current = valueKey;
|
|
157
|
+
setSegments(toSegments(value));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// The digits typed into the segment being filled. State rather than a ref
|
|
161
|
+
// because it is rendered: a year mid-typing shows `202`, not `0202`.
|
|
162
|
+
const [buffer, setBuffer] = useState<{ segment: string; text: string } | null>(null);
|
|
163
|
+
const nodes = useRef<Record<string, HTMLSpanElement | null>>({});
|
|
164
|
+
const hadValue = useRef(isComplete(toSegments(value)));
|
|
165
|
+
|
|
166
|
+
const focusSegment = (name: string | undefined) => {
|
|
167
|
+
if (name) nodes.current[name]?.focus();
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const publish = (next: SegmentValues) => {
|
|
171
|
+
if (!isComplete(next)) {
|
|
172
|
+
if (hadValue.current) {
|
|
173
|
+
hadValue.current = false;
|
|
174
|
+
// Pre-empt the sync for the cleared value too. Without this, emptying
|
|
175
|
+
// one segment round-trips as `undefined` and wipes the others — the
|
|
176
|
+
// user cleared the day, not the whole date. A controlled caller that
|
|
177
|
+
// *rejects* the clear still wins: its value no longer matches this
|
|
178
|
+
// key, so the next render syncs back to it.
|
|
179
|
+
syncedKey.current = "";
|
|
180
|
+
onChange(undefined);
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const composed = fromSegments(next as Record<string, number>);
|
|
185
|
+
const key = keyOf(composed);
|
|
186
|
+
|
|
187
|
+
// `fromSegments` may normalise — February the 31st is the 28th — so the
|
|
188
|
+
// segments follow the value rather than the keystrokes. Otherwise the
|
|
189
|
+
// field reads 02/31 while the value says the 28th.
|
|
190
|
+
const normalised = toSegments(composed);
|
|
191
|
+
if (names.some((name) => normalised[name] !== next[name])) setSegments(normalised);
|
|
192
|
+
|
|
193
|
+
if (key === syncedKey.current) return;
|
|
194
|
+
hadValue.current = true;
|
|
195
|
+
syncedKey.current = key;
|
|
196
|
+
onChange(composed);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* `defer` holds the announcement while a number is still being typed, so a
|
|
201
|
+
* controlled caller is not handed `0002-12-25`, `0020-12-25`, `0202-12-25` in
|
|
202
|
+
* a row — and anything validating against a bound does not flash mid-word.
|
|
203
|
+
*/
|
|
204
|
+
const commit = (next: SegmentValues, defer = false) => {
|
|
205
|
+
setSegments(next);
|
|
206
|
+
if (!defer) publish(next);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const applyDigit = (name: string, digit: string) => {
|
|
210
|
+
let target = name;
|
|
211
|
+
let started = buffer?.segment === name ? buffer.text : "";
|
|
212
|
+
|
|
213
|
+
// At most one hop per digit in practice; bounded so a bad spec cannot spin.
|
|
214
|
+
for (let hop = 0; hop <= spec.length; hop++) {
|
|
215
|
+
const { max, digits } = limitsOf(bySpec(target));
|
|
216
|
+
const combined = started + digit;
|
|
217
|
+
const next = names[names.indexOf(target) + 1];
|
|
218
|
+
|
|
219
|
+
if (digits > 0 && Number(combined) <= max && combined.length <= digits) {
|
|
220
|
+
const numeric = Number(combined);
|
|
221
|
+
const full = combined.length >= digits || numeric * 10 > max;
|
|
222
|
+
setBuffer(full ? null : { segment: target, text: combined });
|
|
223
|
+
commit({ ...segments, [target]: numeric === 0 && limitsOf(bySpec(target)).min > 0 ? null : numeric }, !full);
|
|
224
|
+
focusSegment(full ? next : target);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!next) {
|
|
229
|
+
if (digits === 0) return; // a choice segment takes no digits
|
|
230
|
+
setBuffer({ segment: target, text: digit });
|
|
231
|
+
commit({ ...segments, [target]: Number(digit) === 0 ? null : Number(digit) });
|
|
232
|
+
focusSegment(target);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
target = next;
|
|
237
|
+
started = "";
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/** A letter picks a `choice` option by first letter — `a` for AM, `p` for PM. */
|
|
242
|
+
const applyLetter = (name: string, letter: string) => {
|
|
243
|
+
const segment = bySpec(name);
|
|
244
|
+
if (segment.kind !== "choice") return false;
|
|
245
|
+
const index = segment.options.findIndex((option) => option.toLowerCase().startsWith(letter.toLowerCase()));
|
|
246
|
+
if (index === -1) return false;
|
|
247
|
+
setBuffer(null);
|
|
248
|
+
commit({ ...segments, [name]: index });
|
|
249
|
+
focusSegment(names[names.indexOf(name) + 1]);
|
|
250
|
+
return true;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const step = (name: string, delta: number) => {
|
|
254
|
+
const segment = bySpec(name);
|
|
255
|
+
const { min, max } = limitsOf(segment);
|
|
256
|
+
const current = segments[name];
|
|
257
|
+
if (current === null || current === undefined) {
|
|
258
|
+
commit({ ...segments, [name]: segment.stepFrom ?? min });
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
let next = current + delta;
|
|
262
|
+
// Cyclic fields wrap, which is what an arrow key means on a month or an
|
|
263
|
+
// hour. A year does not — 9999 to 1 is never the intent — and it says so
|
|
264
|
+
// by spanning more than two digits.
|
|
265
|
+
const cyclic = segment.kind === "choice" || limitsOf(segment).digits <= 2;
|
|
266
|
+
if (!cyclic) next = Math.min(Math.max(next, min), max);
|
|
267
|
+
else if (next > max) next = min;
|
|
268
|
+
else if (next < min) next = max;
|
|
269
|
+
commit({ ...segments, [name]: next });
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLSpanElement>, name: string) => {
|
|
273
|
+
if (isDisabled) return;
|
|
274
|
+
|
|
275
|
+
if (event.altKey && event.key === "ArrowDown") {
|
|
276
|
+
event.preventDefault();
|
|
277
|
+
onOpenRequest?.();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const plain = !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
282
|
+
|
|
283
|
+
if (plain && /^[0-9]$/.test(event.key)) {
|
|
284
|
+
event.preventDefault();
|
|
285
|
+
applyDigit(name, event.key);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (plain && /^[a-z]$/i.test(event.key) && applyLetter(name, event.key)) {
|
|
290
|
+
event.preventDefault();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Any plausible separator counts, whatever this field's own separators
|
|
295
|
+
// are: it means "done with this one", and without it a typed `/` is
|
|
296
|
+
// swallowed and the next digit lands on the wrong segment.
|
|
297
|
+
//
|
|
298
|
+
// Only with a number still in progress, though. A segment that already
|
|
299
|
+
// filled up has advanced on its own, and treating the separator as a second
|
|
300
|
+
// advance would skip the segment after it: typing `1/6/2026` would land 2026
|
|
301
|
+
// in the hour, because the `6` had already moved on.
|
|
302
|
+
if (plain && ["/", "-", ".", ",", ":", " "].includes(event.key)) {
|
|
303
|
+
event.preventDefault();
|
|
304
|
+
if (buffer?.segment !== name) return;
|
|
305
|
+
setBuffer(null);
|
|
306
|
+
focusSegment(names[names.indexOf(name) + 1]);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
switch (event.key) {
|
|
311
|
+
case "ArrowUp":
|
|
312
|
+
event.preventDefault();
|
|
313
|
+
setBuffer(null);
|
|
314
|
+
step(name, 1);
|
|
315
|
+
break;
|
|
316
|
+
case "ArrowDown":
|
|
317
|
+
event.preventDefault();
|
|
318
|
+
setBuffer(null);
|
|
319
|
+
step(name, -1);
|
|
320
|
+
break;
|
|
321
|
+
case "ArrowLeft":
|
|
322
|
+
event.preventDefault();
|
|
323
|
+
setBuffer(null);
|
|
324
|
+
focusSegment(names[names.indexOf(name) - 1]);
|
|
325
|
+
break;
|
|
326
|
+
case "ArrowRight":
|
|
327
|
+
event.preventDefault();
|
|
328
|
+
setBuffer(null);
|
|
329
|
+
focusSegment(names[names.indexOf(name) + 1]);
|
|
330
|
+
break;
|
|
331
|
+
case "Backspace": {
|
|
332
|
+
event.preventDefault();
|
|
333
|
+
const typed = buffer?.segment === name ? buffer.text : "";
|
|
334
|
+
if (typed.length > 1) {
|
|
335
|
+
const text = typed.slice(0, -1);
|
|
336
|
+
setBuffer({ segment: name, text });
|
|
337
|
+
commit({ ...segments, [name]: Number(text) === 0 ? null : Number(text) }, true);
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
setBuffer(null);
|
|
341
|
+
if (typed.length === 0 && segments[name] === null) {
|
|
342
|
+
focusSegment(names[names.indexOf(name) - 1]);
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
commit({ ...segments, [name]: null });
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
case "Delete":
|
|
349
|
+
event.preventDefault();
|
|
350
|
+
setBuffer(null);
|
|
351
|
+
commit({ ...segments, [name]: null });
|
|
352
|
+
break;
|
|
353
|
+
case "Enter":
|
|
354
|
+
event.preventDefault();
|
|
355
|
+
onSubmit?.();
|
|
356
|
+
break;
|
|
357
|
+
default:
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const handlePaste = (event: React.ClipboardEvent<HTMLFieldSetElement>) => {
|
|
363
|
+
if (isDisabled || !parsePaste) return;
|
|
364
|
+
event.preventDefault();
|
|
365
|
+
const parsed = parsePaste(event.clipboardData.getData("text").trim());
|
|
366
|
+
if (!parsed) return;
|
|
367
|
+
setBuffer(null);
|
|
368
|
+
commit(parsed);
|
|
369
|
+
focusSegment(names[names.length - 1]);
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
// A `fieldset` rather than a `div role="group"`: the segments are one
|
|
374
|
+
// related set of controls, which is the element's whole job. Tailwind's
|
|
375
|
+
// preflight already strips its default margin, padding and border.
|
|
376
|
+
<fieldset
|
|
377
|
+
id={id}
|
|
378
|
+
aria-label={label}
|
|
379
|
+
aria-invalid={isInvalid || undefined}
|
|
380
|
+
aria-disabled={isDisabled || undefined}
|
|
381
|
+
onMouseDown={(event) => {
|
|
382
|
+
// A click anywhere in the field focuses a segment, the way clicking a
|
|
383
|
+
// text input anywhere puts a caret in it. Without this, only the digits
|
|
384
|
+
// themselves are clickable and the rest of the box silently does
|
|
385
|
+
// nothing — which reads as "typing is broken", because nothing has focus.
|
|
386
|
+
if (isDisabled) return;
|
|
387
|
+
if ((event.target as HTMLElement).closest("[data-segment]")) return;
|
|
388
|
+
event.preventDefault();
|
|
389
|
+
focusSegment(names.find((name) => segments[name] === null) ?? names[0]);
|
|
390
|
+
}}
|
|
391
|
+
onPaste={handlePaste}
|
|
392
|
+
onBlur={(event) => {
|
|
393
|
+
// Only when focus leaves the field entirely — moving between segments is
|
|
394
|
+
// a blur too, and mid-edit is not the moment to announce anything.
|
|
395
|
+
if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;
|
|
396
|
+
// A live buffer is exactly the condition under which a commit was
|
|
397
|
+
// deferred, so it is the only case with anything to flush.
|
|
398
|
+
if (!buffer) return;
|
|
399
|
+
setBuffer(null);
|
|
400
|
+
publish(segments);
|
|
401
|
+
}}
|
|
402
|
+
className={cn("flex flex-1 cursor-text items-center gap-0.5 text-sm", isDisabled && "opacity-50", className)}
|
|
403
|
+
>
|
|
404
|
+
{spec.map((segment) => {
|
|
405
|
+
const current = segments[segment.name] ?? null;
|
|
406
|
+
const { min, max } = limitsOf(segment);
|
|
407
|
+
const typed = buffer?.segment === segment.name ? buffer.text : "";
|
|
408
|
+
const text = displayOf(segment, current, typed);
|
|
409
|
+
return (
|
|
410
|
+
<React.Fragment key={segment.name}>
|
|
411
|
+
{segment.separatorBefore && (
|
|
412
|
+
<span aria-hidden="true" className="text-fg-subtle">
|
|
413
|
+
{segment.separatorBefore}
|
|
414
|
+
</span>
|
|
415
|
+
)}
|
|
416
|
+
<span
|
|
417
|
+
ref={(node) => {
|
|
418
|
+
nodes.current[segment.name] = node;
|
|
419
|
+
}}
|
|
420
|
+
role="spinbutton"
|
|
421
|
+
tabIndex={isDisabled ? -1 : 0}
|
|
422
|
+
aria-label={segment.label}
|
|
423
|
+
aria-valuemin={min}
|
|
424
|
+
aria-valuemax={max}
|
|
425
|
+
aria-valuenow={current ?? undefined}
|
|
426
|
+
aria-valuetext={current === null ? "Empty" : text}
|
|
427
|
+
aria-disabled={isDisabled || undefined}
|
|
428
|
+
data-segment={segment.name}
|
|
429
|
+
onKeyDown={(event) => handleKeyDown(event, segment.name)}
|
|
430
|
+
onFocus={() => {
|
|
431
|
+
if (buffer?.segment !== segment.name) setBuffer(null);
|
|
432
|
+
}}
|
|
433
|
+
className={cn(
|
|
434
|
+
"cursor-text rounded-sm px-0.5 tabular-nums outline-hidden focus:bg-bg-brand-subtle focus:text-fg-on-brand-subtle",
|
|
435
|
+
current === null && "text-fg-subtle"
|
|
436
|
+
)}
|
|
437
|
+
>
|
|
438
|
+
{text}
|
|
439
|
+
</span>
|
|
440
|
+
</React.Fragment>
|
|
441
|
+
);
|
|
442
|
+
})}
|
|
443
|
+
</fieldset>
|
|
444
|
+
);
|
|
445
|
+
}
|
package/src/internal/index.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
export { PickerField, type PickerFieldProps } from "./PickerField";
|
|
2
|
+
export { SegmentedField, type SegmentedFieldProps, type SegmentSpec, type SegmentValues } from "./SegmentedField";
|
|
1
3
|
export { Slot, type SlotProps } from "./Slot";
|
|
2
4
|
export type { WritableRefObject } from "./types";
|
|
@@ -18,19 +18,30 @@ type OverlayStackItem = StackItem & {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
type OverlayContextType = {
|
|
21
|
-
modalRoot
|
|
21
|
+
modalRoot?: FloatingPortalProps["root"];
|
|
22
22
|
modalStack: ReturnType<typeof useStack<OverlayStackItem>>;
|
|
23
|
-
toastRoot
|
|
23
|
+
toastRoot?: FloatingPortalProps["root"];
|
|
24
24
|
toastStack: ReturnType<typeof useStack<OverlayStackItem>>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* `root` omitted when the caller gave none, rather than passed as `undefined`
|
|
29
|
+
* or `null`. The distinction is load-bearing: `FloatingPortal` bails out of
|
|
30
|
+
* creating its portal node entirely on an explicit `null` ("wait for the root
|
|
31
|
+
* to exist"), and only a missing `root` falls through to `document.body`.
|
|
32
|
+
*/
|
|
33
|
+
const rootProp = (root: FloatingPortalProps["root"] | undefined) => (root === undefined ? {} : { root });
|
|
34
|
+
|
|
27
35
|
const OverlayContext = createContext<OverlayContextType>(undefined as unknown as OverlayContextType);
|
|
28
36
|
export const useOverlayContext = () => useContext(OverlayContext);
|
|
29
37
|
|
|
30
38
|
export const OverlayProvider = ({ modal: modalRoot, toast: toastRoot, children }: PropsWithChildren<OverlayContextProps>) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
// The roots pass through unresolved, deliberately. Defaulting them to
|
|
40
|
+
// `document.body` here read the DOM during render, which threw the whole
|
|
41
|
+
// tree under SSR — and it bought nothing: `FloatingPortal` already falls
|
|
42
|
+
// back to `document.body` when no `root` is given, on the client, where a
|
|
43
|
+
// body exists. Both portals below are behind a non-empty stack, and both
|
|
44
|
+
// stacks start empty, so nothing portals on the server either way.
|
|
34
45
|
const modalStack = useStack<OverlayStackItem>([]);
|
|
35
46
|
const toastStack = useStack<OverlayStackItem>([]);
|
|
36
47
|
|
|
@@ -55,12 +66,12 @@ export const OverlayProvider = ({ modal: modalRoot, toast: toastRoot, children }
|
|
|
55
66
|
// Memoize context value to prevent unnecessary re-renders in consumers
|
|
56
67
|
const contextValue = useMemo(
|
|
57
68
|
() => ({
|
|
58
|
-
modalRoot
|
|
69
|
+
modalRoot,
|
|
59
70
|
modalStack,
|
|
60
|
-
toastRoot
|
|
71
|
+
toastRoot,
|
|
61
72
|
toastStack,
|
|
62
73
|
}),
|
|
63
|
-
[
|
|
74
|
+
[modalRoot, modalStack, toastRoot, toastStack]
|
|
64
75
|
);
|
|
65
76
|
|
|
66
77
|
return (
|
|
@@ -69,7 +80,7 @@ export const OverlayProvider = ({ modal: modalRoot, toast: toastRoot, children }
|
|
|
69
80
|
|
|
70
81
|
{/* Modal stack - rendered in portal */}
|
|
71
82
|
{modals.length > 0 && (
|
|
72
|
-
<FloatingPortal
|
|
83
|
+
<FloatingPortal {...rootProp(modalRoot)}>
|
|
73
84
|
{modals.map(({ id, component: Component, data }) => (
|
|
74
85
|
<Component key={id} data={data} />
|
|
75
86
|
))}
|
|
@@ -78,7 +89,7 @@ export const OverlayProvider = ({ modal: modalRoot, toast: toastRoot, children }
|
|
|
78
89
|
|
|
79
90
|
{/* Toast stack - rendered in portal */}
|
|
80
91
|
{toasts.length > 0 && (
|
|
81
|
-
<FloatingPortal
|
|
92
|
+
<FloatingPortal {...rootProp(toastRoot)}>
|
|
82
93
|
<div className="pointer-events-none fixed bottom-6 left-1/2 z-toast flex -translate-x-1/2 flex-col-reverse items-center gap-3">
|
|
83
94
|
{toasts.map(({ id, component: Component, onClose, ...props }) => (
|
|
84
95
|
<div key={id} className="pointer-events-auto">
|
package/src/theme/index.ts
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export type {
|
|
9
|
-
BgKey,
|
|
10
9
|
BgToken,
|
|
11
|
-
BorderKey,
|
|
12
10
|
BorderToken,
|
|
13
11
|
ColorMode,
|
|
14
12
|
ColorModeSchema,
|
|
@@ -16,17 +14,14 @@ export type {
|
|
|
16
14
|
Context,
|
|
17
15
|
CSSVarName,
|
|
18
16
|
Feedback,
|
|
19
|
-
FgKey,
|
|
20
17
|
FgToken,
|
|
21
18
|
HexValue,
|
|
22
19
|
Hierarchy,
|
|
23
|
-
HSLValue,
|
|
24
20
|
Intent,
|
|
25
21
|
Semantic,
|
|
26
22
|
StandaloneToken,
|
|
27
23
|
State,
|
|
28
24
|
ThemeSchema,
|
|
29
|
-
TokenKey,
|
|
30
25
|
TokenName,
|
|
31
26
|
Weight,
|
|
32
27
|
} from "./schema";
|
|
@@ -36,7 +31,6 @@ export {
|
|
|
36
31
|
cssVar,
|
|
37
32
|
feedback,
|
|
38
33
|
hierarchy,
|
|
39
|
-
hsl,
|
|
40
34
|
intents,
|
|
41
35
|
semantics,
|
|
42
36
|
standaloneTokens,
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Badge recipe — the component-token layer for Badge.
|
|
3
|
+
*
|
|
4
|
+
* This is the mapping from `(variant, intent)` to a semantic token. It used
|
|
5
|
+
* to live in `compoundVariants` inside Badge.tsx, where it was compiled into
|
|
6
|
+
* class-name literals and no consumer could reach it. Here it is data, so a
|
|
7
|
+
* consumer can re-point a cell, scope a change to a subtree, or add an intent
|
|
8
|
+
* the library never shipped.
|
|
9
|
+
*
|
|
10
|
+
* The grammar is `--badge-{context}`, context one of bg, fg, border, ring.
|
|
11
|
+
* Note what is deliberately *absent*: intent and variant never appear in a
|
|
12
|
+
* token name. They select, via the `data-` attributes below. Putting them in
|
|
13
|
+
* the name (`--badge-bg-danger`) would restore the combinatorial explosion
|
|
14
|
+
* this layer exists to remove, and would leave a consumer unable to add an
|
|
15
|
+
* intent, because the variable for it would not exist.
|
|
16
|
+
*
|
|
17
|
+
* `@layer components` is load-bearing, not tidiness. The cascade compares
|
|
18
|
+
* layers before specificity, and unlayered author CSS outranks any layered
|
|
19
|
+
* author CSS — so a consumer's `.badge { ... }` (0,1,0) beats the cell rules
|
|
20
|
+
* below (0,3,0) without an `!important`. The corollary is a trap worth
|
|
21
|
+
* knowing: an override written *inside* a layer is compared on specificity
|
|
22
|
+
* again, and silently loses. Consumer overrides go unlayered.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
@layer components {
|
|
26
|
+
/* The floor. Applies when no cell below matches — an intent a consumer has
|
|
27
|
+
added but not yet styled renders as a plain, legible badge rather than
|
|
28
|
+
something broken. Transparent border/background plus normal foreground
|
|
29
|
+
is the resting default, not a new opinion. */
|
|
30
|
+
.badge {
|
|
31
|
+
--badge-bg: transparent;
|
|
32
|
+
--badge-fg: var(--fg-normal);
|
|
33
|
+
--badge-border: transparent;
|
|
34
|
+
--badge-ring: var(--border-brand);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* solid — a filled surface, with text read on top of it. The `fg-on-*`
|
|
38
|
+
partner is the pairing check-contrast.ts verifies, so these cells inherit
|
|
39
|
+
that guarantee rather than restating it. Border stays transparent (the
|
|
40
|
+
floor already sets it); only bg/fg vary. */
|
|
41
|
+
.badge[data-variant="solid"][data-intent="neutral"] {
|
|
42
|
+
--badge-bg: var(--bg-strong);
|
|
43
|
+
--badge-fg: var(--fg-on-strong);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.badge[data-variant="solid"][data-intent="brand"] {
|
|
47
|
+
--badge-bg: var(--bg-brand);
|
|
48
|
+
--badge-fg: var(--fg-on-brand);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.badge[data-variant="solid"][data-intent="danger"] {
|
|
52
|
+
--badge-bg: var(--bg-danger);
|
|
53
|
+
--badge-fg: var(--fg-on-danger);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.badge[data-variant="solid"][data-intent="success"] {
|
|
57
|
+
--badge-bg: var(--bg-success);
|
|
58
|
+
--badge-fg: var(--fg-on-success);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.badge[data-variant="solid"][data-intent="warning"] {
|
|
62
|
+
--badge-bg: var(--bg-warning);
|
|
63
|
+
--badge-fg: var(--fg-on-warning);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.badge[data-variant="solid"][data-intent="muted"] {
|
|
67
|
+
--badge-bg: var(--bg-subtle);
|
|
68
|
+
--badge-fg: var(--fg-subtle);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* soft — a subdued surface, text read on top of it. Border stays
|
|
72
|
+
transparent, same as solid. */
|
|
73
|
+
.badge[data-variant="soft"][data-intent="neutral"] {
|
|
74
|
+
--badge-bg: var(--bg-subtle);
|
|
75
|
+
--badge-fg: var(--fg-normal);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.badge[data-variant="soft"][data-intent="brand"] {
|
|
79
|
+
--badge-bg: var(--bg-brand-subtle);
|
|
80
|
+
--badge-fg: var(--fg-on-brand-subtle);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.badge[data-variant="soft"][data-intent="danger"] {
|
|
84
|
+
--badge-bg: var(--bg-danger-subtle);
|
|
85
|
+
--badge-fg: var(--fg-on-danger-subtle);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.badge[data-variant="soft"][data-intent="success"] {
|
|
89
|
+
--badge-bg: var(--bg-success-subtle);
|
|
90
|
+
--badge-fg: var(--fg-on-success-subtle);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.badge[data-variant="soft"][data-intent="warning"] {
|
|
94
|
+
--badge-bg: var(--bg-warning-subtle);
|
|
95
|
+
--badge-fg: var(--fg-on-warning-subtle);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.badge[data-variant="soft"][data-intent="muted"] {
|
|
99
|
+
--badge-bg: var(--bg-subtle);
|
|
100
|
+
--badge-fg: var(--fg-subtle);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* outline — a resting surface (bg-normal, shared across every intent) with
|
|
104
|
+
the text and border colour carrying the intent. `neutral` and `muted`
|
|
105
|
+
both land on `border-normal`, but differ in foreground, so they stay
|
|
106
|
+
separate cells rather than merged into one selector list. */
|
|
107
|
+
.badge[data-variant="outline"] {
|
|
108
|
+
--badge-bg: var(--bg-normal);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.badge[data-variant="outline"][data-intent="neutral"] {
|
|
112
|
+
--badge-border: var(--border-normal);
|
|
113
|
+
--badge-fg: var(--fg-normal);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.badge[data-variant="outline"][data-intent="brand"] {
|
|
117
|
+
--badge-border: var(--border-brand);
|
|
118
|
+
--badge-fg: var(--fg-brand);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.badge[data-variant="outline"][data-intent="danger"] {
|
|
122
|
+
--badge-border: var(--border-danger);
|
|
123
|
+
--badge-fg: var(--fg-danger);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.badge[data-variant="outline"][data-intent="success"] {
|
|
127
|
+
--badge-border: var(--border-success);
|
|
128
|
+
--badge-fg: var(--fg-success);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.badge[data-variant="outline"][data-intent="warning"] {
|
|
132
|
+
--badge-border: var(--border-warning);
|
|
133
|
+
--badge-fg: var(--fg-warning);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.badge[data-variant="outline"][data-intent="muted"] {
|
|
137
|
+
--badge-border: var(--border-normal);
|
|
138
|
+
--badge-fg: var(--fg-subtle);
|
|
139
|
+
}
|
|
140
|
+
}
|