@sixthshift/design-system 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.
- package/README.md +132 -87
- package/dist/components/Badge/Badge.d.ts +12 -4
- package/dist/components/Badge/Badge.d.ts.map +1 -1
- package/dist/components/Badge/Badge.js +8 -6
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Button/Button.d.ts +26 -3
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +14 -5
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/components/Calendar/Calendar.js +1 -0
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/CalendarView.d.ts +0 -11
- package/dist/components/Calendar/CalendarView.d.ts.map +1 -1
- package/dist/components/Calendar/CalendarView.js +1 -0
- package/dist/components/Calendar/CalendarView.js.map +1 -1
- package/dist/components/Calendar/calendar.hooks.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.hooks.js +1 -0
- package/dist/components/Calendar/calendar.hooks.js.map +1 -1
- package/dist/components/Card/Card.d.ts +2 -2
- package/dist/components/Card/Card.d.ts.map +1 -1
- package/dist/components/Card/Card.js +3 -2
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +1 -0
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.js +1 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.js.map +1 -1
- package/dist/components/Code/Editor/Editor.d.ts.map +1 -1
- package/dist/components/Code/Editor/Editor.js +1 -0
- package/dist/components/Code/Editor/Editor.js.map +1 -1
- package/dist/components/Code/Workspace/StatusBar.d.ts.map +1 -1
- package/dist/components/Code/Workspace/StatusBar.js +1 -0
- package/dist/components/Code/Workspace/StatusBar.js.map +1 -1
- package/dist/components/Code/Workspace/Toolbar.d.ts.map +1 -1
- package/dist/components/Code/Workspace/Toolbar.js +1 -0
- package/dist/components/Code/Workspace/Toolbar.js.map +1 -1
- package/dist/components/Code/Workspace/Workspace.d.ts.map +1 -1
- package/dist/components/Code/Workspace/Workspace.js +1 -0
- package/dist/components/Code/Workspace/Workspace.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -1
- package/dist/components/DatePicker/DatePicker.js +7 -1
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DatePicker/DateSegments.d.ts.map +1 -1
- package/dist/components/DatePicker/DateSegments.js +1 -0
- package/dist/components/DatePicker/DateSegments.js.map +1 -1
- package/dist/components/DatePicker/datepicker.hooks.d.ts.map +1 -1
- package/dist/components/DatePicker/datepicker.hooks.js +1 -0
- package/dist/components/DatePicker/datepicker.hooks.js.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.js +1 -0
- package/dist/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.ts.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.js +7 -1
- package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
- package/dist/components/DateTimePicker/DateTimeSegments.d.ts.map +1 -1
- package/dist/components/DateTimePicker/DateTimeSegments.js +1 -0
- package/dist/components/DateTimePicker/DateTimeSegments.js.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.d.ts.map +1 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js +7 -1
- package/dist/components/DateTimeRangePicker/DateTimeRangePicker.js.map +1 -1
- package/dist/components/FormField/FormField.d.ts +31 -10
- package/dist/components/FormField/FormField.d.ts.map +1 -1
- package/dist/components/FormField/FormField.js +46 -17
- package/dist/components/FormField/FormField.js.map +1 -1
- package/dist/components/FormField/index.d.ts +2 -2
- package/dist/components/FormField/index.d.ts.map +1 -1
- package/dist/components/FormField/index.js +1 -1
- package/dist/components/FormField/index.js.map +1 -1
- package/dist/components/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/components/HoverCard/HoverCard.js +4 -0
- package/dist/components/HoverCard/HoverCard.js.map +1 -1
- package/dist/components/HoverCard/components/HoverCardContent.d.ts +16 -2
- package/dist/components/HoverCard/components/HoverCardContent.d.ts.map +1 -1
- package/dist/components/HoverCard/components/HoverCardContent.js +4 -3
- package/dist/components/HoverCard/components/HoverCardContent.js.map +1 -1
- package/dist/components/HoverCard/components/HoverCardContext.d.ts +2 -0
- package/dist/components/HoverCard/components/HoverCardContext.d.ts.map +1 -1
- package/dist/components/HoverCard/components/HoverCardContext.js +1 -0
- package/dist/components/HoverCard/components/HoverCardContext.js.map +1 -1
- package/dist/components/HoverCard/components/HoverCardTrigger.d.ts.map +1 -1
- package/dist/components/HoverCard/components/HoverCardTrigger.js +1 -0
- package/dist/components/HoverCard/components/HoverCardTrigger.js.map +1 -1
- package/dist/components/Message/Message.d.ts +5 -1
- package/dist/components/Message/Message.d.ts.map +1 -1
- package/dist/components/Message/Message.js +3 -3
- package/dist/components/Message/Message.js.map +1 -1
- package/dist/components/Modal/Modal.d.ts +26 -9
- package/dist/components/Modal/Modal.d.ts.map +1 -1
- package/dist/components/Modal/Modal.js +46 -21
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Modal/components/ModalContext.d.ts.map +1 -1
- package/dist/components/Modal/components/ModalContext.js +1 -0
- package/dist/components/Modal/components/ModalContext.js.map +1 -1
- package/dist/components/Modal/components/ModalHeader.d.ts.map +1 -1
- package/dist/components/Modal/components/ModalHeader.js +1 -0
- package/dist/components/Modal/components/ModalHeader.js.map +1 -1
- package/dist/components/Popover/Popover.d.ts +3 -1
- package/dist/components/Popover/Popover.d.ts.map +1 -1
- package/dist/components/Popover/Popover.js +8 -0
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/components/PopoverBody.d.ts +16 -2
- package/dist/components/Popover/components/PopoverBody.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverBody.js +4 -3
- package/dist/components/Popover/components/PopoverBody.js.map +1 -1
- package/dist/components/Popover/components/PopoverClose.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverClose.js +1 -0
- package/dist/components/Popover/components/PopoverClose.js.map +1 -1
- package/dist/components/Popover/components/PopoverContext.d.ts +2 -0
- package/dist/components/Popover/components/PopoverContext.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverContext.js +1 -0
- package/dist/components/Popover/components/PopoverContext.js.map +1 -1
- package/dist/components/Popover/components/PopoverTrigger.d.ts.map +1 -1
- package/dist/components/Popover/components/PopoverTrigger.js +1 -0
- package/dist/components/Popover/components/PopoverTrigger.js.map +1 -1
- package/dist/components/RadioButton/RadioButton.d.ts.map +1 -1
- package/dist/components/RadioButton/RadioButton.js +1 -0
- package/dist/components/RadioButton/RadioButton.js.map +1 -1
- package/dist/components/RadioButtonGroup/RadioButtonGroup.d.ts.map +1 -1
- package/dist/components/RadioButtonGroup/RadioButtonGroup.js +1 -0
- package/dist/components/RadioButtonGroup/RadioButtonGroup.js.map +1 -1
- package/dist/components/SearchInput/SearchInput.d.ts +10 -7
- package/dist/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/components/SearchInput/SearchInput.js +11 -6
- package/dist/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/components/Select/Select.d.ts +6 -0
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +11 -4
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/SelectDropdown.d.ts +3 -1
- package/dist/components/Select/SelectDropdown.d.ts.map +1 -1
- package/dist/components/Select/SelectDropdown.js +3 -2
- package/dist/components/Select/SelectDropdown.js.map +1 -1
- package/dist/components/Select/SelectTrigger.d.ts.map +1 -1
- package/dist/components/Select/SelectTrigger.js +5 -1
- package/dist/components/Select/SelectTrigger.js.map +1 -1
- package/dist/components/Select/useSelectKeyboard.d.ts.map +1 -1
- package/dist/components/Select/useSelectKeyboard.js +1 -0
- package/dist/components/Select/useSelectKeyboard.js.map +1 -1
- package/dist/components/Sheet/Sheet.d.ts +12 -0
- package/dist/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/components/Sheet/Sheet.js +26 -10
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Sheet/components/SheetContext.d.ts.map +1 -1
- package/dist/components/Sheet/components/SheetContext.js +1 -0
- package/dist/components/Sheet/components/SheetContext.js.map +1 -1
- package/dist/components/Sheet/components/SheetHeader.d.ts.map +1 -1
- package/dist/components/Sheet/components/SheetHeader.js +1 -0
- package/dist/components/Sheet/components/SheetHeader.js.map +1 -1
- package/dist/components/Spinner/Spinner.d.ts +2 -2
- package/dist/components/Spinner/Spinner.js +2 -2
- package/dist/components/Switch/Switch.d.ts.map +1 -1
- package/dist/components/Switch/Switch.js +1 -0
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/Tabs/Tabs.js +1 -0
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tabs/components/TabsContext.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsContext.js +1 -0
- package/dist/components/Tabs/components/TabsContext.js.map +1 -1
- package/dist/components/Tabs/components/TabsList.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsList.js +1 -0
- package/dist/components/Tabs/components/TabsList.js.map +1 -1
- package/dist/components/Tabs/components/TabsPanels.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsPanels.js +1 -0
- package/dist/components/Tabs/components/TabsPanels.js.map +1 -1
- package/dist/components/Tabs/components/TabsTrigger.d.ts.map +1 -1
- package/dist/components/Tabs/components/TabsTrigger.js +2 -1
- package/dist/components/Tabs/components/TabsTrigger.js.map +1 -1
- package/dist/components/TagChip/TagChip.d.ts.map +1 -1
- package/dist/components/TagChip/TagChip.js +1 -0
- package/dist/components/TagChip/TagChip.js.map +1 -1
- package/dist/components/TagInput/TagInput.d.ts +8 -2
- package/dist/components/TagInput/TagInput.d.ts.map +1 -1
- package/dist/components/TagInput/TagInput.js +8 -5
- package/dist/components/TagInput/TagInput.js.map +1 -1
- package/dist/components/Textarea/Textarea.d.ts +21 -5
- package/dist/components/Textarea/Textarea.d.ts.map +1 -1
- package/dist/components/Textarea/Textarea.js +31 -5
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/TimePicker/PeriodSelector.d.ts.map +1 -1
- package/dist/components/TimePicker/PeriodSelector.js +1 -0
- package/dist/components/TimePicker/PeriodSelector.js.map +1 -1
- package/dist/components/TimePicker/TimeColumn.d.ts.map +1 -1
- package/dist/components/TimePicker/TimeColumn.js +1 -0
- package/dist/components/TimePicker/TimeColumn.js.map +1 -1
- package/dist/components/TimePicker/TimePicker.d.ts.map +1 -1
- package/dist/components/TimePicker/TimePicker.js +7 -1
- package/dist/components/TimePicker/TimePicker.js.map +1 -1
- package/dist/components/TimePicker/TimeSegments.d.ts.map +1 -1
- package/dist/components/TimePicker/TimeSegments.js +1 -0
- package/dist/components/TimePicker/TimeSegments.js.map +1 -1
- package/dist/components/Toast/Toast.d.ts +16 -2
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/components/Toast/Toast.js +17 -7
- package/dist/components/Toast/Toast.js.map +1 -1
- package/dist/components/Toggle/Toggle.d.ts +5 -1
- package/dist/components/Toggle/Toggle.d.ts.map +1 -1
- package/dist/components/Toggle/Toggle.js +4 -3
- package/dist/components/Toggle/Toggle.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts +3 -0
- package/dist/components/ToggleGroup/ToggleGroupMultiple.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupMultiple.js +4 -3
- package/dist/components/ToggleGroup/ToggleGroupMultiple.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts +3 -0
- package/dist/components/ToggleGroup/ToggleGroupSingle.d.ts.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupSingle.js +4 -3
- package/dist/components/ToggleGroup/ToggleGroupSingle.js.map +1 -1
- package/dist/components/ToggleGroup/toggleGroup.types.d.ts +13 -0
- package/dist/components/ToggleGroup/toggleGroup.types.d.ts.map +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +3 -1
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +4 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/Tooltip/components/TooltipBody.d.ts +16 -2
- package/dist/components/Tooltip/components/TooltipBody.d.ts.map +1 -1
- package/dist/components/Tooltip/components/TooltipBody.js +4 -3
- package/dist/components/Tooltip/components/TooltipBody.js.map +1 -1
- package/dist/components/Tooltip/components/TooltipContext.d.ts +2 -0
- package/dist/components/Tooltip/components/TooltipContext.d.ts.map +1 -1
- package/dist/components/Tooltip/components/TooltipContext.js +1 -0
- package/dist/components/Tooltip/components/TooltipContext.js.map +1 -1
- package/dist/components/Tooltip/components/TooltipTrigger.d.ts.map +1 -1
- package/dist/components/Tooltip/components/TooltipTrigger.js +1 -0
- package/dist/components/Tooltip/components/TooltipTrigger.js.map +1 -1
- package/dist/hooks/useCollapsible.d.ts.map +1 -1
- package/dist/hooks/useCollapsible.js +1 -0
- package/dist/hooks/useCollapsible.js.map +1 -1
- package/dist/hooks/useControllableState.d.ts.map +1 -1
- package/dist/hooks/useControllableState.js +1 -0
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/hooks/useDebouncedCallback.d.ts.map +1 -1
- package/dist/hooks/useDebouncedCallback.js +1 -0
- package/dist/hooks/useDebouncedCallback.js.map +1 -1
- package/dist/hooks/useDebouncedState.d.ts.map +1 -1
- package/dist/hooks/useDebouncedState.js +1 -0
- package/dist/hooks/useDebouncedState.js.map +1 -1
- package/dist/hooks/useDeviceFormFactor.d.ts.map +1 -1
- package/dist/hooks/useDeviceFormFactor.js +1 -0
- package/dist/hooks/useDeviceFormFactor.js.map +1 -1
- package/dist/hooks/useLocalStorage.d.ts.map +1 -1
- package/dist/hooks/useLocalStorage.js +1 -0
- package/dist/hooks/useLocalStorage.js.map +1 -1
- package/dist/hooks/useMergedFloatingRef.d.ts.map +1 -1
- package/dist/hooks/useMergedFloatingRef.js +1 -0
- package/dist/hooks/useMergedFloatingRef.js.map +1 -1
- package/dist/hooks/usePresence.d.ts.map +1 -1
- package/dist/hooks/usePresence.js +1 -0
- package/dist/hooks/usePresence.js.map +1 -1
- package/dist/hooks/useStack.d.ts.map +1 -1
- package/dist/hooks/useStack.js +34 -10
- package/dist/hooks/useStack.js.map +1 -1
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useTheme.js +1 -0
- package/dist/hooks/useTheme.js.map +1 -1
- package/dist/internal/PickerField.d.ts.map +1 -1
- package/dist/internal/PickerField.js +1 -0
- package/dist/internal/PickerField.js.map +1 -1
- package/dist/internal/SegmentedField.d.ts.map +1 -1
- package/dist/internal/SegmentedField.js +1 -0
- package/dist/internal/SegmentedField.js.map +1 -1
- package/dist/internal/brandScope.d.ts +25 -0
- package/dist/internal/brandScope.d.ts.map +1 -0
- package/dist/internal/brandScope.js +37 -0
- package/dist/internal/brandScope.js.map +1 -0
- package/dist/internal/escapeLayers.d.ts +12 -0
- package/dist/internal/escapeLayers.d.ts.map +1 -0
- package/dist/internal/escapeLayers.js +48 -0
- package/dist/internal/escapeLayers.js.map +1 -0
- package/dist/lib/ErrorBoundary.d.ts.map +1 -1
- package/dist/lib/ErrorBoundary.js +1 -0
- package/dist/lib/ErrorBoundary.js.map +1 -1
- package/dist/lib/contexts/ComponentsContext/ComponentsContext.d.ts.map +1 -1
- package/dist/lib/contexts/ComponentsContext/ComponentsContext.js +1 -0
- package/dist/lib/contexts/ComponentsContext/ComponentsContext.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/OverlayContext.d.ts +9 -4
- package/dist/lib/contexts/OverlayContext/OverlayContext.d.ts.map +1 -1
- package/dist/lib/contexts/OverlayContext/OverlayContext.js +25 -12
- package/dist/lib/contexts/OverlayContext/OverlayContext.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/ToastStack.d.ts +20 -0
- package/dist/lib/contexts/OverlayContext/ToastStack.d.ts.map +1 -0
- package/dist/lib/contexts/OverlayContext/ToastStack.js +45 -0
- package/dist/lib/contexts/OverlayContext/ToastStack.js.map +1 -0
- package/dist/lib/contexts/OverlayContext/hooks/useModal.d.ts.map +1 -1
- package/dist/lib/contexts/OverlayContext/hooks/useModal.js +1 -0
- package/dist/lib/contexts/OverlayContext/hooks/useModal.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/hooks/useToast.d.ts +27 -10
- package/dist/lib/contexts/OverlayContext/hooks/useToast.d.ts.map +1 -1
- package/dist/lib/contexts/OverlayContext/hooks/useToast.js +31 -49
- package/dist/lib/contexts/OverlayContext/hooks/useToast.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/index.d.ts +2 -0
- package/dist/lib/contexts/OverlayContext/index.d.ts.map +1 -1
- package/dist/lib/contexts/OverlayContext/index.js +2 -0
- package/dist/lib/contexts/OverlayContext/index.js.map +1 -1
- package/dist/lib/contexts/OverlayContext/toastStore.d.ts +68 -0
- package/dist/lib/contexts/OverlayContext/toastStore.d.ts.map +1 -0
- package/dist/lib/contexts/OverlayContext/toastStore.js +69 -0
- package/dist/lib/contexts/OverlayContext/toastStore.js.map +1 -0
- package/dist/lib/withErrorBoundary.d.ts.map +1 -1
- package/dist/lib/withErrorBoundary.js +1 -0
- package/dist/lib/withErrorBoundary.js.map +1 -1
- package/dist/lib/withSuspenseAndErrorBoundary.d.ts.map +1 -1
- package/dist/lib/withSuspenseAndErrorBoundary.js +1 -0
- package/dist/lib/withSuspenseAndErrorBoundary.js.map +1 -1
- package/dist/{theme/schema.d.ts → theming/vocabulary.d.ts} +4 -4
- package/dist/theming/vocabulary.d.ts.map +1 -0
- package/dist/{theme/schema.js → theming/vocabulary.js} +4 -4
- package/dist/theming/vocabulary.js.map +1 -0
- package/package.json +18 -6
- package/src/components/Badge/Badge.tsx +12 -6
- package/src/components/Button/Button.tsx +25 -5
- package/src/{theme/recipes/button.css → components/Button/button.recipe.css} +2 -2
- package/src/components/Calendar/Calendar.tsx +2 -0
- package/src/components/Calendar/CalendarView.tsx +2 -0
- package/src/components/Calendar/calendar.hooks.ts +2 -0
- package/src/components/Card/Card.tsx +4 -2
- package/src/components/Checkbox/Checkbox.tsx +2 -0
- package/src/components/CheckboxGroup/CheckboxGroup.tsx +2 -0
- package/src/components/Code/Editor/Editor.tsx +2 -0
- package/src/components/Code/Workspace/StatusBar.tsx +2 -0
- package/src/components/Code/Workspace/Toolbar.tsx +2 -0
- package/src/components/Code/Workspace/Workspace.tsx +2 -0
- package/src/components/DatePicker/DatePicker.tsx +10 -0
- package/src/components/DatePicker/DateSegments.tsx +2 -0
- package/src/components/DatePicker/datepicker.hooks.ts +2 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +2 -0
- package/src/components/DateTimePicker/DateTimePicker.tsx +10 -1
- package/src/components/DateTimePicker/DateTimeSegments.tsx +2 -0
- package/src/components/DateTimeRangePicker/DateTimeRangePicker.tsx +10 -1
- package/src/components/FormField/FormField.tsx +94 -42
- package/src/components/FormField/index.ts +2 -2
- package/src/components/HoverCard/HoverCard.tsx +5 -0
- package/src/components/HoverCard/components/HoverCardContent.tsx +13 -3
- package/src/components/HoverCard/components/HoverCardContext.tsx +4 -0
- package/src/components/HoverCard/components/HoverCardTrigger.tsx +2 -0
- package/src/components/Message/Message.tsx +27 -23
- package/src/components/Modal/Modal.tsx +88 -51
- package/src/components/Modal/components/ModalContext.tsx +2 -0
- package/src/components/Modal/components/ModalHeader.tsx +2 -0
- package/src/components/Popover/Popover.tsx +10 -0
- package/src/components/Popover/components/PopoverBody.tsx +13 -3
- package/src/components/Popover/components/PopoverClose.tsx +2 -0
- package/src/components/Popover/components/PopoverContext.tsx +4 -0
- package/src/components/Popover/components/PopoverTrigger.tsx +2 -0
- package/src/components/RadioButton/RadioButton.tsx +2 -0
- package/src/components/RadioButtonGroup/RadioButtonGroup.tsx +2 -0
- package/src/components/SearchInput/SearchInput.tsx +15 -8
- package/src/components/Select/Select.tsx +27 -2
- package/src/components/Select/SelectDropdown.tsx +6 -0
- package/src/components/Select/SelectTrigger.tsx +5 -0
- package/src/components/Select/useSelectKeyboard.ts +2 -0
- package/src/components/Sheet/Sheet.tsx +59 -34
- package/src/components/Sheet/components/SheetContext.tsx +2 -0
- package/src/components/Sheet/components/SheetHeader.tsx +2 -0
- package/src/components/Spinner/Spinner.tsx +2 -2
- package/src/components/Switch/Switch.tsx +2 -0
- package/src/components/Tabs/Tabs.tsx +2 -0
- package/src/components/Tabs/components/TabsContext.tsx +2 -0
- package/src/components/Tabs/components/TabsList.tsx +2 -0
- package/src/components/Tabs/components/TabsPanels.tsx +2 -0
- package/src/components/Tabs/components/TabsTrigger.tsx +3 -1
- package/src/{theme/recipes/tabs.css → components/Tabs/tabs.recipe.css} +1 -1
- package/src/components/TagChip/TagChip.tsx +2 -0
- package/src/components/TagInput/TagInput.tsx +15 -6
- package/src/components/Textarea/Textarea.tsx +42 -6
- package/src/{theme/recipes/textarea.css → components/Textarea/textarea.recipe.css} +1 -1
- package/src/components/TimePicker/PeriodSelector.tsx +2 -0
- package/src/components/TimePicker/TimeColumn.tsx +2 -0
- package/src/components/TimePicker/TimePicker.tsx +10 -0
- package/src/components/TimePicker/TimeSegments.tsx +2 -0
- package/src/components/Toast/Toast.tsx +26 -6
- package/src/components/Toggle/Toggle.tsx +20 -3
- package/src/components/ToggleGroup/ToggleGroupMultiple.tsx +8 -1
- package/src/components/ToggleGroup/ToggleGroupSingle.tsx +8 -0
- package/src/components/ToggleGroup/toggleGroup.types.ts +13 -0
- package/src/components/Tooltip/Tooltip.tsx +5 -0
- package/src/components/Tooltip/components/TooltipBody.tsx +13 -3
- package/src/components/Tooltip/components/TooltipContext.tsx +4 -0
- package/src/components/Tooltip/components/TooltipTrigger.tsx +2 -0
- package/src/hooks/useCollapsible.ts +2 -0
- package/src/hooks/useControllableState.ts +2 -0
- package/src/hooks/useDebouncedCallback.ts +2 -0
- package/src/hooks/useDebouncedState.ts +2 -0
- package/src/hooks/useDeviceFormFactor.ts +2 -0
- package/src/hooks/useLocalStorage.ts +2 -0
- package/src/hooks/useMergedFloatingRef.ts +2 -0
- package/src/hooks/usePresence.ts +2 -0
- package/src/hooks/useStack.ts +35 -12
- package/src/hooks/useTheme.ts +2 -0
- package/src/internal/PickerField.tsx +2 -0
- package/src/internal/SegmentedField.tsx +2 -0
- package/src/internal/brandScope.ts +39 -0
- package/src/internal/escapeLayers.ts +53 -0
- package/src/lib/ErrorBoundary.tsx +2 -0
- package/src/lib/contexts/ComponentsContext/ComponentsContext.tsx +2 -0
- package/src/lib/contexts/OverlayContext/OverlayContext.tsx +42 -26
- package/src/lib/contexts/OverlayContext/ToastStack.tsx +71 -0
- package/src/lib/contexts/OverlayContext/hooks/useModal.tsx +2 -0
- package/src/lib/contexts/OverlayContext/hooks/useToast.ts +30 -73
- package/src/lib/contexts/OverlayContext/index.ts +2 -0
- package/src/lib/contexts/OverlayContext/toastStore.ts +138 -0
- package/src/lib/withErrorBoundary.tsx +2 -0
- package/src/lib/withSuspenseAndErrorBoundary.tsx +2 -0
- package/src/theme/linen/index.css +11 -0
- package/src/theme/linen/palette.css +87 -0
- package/src/theme/linen/theme.css +371 -0
- package/src/theming/tailwind.css +356 -0
- package/src/{theme/schema.ts → theming/vocabulary.ts} +3 -3
- package/dist/theme/index.d.ts +0 -9
- package/dist/theme/index.d.ts.map +0 -1
- package/dist/theme/index.js +0 -8
- package/dist/theme/index.js.map +0 -1
- package/dist/theme/schema.d.ts.map +0 -1
- package/dist/theme/schema.js.map +0 -1
- package/src/theme/index.ts +0 -39
- package/src/theme/recipes/index.css +0 -28
- package/src/theme/tokens.css +0 -824
- /package/src/{theme/recipes/badge.css → components/Badge/badge.recipe.css} +0 -0
- /package/src/{theme/recipes/card.css → components/Card/card.recipe.css} +0 -0
- /package/src/{theme/recipes/checkbox.css → components/Checkbox/checkbox.recipe.css} +0 -0
- /package/src/{theme/recipes/field.css → components/Field/field.recipe.css} +0 -0
- /package/src/{theme/recipes/input.css → components/Input/input.recipe.css} +0 -0
- /package/src/{theme/recipes/message.css → components/Message/message.recipe.css} +0 -0
- /package/src/{theme/recipes/modal.css → components/Modal/modal.recipe.css} +0 -0
- /package/src/{theme/recipes/radio-button.css → components/RadioButton/radio-button.recipe.css} +0 -0
- /package/src/{theme/recipes/search-input.css → components/SearchInput/search-input.recipe.css} +0 -0
- /package/src/{theme/recipes/select.css → components/Select/select.recipe.css} +0 -0
- /package/src/{theme/recipes/sheet.css → components/Sheet/sheet.recipe.css} +0 -0
- /package/src/{theme/recipes/spinner.css → components/Spinner/spinner.recipe.css} +0 -0
- /package/src/{theme/recipes/switch.css → components/Switch/switch.recipe.css} +0 -0
- /package/src/{theme/recipes/tag-chip.css → components/TagChip/tag-chip.recipe.css} +0 -0
- /package/src/{theme/recipes/toggle.css → components/Toggle/toggle.recipe.css} +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { FloatingPortal, type FloatingPortalProps } from "@floating-ui/react";
|
|
2
4
|
import { Button } from "@sixthshift/design-system/button";
|
|
3
5
|
import { usePresence } from "@sixthshift/design-system/hooks";
|
|
@@ -19,6 +21,13 @@ export type ToastProps = Omit<MessageProps, "size"> & {
|
|
|
19
21
|
onAction?: () => void;
|
|
20
22
|
/** Portal root element (default: document.body) */
|
|
21
23
|
root?: FloatingPortalProps["root"];
|
|
24
|
+
/**
|
|
25
|
+
* Set to `false` to play the exit animation and then call `onClose`. This is
|
|
26
|
+
* how a stack dismisses a toast on a timer: the toast stays mounted through
|
|
27
|
+
* its fade-out, and the stack drops it when `onClose` fires.
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
open?: boolean;
|
|
22
31
|
/**
|
|
23
32
|
* Whether Toast should render in a portal and position itself.
|
|
24
33
|
* Set to false when Toast is rendered by a parent that handles positioning (e.g., OverlayContext).
|
|
@@ -50,8 +59,8 @@ export type ToastProps = Omit<MessageProps, "size"> & {
|
|
|
50
59
|
* portals itself (`FloatingPortal`, optionally to a custom `root`) and
|
|
51
60
|
* applies the fixed bottom-center classes itself. Set it to `false` when a
|
|
52
61
|
* parent already handles portalling and position — this is how
|
|
53
|
-
* `
|
|
54
|
-
*
|
|
62
|
+
* `ToastStack` renders it. Toast has no built-in auto-dismiss timer; that's
|
|
63
|
+
* `ToastStack`'s job, one layer up, driven through `open`.
|
|
55
64
|
*
|
|
56
65
|
* Exit animation (`usePresence`) keeps Toast mounted through its fade-out,
|
|
57
66
|
* so `onClose` fires only after the animation completes. Toast has no focus
|
|
@@ -59,13 +68,20 @@ export type ToastProps = Omit<MessageProps, "size"> & {
|
|
|
59
68
|
* a dialog.
|
|
60
69
|
*/
|
|
61
70
|
export const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
|
|
62
|
-
({ className, intent = "neutral", title, icon, action, onAction, onClose, root, standalone = true, children, ...props }, ref) => {
|
|
71
|
+
({ className, intent = "neutral", brand, title, icon, action, onAction, onClose, root, open = true, standalone = true, children, ...props }, ref) => {
|
|
63
72
|
const { ref: presenceRef, state, isMounted, show, hide } = usePresence();
|
|
64
73
|
|
|
65
|
-
//
|
|
74
|
+
// `open` drives presence: enter on mount, exit when it flips false. The
|
|
75
|
+
// close handler is read through a ref so a new identity does not replay
|
|
76
|
+
// the exit.
|
|
77
|
+
const onCloseRef = React.useRef(onClose);
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
onCloseRef.current = onClose;
|
|
80
|
+
});
|
|
66
81
|
React.useEffect(() => {
|
|
67
|
-
show();
|
|
68
|
-
|
|
82
|
+
if (open) show();
|
|
83
|
+
else hide(() => onCloseRef.current?.());
|
|
84
|
+
}, [open, show, hide]);
|
|
69
85
|
|
|
70
86
|
// Handle close with exit animation
|
|
71
87
|
const handleClose = React.useCallback(() => {
|
|
@@ -102,6 +118,10 @@ export const Toast = React.forwardRef<HTMLDivElement, ToastProps>(
|
|
|
102
118
|
isExiting && "animate-fade-out",
|
|
103
119
|
className
|
|
104
120
|
)}
|
|
121
|
+
// On the wrapper rather than the Message, so the dismiss and action
|
|
122
|
+
// buttons are in the same scope. A toast has no trigger to inherit
|
|
123
|
+
// from: it is opened from code, often long after the click.
|
|
124
|
+
data-brand={brand}
|
|
105
125
|
{...props}
|
|
106
126
|
>
|
|
107
127
|
<Message intent={intent}>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { useControllableState } from "@sixthshift/design-system/hooks";
|
|
2
4
|
import { cn } from "@sixthshift/design-system/utils";
|
|
3
5
|
import type { VariantProps } from "class-variance-authority";
|
|
@@ -13,6 +15,8 @@ export type ToggleProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "o
|
|
|
13
15
|
VariantProps<typeof buttonVariants> & {
|
|
14
16
|
variant?: ButtonVariant | undefined;
|
|
15
17
|
intent?: ButtonIntent | undefined;
|
|
18
|
+
/** Name of a brand the theme defines, rendered as `data-brand`. Omitted, the toggle follows the nearest `data-brand` ancestor. */
|
|
19
|
+
brand?: string | undefined;
|
|
16
20
|
/** Square the toggle at its current size, for an icon with no label. */
|
|
17
21
|
iconOnly?: boolean;
|
|
18
22
|
/** Controlled pressed state */
|
|
@@ -32,7 +36,7 @@ export type ToggleProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "o
|
|
|
32
36
|
* Built directly on Button: it calls `buttonRecipe(...)` and takes the same
|
|
33
37
|
* `variant`/`intent`/`size` axes Button does, plus `iconOnly` for a toolbar
|
|
34
38
|
* toggle whose whole content is an icon. The
|
|
35
|
-
* pressed-state colour mapping lives in `src/
|
|
39
|
+
* pressed-state colour mapping lives in `src/components/Toggle/toggle.recipe.css`,
|
|
36
40
|
* keyed off the `data-state="on" | "off"` attribute this component renders
|
|
37
41
|
* alongside `aria-pressed`.
|
|
38
42
|
*
|
|
@@ -41,7 +45,20 @@ export type ToggleProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "o
|
|
|
41
45
|
*/
|
|
42
46
|
const Toggle = React.forwardRef<HTMLButtonElement, ToggleProps>(
|
|
43
47
|
(
|
|
44
|
-
{
|
|
48
|
+
{
|
|
49
|
+
className,
|
|
50
|
+
variant,
|
|
51
|
+
intent,
|
|
52
|
+
brand,
|
|
53
|
+
size,
|
|
54
|
+
iconOnly = false,
|
|
55
|
+
pressed: controlledPressed,
|
|
56
|
+
defaultPressed = false,
|
|
57
|
+
onPressedChange,
|
|
58
|
+
disabled,
|
|
59
|
+
children,
|
|
60
|
+
...props
|
|
61
|
+
},
|
|
45
62
|
ref
|
|
46
63
|
) => {
|
|
47
64
|
const [pressed, setPressed] = useControllableState({
|
|
@@ -50,7 +67,7 @@ const Toggle = React.forwardRef<HTMLButtonElement, ToggleProps>(
|
|
|
50
67
|
onChange: onPressedChange,
|
|
51
68
|
});
|
|
52
69
|
|
|
53
|
-
const recipe = buttonRecipe({ variant, intent, size, iconOnly });
|
|
70
|
+
const recipe = buttonRecipe({ variant, intent, brand, size, iconOnly });
|
|
54
71
|
|
|
55
72
|
return (
|
|
56
73
|
<button
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { useControllableState } from "@sixthshift/design-system/hooks";
|
|
2
4
|
import * as React from "react";
|
|
3
5
|
import { ToggleGroupContainer } from "./ToggleGroupContainer";
|
|
@@ -15,10 +17,13 @@ const ToggleGroupMultiple = React.forwardRef<HTMLDivElement, ToggleGroupMultiple
|
|
|
15
17
|
orientation = "horizontal",
|
|
16
18
|
variant = "solid",
|
|
17
19
|
intent = "neutral",
|
|
20
|
+
brand,
|
|
18
21
|
size = "md",
|
|
19
22
|
iconOnly = false,
|
|
20
23
|
disabled,
|
|
21
24
|
className,
|
|
25
|
+
name,
|
|
26
|
+
form,
|
|
22
27
|
...props
|
|
23
28
|
},
|
|
24
29
|
ref
|
|
@@ -35,7 +40,7 @@ const ToggleGroupMultiple = React.forwardRef<HTMLDivElement, ToggleGroupMultiple
|
|
|
35
40
|
};
|
|
36
41
|
|
|
37
42
|
return (
|
|
38
|
-
<ToggleGroupContainer ref={ref} role="group" appearance={appearance} orientation={orientation} className={className} {...props}>
|
|
43
|
+
<ToggleGroupContainer ref={ref} role="group" data-brand={brand} appearance={appearance} orientation={orientation} className={className} {...props}>
|
|
39
44
|
{options.map((option, index) => (
|
|
40
45
|
<ToggleGroupItem
|
|
41
46
|
key={option.value}
|
|
@@ -54,6 +59,8 @@ const ToggleGroupMultiple = React.forwardRef<HTMLDivElement, ToggleGroupMultiple
|
|
|
54
59
|
onClick={() => handleToggle(option.value)}
|
|
55
60
|
/>
|
|
56
61
|
))}
|
|
62
|
+
{/* Mirrors the selection for native form submission, same contract as Checkbox/DatePicker. */}
|
|
63
|
+
{name && value.map((v) => <input key={v} type="hidden" name={`${name}[]`} value={v} {...(form ? { form } : {})} />)}
|
|
57
64
|
</ToggleGroupContainer>
|
|
58
65
|
);
|
|
59
66
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { useControllableState } from "@sixthshift/design-system/hooks";
|
|
2
4
|
import * as React from "react";
|
|
3
5
|
import { getRovingTargetIndex } from "../../internal/rovingFocus";
|
|
@@ -17,10 +19,13 @@ const ToggleGroupSingle = React.forwardRef<HTMLDivElement, ToggleGroupSingleProp
|
|
|
17
19
|
orientation = "horizontal",
|
|
18
20
|
variant = "solid",
|
|
19
21
|
intent = "neutral",
|
|
22
|
+
brand,
|
|
20
23
|
size = "md",
|
|
21
24
|
iconOnly = false,
|
|
22
25
|
disabled,
|
|
23
26
|
className,
|
|
27
|
+
name,
|
|
28
|
+
form,
|
|
24
29
|
...props
|
|
25
30
|
},
|
|
26
31
|
ref
|
|
@@ -72,6 +77,7 @@ const ToggleGroupSingle = React.forwardRef<HTMLDivElement, ToggleGroupSingleProp
|
|
|
72
77
|
<ToggleGroupContainer
|
|
73
78
|
ref={mergedRef}
|
|
74
79
|
role="radiogroup"
|
|
80
|
+
data-brand={brand}
|
|
75
81
|
onKeyDown={handleKeyDown}
|
|
76
82
|
appearance={appearance}
|
|
77
83
|
orientation={orientation}
|
|
@@ -98,6 +104,8 @@ const ToggleGroupSingle = React.forwardRef<HTMLDivElement, ToggleGroupSingleProp
|
|
|
98
104
|
onClick={() => handleSelect(option.value)}
|
|
99
105
|
/>
|
|
100
106
|
))}
|
|
107
|
+
{/* Mirrors the selection for native form submission, same contract as Checkbox/DatePicker. */}
|
|
108
|
+
{name && value && <input type="hidden" name={name} value={value} {...(form ? { form } : {})} />}
|
|
101
109
|
</ToggleGroupContainer>
|
|
102
110
|
);
|
|
103
111
|
}
|
|
@@ -33,12 +33,25 @@ export type ToggleGroupBaseProps = Omit<React.HTMLAttributes<HTMLDivElement>, "o
|
|
|
33
33
|
variant?: Exclude<ButtonVariantName, "link">;
|
|
34
34
|
/** Color intent */
|
|
35
35
|
intent?: ButtonIntentName;
|
|
36
|
+
/**
|
|
37
|
+
* Name of a brand the theme defines. Rendered once, as `data-brand` on the
|
|
38
|
+
* group element, so every item inherits it. Omitted, the group follows the
|
|
39
|
+
* nearest `data-brand` ancestor.
|
|
40
|
+
*/
|
|
41
|
+
brand?: string | undefined;
|
|
36
42
|
/** Button size (xl excluded — too large for grouped toggles) */
|
|
37
43
|
size?: Exclude<ToggleProp<"size">, "xl">;
|
|
38
44
|
/** Square every item at the current size, for icon-only options */
|
|
39
45
|
iconOnly?: boolean;
|
|
40
46
|
/** Disable all options */
|
|
41
47
|
disabled?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Input name for native form submission. The selection is mirrored into
|
|
50
|
+
* hidden `<input>`s — `name` in single mode, `${name}[]` in multiple mode.
|
|
51
|
+
*/
|
|
52
|
+
name?: string;
|
|
53
|
+
/** The `form` attribute for the hidden input(s), for a group rendered outside its `<form>`. */
|
|
54
|
+
form?: string;
|
|
42
55
|
};
|
|
43
56
|
|
|
44
57
|
export type ToggleGroupSingleProps = ToggleGroupBaseProps & {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { autoUpdate, flip, offset, type Placement, shift, useDismiss, useFloating, useFocus, useHover, useInteractions, useRole } from "@floating-ui/react";
|
|
2
4
|
import { useControllableState } from "@sixthshift/design-system/hooks";
|
|
5
|
+
import { closestBrand } from "../../internal/brandScope";
|
|
3
6
|
import { TooltipBody } from "./components/TooltipBody";
|
|
4
7
|
import { TooltipContext } from "./components/TooltipContext";
|
|
5
8
|
import { TooltipTrigger } from "./components/TooltipTrigger";
|
|
@@ -53,6 +56,8 @@ const TooltipRoot = ({ open: controlledOpen, onOpenChange, placement = "top", de
|
|
|
53
56
|
setFloating: refs.setFloating,
|
|
54
57
|
},
|
|
55
58
|
floatingStyles,
|
|
59
|
+
// Read at render: `domReference` is state, so this updates once the trigger mounts.
|
|
60
|
+
inheritedBrand: closestBrand(context.elements.domReference),
|
|
56
61
|
getReferenceProps,
|
|
57
62
|
getFloatingProps,
|
|
58
63
|
};
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { FloatingPortal } from "@floating-ui/react";
|
|
2
4
|
import { cn } from "@sixthshift/design-system/utils";
|
|
3
5
|
import * as React from "react";
|
|
4
6
|
import { useTooltipContext } from "./TooltipContext";
|
|
5
7
|
|
|
6
|
-
export type TooltipBodyProps = React.HTMLAttributes<HTMLDivElement
|
|
8
|
+
export type TooltipBodyProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
9
|
+
/**
|
|
10
|
+
* Name of a brand the theme defines, rendered as `data-brand`. Omitted, the
|
|
11
|
+
* body copies the brand scope of its trigger, which the portal would
|
|
12
|
+
* otherwise leave behind.
|
|
13
|
+
*/
|
|
14
|
+
brand?: string | undefined;
|
|
15
|
+
};
|
|
7
16
|
|
|
8
|
-
export const TooltipBody = React.forwardRef<HTMLDivElement, TooltipBodyProps>(({ className, children, ...props }, forwardedRef) => {
|
|
9
|
-
const { open, refs, floatingStyles, getFloatingProps } = useTooltipContext();
|
|
17
|
+
export const TooltipBody = React.forwardRef<HTMLDivElement, TooltipBodyProps>(({ className, brand, children, ...props }, forwardedRef) => {
|
|
18
|
+
const { open, refs, floatingStyles, inheritedBrand, getFloatingProps } = useTooltipContext();
|
|
10
19
|
|
|
11
20
|
if (!open) return null;
|
|
12
21
|
|
|
@@ -19,6 +28,7 @@ export const TooltipBody = React.forwardRef<HTMLDivElement, TooltipBodyProps>(({
|
|
|
19
28
|
else if (forwardedRef) forwardedRef.current = node;
|
|
20
29
|
}}
|
|
21
30
|
style={floatingStyles}
|
|
31
|
+
data-brand={brand ?? inheritedBrand}
|
|
22
32
|
className={cn("z-popover rounded-lg border border-border-normal bg-bg-normal px-2.5 py-1.5 text-fg-normal text-xs shadow-lg", className)}
|
|
23
33
|
{...getFloatingProps(props)}
|
|
24
34
|
>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { createContext, useContext } from "react";
|
|
2
4
|
|
|
3
5
|
export type TooltipContextValue = {
|
|
@@ -7,6 +9,8 @@ export type TooltipContextValue = {
|
|
|
7
9
|
setFloating: (node: HTMLElement | null) => void;
|
|
8
10
|
};
|
|
9
11
|
floatingStyles: React.CSSProperties;
|
|
12
|
+
/** The trigger's brand scope, re-stamped on the portalled body. */
|
|
13
|
+
inheritedBrand: string | undefined;
|
|
10
14
|
getReferenceProps: (props?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
|
|
11
15
|
getFloatingProps: (props?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
|
|
12
16
|
};
|
package/src/hooks/usePresence.ts
CHANGED
package/src/hooks/useStack.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type Dispatch, type Reducer, startTransition, useCallback, useEffect, useReducer, useRef } from "react";
|
|
2
4
|
|
|
3
5
|
type Id = string | number;
|
|
4
6
|
type Transition = {
|
|
@@ -70,23 +72,44 @@ export function useStack<T extends StackItem>(initialStack: T[] = []): [T[], Sta
|
|
|
70
72
|
|
|
71
73
|
const [state, dispatch] = useReducer(reducer, initialStack);
|
|
72
74
|
|
|
75
|
+
// One removal timer per transitioning item. The effect re-runs on every
|
|
76
|
+
// state change, so timers are tracked in a ref keyed by item id: an item
|
|
77
|
+
// already scheduled is never scheduled again (re-running the effect must not
|
|
78
|
+
// reset or duplicate its countdown), and a timer whose item has left the
|
|
79
|
+
// stack by other means is cancelled rather than left to fire at a reused id.
|
|
80
|
+
const removalTimersRef = useRef(new Map<Id, ReturnType<typeof setTimeout>>());
|
|
81
|
+
|
|
73
82
|
useEffect(() => {
|
|
74
|
-
const
|
|
83
|
+
const timers = removalTimersRef.current;
|
|
84
|
+
const transitioning = new Set(state.filter((item) => item.transition).map((item) => item.id));
|
|
75
85
|
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
for (const [id, timer] of timers) {
|
|
87
|
+
if (!transitioning.has(id)) {
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
timers.delete(id);
|
|
90
|
+
}
|
|
78
91
|
}
|
|
79
92
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
87
|
-
}
|
|
93
|
+
for (const item of state) {
|
|
94
|
+
if (!item.transition || timers.has(item.id)) continue;
|
|
95
|
+
const timer = setTimeout(() => {
|
|
96
|
+
timers.delete(item.id);
|
|
97
|
+
dispatch({ type: "remove", id: item.id });
|
|
98
|
+
}, item.transition.duration);
|
|
99
|
+
timers.set(item.id, timer);
|
|
100
|
+
}
|
|
88
101
|
}, [state]);
|
|
89
102
|
|
|
103
|
+
// Unmount only: without this, a stack unmounted mid-transition dispatches
|
|
104
|
+
// into an unmounted reducer.
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
const timers = removalTimersRef.current;
|
|
107
|
+
return () => {
|
|
108
|
+
for (const timer of timers.values()) clearTimeout(timer);
|
|
109
|
+
timers.clear();
|
|
110
|
+
};
|
|
111
|
+
}, []);
|
|
112
|
+
|
|
90
113
|
// Memoize the dispatch wrapper to prevent unnecessary re-renders
|
|
91
114
|
// dispatch from useReducer is stable, so this only creates once
|
|
92
115
|
const wrappedDispatch = useCallback((params: Action<T>) => {
|
package/src/hooks/useTheme.ts
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The brand an element sits in: the `data-brand` of it or its nearest
|
|
7
|
+
* ancestor, or `undefined` outside any scope.
|
|
8
|
+
*
|
|
9
|
+
* Overlays need this because a portal moves their content out from under the
|
|
10
|
+
* element that set `data-brand`, so CSS inheritance no longer carries it. The
|
|
11
|
+
* overlay reads the brand off its trigger and re-stamps it on its own element.
|
|
12
|
+
* The value is copied verbatim, unknown names included: the theme only gives
|
|
13
|
+
* listed names meaning, so an unknown one resolves exactly as it would have in
|
|
14
|
+
* place.
|
|
15
|
+
*/
|
|
16
|
+
export function closestBrand(element: Element | null | undefined): string | undefined {
|
|
17
|
+
return element?.closest?.("[data-brand]")?.getAttribute("data-brand") ?? undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const focusedBrand = () => (typeof document === "undefined" ? undefined : closestBrand(document.activeElement));
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The brand of whatever held focus when the calling overlay opened.
|
|
24
|
+
*
|
|
25
|
+
* For Modal and Sheet, which have no reference element: the thing that opened
|
|
26
|
+
* them is almost always the focused control, and it still holds focus during
|
|
27
|
+
* the render that opens them, before the focus manager moves it. Captured on
|
|
28
|
+
* each closed → open transition and kept through the close, so neither focus
|
|
29
|
+
* moving into the dialog nor the exit animation changes it. When nothing useful
|
|
30
|
+
* was focused (Safari does not focus a clicked button) this is `undefined`, and
|
|
31
|
+
* the overlay inherits from wherever its portal landed.
|
|
32
|
+
*/
|
|
33
|
+
export function useOpenerBrand(open: boolean): string | undefined {
|
|
34
|
+
const [captured, setCaptured] = useState(() => ({ open, brand: open ? focusedBrand() : undefined }));
|
|
35
|
+
// Adjusting state during render, React's pattern for deriving from a prop
|
|
36
|
+
// change: an effect would run after the focus manager has already moved focus.
|
|
37
|
+
if (captured.open !== open) setCaptured({ open, brand: open ? focusedBrand() : captured.brand });
|
|
38
|
+
return captured.brand;
|
|
39
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registry of open "escape layers" — transient floating overlays (popovers,
|
|
7
|
+
* select dropdowns, picker calendars) that should consume an Escape press
|
|
8
|
+
* before any dialog beneath them reacts to it.
|
|
9
|
+
*
|
|
10
|
+
* The dialogs and these overlays each listen for Escape on `document`
|
|
11
|
+
* independently (floating-ui's `useDismiss` has no tree here), and document
|
|
12
|
+
* listeners fire in registration order — usually the dialog's first, since it
|
|
13
|
+
* opened first. So a dialog cannot rely on `defaultPrevented`; instead it asks
|
|
14
|
+
* this registry whether a layer is open and, if so, leaves the Escape to it.
|
|
15
|
+
* The registry is read synchronously during the event, before React commits
|
|
16
|
+
* the layer's close, so the layer that is handling this Escape still counts.
|
|
17
|
+
*
|
|
18
|
+
* Module-level on purpose: Popover, Select and Modal live in separate subpath
|
|
19
|
+
* entries with no shared context, and a context would also miss overlays
|
|
20
|
+
* rendered outside an `OverlayProvider`.
|
|
21
|
+
*/
|
|
22
|
+
const transientLayers = new Set<symbol>();
|
|
23
|
+
const dialogLayers = new Set<symbol>();
|
|
24
|
+
|
|
25
|
+
/** True while any transient escape-consuming overlay (popover-like) is open. */
|
|
26
|
+
export const hasOpenEscapeLayer = () => transientLayers.size > 0;
|
|
27
|
+
|
|
28
|
+
/** True while any modal dialog is open. A non-modal Sheet under a Modal defers Escape to it. */
|
|
29
|
+
export const hasOpenEscapeDialog = () => dialogLayers.size > 0;
|
|
30
|
+
|
|
31
|
+
function useRegistration(registry: Set<symbol>, active: boolean) {
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!active) return;
|
|
34
|
+
const token = Symbol("escape-layer");
|
|
35
|
+
registry.add(token);
|
|
36
|
+
return () => {
|
|
37
|
+
registry.delete(token);
|
|
38
|
+
};
|
|
39
|
+
}, [registry, active]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Marks this component as an open transient escape layer while `active` is
|
|
44
|
+
* true. Call with the overlay's `open` state.
|
|
45
|
+
*/
|
|
46
|
+
export function useEscapeLayer(active: boolean) {
|
|
47
|
+
useRegistration(transientLayers, active);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Marks this component as an open modal dialog while `active` is true. */
|
|
51
|
+
export function useEscapeDialog(active: boolean) {
|
|
52
|
+
useRegistration(dialogLayers, active);
|
|
53
|
+
}
|