@gnome-ui/react 1.44.0 β 1.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/components/AboutDialog/AboutDialog.cjs +1 -1
- package/dist/components/AboutDialog/AboutDialog.cjs.map +1 -1
- package/dist/components/AboutDialog/AboutDialog.js +1 -1
- package/dist/components/AboutDialog/AboutDialog.js.map +1 -1
- package/dist/components/AboutDialog/AboutDialog.module.css.cjs +1 -1
- package/dist/components/AboutDialog/AboutDialog.module.css.cjs.map +1 -1
- package/dist/components/AboutDialog/AboutDialog.module.css.js +3 -3
- package/dist/components/AboutDialog/AboutDialog.module.css.js.map +1 -1
- package/dist/components/AboutDialog/index.d.ts +1 -1
- package/dist/components/ActionRow/ActionRow.cjs.map +1 -1
- package/dist/components/ActionRow/ActionRow.d.ts +1 -1
- package/dist/components/ActionRow/ActionRow.js.map +1 -1
- package/dist/components/ActionRow/ActionRow.module.css.cjs +1 -1
- package/dist/components/ActionRow/ActionRow.module.css.cjs.map +1 -1
- package/dist/components/ActionRow/ActionRow.module.css.js +9 -9
- package/dist/components/ActionRow/ActionRow.module.css.js.map +1 -1
- package/dist/components/ActionRow/index.d.ts +1 -1
- package/dist/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.d.ts +2 -2
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.module.css.cjs +1 -1
- package/dist/components/Avatar/Avatar.module.css.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.module.css.js +16 -16
- package/dist/components/Avatar/Avatar.module.css.js.map +1 -1
- package/dist/components/Avatar/index.d.ts +1 -1
- package/dist/components/AvatarRotator/AvatarRotator.cjs.map +1 -1
- package/dist/components/AvatarRotator/AvatarRotator.js.map +1 -1
- package/dist/components/AvatarRotator/index.d.ts +1 -1
- package/dist/components/Badge/Badge.cjs.map +1 -1
- package/dist/components/Badge/Badge.d.ts +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.module.css.cjs +1 -1
- package/dist/components/Badge/Badge.module.css.cjs.map +1 -1
- package/dist/components/Badge/Badge.module.css.js +9 -9
- package/dist/components/Badge/Badge.module.css.js.map +1 -1
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/Banner/Banner.cjs.map +1 -1
- package/dist/components/Banner/Banner.d.ts +1 -1
- package/dist/components/Banner/Banner.js.map +1 -1
- package/dist/components/Banner/Banner.module.css.cjs +1 -1
- package/dist/components/Banner/Banner.module.css.cjs.map +1 -1
- package/dist/components/Banner/Banner.module.css.js +5 -5
- package/dist/components/Banner/Banner.module.css.js.map +1 -1
- package/dist/components/Banner/index.d.ts +1 -1
- package/dist/components/Bin/Bin.cjs.map +1 -1
- package/dist/components/Bin/Bin.js.map +1 -1
- package/dist/components/Bin/index.d.ts +1 -1
- package/dist/components/Blockquote/Blockquote.cjs.map +1 -1
- package/dist/components/Blockquote/Blockquote.d.ts +1 -1
- package/dist/components/Blockquote/Blockquote.js.map +1 -1
- package/dist/components/Blockquote/Blockquote.module.css.cjs +1 -1
- package/dist/components/Blockquote/Blockquote.module.css.cjs.map +1 -1
- package/dist/components/Blockquote/Blockquote.module.css.js +11 -11
- package/dist/components/Blockquote/Blockquote.module.css.js.map +1 -1
- package/dist/components/Blockquote/index.d.ts +1 -1
- package/dist/components/BottomSheet/BottomSheet.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.d.ts +1 -1
- package/dist/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.module.css.cjs +1 -1
- package/dist/components/BottomSheet/BottomSheet.module.css.cjs.map +1 -1
- package/dist/components/BottomSheet/BottomSheet.module.css.js +3 -3
- package/dist/components/BottomSheet/BottomSheet.module.css.js.map +1 -1
- package/dist/components/BottomSheet/index.d.ts +1 -1
- package/dist/components/Box/Box.cjs.map +1 -1
- package/dist/components/Box/Box.d.ts +3 -3
- package/dist/components/Box/Box.js.map +1 -1
- package/dist/components/Box/index.d.ts +1 -1
- package/dist/components/BoxedList/BoxedList.cjs +1 -1
- package/dist/components/BoxedList/BoxedList.cjs.map +1 -1
- package/dist/components/BoxedList/BoxedList.d.ts +1 -1
- package/dist/components/BoxedList/BoxedList.js +0 -1
- package/dist/components/BoxedList/BoxedList.js.map +1 -1
- package/dist/components/BoxedList/BoxedList.module.css.cjs +1 -1
- package/dist/components/BoxedList/BoxedList.module.css.cjs.map +1 -1
- package/dist/components/BoxedList/BoxedList.module.css.js +5 -5
- package/dist/components/BoxedList/BoxedList.module.css.js.map +1 -1
- package/dist/components/BoxedList/index.d.ts +1 -1
- package/dist/components/BreakpointBin/BreakpointBin.cjs +1 -1
- package/dist/components/BreakpointBin/BreakpointBin.cjs.map +1 -1
- package/dist/components/BreakpointBin/BreakpointBin.d.ts +1 -1
- package/dist/components/BreakpointBin/BreakpointBin.js +1 -1
- package/dist/components/BreakpointBin/BreakpointBin.js.map +1 -1
- package/dist/components/BreakpointBin/index.d.ts +1 -1
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.d.ts +3 -3
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/Button.module.css.cjs +1 -1
- package/dist/components/Button/Button.module.css.cjs.map +1 -1
- package/dist/components/Button/Button.module.css.js +11 -11
- package/dist/components/Button/Button.module.css.js.map +1 -1
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/ButtonContent/ButtonContent.cjs.map +1 -1
- package/dist/components/ButtonContent/ButtonContent.d.ts +1 -1
- package/dist/components/ButtonContent/ButtonContent.js.map +1 -1
- package/dist/components/ButtonContent/index.d.ts +1 -1
- package/dist/components/ButtonRow/ButtonRow.cjs.map +1 -1
- package/dist/components/ButtonRow/ButtonRow.d.ts +1 -1
- package/dist/components/ButtonRow/ButtonRow.js.map +1 -1
- package/dist/components/ButtonRow/ButtonRow.module.css.cjs +1 -1
- package/dist/components/ButtonRow/ButtonRow.module.css.cjs.map +1 -1
- package/dist/components/ButtonRow/ButtonRow.module.css.js +7 -7
- package/dist/components/ButtonRow/ButtonRow.module.css.js.map +1 -1
- package/dist/components/ButtonRow/index.d.ts +1 -1
- package/dist/components/Card/Card.cjs.map +1 -1
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Card/Card.module.css.cjs +1 -1
- package/dist/components/Card/Card.module.css.cjs.map +1 -1
- package/dist/components/Card/Card.module.css.js +5 -5
- package/dist/components/Card/Card.module.css.js.map +1 -1
- package/dist/components/Card/index.d.ts +1 -1
- package/dist/components/Carousel/Carousel.cjs +1 -1
- package/dist/components/Carousel/Carousel.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.d.ts +1 -1
- package/dist/components/Carousel/Carousel.js +7 -6
- package/dist/components/Carousel/Carousel.js.map +1 -1
- package/dist/components/Carousel/Carousel.module.css.cjs +1 -1
- package/dist/components/Carousel/Carousel.module.css.cjs.map +1 -1
- package/dist/components/Carousel/Carousel.module.css.js +10 -10
- package/dist/components/Carousel/Carousel.module.css.js.map +1 -1
- package/dist/components/Carousel/index.d.ts +1 -1
- package/dist/components/CheckRow/CheckRow.cjs.map +1 -1
- package/dist/components/CheckRow/CheckRow.d.ts +1 -1
- package/dist/components/CheckRow/CheckRow.js.map +1 -1
- package/dist/components/CheckRow/CheckRow.module.css.cjs +1 -1
- package/dist/components/CheckRow/CheckRow.module.css.cjs.map +1 -1
- package/dist/components/CheckRow/CheckRow.module.css.js +10 -10
- package/dist/components/CheckRow/CheckRow.module.css.js.map +1 -1
- package/dist/components/CheckRow/index.d.ts +1 -1
- package/dist/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +2 -2
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.css.cjs +1 -1
- package/dist/components/Checkbox/Checkbox.module.css.cjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.module.css.js +1 -1
- package/dist/components/Checkbox/Checkbox.module.css.js.map +1 -1
- package/dist/components/Checkbox/index.d.ts +1 -1
- package/dist/components/Chip/Chip.cjs.map +1 -1
- package/dist/components/Chip/Chip.d.ts +1 -1
- package/dist/components/Chip/Chip.js.map +1 -1
- package/dist/components/Chip/Chip.module.css.cjs +1 -1
- package/dist/components/Chip/Chip.module.css.cjs.map +1 -1
- package/dist/components/Chip/Chip.module.css.js +7 -7
- package/dist/components/Chip/Chip.module.css.js.map +1 -1
- package/dist/components/Chip/index.d.ts +1 -1
- package/dist/components/Clamp/Clamp.cjs.map +1 -1
- package/dist/components/Clamp/Clamp.js.map +1 -1
- package/dist/components/Clamp/index.d.ts +1 -1
- package/dist/components/ColorPicker/ColorPicker.cjs.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.d.ts +6 -6
- package/dist/components/ColorPicker/ColorPicker.js.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.module.css.cjs +1 -1
- package/dist/components/ColorPicker/ColorPicker.module.css.cjs.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.module.css.js +4 -4
- package/dist/components/ColorPicker/ColorPicker.module.css.js.map +1 -1
- package/dist/components/ColorPicker/index.d.ts +1 -1
- package/dist/components/ColumnView/ColumnView.cjs +1 -1
- package/dist/components/ColumnView/ColumnView.cjs.map +1 -1
- package/dist/components/ColumnView/ColumnView.d.ts +3 -3
- package/dist/components/ColumnView/ColumnView.js +2 -5
- package/dist/components/ColumnView/ColumnView.js.map +1 -1
- package/dist/components/ColumnView/ColumnView.module.css.cjs +1 -1
- package/dist/components/ColumnView/ColumnView.module.css.cjs.map +1 -1
- package/dist/components/ColumnView/ColumnView.module.css.js +22 -22
- package/dist/components/ColumnView/ColumnView.module.css.js.map +1 -1
- package/dist/components/ColumnView/index.d.ts +1 -1
- package/dist/components/ComboRow/ComboRow.cjs +1 -1
- package/dist/components/ComboRow/ComboRow.cjs.map +1 -1
- package/dist/components/ComboRow/ComboRow.d.ts +1 -1
- package/dist/components/ComboRow/ComboRow.js +0 -2
- package/dist/components/ComboRow/ComboRow.js.map +1 -1
- package/dist/components/ComboRow/ComboRow.module.css.cjs +1 -1
- package/dist/components/ComboRow/ComboRow.module.css.cjs.map +1 -1
- package/dist/components/ComboRow/ComboRow.module.css.js +3 -3
- package/dist/components/ComboRow/ComboRow.module.css.js.map +1 -1
- package/dist/components/ComboRow/index.d.ts +1 -1
- package/dist/components/ContributionGraph/ContributionGraph.cjs +1 -1
- package/dist/components/ContributionGraph/ContributionGraph.cjs.map +1 -1
- package/dist/components/ContributionGraph/ContributionGraph.js +41 -41
- package/dist/components/ContributionGraph/ContributionGraph.js.map +1 -1
- package/dist/components/ContributionGraph/index.d.ts +1 -1
- package/dist/components/CountDownTimer/CountDownTimer.cjs.map +1 -1
- package/dist/components/CountDownTimer/CountDownTimer.d.ts +3 -3
- package/dist/components/CountDownTimer/CountDownTimer.js.map +1 -1
- package/dist/components/CountDownTimer/index.d.ts +1 -1
- package/dist/components/Dialog/Dialog.cjs.map +1 -1
- package/dist/components/Dialog/Dialog.d.ts +4 -4
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.module.css.cjs +1 -1
- package/dist/components/Dialog/Dialog.module.css.cjs.map +1 -1
- package/dist/components/Dialog/Dialog.module.css.js +6 -6
- package/dist/components/Dialog/Dialog.module.css.js.map +1 -1
- package/dist/components/Dialog/dialogUtils.cjs.map +1 -1
- package/dist/components/Dialog/dialogUtils.js.map +1 -1
- package/dist/components/Dialog/index.d.ts +1 -1
- package/dist/components/Drawer/Drawer.cjs +1 -1
- package/dist/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.d.ts +3 -3
- package/dist/components/Drawer/Drawer.js +49 -38
- package/dist/components/Drawer/Drawer.js.map +1 -1
- package/dist/components/Drawer/Drawer.module.css.cjs +1 -1
- package/dist/components/Drawer/Drawer.module.css.cjs.map +1 -1
- package/dist/components/Drawer/Drawer.module.css.js +7 -6
- package/dist/components/Drawer/Drawer.module.css.js.map +1 -1
- package/dist/components/Drawer/index.d.ts +1 -1
- package/dist/components/Dropdown/Dropdown.cjs.map +1 -1
- package/dist/components/Dropdown/Dropdown.d.ts +2 -2
- package/dist/components/Dropdown/Dropdown.js.map +1 -1
- package/dist/components/Dropdown/Dropdown.module.css.cjs +1 -1
- package/dist/components/Dropdown/Dropdown.module.css.cjs.map +1 -1
- package/dist/components/Dropdown/Dropdown.module.css.js +3 -3
- package/dist/components/Dropdown/Dropdown.module.css.js.map +1 -1
- package/dist/components/Dropdown/index.d.ts +1 -1
- package/dist/components/EntryRow/EntryRow.cjs.map +1 -1
- package/dist/components/EntryRow/EntryRow.js.map +1 -1
- package/dist/components/EntryRow/EntryRow.module.css.cjs +1 -1
- package/dist/components/EntryRow/EntryRow.module.css.cjs.map +1 -1
- package/dist/components/EntryRow/EntryRow.module.css.js +10 -10
- package/dist/components/EntryRow/EntryRow.module.css.js.map +1 -1
- package/dist/components/EntryRow/index.d.ts +1 -1
- package/dist/components/ExpanderRow/ExpanderRow.cjs.map +1 -1
- package/dist/components/ExpanderRow/ExpanderRow.js.map +1 -1
- package/dist/components/ExpanderRow/ExpanderRow.module.css.cjs +1 -1
- package/dist/components/ExpanderRow/ExpanderRow.module.css.cjs.map +1 -1
- package/dist/components/ExpanderRow/ExpanderRow.module.css.js +14 -14
- package/dist/components/ExpanderRow/ExpanderRow.module.css.js.map +1 -1
- package/dist/components/ExpanderRow/index.d.ts +1 -1
- package/dist/components/Footer/Footer.cjs.map +1 -1
- package/dist/components/Footer/Footer.js.map +1 -1
- package/dist/components/Footer/index.d.ts +1 -1
- package/dist/components/Frame/Frame.cjs.map +1 -1
- package/dist/components/Frame/Frame.js.map +1 -1
- package/dist/components/Frame/index.d.ts +1 -1
- package/dist/components/GnomeProvider/GnomeContext.cjs.map +1 -1
- package/dist/components/GnomeProvider/GnomeContext.d.ts +5 -5
- package/dist/components/GnomeProvider/GnomeContext.js.map +1 -1
- package/dist/components/GnomeProvider/GnomeProvider.cjs.map +1 -1
- package/dist/components/GnomeProvider/GnomeProvider.js.map +1 -1
- package/dist/components/HeaderBar/HeaderBar.cjs.map +1 -1
- package/dist/components/HeaderBar/HeaderBar.d.ts +1 -1
- package/dist/components/HeaderBar/HeaderBar.js.map +1 -1
- package/dist/components/HeaderBar/index.d.ts +1 -1
- package/dist/components/Icon/Icon.cjs.map +1 -1
- package/dist/components/Icon/Icon.d.ts +2 -2
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/Icon/index.d.ts +1 -1
- package/dist/components/IconButton/IconButton.cjs.map +1 -1
- package/dist/components/IconButton/IconButton.d.ts +2 -2
- package/dist/components/IconButton/IconButton.js.map +1 -1
- package/dist/components/IconButton/index.d.ts +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.cjs +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.cjs.map +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.d.ts +3 -3
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.js +8 -8
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.js.map +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.module.css.cjs +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.module.css.cjs.map +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.module.css.js +10 -10
- package/dist/components/InlineViewSwitcher/InlineViewSwitcher.module.css.js.map +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.cjs.map +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.d.ts +1 -1
- package/dist/components/InlineViewSwitcher/InlineViewSwitcherItem.js.map +1 -1
- package/dist/components/InlineViewSwitcher/index.d.ts +2 -2
- package/dist/components/Link/Link.cjs.map +1 -1
- package/dist/components/Link/Link.js.map +1 -1
- package/dist/components/Link/Link.module.css.cjs +1 -1
- package/dist/components/Link/Link.module.css.cjs.map +1 -1
- package/dist/components/Link/Link.module.css.js +2 -2
- package/dist/components/Link/Link.module.css.js.map +1 -1
- package/dist/components/Link/index.d.ts +1 -1
- package/dist/components/LinkedGroup/LinkedGroup.cjs.map +1 -1
- package/dist/components/LinkedGroup/LinkedGroup.js.map +1 -1
- package/dist/components/LinkedGroup/LinkedGroup.module.css.cjs +1 -1
- package/dist/components/LinkedGroup/LinkedGroup.module.css.cjs.map +1 -1
- package/dist/components/LinkedGroup/LinkedGroup.module.css.js +2 -2
- package/dist/components/LinkedGroup/LinkedGroup.module.css.js.map +1 -1
- package/dist/components/LinkedGroup/index.d.ts +1 -1
- package/dist/components/NavigationSplitView/NavigationSplitView.cjs.map +1 -1
- package/dist/components/NavigationSplitView/NavigationSplitView.d.ts +1 -1
- package/dist/components/NavigationSplitView/NavigationSplitView.js.map +1 -1
- package/dist/components/NavigationSplitView/index.d.ts +1 -1
- package/dist/components/NavigationView/NavigationView.cjs.map +1 -1
- package/dist/components/NavigationView/NavigationView.d.ts +2 -2
- package/dist/components/NavigationView/NavigationView.js.map +1 -1
- package/dist/components/NavigationView/NavigationView.module.css.cjs +1 -1
- package/dist/components/NavigationView/NavigationView.module.css.cjs.map +1 -1
- package/dist/components/NavigationView/NavigationView.module.css.js +3 -3
- package/dist/components/NavigationView/NavigationView.module.css.js.map +1 -1
- package/dist/components/NavigationView/index.d.ts +2 -2
- package/dist/components/OverlaySplitView/OverlaySplitView.cjs.map +1 -1
- package/dist/components/OverlaySplitView/OverlaySplitView.d.ts +2 -2
- package/dist/components/OverlaySplitView/OverlaySplitView.js.map +1 -1
- package/dist/components/OverlaySplitView/OverlaySplitView.module.css.cjs +1 -1
- package/dist/components/OverlaySplitView/OverlaySplitView.module.css.cjs.map +1 -1
- package/dist/components/OverlaySplitView/OverlaySplitView.module.css.js +12 -12
- package/dist/components/OverlaySplitView/OverlaySplitView.module.css.js.map +1 -1
- package/dist/components/OverlaySplitView/index.d.ts +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.cjs.map +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.d.ts +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.js.map +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.module.css.cjs +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.module.css.cjs.map +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.module.css.js +1 -1
- package/dist/components/PasswordEntryRow/PasswordEntryRow.module.css.js.map +1 -1
- package/dist/components/PasswordEntryRow/index.d.ts +1 -1
- package/dist/components/PathBar/PathBar.cjs.map +1 -1
- package/dist/components/PathBar/PathBar.js.map +1 -1
- package/dist/components/PathBar/PathBar.module.css.cjs +1 -1
- package/dist/components/PathBar/PathBar.module.css.cjs.map +1 -1
- package/dist/components/PathBar/PathBar.module.css.js +7 -7
- package/dist/components/PathBar/PathBar.module.css.js.map +1 -1
- package/dist/components/PathBar/index.d.ts +1 -1
- package/dist/components/Popover/Popover.cjs.map +1 -1
- package/dist/components/Popover/Popover.d.ts +2 -2
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/Popover.module.css.cjs +1 -1
- package/dist/components/Popover/Popover.module.css.cjs.map +1 -1
- package/dist/components/Popover/Popover.module.css.js +7 -7
- package/dist/components/Popover/Popover.module.css.js.map +1 -1
- package/dist/components/Popover/index.d.ts +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.cjs +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.cjs.map +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.d.ts +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.js +0 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.js.map +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.module.css.cjs +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.module.css.cjs.map +1 -1
- package/dist/components/PreferencesDialog/PreferencesDialog.module.css.js +3 -3
- package/dist/components/PreferencesDialog/PreferencesDialog.module.css.js.map +1 -1
- package/dist/components/PreferencesDialog/index.d.ts +1 -1
- package/dist/components/PreferencesGroup/PreferencesGroup.cjs.map +1 -1
- package/dist/components/PreferencesGroup/PreferencesGroup.js.map +1 -1
- package/dist/components/PreferencesGroup/index.d.ts +1 -1
- package/dist/components/PreferencesPage/PreferencesPage.cjs.map +1 -1
- package/dist/components/PreferencesPage/PreferencesPage.js.map +1 -1
- package/dist/components/PreferencesPage/index.d.ts +1 -1
- package/dist/components/ProgressBar/ProgressBar.cjs.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.d.ts +4 -4
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.module.css.cjs +1 -1
- package/dist/components/ProgressBar/ProgressBar.module.css.cjs.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.module.css.js +8 -8
- package/dist/components/ProgressBar/ProgressBar.module.css.js.map +1 -1
- package/dist/components/ProgressBar/index.d.ts +1 -1
- package/dist/components/RadioButton/RadioButton.cjs.map +1 -1
- package/dist/components/RadioButton/RadioButton.d.ts +2 -2
- package/dist/components/RadioButton/RadioButton.js.map +1 -1
- package/dist/components/RadioButton/RadioButton.module.css.cjs +1 -1
- package/dist/components/RadioButton/RadioButton.module.css.cjs.map +1 -1
- package/dist/components/RadioButton/RadioButton.module.css.js +1 -1
- package/dist/components/RadioButton/RadioButton.module.css.js.map +1 -1
- package/dist/components/RadioButton/index.d.ts +1 -1
- package/dist/components/SearchBar/SearchBar.cjs +1 -1
- package/dist/components/SearchBar/SearchBar.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.d.ts +1 -1
- package/dist/components/SearchBar/SearchBar.js +1 -3
- package/dist/components/SearchBar/SearchBar.js.map +1 -1
- package/dist/components/SearchBar/SearchBar.module.css.cjs +1 -1
- package/dist/components/SearchBar/SearchBar.module.css.cjs.map +1 -1
- package/dist/components/SearchBar/SearchBar.module.css.js +13 -13
- package/dist/components/SearchBar/SearchBar.module.css.js.map +1 -1
- package/dist/components/SearchBar/index.d.ts +1 -1
- package/dist/components/SegmentedBar/SegmentedBar.cjs +2 -0
- package/dist/components/SegmentedBar/SegmentedBar.cjs.map +1 -0
- package/dist/components/SegmentedBar/SegmentedBar.d.ts +42 -0
- package/dist/components/SegmentedBar/SegmentedBar.js +40 -0
- package/dist/components/SegmentedBar/SegmentedBar.js.map +1 -0
- package/dist/components/SegmentedBar/SegmentedBar.module.css.cjs +2 -0
- package/dist/components/SegmentedBar/SegmentedBar.module.css.cjs.map +1 -0
- package/dist/components/SegmentedBar/SegmentedBar.module.css.js +18 -0
- package/dist/components/SegmentedBar/SegmentedBar.module.css.js.map +1 -0
- package/dist/components/SegmentedBar/index.d.ts +2 -0
- package/dist/components/SegmentedBar.cjs +1 -0
- package/dist/components/SegmentedBar.d.ts +2 -0
- package/dist/components/SegmentedBar.js +2 -0
- package/dist/components/Separator/Separator.cjs.map +1 -1
- package/dist/components/Separator/Separator.d.ts +1 -1
- package/dist/components/Separator/Separator.js.map +1 -1
- package/dist/components/Separator/index.d.ts +1 -1
- package/dist/components/ShortcutLabel/ShortcutLabel.cjs.map +1 -1
- package/dist/components/ShortcutLabel/ShortcutLabel.js.map +1 -1
- package/dist/components/ShortcutLabel/index.d.ts +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.cjs +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.cjs.map +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.js +0 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.js.map +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.cjs +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.cjs.map +1 -1
- package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.js +3 -3
- package/dist/components/ShortcutsDialog/ShortcutsDialog.module.css.js.map +1 -1
- package/dist/components/ShortcutsDialog/index.d.ts +1 -1
- package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.d.ts +2 -2
- package/dist/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.module.css.cjs +1 -1
- package/dist/components/Sidebar/Sidebar.module.css.cjs.map +1 -1
- package/dist/components/Sidebar/Sidebar.module.css.js +2 -2
- package/dist/components/Sidebar/Sidebar.module.css.js.map +1 -1
- package/dist/components/Sidebar/SidebarItem.cjs.map +1 -1
- package/dist/components/Sidebar/SidebarItem.d.ts +1 -1
- package/dist/components/Sidebar/SidebarItem.js.map +1 -1
- package/dist/components/Sidebar/SidebarSection.cjs +1 -1
- package/dist/components/Sidebar/SidebarSection.cjs.map +1 -1
- package/dist/components/Sidebar/SidebarSection.d.ts +1 -1
- package/dist/components/Sidebar/SidebarSection.js +0 -1
- package/dist/components/Sidebar/SidebarSection.js.map +1 -1
- package/dist/components/Sidebar/index.d.ts +4 -4
- package/dist/components/Sidebar.cjs +1 -1
- package/dist/components/Sidebar.js +3 -3
- package/dist/components/Skeleton/Skeleton.cjs.map +1 -1
- package/dist/components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.module.css.cjs +1 -1
- package/dist/components/Skeleton/Skeleton.module.css.cjs.map +1 -1
- package/dist/components/Skeleton/Skeleton.module.css.js +7 -7
- package/dist/components/Skeleton/Skeleton.module.css.js.map +1 -1
- package/dist/components/Skeleton/index.d.ts +1 -1
- package/dist/components/Slider/Slider.cjs.map +1 -1
- package/dist/components/Slider/Slider.d.ts +5 -5
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Slider/Slider.module.css.cjs +1 -1
- package/dist/components/Slider/Slider.module.css.cjs.map +1 -1
- package/dist/components/Slider/Slider.module.css.js +9 -9
- package/dist/components/Slider/Slider.module.css.js.map +1 -1
- package/dist/components/Slider/index.d.ts +1 -1
- package/dist/components/SpinButton/SpinButton.cjs.map +1 -1
- package/dist/components/SpinButton/SpinButton.d.ts +4 -4
- package/dist/components/SpinButton/SpinButton.js.map +1 -1
- package/dist/components/SpinButton/SpinButton.module.css.cjs +1 -1
- package/dist/components/SpinButton/SpinButton.module.css.cjs.map +1 -1
- package/dist/components/SpinButton/SpinButton.module.css.js +4 -4
- package/dist/components/SpinButton/SpinButton.module.css.js.map +1 -1
- package/dist/components/SpinButton/index.d.ts +1 -1
- package/dist/components/SpinRow/SpinRow.cjs.map +1 -1
- package/dist/components/SpinRow/SpinRow.d.ts +1 -1
- package/dist/components/SpinRow/SpinRow.js.map +1 -1
- package/dist/components/SpinRow/SpinRow.module.css.cjs +1 -1
- package/dist/components/SpinRow/SpinRow.module.css.cjs.map +1 -1
- package/dist/components/SpinRow/SpinRow.module.css.js +9 -9
- package/dist/components/SpinRow/SpinRow.module.css.js.map +1 -1
- package/dist/components/SpinRow/index.d.ts +1 -1
- package/dist/components/Spinner/Spinner.cjs.map +1 -1
- package/dist/components/Spinner/Spinner.d.ts +1 -1
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/Spinner/Spinner.module.css.cjs +1 -1
- package/dist/components/Spinner/Spinner.module.css.cjs.map +1 -1
- package/dist/components/Spinner/Spinner.module.css.js +5 -5
- package/dist/components/Spinner/Spinner.module.css.js.map +1 -1
- package/dist/components/Spinner/index.d.ts +1 -1
- package/dist/components/SplitButton/SplitButton.cjs.map +1 -1
- package/dist/components/SplitButton/SplitButton.d.ts +2 -2
- package/dist/components/SplitButton/SplitButton.js.map +1 -1
- package/dist/components/SplitButton/SplitButton.module.css.cjs +1 -1
- package/dist/components/SplitButton/SplitButton.module.css.cjs.map +1 -1
- package/dist/components/SplitButton/SplitButton.module.css.js +10 -10
- package/dist/components/SplitButton/SplitButton.module.css.js.map +1 -1
- package/dist/components/SplitButton/index.d.ts +1 -1
- package/dist/components/StatusBadge/StatusBadge.cjs.map +1 -1
- package/dist/components/StatusBadge/StatusBadge.d.ts +1 -1
- package/dist/components/StatusBadge/StatusBadge.js.map +1 -1
- package/dist/components/StatusBadge/StatusBadge.module.css.cjs +1 -1
- package/dist/components/StatusBadge/StatusBadge.module.css.cjs.map +1 -1
- package/dist/components/StatusBadge/StatusBadge.module.css.js +7 -7
- package/dist/components/StatusBadge/StatusBadge.module.css.js.map +1 -1
- package/dist/components/StatusBadge/index.d.ts +1 -1
- package/dist/components/StatusPage/StatusPage.cjs.map +1 -1
- package/dist/components/StatusPage/StatusPage.d.ts +1 -1
- package/dist/components/StatusPage/StatusPage.js.map +1 -1
- package/dist/components/StatusPage/index.d.ts +1 -1
- package/dist/components/Switch/Switch.cjs.map +1 -1
- package/dist/components/Switch/Switch.d.ts +2 -2
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Switch/Switch.module.css.cjs +1 -1
- package/dist/components/Switch/Switch.module.css.cjs.map +1 -1
- package/dist/components/Switch/Switch.module.css.js +1 -1
- package/dist/components/Switch/Switch.module.css.js.map +1 -1
- package/dist/components/Switch/index.d.ts +1 -1
- package/dist/components/SwitchRow/SwitchRow.cjs.map +1 -1
- package/dist/components/SwitchRow/SwitchRow.d.ts +1 -1
- package/dist/components/SwitchRow/SwitchRow.js.map +1 -1
- package/dist/components/SwitchRow/SwitchRow.module.css.cjs +1 -1
- package/dist/components/SwitchRow/SwitchRow.module.css.cjs.map +1 -1
- package/dist/components/SwitchRow/SwitchRow.module.css.js +9 -9
- package/dist/components/SwitchRow/SwitchRow.module.css.js.map +1 -1
- package/dist/components/SwitchRow/index.d.ts +1 -1
- package/dist/components/Tabs/TabBar.cjs +1 -1
- package/dist/components/Tabs/TabBar.cjs.map +1 -1
- package/dist/components/Tabs/TabBar.d.ts +2 -2
- package/dist/components/Tabs/TabBar.js +8 -8
- package/dist/components/Tabs/TabBar.js.map +1 -1
- package/dist/components/Tabs/TabItem.cjs +1 -1
- package/dist/components/Tabs/TabItem.cjs.map +1 -1
- package/dist/components/Tabs/TabItem.d.ts +4 -2
- package/dist/components/Tabs/TabItem.js +34 -32
- package/dist/components/Tabs/TabItem.js.map +1 -1
- package/dist/components/Tabs/TabPanel.cjs +1 -1
- package/dist/components/Tabs/TabPanel.cjs.map +1 -1
- package/dist/components/Tabs/TabPanel.js +0 -1
- package/dist/components/Tabs/TabPanel.js.map +1 -1
- package/dist/components/Tabs/Tabs.module.css.cjs +1 -1
- package/dist/components/Tabs/Tabs.module.css.cjs.map +1 -1
- package/dist/components/Tabs/Tabs.module.css.js +10 -9
- package/dist/components/Tabs/Tabs.module.css.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +3 -3
- package/dist/components/TerminalView/TerminalView.cjs +1 -1
- package/dist/components/TerminalView/TerminalView.cjs.map +1 -1
- package/dist/components/TerminalView/TerminalView.d.ts +1 -1
- package/dist/components/TerminalView/TerminalView.js +1 -1
- package/dist/components/TerminalView/TerminalView.js.map +1 -1
- package/dist/components/TerminalView/index.d.ts +1 -1
- package/dist/components/Text/Text.cjs.map +1 -1
- package/dist/components/Text/Text.d.ts +2 -2
- package/dist/components/Text/Text.js.map +1 -1
- package/dist/components/Text/index.d.ts +1 -1
- package/dist/components/TextField/TextField.cjs.map +1 -1
- package/dist/components/TextField/TextField.d.ts +1 -1
- package/dist/components/TextField/TextField.js.map +1 -1
- package/dist/components/TextField/TextField.module.css.cjs +1 -1
- package/dist/components/TextField/TextField.module.css.cjs.map +1 -1
- package/dist/components/TextField/TextField.module.css.js +7 -7
- package/dist/components/TextField/TextField.module.css.js.map +1 -1
- package/dist/components/TextField/index.d.ts +1 -1
- package/dist/components/Timeline/Timeline.cjs.map +1 -1
- package/dist/components/Timeline/Timeline.d.ts +2 -2
- package/dist/components/Timeline/Timeline.js.map +1 -1
- package/dist/components/Timeline/index.d.ts +1 -1
- package/dist/components/Toast/Toast.cjs +1 -1
- package/dist/components/Toast/Toast.cjs.map +1 -1
- package/dist/components/Toast/Toast.d.ts +1 -1
- package/dist/components/Toast/Toast.js +39 -35
- package/dist/components/Toast/Toast.js.map +1 -1
- package/dist/components/Toast/Toast.module.css.cjs +1 -1
- package/dist/components/Toast/Toast.module.css.cjs.map +1 -1
- package/dist/components/Toast/Toast.module.css.js +2 -2
- package/dist/components/Toast/Toast.module.css.js.map +1 -1
- package/dist/components/Toast/Toaster.cjs.map +1 -1
- package/dist/components/Toast/Toaster.d.ts +1 -1
- package/dist/components/Toast/Toaster.js.map +1 -1
- package/dist/components/Toast/index.d.ts +2 -2
- package/dist/components/ToggleGroup/ToggleGroup.cjs +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.d.ts +2 -2
- package/dist/components/ToggleGroup/ToggleGroup.js +8 -8
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.module.css.cjs +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.module.css.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.module.css.js +6 -6
- package/dist/components/ToggleGroup/ToggleGroup.module.css.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.cjs.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.d.ts +1 -1
- package/dist/components/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/components/ToggleGroup/index.d.ts +2 -2
- package/dist/components/Toolbar/Spacer.cjs.map +1 -1
- package/dist/components/Toolbar/Spacer.d.ts +1 -2
- package/dist/components/Toolbar/Spacer.js.map +1 -1
- package/dist/components/Toolbar/Toolbar.cjs.map +1 -1
- package/dist/components/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/Toolbar/index.d.ts +3 -3
- package/dist/components/Toolbar.cjs +1 -1
- package/dist/components/Toolbar.js +3 -3
- package/dist/components/ToolbarView/ToolbarView.cjs.map +1 -1
- package/dist/components/ToolbarView/ToolbarView.js.map +1 -1
- package/dist/components/ToolbarView/index.d.ts +1 -1
- package/dist/components/Tooltip/Tooltip.cjs +1 -1
- package/dist/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.d.ts +2 -2
- package/dist/components/Tooltip/Tooltip.js +4 -4
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.module.css.cjs +1 -1
- package/dist/components/Tooltip/Tooltip.module.css.cjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.module.css.js +6 -6
- package/dist/components/Tooltip/Tooltip.module.css.js.map +1 -1
- package/dist/components/Tooltip/index.d.ts +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.cjs +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.cjs.map +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.d.ts +2 -2
- package/dist/components/ViewSwitcher/ViewSwitcher.js +8 -8
- package/dist/components/ViewSwitcher/ViewSwitcher.js.map +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.module.css.cjs +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.module.css.cjs.map +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcher.module.css.js +5 -5
- package/dist/components/ViewSwitcher/ViewSwitcher.module.css.js.map +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcherItem.cjs.map +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcherItem.d.ts +1 -1
- package/dist/components/ViewSwitcher/ViewSwitcherItem.js.map +1 -1
- package/dist/components/ViewSwitcher/index.d.ts +2 -2
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.cjs.map +1 -1
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.js.map +1 -1
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.module.css.cjs +1 -1
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.module.css.cjs.map +1 -1
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.module.css.js +1 -1
- package/dist/components/ViewSwitcherBar/ViewSwitcherBar.module.css.js.map +1 -1
- package/dist/components/ViewSwitcherBar/index.d.ts +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.cjs +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.cjs.map +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.d.ts +2 -2
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.js +8 -8
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.js.map +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.module.css.cjs +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.module.css.cjs.map +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.module.css.js +14 -14
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebar.module.css.js.map +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.cjs.map +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.d.ts +1 -1
- package/dist/components/ViewSwitcherSidebar/ViewSwitcherSidebarItem.js.map +1 -1
- package/dist/components/ViewSwitcherSidebar/index.d.ts +2 -2
- package/dist/components/WindowTitle/WindowTitle.cjs.map +1 -1
- package/dist/components/WindowTitle/WindowTitle.js.map +1 -1
- package/dist/components/WindowTitle/index.d.ts +1 -1
- package/dist/components/WrapBox/WrapBox.cjs.map +1 -1
- package/dist/components/WrapBox/WrapBox.d.ts +2 -2
- package/dist/components/WrapBox/WrapBox.js.map +1 -1
- package/dist/components/WrapBox/index.d.ts +1 -1
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/useBreakpoint.cjs +1 -1
- package/dist/hooks/useBreakpoint.cjs.map +1 -1
- package/dist/hooks/useBreakpoint.js +12 -12
- package/dist/hooks/useBreakpoint.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +153 -151
- package/dist/index.js +35 -34
- package/dist/style.css +1 -1
- package/package.json +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordEntryRow.module.css.cjs","names":[],"sources":["../../../src/components/PasswordEntryRow/PasswordEntryRow.module.css"],"sourcesContent":["/* βββ Reveal button βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.revealButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--gnome-radius-small, 6px);\n background: transparent;\n cursor: pointer;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n opacity: var(--gnome-opacity-dim, 0.55);\n flex-shrink: 0;\n\n transition:\n opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.revealButton:hover {\n opacity: 1;\n background: var(--gnome-button-bg-color, rgba(0, 0, 0, 0.07));\n}\n\n.revealButton:active {\n background: var(--gnome-button-active-bg-color, rgba(0, 0, 0, 0.14));\n}\n\n.revealButton:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n
|
|
1
|
+
{"version":3,"file":"PasswordEntryRow.module.css.cjs","names":[],"sources":["../../../src/components/PasswordEntryRow/PasswordEntryRow.module.css"],"sourcesContent":["/* βββ Reveal button βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.revealButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--gnome-radius-small, 6px);\n background: transparent;\n cursor: pointer;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n opacity: var(--gnome-opacity-dim, 0.55);\n flex-shrink: 0;\n\n transition:\n opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.revealButton:hover {\n opacity: 1;\n background: var(--gnome-button-bg-color, rgba(0, 0, 0, 0.07));\n}\n\n.revealButton:active {\n background: var(--gnome-button-active-bg-color, rgba(0, 0, 0, 0.14));\n}\n\n.revealButton:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n opacity: 1;\n}\n\n.revealButton:disabled {\n pointer-events: none;\n opacity: var(--gnome-opacity-disabled, 0.5);\n}\n\n/* βββ Reduced motion ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .revealButton {\n transition: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordEntryRow.module.css.js","names":[],"sources":["../../../src/components/PasswordEntryRow/PasswordEntryRow.module.css"],"sourcesContent":["/* βββ Reveal button βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.revealButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--gnome-radius-small, 6px);\n background: transparent;\n cursor: pointer;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n opacity: var(--gnome-opacity-dim, 0.55);\n flex-shrink: 0;\n\n transition:\n opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.revealButton:hover {\n opacity: 1;\n background: var(--gnome-button-bg-color, rgba(0, 0, 0, 0.07));\n}\n\n.revealButton:active {\n background: var(--gnome-button-active-bg-color, rgba(0, 0, 0, 0.14));\n}\n\n.revealButton:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n
|
|
1
|
+
{"version":3,"file":"PasswordEntryRow.module.css.js","names":[],"sources":["../../../src/components/PasswordEntryRow/PasswordEntryRow.module.css"],"sourcesContent":["/* βββ Reveal button βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.revealButton {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--gnome-radius-small, 6px);\n background: transparent;\n cursor: pointer;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n opacity: var(--gnome-opacity-dim, 0.55);\n flex-shrink: 0;\n\n transition:\n opacity var(--gnome-duration-fast) var(--gnome-easing-default),\n background var(--gnome-duration-fast) var(--gnome-easing-default);\n}\n\n.revealButton:hover {\n opacity: 1;\n background: var(--gnome-button-bg-color, rgba(0, 0, 0, 0.07));\n}\n\n.revealButton:active {\n background: var(--gnome-button-active-bg-color, rgba(0, 0, 0, 0.14));\n}\n\n.revealButton:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 3px))\n var(--gnome-focus-ring-color, #3584e4);\n opacity: 1;\n}\n\n.revealButton:disabled {\n pointer-events: none;\n opacity: var(--gnome-opacity-disabled, 0.5);\n}\n\n/* βββ Reduced motion ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .revealButton {\n transition: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathBar.cjs","names":[],"sources":["../../../src/components/PathBar/PathBar.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"PathBar.cjs","names":[],"sources":["../../../src/components/PathBar/PathBar.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport styles from './PathBar.module.css';\n\nexport interface PathBarSegment {\n /** Display label for this path segment. */\n label: string;\n /** Opaque path value passed to `onNavigate` when the segment is clicked. */\n path: string;\n /** Optional icon placed before the label (e.g. a folder icon). */\n icon?: ReactNode;\n}\n\nexport interface PathBarProps extends HTMLAttributes<HTMLElement> {\n /**\n * Ordered path segments from root to current location.\n * The last segment is the current folder and is rendered non-interactive.\n */\n segments: PathBarSegment[];\n /**\n * Called when the user clicks on a non-current segment.\n * Receives the `path` and zero-based `index` of the clicked segment.\n */\n onNavigate?: (path: string, index: number) => void;\n}\n\n/**\n * Breadcrumb path bar for navigating a hierarchical location.\n *\n * Mirrors the location bar in GNOME Files (Nautilus). Segments are separated\n * by chevron dividers. All segments except the last are interactive β clicking\n * them calls `onNavigate`. The last segment represents the current location and\n * is rendered as a static label.\n *\n * @see https://developer.gnome.org/hig/patterns/nav/search.html\n */\nexport function PathBar({ segments, onNavigate, className, ...props }: PathBarProps) {\n return (\n <nav\n aria-label=\"Breadcrumb\"\n className={[styles.pathBar, className].filter(Boolean).join(' ')}\n {...props}\n >\n <ol className={styles.list} aria-label=\"Path segments\">\n {segments.map((segment, index) => {\n const isCurrent = index === segments.length - 1;\n\n return (\n <li key={segment.path} className={styles.item}>\n {/* Separator chevron (not before the first segment) */}\n {index > 0 && (\n <span className={styles.separator} aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" focusable=\"false\">\n <path\n d=\"M4 2l4 4-4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n )}\n\n {isCurrent ? (\n /* Current folder β non-interactive */\n <span className={styles.current} aria-current=\"page\">\n {segment.icon && (\n <span className={styles.icon} aria-hidden=\"true\">\n {segment.icon}\n </span>\n )}\n {segment.label}\n </span>\n ) : (\n /* Ancestor folder β clickable */\n <button\n type=\"button\"\n className={styles.segment}\n onClick={() => onNavigate?.(segment.path, index)}\n >\n {segment.icon && (\n <span className={styles.icon} aria-hidden=\"true\">\n {segment.icon}\n </span>\n )}\n {segment.label}\n </button>\n )}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n"],"mappings":"+EAoCA,SAAgB,EAAQ,CAAE,WAAU,aAAY,YAAW,GAAG,GAAuB,CACnF,OACE,EAAA,EAAA,KAAC,MAAD,CACE,aAAW,aACX,UAAW,CAAC,EAAA,QAAO,QAAS,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,CAChE,GAAI,YAEJ,EAAA,EAAA,KAAC,KAAD,CAAI,UAAW,EAAA,QAAO,KAAM,aAAW,yBACpC,EAAS,KAAK,EAAS,IAAU,CAChC,IAAM,EAAY,IAAU,EAAS,OAAS,EAE9C,OACE,EAAA,EAAA,MAAC,KAAD,CAAuB,UAAW,EAAA,QAAO,cAAzC,CAEG,EAAQ,IACP,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,UAAW,cAAY,iBAC7C,EAAA,EAAA,KAAC,MAAD,CAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,UAAU,kBACxD,EAAA,EAAA,KAAC,OAAD,CACE,EAAE,eACF,KAAK,OACL,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,QACf,CAAA,CACE,CAAA,CACD,CAAA,CAGR,GAEC,EAAA,EAAA,MAAC,OAAD,CAAM,UAAW,EAAA,QAAO,QAAS,eAAa,gBAA9C,CACG,EAAQ,OACP,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,KAAM,cAAY,gBACvC,EAAQ,KACJ,CAAA,CAER,EAAQ,MACJ,IAGP,EAAA,EAAA,MAAC,SAAD,CACE,KAAK,SACL,UAAW,EAAA,QAAO,QAClB,YAAe,IAAa,EAAQ,KAAM,EAAM,UAHlD,CAKG,EAAQ,OACP,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,KAAM,cAAY,gBACvC,EAAQ,KACJ,CAAA,CAER,EAAQ,MACF,GAER,EA1CI,EAAQ,KA0CZ,EAEP,CACC,CAAA,CACD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathBar.js","names":[],"sources":["../../../src/components/PathBar/PathBar.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"PathBar.js","names":[],"sources":["../../../src/components/PathBar/PathBar.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport styles from './PathBar.module.css';\n\nexport interface PathBarSegment {\n /** Display label for this path segment. */\n label: string;\n /** Opaque path value passed to `onNavigate` when the segment is clicked. */\n path: string;\n /** Optional icon placed before the label (e.g. a folder icon). */\n icon?: ReactNode;\n}\n\nexport interface PathBarProps extends HTMLAttributes<HTMLElement> {\n /**\n * Ordered path segments from root to current location.\n * The last segment is the current folder and is rendered non-interactive.\n */\n segments: PathBarSegment[];\n /**\n * Called when the user clicks on a non-current segment.\n * Receives the `path` and zero-based `index` of the clicked segment.\n */\n onNavigate?: (path: string, index: number) => void;\n}\n\n/**\n * Breadcrumb path bar for navigating a hierarchical location.\n *\n * Mirrors the location bar in GNOME Files (Nautilus). Segments are separated\n * by chevron dividers. All segments except the last are interactive β clicking\n * them calls `onNavigate`. The last segment represents the current location and\n * is rendered as a static label.\n *\n * @see https://developer.gnome.org/hig/patterns/nav/search.html\n */\nexport function PathBar({ segments, onNavigate, className, ...props }: PathBarProps) {\n return (\n <nav\n aria-label=\"Breadcrumb\"\n className={[styles.pathBar, className].filter(Boolean).join(' ')}\n {...props}\n >\n <ol className={styles.list} aria-label=\"Path segments\">\n {segments.map((segment, index) => {\n const isCurrent = index === segments.length - 1;\n\n return (\n <li key={segment.path} className={styles.item}>\n {/* Separator chevron (not before the first segment) */}\n {index > 0 && (\n <span className={styles.separator} aria-hidden=\"true\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" focusable=\"false\">\n <path\n d=\"M4 2l4 4-4 4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n )}\n\n {isCurrent ? (\n /* Current folder β non-interactive */\n <span className={styles.current} aria-current=\"page\">\n {segment.icon && (\n <span className={styles.icon} aria-hidden=\"true\">\n {segment.icon}\n </span>\n )}\n {segment.label}\n </span>\n ) : (\n /* Ancestor folder β clickable */\n <button\n type=\"button\"\n className={styles.segment}\n onClick={() => onNavigate?.(segment.path, index)}\n >\n {segment.icon && (\n <span className={styles.icon} aria-hidden=\"true\">\n {segment.icon}\n </span>\n )}\n {segment.label}\n </button>\n )}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n"],"mappings":";;;AAoCA,SAAgB,EAAQ,EAAE,aAAU,eAAY,cAAW,GAAG,KAAuB;AACnF,QACE,kBAAC,OAAD;EACE,cAAW;EACX,WAAW,CAAC,EAAO,SAAS,EAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;EAChE,GAAI;YAEJ,kBAAC,MAAD;GAAI,WAAW,EAAO;GAAM,cAAW;aACpC,EAAS,KAAK,GAAS,MAAU;IAChC,IAAM,IAAY,MAAU,EAAS,SAAS;AAE9C,WACE,kBAAC,MAAD;KAAuB,WAAW,EAAO;eAAzC,CAEG,IAAQ,KACP,kBAAC,QAAD;MAAM,WAAW,EAAO;MAAW,eAAY;gBAC7C,kBAAC,OAAD;OAAK,OAAM;OAAK,QAAO;OAAK,SAAQ;OAAY,WAAU;iBACxD,kBAAC,QAAD;QACE,GAAE;QACF,MAAK;QACL,QAAO;QACP,aAAY;QACZ,eAAc;QACd,gBAAe;QACf,CAAA;OACE,CAAA;MACD,CAAA,EAGR,IAEC,kBAAC,QAAD;MAAM,WAAW,EAAO;MAAS,gBAAa;gBAA9C,CACG,EAAQ,QACP,kBAAC,QAAD;OAAM,WAAW,EAAO;OAAM,eAAY;iBACvC,EAAQ;OACJ,CAAA,EAER,EAAQ,MACJ;UAGP,kBAAC,UAAD;MACE,MAAK;MACL,WAAW,EAAO;MAClB,eAAe,IAAa,EAAQ,MAAM,EAAM;gBAHlD,CAKG,EAAQ,QACP,kBAAC,QAAD;OAAM,WAAW,EAAO;OAAM,eAAY;iBACvC,EAAQ;OACJ,CAAA,EAER,EAAQ,MACF;QAER;OA1CI,EAAQ,KA0CZ;KAEP;GACC,CAAA;EACD,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={pathBar:`
|
|
1
|
+
var e={pathBar:`_pathBar_12z8k_3`,list:`_list_12z8k_12`,item:`_item_12z8k_25`,separator:`_separator_12z8k_33`,segment:`_segment_12z8k_44`,current:`_current_12z8k_81`,icon:`_icon_12z8k_98`};exports.default=e;
|
|
2
2
|
//# sourceMappingURL=PathBar.module.css.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathBar.module.css.cjs","names":[],"sources":["../../../src/components/PathBar/PathBar.module.css"],"sourcesContent":["/* βββ Root ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.pathBar {\n display: flex;\n align-items: center;\n min-width: 0;\n font-family: var(--gnome-font-family, sans-serif);\n}\n\n/* βββ List ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n min-width: 0;\n}\n\n/* βββ Item ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.item {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* βββ Separator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.separator {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.35));\n opacity: 0.5;\n margin: 0 1px;\n}\n\n/* βββ Ancestor segment (button) βββββββββββββββββββββββββββββββββββββββββββββ */\n\n.segment {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: var(--gnome-radius-sm, 6px);\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 160px;\n transition: background-color var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n}\n\n.segment:hover {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.06));\n}\n\n.segment:active {\n background-color: var(--gnome-active-overlay, rgba(0, 0, 0, 0.12));\n}\n\n.segment:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n
|
|
1
|
+
{"version":3,"file":"PathBar.module.css.cjs","names":[],"sources":["../../../src/components/PathBar/PathBar.module.css"],"sourcesContent":["/* βββ Root ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.pathBar {\n display: flex;\n align-items: center;\n min-width: 0;\n font-family: var(--gnome-font-family, sans-serif);\n}\n\n/* βββ List ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n min-width: 0;\n}\n\n/* βββ Item ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.item {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* βββ Separator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.separator {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.35));\n opacity: 0.5;\n margin: 0 1px;\n}\n\n/* βββ Ancestor segment (button) βββββββββββββββββββββββββββββββββββββββββββββ */\n\n.segment {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: var(--gnome-radius-sm, 6px);\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 160px;\n transition: background-color var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n}\n\n.segment:hover {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.06));\n}\n\n.segment:active {\n background-color: var(--gnome-active-overlay, rgba(0, 0, 0, 0.12));\n}\n\n.segment:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* βββ Current segment (non-interactive) ββββββββββββββββββββββββββββββββββββ */\n\n.current {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n font-weight: var(--gnome-font-weight-semibold, 600);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n/* βββ Icon ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* βββ Reduced motion ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .segment {\n transition: none;\n }\n}\n\n/* βββ Dark mode βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-color-scheme: dark) {\n .segment:hover {\n background-color: rgba(255, 255, 255, 0.08);\n }\n\n .segment:active {\n background-color: rgba(255, 255, 255, 0.14);\n }\n}\n"],"mappings":""}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
var e = {
|
|
2
|
-
pathBar: "
|
|
3
|
-
list: "
|
|
4
|
-
item: "
|
|
5
|
-
separator: "
|
|
6
|
-
segment: "
|
|
7
|
-
current: "
|
|
8
|
-
icon: "
|
|
2
|
+
pathBar: "_pathBar_12z8k_3",
|
|
3
|
+
list: "_list_12z8k_12",
|
|
4
|
+
item: "_item_12z8k_25",
|
|
5
|
+
separator: "_separator_12z8k_33",
|
|
6
|
+
segment: "_segment_12z8k_44",
|
|
7
|
+
current: "_current_12z8k_81",
|
|
8
|
+
icon: "_icon_12z8k_98"
|
|
9
9
|
};
|
|
10
10
|
//#endregion
|
|
11
11
|
export { e as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PathBar.module.css.js","names":[],"sources":["../../../src/components/PathBar/PathBar.module.css"],"sourcesContent":["/* βββ Root ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.pathBar {\n display: flex;\n align-items: center;\n min-width: 0;\n font-family: var(--gnome-font-family, sans-serif);\n}\n\n/* βββ List ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n min-width: 0;\n}\n\n/* βββ Item ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.item {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* βββ Separator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.separator {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.35));\n opacity: 0.5;\n margin: 0 1px;\n}\n\n/* βββ Ancestor segment (button) βββββββββββββββββββββββββββββββββββββββββββββ */\n\n.segment {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: var(--gnome-radius-sm, 6px);\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 160px;\n transition: background-color var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n}\n\n.segment:hover {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.06));\n}\n\n.segment:active {\n background-color: var(--gnome-active-overlay, rgba(0, 0, 0, 0.12));\n}\n\n.segment:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n
|
|
1
|
+
{"version":3,"file":"PathBar.module.css.js","names":[],"sources":["../../../src/components/PathBar/PathBar.module.css"],"sourcesContent":["/* βββ Root ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.pathBar {\n display: flex;\n align-items: center;\n min-width: 0;\n font-family: var(--gnome-font-family, sans-serif);\n}\n\n/* βββ List ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.list {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0;\n margin: 0;\n padding: 0;\n list-style: none;\n min-width: 0;\n}\n\n/* βββ Item ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.item {\n display: flex;\n align-items: center;\n min-width: 0;\n}\n\n/* βββ Separator βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.separator {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.35));\n opacity: 0.5;\n margin: 0 1px;\n}\n\n/* βββ Ancestor segment (button) βββββββββββββββββββββββββββββββββββββββββββββ */\n\n.segment {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n border-radius: var(--gnome-radius-sm, 6px);\n border: none;\n background: transparent;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 160px;\n transition: background-color var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n}\n\n.segment:hover {\n background-color: var(--gnome-hover-overlay, rgba(0, 0, 0, 0.06));\n}\n\n.segment:active {\n background-color: var(--gnome-active-overlay, rgba(0, 0, 0, 0.12));\n}\n\n.segment:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fafafa),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* βββ Current segment (non-interactive) ββββββββββββββββββββββββββββββββββββ */\n\n.current {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n font-family: inherit;\n font-size: var(--gnome-font-size-body, 1rem);\n font-weight: var(--gnome-font-weight-semibold, 600);\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 200px;\n}\n\n/* βββ Icon ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.icon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* βββ Reduced motion ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .segment {\n transition: none;\n }\n}\n\n/* βββ Dark mode βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-color-scheme: dark) {\n .segment:hover {\n background-color: rgba(255, 255, 255, 0.08);\n }\n\n .segment:active {\n background-color: rgba(255, 255, 255, 0.14);\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.cjs","names":[],"sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n useState,\n useRef,\n useId,\n useEffect,\n useCallback,\n cloneElement,\n type ReactElement,\n type HTMLAttributes,\n type ReactNode,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./Popover.module.css\";\n\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport interface PopoverProps {\n /**\n * The rich content rendered inside the popover panel.\n * Can include interactive elements (buttons, links, forms).\n */\n content: ReactNode;\n /**\n * Preferred placement relative to the trigger.\n * Flips automatically when there is not enough viewport space.\n * Defaults to `\"bottom\"`.\n */\n placement?: PopoverPlacement;\n /**\n * Whether the popover is open (controlled mode).\n * Omit to use uncontrolled mode where the trigger toggles it.\n */\n open?: boolean;\n /**\n * Called when the popover requests to be closed\n * (Escape key, outside click, or trigger click while open).\n */\n onClose?: () => void;\n /**\n * Called when open state should change (controlled mode).\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger element. Must be a single React element that can\n * receive `ref` and click/keyboard event props.\n */\n children: ReactElement<HTMLAttributes<HTMLElement>>;\n}\n\ninterface Position {\n top: number;\n left: number;\n placement: PopoverPlacement;\n /** Arrow center offset in px from the near edge of the panel.\n * Horizontal (left) for top/bottom; vertical (top) for left/right.\n * Undefined means use the default 50% CSS. */\n arrowOffset?: number;\n}\n\nconst GAP = 8;\nconst MARGIN = 10;\nconst ARROW_HALF = 6; // half of the 12 px arrow\n\nfunction computePosition(\n trigger: DOMRect,\n popover: DOMRect,\n preferred: PopoverPlacement\n): Position {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const order: PopoverPlacement[] = [\n preferred,\n preferred === \"top\" ? \"bottom\"\n : preferred === \"bottom\" ? \"top\"\n : preferred === \"left\" ? \"right\"\n : \"left\",\n \"bottom\", \"top\", \"left\", \"right\",\n ];\n\n // De-duplicate while preserving order\n const candidates = [...new Set(order)];\n\n function calcRaw(p: PopoverPlacement): { top: number; left: number } {\n if (p === \"bottom\") return {\n top: trigger.bottom + GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n if (p === \"top\") return {\n top: trigger.top - popover.height - GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n if (p === \"left\") return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.left - popover.width - GAP,\n };\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.right + GAP,\n };\n }\n\n // First pass: find a placement that fits both axes perfectly.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n if (fitsH && fitsV) {\n // Always use pixel arrowOffset (never rely on CSS left:50%) so the arrow\n // points exactly at the trigger center regardless of sub-pixel rounding.\n const arrowOffset =\n p === \"top\" || p === \"bottom\"\n ? trigger.left + trigger.width / 2 - left\n : trigger.top + trigger.height / 2 - top;\n return { top, left, placement: p, arrowOffset };\n }\n }\n\n // Second pass: fits the primary axis; clamp the secondary axis and\n // shift the arrow so it still points at the trigger center.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n\n if ((p === \"top\" || p === \"bottom\") && fitsV) {\n const clampedLeft = Math.max(MARGIN, Math.min(left, vw - popover.width - MARGIN));\n const rawOffset = trigger.left + trigger.width / 2 - clampedLeft;\n return {\n top, left: clampedLeft, placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.width - ARROW_HALF - 4)),\n };\n }\n\n if ((p === \"left\" || p === \"right\") && fitsH) {\n const clampedTop = Math.max(MARGIN, Math.min(top, vh - popover.height - MARGIN));\n const rawOffset = trigger.top + trigger.height / 2 - clampedTop;\n return {\n top: clampedTop, left, placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.height - ARROW_HALF - 4)),\n };\n }\n }\n\n // Fallback: clamp bottom placement and shift arrow to match trigger.\n const fbTop = trigger.bottom + GAP;\n const fbLeft = trigger.left + trigger.width / 2 - popover.width / 2;\n const clampedTop = Math.max(MARGIN, Math.min(fbTop, vh - popover.height - MARGIN));\n const clampedLeft = Math.max(MARGIN, Math.min(fbLeft, vw - popover.width - MARGIN));\n const rawArrowOffset = trigger.left + trigger.width / 2 - clampedLeft;\n return {\n top: clampedTop,\n left: clampedLeft,\n placement: \"bottom\",\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawArrowOffset, popover.width - ARROW_HALF - 4)),\n };\n}\n\n/**\n * Floating panel anchored to a trigger element.\n *\n * Unlike `Tooltip`, a Popover can contain rich interactive content\n * (menus, forms, details). It follows the Adwaita `GtkPopover` pattern.\n *\n * - Supports both controlled (`open` + `onClose`) and uncontrolled modes.\n * - Auto-positions with viewport-aware flip.\n * - Closes on Escape, outside click, or trigger re-click.\n * - Focus is moved into the panel on open; returns to the trigger on close.\n * - `aria-haspopup=\"dialog\"` + `aria-expanded` wired to the trigger.\n * - `role=\"dialog\"` on the panel with `aria-labelledby` when a heading is present.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Popover.html\n */\nexport function Popover({\n content,\n placement: preferredPlacement = \"bottom\",\n open: controlledOpen,\n onClose,\n onOpenChange,\n children,\n}: PopoverProps) {\n const isControlled = controlledOpen !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n\n const [pos, setPos] = useState<Position | null>(null);\n\n const triggerId = useId();\n const popoverId = useId();\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<Element | null>(null);\n\n const close = useCallback(() => {\n if (isControlled) {\n onClose?.();\n } else {\n setUncontrolledOpen(false);\n }\n onOpenChange?.(false);\n }, [isControlled, onClose, onOpenChange]);\n\n const toggle = useCallback(() => {\n if (open) {\n close();\n } else {\n if (!isControlled) setUncontrolledOpen(true);\n onOpenChange?.(true);\n }\n }, [open, close, isControlled, onOpenChange]);\n\n // Position panel\n const place = useCallback(() => {\n if (!triggerRef.current || !panelRef.current) return;\n setPos(\n computePosition(\n triggerRef.current.getBoundingClientRect(),\n panelRef.current.getBoundingClientRect(),\n preferredPlacement\n )\n );\n }, [preferredPlacement]);\n\n // Reposition on open, scroll, resize\n useEffect(() => {\n if (!open) return;\n // Two RAF: first lets panel mount with hidden styles so we can measure it;\n // second applies the measured position.\n const id = requestAnimationFrame(() => {\n place();\n window.addEventListener(\"scroll\", place, { passive: true, capture: true });\n window.addEventListener(\"resize\", place, { passive: true });\n });\n return () => {\n cancelAnimationFrame(id);\n window.removeEventListener(\"scroll\", place, { capture: true });\n window.removeEventListener(\"resize\", place);\n };\n }, [open, place]);\n\n // Save / restore focus\n useEffect(() => {\n if (open) {\n previouslyFocused.current = document.activeElement;\n requestAnimationFrame(() => {\n const first = panelRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n (first ?? panelRef.current)?.focus();\n });\n } else {\n (previouslyFocused.current as HTMLElement | null)?.focus();\n setPos(null);\n }\n }, [open]);\n\n // Close on outside pointer\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !panelRef.current?.contains(e.target as Node)\n ) {\n close();\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open, close]);\n\n // Escape key\n const handlePanelKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Escape\") { e.stopPropagation(); close(); }\n },\n [close]\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const trigger = cloneElement(children as any, {\n ref: triggerRef,\n id: triggerId,\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": open,\n \"aria-controls\": open ? popoverId : undefined,\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n toggle();\n children.props.onClick?.(e);\n },\n });\n\n const panel = (\n <div\n ref={panelRef}\n id={popoverId}\n role=\"dialog\"\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[\n styles.panel,\n pos ? styles[pos.placement] : null,\n open && pos ? styles.visible : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={\n pos\n ? { top: pos.top, left: pos.left }\n : { visibility: \"hidden\", pointerEvents: \"none\", top: -9999, left: -9999 }\n }\n onKeyDown={handlePanelKeyDown}\n >\n {/* Arrow β offset shifts it to point at the trigger when the panel is clamped */}\n <div\n className={styles.arrow}\n aria-hidden=\"true\"\n style={\n pos?.arrowOffset !== undefined\n ? pos.placement === \"top\" || pos.placement === \"bottom\"\n ? { left: pos.arrowOffset - ARROW_HALF, marginLeft: 0 }\n : { top: pos.arrowOffset - ARROW_HALF, marginTop: 0 }\n : undefined\n }\n />\n {content}\n </div>\n );\n\n return (\n <>\n {trigger}\n {open &&\n (typeof document !== \"undefined\"\n ? createPortal(panel, document.body)\n : panel)}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.cjs","names":[],"sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n cloneElement,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport styles from './Popover.module.css';\n\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface PopoverProps {\n /**\n * The rich content rendered inside the popover panel.\n * Can include interactive elements (buttons, links, forms).\n */\n content: ReactNode;\n /**\n * Preferred placement relative to the trigger.\n * Flips automatically when there is not enough viewport space.\n * Defaults to `\"bottom\"`.\n */\n placement?: PopoverPlacement;\n /**\n * Whether the popover is open (controlled mode).\n * Omit to use uncontrolled mode where the trigger toggles it.\n */\n open?: boolean;\n /**\n * Called when the popover requests to be closed\n * (Escape key, outside click, or trigger click while open).\n */\n onClose?: () => void;\n /**\n * Called when open state should change (controlled mode).\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger element. Must be a single React element that can\n * receive `ref` and click/keyboard event props.\n */\n children: ReactElement<HTMLAttributes<HTMLElement>>;\n}\n\ninterface Position {\n top: number;\n left: number;\n placement: PopoverPlacement;\n /** Arrow center offset in px from the near edge of the panel.\n * Horizontal (left) for top/bottom; vertical (top) for left/right.\n * Undefined means use the default 50% CSS. */\n arrowOffset?: number;\n}\n\nconst GAP = 8;\nconst MARGIN = 10;\nconst ARROW_HALF = 6; // half of the 12 px arrow\n\nfunction computePosition(\n trigger: DOMRect,\n popover: DOMRect,\n preferred: PopoverPlacement,\n): Position {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const order: PopoverPlacement[] = [\n preferred,\n preferred === 'top'\n ? 'bottom'\n : preferred === 'bottom'\n ? 'top'\n : preferred === 'left'\n ? 'right'\n : 'left',\n 'bottom',\n 'top',\n 'left',\n 'right',\n ];\n\n // De-duplicate while preserving order\n const candidates = [...new Set(order)];\n\n function calcRaw(p: PopoverPlacement): { top: number; left: number } {\n if (p === 'bottom') {\n return {\n top: trigger.bottom + GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n }\n\n if (p === 'top') {\n return {\n top: trigger.top - popover.height - GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n }\n\n if (p === 'left') {\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.left - popover.width - GAP,\n };\n }\n\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.right + GAP,\n };\n }\n\n // First pass: find a placement that fits both axes perfectly.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n\n if (fitsH && fitsV) {\n // Always use pixel arrowOffset (never rely on CSS left:50%) so the arrow\n // points exactly at the trigger center regardless of sub-pixel rounding.\n const arrowOffset =\n p === 'top' || p === 'bottom'\n ? trigger.left + trigger.width / 2 - left\n : trigger.top + trigger.height / 2 - top;\n\n return { top, left, placement: p, arrowOffset };\n }\n }\n\n // Second pass: fits the primary axis; clamp the secondary axis and\n // shift the arrow so it still points at the trigger center.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n\n if ((p === 'top' || p === 'bottom') && fitsV) {\n const clampedLeft = Math.max(MARGIN, Math.min(left, vw - popover.width - MARGIN));\n const rawOffset = trigger.left + trigger.width / 2 - clampedLeft;\n\n return {\n top,\n left: clampedLeft,\n placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.width - ARROW_HALF - 4)),\n };\n }\n\n if ((p === 'left' || p === 'right') && fitsH) {\n const clampedTop = Math.max(MARGIN, Math.min(top, vh - popover.height - MARGIN));\n const rawOffset = trigger.top + trigger.height / 2 - clampedTop;\n\n return {\n top: clampedTop,\n left,\n placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.height - ARROW_HALF - 4)),\n };\n }\n }\n\n // Fallback: clamp bottom placement and shift arrow to match trigger.\n const fbTop = trigger.bottom + GAP;\n const fbLeft = trigger.left + trigger.width / 2 - popover.width / 2;\n const clampedTop = Math.max(MARGIN, Math.min(fbTop, vh - popover.height - MARGIN));\n const clampedLeft = Math.max(MARGIN, Math.min(fbLeft, vw - popover.width - MARGIN));\n const rawArrowOffset = trigger.left + trigger.width / 2 - clampedLeft;\n\n return {\n top: clampedTop,\n left: clampedLeft,\n placement: 'bottom',\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawArrowOffset, popover.width - ARROW_HALF - 4)),\n };\n}\n\n/**\n * Floating panel anchored to a trigger element.\n *\n * Unlike `Tooltip`, a Popover can contain rich interactive content\n * (menus, forms, details). It follows the Adwaita `GtkPopover` pattern.\n *\n * - Supports both controlled (`open` + `onClose`) and uncontrolled modes.\n * - Auto-positions with viewport-aware flip.\n * - Closes on Escape, outside click, or trigger re-click.\n * - Focus is moved into the panel on open; returns to the trigger on close.\n * - `aria-haspopup=\"dialog\"` + `aria-expanded` wired to the trigger.\n * - `role=\"dialog\"` on the panel with `aria-labelledby` when a heading is present.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Popover.html\n */\nexport function Popover({\n content,\n placement: preferredPlacement = 'bottom',\n open: controlledOpen,\n onClose,\n onOpenChange,\n children,\n}: PopoverProps) {\n const isControlled = controlledOpen !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n\n const [pos, setPos] = useState<Position | null>(null);\n\n const triggerId = useId();\n const popoverId = useId();\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<Element | null>(null);\n\n const close = useCallback(() => {\n if (isControlled) {\n onClose?.();\n } else {\n setUncontrolledOpen(false);\n }\n\n onOpenChange?.(false);\n }, [isControlled, onClose, onOpenChange]);\n\n const toggle = useCallback(() => {\n if (open) {\n close();\n } else {\n if (!isControlled) {\n setUncontrolledOpen(true);\n }\n\n onOpenChange?.(true);\n }\n }, [open, close, isControlled, onOpenChange]);\n\n // Position panel\n const place = useCallback(() => {\n if (!triggerRef.current || !panelRef.current) {\n return;\n }\n\n setPos(\n computePosition(\n triggerRef.current.getBoundingClientRect(),\n panelRef.current.getBoundingClientRect(),\n preferredPlacement,\n ),\n );\n }, [preferredPlacement]);\n\n // Reposition on open, scroll, resize\n useEffect(() => {\n if (!open) {\n return;\n }\n\n // Two RAF: first lets panel mount with hidden styles so we can measure it;\n // second applies the measured position.\n const id = requestAnimationFrame(() => {\n place();\n window.addEventListener('scroll', place, { passive: true, capture: true });\n window.addEventListener('resize', place, { passive: true });\n });\n\n return () => {\n cancelAnimationFrame(id);\n window.removeEventListener('scroll', place, { capture: true });\n window.removeEventListener('resize', place);\n };\n }, [open, place]);\n\n // Save / restore focus\n useEffect(() => {\n if (open) {\n previouslyFocused.current = document.activeElement;\n requestAnimationFrame(() => {\n const first = panelRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n (first ?? panelRef.current)?.focus();\n });\n } else {\n (previouslyFocused.current as HTMLElement | null)?.focus();\n setPos(null);\n }\n }, [open]);\n\n // Close on outside pointer\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !panelRef.current?.contains(e.target as Node)\n ) {\n close();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, close]);\n\n // Escape key\n const handlePanelKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n close();\n }\n },\n [close],\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const trigger = cloneElement(children as any, {\n ref: triggerRef,\n id: triggerId,\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n 'aria-controls': open ? popoverId : undefined,\n onClick: (e: ReactMouseEvent<HTMLElement>) => {\n toggle();\n children.props.onClick?.(e);\n },\n });\n\n const panel = (\n <div\n ref={panelRef}\n id={popoverId}\n role=\"dialog\"\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[\n styles.panel,\n pos ? styles[pos.placement] : null,\n open && pos ? styles.visible : null,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n pos\n ? { top: pos.top, left: pos.left }\n : { visibility: 'hidden', pointerEvents: 'none', top: -9999, left: -9999 }\n }\n onKeyDown={handlePanelKeyDown}\n >\n {/* Arrow β offset shifts it to point at the trigger when the panel is clamped */}\n <div\n className={styles.arrow}\n aria-hidden=\"true\"\n style={\n pos?.arrowOffset !== undefined\n ? pos.placement === 'top' || pos.placement === 'bottom'\n ? { left: pos.arrowOffset - ARROW_HALF, marginLeft: 0 }\n : { top: pos.arrowOffset - ARROW_HALF, marginTop: 0 }\n : undefined\n }\n />\n {content}\n </div>\n );\n\n return (\n <>\n {trigger}\n {open && (typeof document !== 'undefined' ? createPortal(panel, document.body) : panel)}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type PopoverPlacement =
|
|
1
|
+
import { HTMLAttributes, ReactElement, ReactNode } from 'react';
|
|
2
|
+
export type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
3
3
|
export interface PopoverProps {
|
|
4
4
|
/**
|
|
5
5
|
* The rich content rendered inside the popover panel.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.js","names":[],"sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n useState,\n useRef,\n useId,\n useEffect,\n useCallback,\n cloneElement,\n type ReactElement,\n type HTMLAttributes,\n type ReactNode,\n type KeyboardEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./Popover.module.css\";\n\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"left\" | \"right\";\n\nexport interface PopoverProps {\n /**\n * The rich content rendered inside the popover panel.\n * Can include interactive elements (buttons, links, forms).\n */\n content: ReactNode;\n /**\n * Preferred placement relative to the trigger.\n * Flips automatically when there is not enough viewport space.\n * Defaults to `\"bottom\"`.\n */\n placement?: PopoverPlacement;\n /**\n * Whether the popover is open (controlled mode).\n * Omit to use uncontrolled mode where the trigger toggles it.\n */\n open?: boolean;\n /**\n * Called when the popover requests to be closed\n * (Escape key, outside click, or trigger click while open).\n */\n onClose?: () => void;\n /**\n * Called when open state should change (controlled mode).\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger element. Must be a single React element that can\n * receive `ref` and click/keyboard event props.\n */\n children: ReactElement<HTMLAttributes<HTMLElement>>;\n}\n\ninterface Position {\n top: number;\n left: number;\n placement: PopoverPlacement;\n /** Arrow center offset in px from the near edge of the panel.\n * Horizontal (left) for top/bottom; vertical (top) for left/right.\n * Undefined means use the default 50% CSS. */\n arrowOffset?: number;\n}\n\nconst GAP = 8;\nconst MARGIN = 10;\nconst ARROW_HALF = 6; // half of the 12 px arrow\n\nfunction computePosition(\n trigger: DOMRect,\n popover: DOMRect,\n preferred: PopoverPlacement\n): Position {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const order: PopoverPlacement[] = [\n preferred,\n preferred === \"top\" ? \"bottom\"\n : preferred === \"bottom\" ? \"top\"\n : preferred === \"left\" ? \"right\"\n : \"left\",\n \"bottom\", \"top\", \"left\", \"right\",\n ];\n\n // De-duplicate while preserving order\n const candidates = [...new Set(order)];\n\n function calcRaw(p: PopoverPlacement): { top: number; left: number } {\n if (p === \"bottom\") return {\n top: trigger.bottom + GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n if (p === \"top\") return {\n top: trigger.top - popover.height - GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n if (p === \"left\") return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.left - popover.width - GAP,\n };\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.right + GAP,\n };\n }\n\n // First pass: find a placement that fits both axes perfectly.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n if (fitsH && fitsV) {\n // Always use pixel arrowOffset (never rely on CSS left:50%) so the arrow\n // points exactly at the trigger center regardless of sub-pixel rounding.\n const arrowOffset =\n p === \"top\" || p === \"bottom\"\n ? trigger.left + trigger.width / 2 - left\n : trigger.top + trigger.height / 2 - top;\n return { top, left, placement: p, arrowOffset };\n }\n }\n\n // Second pass: fits the primary axis; clamp the secondary axis and\n // shift the arrow so it still points at the trigger center.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n\n if ((p === \"top\" || p === \"bottom\") && fitsV) {\n const clampedLeft = Math.max(MARGIN, Math.min(left, vw - popover.width - MARGIN));\n const rawOffset = trigger.left + trigger.width / 2 - clampedLeft;\n return {\n top, left: clampedLeft, placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.width - ARROW_HALF - 4)),\n };\n }\n\n if ((p === \"left\" || p === \"right\") && fitsH) {\n const clampedTop = Math.max(MARGIN, Math.min(top, vh - popover.height - MARGIN));\n const rawOffset = trigger.top + trigger.height / 2 - clampedTop;\n return {\n top: clampedTop, left, placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.height - ARROW_HALF - 4)),\n };\n }\n }\n\n // Fallback: clamp bottom placement and shift arrow to match trigger.\n const fbTop = trigger.bottom + GAP;\n const fbLeft = trigger.left + trigger.width / 2 - popover.width / 2;\n const clampedTop = Math.max(MARGIN, Math.min(fbTop, vh - popover.height - MARGIN));\n const clampedLeft = Math.max(MARGIN, Math.min(fbLeft, vw - popover.width - MARGIN));\n const rawArrowOffset = trigger.left + trigger.width / 2 - clampedLeft;\n return {\n top: clampedTop,\n left: clampedLeft,\n placement: \"bottom\",\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawArrowOffset, popover.width - ARROW_HALF - 4)),\n };\n}\n\n/**\n * Floating panel anchored to a trigger element.\n *\n * Unlike `Tooltip`, a Popover can contain rich interactive content\n * (menus, forms, details). It follows the Adwaita `GtkPopover` pattern.\n *\n * - Supports both controlled (`open` + `onClose`) and uncontrolled modes.\n * - Auto-positions with viewport-aware flip.\n * - Closes on Escape, outside click, or trigger re-click.\n * - Focus is moved into the panel on open; returns to the trigger on close.\n * - `aria-haspopup=\"dialog\"` + `aria-expanded` wired to the trigger.\n * - `role=\"dialog\"` on the panel with `aria-labelledby` when a heading is present.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Popover.html\n */\nexport function Popover({\n content,\n placement: preferredPlacement = \"bottom\",\n open: controlledOpen,\n onClose,\n onOpenChange,\n children,\n}: PopoverProps) {\n const isControlled = controlledOpen !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n\n const [pos, setPos] = useState<Position | null>(null);\n\n const triggerId = useId();\n const popoverId = useId();\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<Element | null>(null);\n\n const close = useCallback(() => {\n if (isControlled) {\n onClose?.();\n } else {\n setUncontrolledOpen(false);\n }\n onOpenChange?.(false);\n }, [isControlled, onClose, onOpenChange]);\n\n const toggle = useCallback(() => {\n if (open) {\n close();\n } else {\n if (!isControlled) setUncontrolledOpen(true);\n onOpenChange?.(true);\n }\n }, [open, close, isControlled, onOpenChange]);\n\n // Position panel\n const place = useCallback(() => {\n if (!triggerRef.current || !panelRef.current) return;\n setPos(\n computePosition(\n triggerRef.current.getBoundingClientRect(),\n panelRef.current.getBoundingClientRect(),\n preferredPlacement\n )\n );\n }, [preferredPlacement]);\n\n // Reposition on open, scroll, resize\n useEffect(() => {\n if (!open) return;\n // Two RAF: first lets panel mount with hidden styles so we can measure it;\n // second applies the measured position.\n const id = requestAnimationFrame(() => {\n place();\n window.addEventListener(\"scroll\", place, { passive: true, capture: true });\n window.addEventListener(\"resize\", place, { passive: true });\n });\n return () => {\n cancelAnimationFrame(id);\n window.removeEventListener(\"scroll\", place, { capture: true });\n window.removeEventListener(\"resize\", place);\n };\n }, [open, place]);\n\n // Save / restore focus\n useEffect(() => {\n if (open) {\n previouslyFocused.current = document.activeElement;\n requestAnimationFrame(() => {\n const first = panelRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n (first ?? panelRef.current)?.focus();\n });\n } else {\n (previouslyFocused.current as HTMLElement | null)?.focus();\n setPos(null);\n }\n }, [open]);\n\n // Close on outside pointer\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !panelRef.current?.contains(e.target as Node)\n ) {\n close();\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open, close]);\n\n // Escape key\n const handlePanelKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Escape\") { e.stopPropagation(); close(); }\n },\n [close]\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const trigger = cloneElement(children as any, {\n ref: triggerRef,\n id: triggerId,\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": open,\n \"aria-controls\": open ? popoverId : undefined,\n onClick: (e: React.MouseEvent<HTMLElement>) => {\n toggle();\n children.props.onClick?.(e);\n },\n });\n\n const panel = (\n <div\n ref={panelRef}\n id={popoverId}\n role=\"dialog\"\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[\n styles.panel,\n pos ? styles[pos.placement] : null,\n open && pos ? styles.visible : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={\n pos\n ? { top: pos.top, left: pos.left }\n : { visibility: \"hidden\", pointerEvents: \"none\", top: -9999, left: -9999 }\n }\n onKeyDown={handlePanelKeyDown}\n >\n {/* Arrow β offset shifts it to point at the trigger when the panel is clamped */}\n <div\n className={styles.arrow}\n aria-hidden=\"true\"\n style={\n pos?.arrowOffset !== undefined\n ? pos.placement === \"top\" || pos.placement === \"bottom\"\n ? { left: pos.arrowOffset - ARROW_HALF, marginLeft: 0 }\n : { top: pos.arrowOffset - ARROW_HALF, marginTop: 0 }\n : undefined\n }\n />\n {content}\n </div>\n );\n\n return (\n <>\n {trigger}\n {open &&\n (typeof document !== \"undefined\"\n ? createPortal(panel, document.body)\n : panel)}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.js","names":[],"sources":["../../../src/components/Popover/Popover.tsx"],"sourcesContent":["import {\n cloneElement,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport styles from './Popover.module.css';\n\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface PopoverProps {\n /**\n * The rich content rendered inside the popover panel.\n * Can include interactive elements (buttons, links, forms).\n */\n content: ReactNode;\n /**\n * Preferred placement relative to the trigger.\n * Flips automatically when there is not enough viewport space.\n * Defaults to `\"bottom\"`.\n */\n placement?: PopoverPlacement;\n /**\n * Whether the popover is open (controlled mode).\n * Omit to use uncontrolled mode where the trigger toggles it.\n */\n open?: boolean;\n /**\n * Called when the popover requests to be closed\n * (Escape key, outside click, or trigger click while open).\n */\n onClose?: () => void;\n /**\n * Called when open state should change (controlled mode).\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The trigger element. Must be a single React element that can\n * receive `ref` and click/keyboard event props.\n */\n children: ReactElement<HTMLAttributes<HTMLElement>>;\n}\n\ninterface Position {\n top: number;\n left: number;\n placement: PopoverPlacement;\n /** Arrow center offset in px from the near edge of the panel.\n * Horizontal (left) for top/bottom; vertical (top) for left/right.\n * Undefined means use the default 50% CSS. */\n arrowOffset?: number;\n}\n\nconst GAP = 8;\nconst MARGIN = 10;\nconst ARROW_HALF = 6; // half of the 12 px arrow\n\nfunction computePosition(\n trigger: DOMRect,\n popover: DOMRect,\n preferred: PopoverPlacement,\n): Position {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const order: PopoverPlacement[] = [\n preferred,\n preferred === 'top'\n ? 'bottom'\n : preferred === 'bottom'\n ? 'top'\n : preferred === 'left'\n ? 'right'\n : 'left',\n 'bottom',\n 'top',\n 'left',\n 'right',\n ];\n\n // De-duplicate while preserving order\n const candidates = [...new Set(order)];\n\n function calcRaw(p: PopoverPlacement): { top: number; left: number } {\n if (p === 'bottom') {\n return {\n top: trigger.bottom + GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n }\n\n if (p === 'top') {\n return {\n top: trigger.top - popover.height - GAP,\n left: trigger.left + trigger.width / 2 - popover.width / 2,\n };\n }\n\n if (p === 'left') {\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.left - popover.width - GAP,\n };\n }\n\n return {\n top: trigger.top + trigger.height / 2 - popover.height / 2,\n left: trigger.right + GAP,\n };\n }\n\n // First pass: find a placement that fits both axes perfectly.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n\n if (fitsH && fitsV) {\n // Always use pixel arrowOffset (never rely on CSS left:50%) so the arrow\n // points exactly at the trigger center regardless of sub-pixel rounding.\n const arrowOffset =\n p === 'top' || p === 'bottom'\n ? trigger.left + trigger.width / 2 - left\n : trigger.top + trigger.height / 2 - top;\n\n return { top, left, placement: p, arrowOffset };\n }\n }\n\n // Second pass: fits the primary axis; clamp the secondary axis and\n // shift the arrow so it still points at the trigger center.\n for (const p of candidates) {\n const { top, left } = calcRaw(p);\n const fitsV = top >= MARGIN && top + popover.height <= vh - MARGIN;\n const fitsH = left >= MARGIN && left + popover.width <= vw - MARGIN;\n\n if ((p === 'top' || p === 'bottom') && fitsV) {\n const clampedLeft = Math.max(MARGIN, Math.min(left, vw - popover.width - MARGIN));\n const rawOffset = trigger.left + trigger.width / 2 - clampedLeft;\n\n return {\n top,\n left: clampedLeft,\n placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.width - ARROW_HALF - 4)),\n };\n }\n\n if ((p === 'left' || p === 'right') && fitsH) {\n const clampedTop = Math.max(MARGIN, Math.min(top, vh - popover.height - MARGIN));\n const rawOffset = trigger.top + trigger.height / 2 - clampedTop;\n\n return {\n top: clampedTop,\n left,\n placement: p,\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawOffset, popover.height - ARROW_HALF - 4)),\n };\n }\n }\n\n // Fallback: clamp bottom placement and shift arrow to match trigger.\n const fbTop = trigger.bottom + GAP;\n const fbLeft = trigger.left + trigger.width / 2 - popover.width / 2;\n const clampedTop = Math.max(MARGIN, Math.min(fbTop, vh - popover.height - MARGIN));\n const clampedLeft = Math.max(MARGIN, Math.min(fbLeft, vw - popover.width - MARGIN));\n const rawArrowOffset = trigger.left + trigger.width / 2 - clampedLeft;\n\n return {\n top: clampedTop,\n left: clampedLeft,\n placement: 'bottom',\n arrowOffset: Math.max(ARROW_HALF + 4, Math.min(rawArrowOffset, popover.width - ARROW_HALF - 4)),\n };\n}\n\n/**\n * Floating panel anchored to a trigger element.\n *\n * Unlike `Tooltip`, a Popover can contain rich interactive content\n * (menus, forms, details). It follows the Adwaita `GtkPopover` pattern.\n *\n * - Supports both controlled (`open` + `onClose`) and uncontrolled modes.\n * - Auto-positions with viewport-aware flip.\n * - Closes on Escape, outside click, or trigger re-click.\n * - Focus is moved into the panel on open; returns to the trigger on close.\n * - `aria-haspopup=\"dialog\"` + `aria-expanded` wired to the trigger.\n * - `role=\"dialog\"` on the panel with `aria-labelledby` when a heading is present.\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Popover.html\n */\nexport function Popover({\n content,\n placement: preferredPlacement = 'bottom',\n open: controlledOpen,\n onClose,\n onOpenChange,\n children,\n}: PopoverProps) {\n const isControlled = controlledOpen !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const open = isControlled ? controlledOpen : uncontrolledOpen;\n\n const [pos, setPos] = useState<Position | null>(null);\n\n const triggerId = useId();\n const popoverId = useId();\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const previouslyFocused = useRef<Element | null>(null);\n\n const close = useCallback(() => {\n if (isControlled) {\n onClose?.();\n } else {\n setUncontrolledOpen(false);\n }\n\n onOpenChange?.(false);\n }, [isControlled, onClose, onOpenChange]);\n\n const toggle = useCallback(() => {\n if (open) {\n close();\n } else {\n if (!isControlled) {\n setUncontrolledOpen(true);\n }\n\n onOpenChange?.(true);\n }\n }, [open, close, isControlled, onOpenChange]);\n\n // Position panel\n const place = useCallback(() => {\n if (!triggerRef.current || !panelRef.current) {\n return;\n }\n\n setPos(\n computePosition(\n triggerRef.current.getBoundingClientRect(),\n panelRef.current.getBoundingClientRect(),\n preferredPlacement,\n ),\n );\n }, [preferredPlacement]);\n\n // Reposition on open, scroll, resize\n useEffect(() => {\n if (!open) {\n return;\n }\n\n // Two RAF: first lets panel mount with hidden styles so we can measure it;\n // second applies the measured position.\n const id = requestAnimationFrame(() => {\n place();\n window.addEventListener('scroll', place, { passive: true, capture: true });\n window.addEventListener('resize', place, { passive: true });\n });\n\n return () => {\n cancelAnimationFrame(id);\n window.removeEventListener('scroll', place, { capture: true });\n window.removeEventListener('resize', place);\n };\n }, [open, place]);\n\n // Save / restore focus\n useEffect(() => {\n if (open) {\n previouslyFocused.current = document.activeElement;\n requestAnimationFrame(() => {\n const first = panelRef.current?.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n\n (first ?? panelRef.current)?.focus();\n });\n } else {\n (previouslyFocused.current as HTMLElement | null)?.focus();\n setPos(null);\n }\n }, [open]);\n\n // Close on outside pointer\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handler = (e: MouseEvent) => {\n if (\n !triggerRef.current?.contains(e.target as Node) &&\n !panelRef.current?.contains(e.target as Node)\n ) {\n close();\n }\n };\n\n document.addEventListener('mousedown', handler);\n\n return () => document.removeEventListener('mousedown', handler);\n }, [open, close]);\n\n // Escape key\n const handlePanelKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n close();\n }\n },\n [close],\n );\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const trigger = cloneElement(children as any, {\n ref: triggerRef,\n id: triggerId,\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n 'aria-controls': open ? popoverId : undefined,\n onClick: (e: ReactMouseEvent<HTMLElement>) => {\n toggle();\n children.props.onClick?.(e);\n },\n });\n\n const panel = (\n <div\n ref={panelRef}\n id={popoverId}\n role=\"dialog\"\n aria-labelledby={triggerId}\n tabIndex={-1}\n className={[\n styles.panel,\n pos ? styles[pos.placement] : null,\n open && pos ? styles.visible : null,\n ]\n .filter(Boolean)\n .join(' ')}\n style={\n pos\n ? { top: pos.top, left: pos.left }\n : { visibility: 'hidden', pointerEvents: 'none', top: -9999, left: -9999 }\n }\n onKeyDown={handlePanelKeyDown}\n >\n {/* Arrow β offset shifts it to point at the trigger when the panel is clamped */}\n <div\n className={styles.arrow}\n aria-hidden=\"true\"\n style={\n pos?.arrowOffset !== undefined\n ? pos.placement === 'top' || pos.placement === 'bottom'\n ? { left: pos.arrowOffset - ARROW_HALF, marginLeft: 0 }\n : { top: pos.arrowOffset - ARROW_HALF, marginTop: 0 }\n : undefined\n }\n />\n {content}\n </div>\n );\n\n return (\n <>\n {trigger}\n {open && (typeof document !== 'undefined' ? createPortal(panel, document.body) : panel)}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={panel:`
|
|
1
|
+
var e={panel:`_panel_46zzm_3`,visible:`_visible_46zzm_36`,arrow:`_arrow_46zzm_44`,bottom:`_bottom_46zzm_59`,top:`_top_46zzm_67`,left:`_left_46zzm_75`,right:`_right_46zzm_83`};exports.default=e;
|
|
2
2
|
//# sourceMappingURL=Popover.module.css.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.module.css.cjs","names":[],"sources":["../../../src/components/Popover/Popover.module.css"],"sourcesContent":["/* βββ Panel ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.panel {\n position: fixed;\n z-index: 10200; /* above Toaster (9999), below Dialog (10000) */\n\n min-width: 180px;\n max-width: 320px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n border-radius: var(--gnome-radius-lg, 12px);\n box-shadow:\n 0 4px 20px rgba(0, 0, 0, 0.14),\n 0 1px 4px
|
|
1
|
+
{"version":3,"file":"Popover.module.css.cjs","names":[],"sources":["../../../src/components/Popover/Popover.module.css"],"sourcesContent":["/* βββ Panel ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.panel {\n position: fixed;\n z-index: 10200; /* above Toaster (9999), below Dialog (10000) */\n\n min-width: 180px;\n max-width: 320px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n border-radius: var(--gnome-radius-lg, 12px);\n box-shadow:\n 0 4px 20px rgba(0, 0, 0, 0.14),\n 0 1px 4px rgba(0, 0, 0, 0.08);\n\n padding: var(--gnome-space-2, 12px);\n\n font-family: var(--gnome-font-family);\n\n /* Hidden before position is known */\n opacity: 0;\n transform: scale(0.95);\n transition:\n opacity var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease),\n transform var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n\n /* Don't intercept events while invisible */\n pointer-events: none;\n\n outline: none;\n}\n\n.visible {\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n}\n\n/* βββ Arrow ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.arrow {\n position: absolute;\n width: 12px;\n height: 12px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n\n /* Arrow points toward the trigger */\n transform: rotate(45deg);\n pointer-events: none;\n z-index: -1;\n}\n\n/* Position arrow on each side */\n.bottom .arrow {\n top: -6px;\n left: 50%;\n margin-left: -6px;\n border-right-color: transparent;\n border-bottom-color: transparent;\n}\n\n.top .arrow {\n bottom: -6px;\n left: 50%;\n margin-left: -6px;\n border-left-color: transparent;\n border-top-color: transparent;\n}\n\n.left .arrow {\n right: -6px;\n top: 50%;\n margin-top: -6px;\n border-left-color: transparent;\n border-bottom-color: transparent;\n}\n\n.right .arrow {\n left: -6px;\n top: 50%;\n margin-top: -6px;\n border-right-color: transparent;\n border-top-color: transparent;\n}\n\n/* βββ Dark mode ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-color-scheme: dark) {\n .panel {\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #383838));\n border-color: rgba(255, 255, 255, 0.1);\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.4),\n 0 1px 4px rgba(0, 0, 0, 0.3);\n }\n\n .arrow {\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #383838));\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .bottom .arrow {\n border-right-color: transparent;\n border-bottom-color: transparent;\n }\n .top .arrow {\n border-left-color: transparent;\n border-top-color: transparent;\n }\n .left .arrow {\n border-left-color: transparent;\n border-bottom-color: transparent;\n }\n .right .arrow {\n border-right-color: transparent;\n border-top-color: transparent;\n }\n}\n\n/* βββ Reduced motion βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .panel {\n transition: opacity var(--gnome-duration-fast, 100ms) linear;\n transform: none;\n }\n\n .visible {\n transform: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
var e = {
|
|
2
|
-
panel: "
|
|
3
|
-
visible: "
|
|
4
|
-
arrow: "
|
|
5
|
-
bottom: "
|
|
6
|
-
top: "
|
|
7
|
-
left: "
|
|
8
|
-
right: "
|
|
2
|
+
panel: "_panel_46zzm_3",
|
|
3
|
+
visible: "_visible_46zzm_36",
|
|
4
|
+
arrow: "_arrow_46zzm_44",
|
|
5
|
+
bottom: "_bottom_46zzm_59",
|
|
6
|
+
top: "_top_46zzm_67",
|
|
7
|
+
left: "_left_46zzm_75",
|
|
8
|
+
right: "_right_46zzm_83"
|
|
9
9
|
};
|
|
10
10
|
//#endregion
|
|
11
11
|
export { e as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.module.css.js","names":[],"sources":["../../../src/components/Popover/Popover.module.css"],"sourcesContent":["/* βββ Panel ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.panel {\n position: fixed;\n z-index: 10200; /* above Toaster (9999), below Dialog (10000) */\n\n min-width: 180px;\n max-width: 320px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n border-radius: var(--gnome-radius-lg, 12px);\n box-shadow:\n 0 4px 20px rgba(0, 0, 0, 0.14),\n 0 1px 4px
|
|
1
|
+
{"version":3,"file":"Popover.module.css.js","names":[],"sources":["../../../src/components/Popover/Popover.module.css"],"sourcesContent":["/* βββ Panel ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.panel {\n position: fixed;\n z-index: 10200; /* above Toaster (9999), below Dialog (10000) */\n\n min-width: 180px;\n max-width: 320px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n color: var(--gnome-window-fg-color, rgba(0, 0, 0, 0.8));\n\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n border-radius: var(--gnome-radius-lg, 12px);\n box-shadow:\n 0 4px 20px rgba(0, 0, 0, 0.14),\n 0 1px 4px rgba(0, 0, 0, 0.08);\n\n padding: var(--gnome-space-2, 12px);\n\n font-family: var(--gnome-font-family);\n\n /* Hidden before position is known */\n opacity: 0;\n transform: scale(0.95);\n transition:\n opacity var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease),\n transform var(--gnome-duration-fast, 100ms) var(--gnome-easing-default, ease);\n\n /* Don't intercept events while invisible */\n pointer-events: none;\n\n outline: none;\n}\n\n.visible {\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n}\n\n/* βββ Arrow ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n.arrow {\n position: absolute;\n width: 12px;\n height: 12px;\n\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #ffffff));\n border: 1px solid var(--gnome-card-shade-color, rgba(0, 0, 0, 0.1));\n\n /* Arrow points toward the trigger */\n transform: rotate(45deg);\n pointer-events: none;\n z-index: -1;\n}\n\n/* Position arrow on each side */\n.bottom .arrow {\n top: -6px;\n left: 50%;\n margin-left: -6px;\n border-right-color: transparent;\n border-bottom-color: transparent;\n}\n\n.top .arrow {\n bottom: -6px;\n left: 50%;\n margin-left: -6px;\n border-left-color: transparent;\n border-top-color: transparent;\n}\n\n.left .arrow {\n right: -6px;\n top: 50%;\n margin-top: -6px;\n border-left-color: transparent;\n border-bottom-color: transparent;\n}\n\n.right .arrow {\n left: -6px;\n top: 50%;\n margin-top: -6px;\n border-right-color: transparent;\n border-top-color: transparent;\n}\n\n/* βββ Dark mode ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-color-scheme: dark) {\n .panel {\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #383838));\n border-color: rgba(255, 255, 255, 0.1);\n box-shadow:\n 0 4px 24px rgba(0, 0, 0, 0.4),\n 0 1px 4px rgba(0, 0, 0, 0.3);\n }\n\n .arrow {\n background-color: var(--gnome-popover-bg-color, var(--gnome-card-bg-color, #383838));\n border-color: rgba(255, 255, 255, 0.1);\n }\n\n .bottom .arrow {\n border-right-color: transparent;\n border-bottom-color: transparent;\n }\n .top .arrow {\n border-left-color: transparent;\n border-top-color: transparent;\n }\n .left .arrow {\n border-left-color: transparent;\n border-bottom-color: transparent;\n }\n .right .arrow {\n border-right-color: transparent;\n border-top-color: transparent;\n }\n}\n\n/* βββ Reduced motion βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */\n\n@media (prefers-reduced-motion: reduce) {\n .panel {\n transition: opacity var(--gnome-duration-fast, 100ms) linear;\n transform: none;\n }\n\n .visible {\n transform: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`./PreferencesDialog.module.css.cjs`);let t=require(`react`),n=require(`react-dom`),r=require(`react/jsx-runtime`);var i=`button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])`;function a(e,t){if(e.key!==`Tab`)return;let n=Array.from(t.current?.querySelectorAll(i)??[]);if(!n.length)return;let r=n[0],a=n[n.length-1];e.shiftKey?document.activeElement===r&&(e.preventDefault(),a.focus()):document.activeElement===a&&(e.preventDefault(),r.focus())}function o({open:o,onClose:s,children:c,searchable:l=!0,className:u,...d}){let f=(0,t.useRef)(null),p=(0,t.useRef)(null),m=(0,t.useId)(),h=t.Children.toArray(c).filter(e=>(0,t.isValidElement)(e)),[g,_]=(0,t.useState)(0),[v,y]=(0,t.useState)(``);(0,t.useEffect)(()=>{if(o){_(0),y(``);let e=requestAnimationFrame(()=>{l&&p.current?p.current.focus():(f.current?.querySelector(i))?.focus()});return()=>cancelAnimationFrame(e)}},[o,l]);let b=(0,t.useCallback)(e=>{if(e.key===`Escape`){e.stopPropagation(),s();return}a(e,f)},[s]),x=h.length>1,S=h[g]??h[0],C=v.trim().toLowerCase();return o?(0,n.createPortal)((0,r.jsx)(`div`,{className:e.default.backdrop,onClick:e=>{e.target===e.currentTarget&&s()},role:`presentation`,children:(0,r.jsxs)(`div`,{ref:f,role:`dialog`,"aria-modal":`true`,"aria-labelledby":m,className:[e.default.dialog,x?e.default.dialogMulti:null,u].filter(Boolean).join(` `),onKeyDown:b,...d,children:[(0,r.jsxs)(`div`,{className:e.default.header,children:[(0,r.jsx)(`button`,{type:`button`,className:e.default.closeBtn,onClick:s,"aria-label":`Close preferences`,children:`β`}),(0,r.jsx)(`span`,{id:m,className:e.default.title,children:`Preferences`}),l&&(0,r.jsx)(`div`,{className:e.default.searchWrap,children:(0,r.jsx)(`input`,{ref:p,type:`search`,placeholder:`Searchβ¦`,value:v,onChange:e=>y(e.target.value),className:e.default.searchInput,"aria-label":`Search preferences`})})]}),(0,r.jsxs)(`div`,{className:e.default.body,children:[x&&(0,r.jsx)(`nav`,{className:e.default.sidebar,"aria-label":`Preferences pages`,children:(0,r.jsx)(`ul`,{
|
|
1
|
+
const e=require(`./PreferencesDialog.module.css.cjs`);let t=require(`react`),n=require(`react-dom`),r=require(`react/jsx-runtime`);var i=`button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])`;function a(e,t){if(e.key!==`Tab`)return;let n=Array.from(t.current?.querySelectorAll(i)??[]);if(!n.length)return;let r=n[0],a=n[n.length-1];e.shiftKey?document.activeElement===r&&(e.preventDefault(),a.focus()):document.activeElement===a&&(e.preventDefault(),r.focus())}function o({open:o,onClose:s,children:c,searchable:l=!0,className:u,...d}){let f=(0,t.useRef)(null),p=(0,t.useRef)(null),m=(0,t.useId)(),h=t.Children.toArray(c).filter(e=>(0,t.isValidElement)(e)),[g,_]=(0,t.useState)(0),[v,y]=(0,t.useState)(``);(0,t.useEffect)(()=>{if(o){_(0),y(``);let e=requestAnimationFrame(()=>{l&&p.current?p.current.focus():(f.current?.querySelector(i))?.focus()});return()=>cancelAnimationFrame(e)}},[o,l]);let b=(0,t.useCallback)(e=>{if(e.key===`Escape`){e.stopPropagation(),s();return}a(e,f)},[s]),x=h.length>1,S=h[g]??h[0],C=v.trim().toLowerCase();return o?(0,n.createPortal)((0,r.jsx)(`div`,{className:e.default.backdrop,onClick:e=>{e.target===e.currentTarget&&s()},role:`presentation`,children:(0,r.jsxs)(`div`,{ref:f,role:`dialog`,"aria-modal":`true`,"aria-labelledby":m,className:[e.default.dialog,x?e.default.dialogMulti:null,u].filter(Boolean).join(` `),onKeyDown:b,...d,children:[(0,r.jsxs)(`div`,{className:e.default.header,children:[(0,r.jsx)(`button`,{type:`button`,className:e.default.closeBtn,onClick:s,"aria-label":`Close preferences`,children:`β`}),(0,r.jsx)(`span`,{id:m,className:e.default.title,children:`Preferences`}),l&&(0,r.jsx)(`div`,{className:e.default.searchWrap,children:(0,r.jsx)(`input`,{ref:p,type:`search`,placeholder:`Searchβ¦`,value:v,onChange:e=>y(e.target.value),className:e.default.searchInput,"aria-label":`Search preferences`})})]}),(0,r.jsxs)(`div`,{className:e.default.body,children:[x&&(0,r.jsx)(`nav`,{className:e.default.sidebar,"aria-label":`Preferences pages`,children:(0,r.jsx)(`ul`,{className:e.default.navList,children:h.map((t,n)=>(0,r.jsx)(`li`,{role:`presentation`,children:(0,r.jsxs)(`button`,{role:`tab`,type:`button`,"aria-selected":n===g,className:[e.default.navItem,n===g?e.default.navItemActive:null].filter(Boolean).join(` `),onClick:()=>_(n),children:[t.props.iconName&&(0,r.jsx)(`span`,{className:[e.default.navIcon,`icon`,t.props.iconName].join(` `),"aria-hidden":`true`}),(0,r.jsx)(`span`,{className:e.default.navLabel,children:t.props.title})]})},n))})}),(0,r.jsx)(`div`,{className:e.default.pageWrap,children:S&&(0,t.cloneElement)(S,{"data-search-query":C||void 0})})]})]})}),document.body):null}exports.PreferencesDialog=o;
|
|
2
2
|
//# sourceMappingURL=PreferencesDialog.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreferencesDialog.cjs","names":[],"sources":["../../../src/components/PreferencesDialog/PreferencesDialog.tsx"],"sourcesContent":["import {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./PreferencesDialog.module.css\";\nimport type { PreferencesPageProps } from \"../PreferencesPage/PreferencesPage\";\n\n// βββ Focus trap βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction trapFocus(\n e: KeyboardEvent<HTMLDivElement>,\n ref: React.RefObject<HTMLDivElement | null>\n) {\n if (e.key !== \"Tab\") return;\n const focusable = Array.from(\n ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []\n );\n if (!focusable.length) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n}\n\n// βββ Types ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nexport interface PreferencesDialogProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Whether the dialog is open. */\n open: boolean;\n /** Called when the user requests to close the dialog. */\n onClose: () => void;\n /**\n * `PreferencesPage` children. Each page appears as a sidebar entry.\n * When only one page is provided the sidebar is hidden.\n */\n children?: ReactNode;\n /**\n * Whether to show a search bar in the header.\n * When `true` the user can filter group/row content by typing.\n * Defaults to `true`.\n */\n searchable?: boolean;\n}\n\n// βββ Component ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n/**\n * Multi-page settings dialog using `PreferencesPage` tabs.\n *\n * Renders a wide modal with an optional sidebar listing pages. Each\n * `PreferencesPage` child becomes a navigation entry. Supports built-in\n * search when `searchable` is `true` (the default).\n *\n * Mirrors `AdwPreferencesDialog`.\n *\n * @example\n * ```tsx\n * <PreferencesDialog open={open} onClose={() => setOpen(false)}>\n * <PreferencesPage title=\"General\" iconName=\"preferences-system-symbolic\">\n * <PreferencesGroup title=\"Appearance\">\n * <BoxedList>\n * <SwitchRow title=\"Dark mode\" />\n * </BoxedList>\n * </PreferencesGroup>\n * </PreferencesPage>\n * </PreferencesDialog>\n * ```\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.PreferencesDialog.html\n */\nexport function PreferencesDialog({\n open,\n onClose,\n children,\n searchable = true,\n className,\n ...props\n}: PreferencesDialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const titleId = useId();\n\n const pages = Children.toArray(children).filter(\n (c): c is ReactElement<PreferencesPageProps> =>\n isValidElement(c)\n ) as ReactElement<PreferencesPageProps>[];\n\n const [activeIndex, setActiveIndex] = useState(0);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // Reset state when dialog opens\n useEffect(() => {\n if (open) {\n setActiveIndex(0);\n setSearchQuery(\"\");\n // Focus search or first focusable after open animation\n const id = requestAnimationFrame(() => {\n if (searchable && searchRef.current) {\n searchRef.current.focus();\n } else {\n const first = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE);\n first?.focus();\n }\n });\n return () => cancelAnimationFrame(id);\n }\n }, [open, searchable]);\n\n // Close on Escape\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n onClose();\n return;\n }\n trapFocus(e, dialogRef);\n },\n [onClose]\n );\n\n const multiPage = pages.length > 1;\n const activePage = pages[activeIndex] ?? pages[0];\n\n // Filter content by search query\n const query = searchQuery.trim().toLowerCase();\n\n if (!open) return null;\n\n return createPortal(\n <div\n className={styles.backdrop}\n onClick={(e) => {\n if (e.target === e.currentTarget) onClose();\n }}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className={[\n styles.dialog,\n multiPage ? styles.dialogMulti : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {/* ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.closeBtn}\n onClick={onClose}\n aria-label=\"Close preferences\"\n >\n β\n </button>\n <span id={titleId} className={styles.title}>\n Preferences\n </span>\n {searchable && (\n <div className={styles.searchWrap}>\n <input\n ref={searchRef}\n type=\"search\"\n placeholder=\"Searchβ¦\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={styles.searchInput}\n aria-label=\"Search preferences\"\n />\n </div>\n )}\n </div>\n\n {/* ββ Body βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.body}>\n {/* Sidebar β only shown when there are multiple pages */}\n {multiPage && (\n <nav className={styles.sidebar} aria-label=\"Preferences pages\">\n <ul role=\"tablist\" className={styles.navList}>\n {pages.map((page, i) => (\n <li key={i} role=\"presentation\">\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={i === activeIndex}\n className={[\n styles.navItem,\n i === activeIndex ? styles.navItemActive : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n onClick={() => setActiveIndex(i)}\n >\n {page.props.iconName && (\n <span\n className={[\n styles.navIcon,\n \"icon\",\n page.props.iconName,\n ].join(\" \")}\n aria-hidden=\"true\"\n />\n )}\n <span className={styles.navLabel}>\n {page.props.title}\n </span>\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )}\n\n {/* Page content */}\n <div className={styles.pageWrap}>\n {activePage &&\n cloneElement(activePage, {\n \"data-search-query\": query || undefined,\n } as Partial<PreferencesPageProps>)}\n </div>\n </div>\n </div>\n </div>,\n document.body\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PreferencesDialog.cjs","names":[],"sources":["../../../src/components/PreferencesDialog/PreferencesDialog.tsx"],"sourcesContent":["import {\n Children,\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport type { PreferencesPageProps } from '../PreferencesPage/PreferencesPage';\n\nimport styles from './PreferencesDialog.module.css';\n\n// βββ Focus trap βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction trapFocus(e: KeyboardEvent<HTMLDivElement>, ref: RefObject<HTMLDivElement | null>) {\n if (e.key !== 'Tab') {\n return;\n }\n\n const focusable = Array.from(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []);\n\n if (!focusable.length) {\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n}\n\n// βββ Types ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nexport interface PreferencesDialogProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Whether the dialog is open. */\n open: boolean;\n /** Called when the user requests to close the dialog. */\n onClose: () => void;\n /**\n * `PreferencesPage` children. Each page appears as a sidebar entry.\n * When only one page is provided the sidebar is hidden.\n */\n children?: ReactNode;\n /**\n * Whether to show a search bar in the header.\n * When `true` the user can filter group/row content by typing.\n * Defaults to `true`.\n */\n searchable?: boolean;\n}\n\n// βββ Component ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n/**\n * Multi-page settings dialog using `PreferencesPage` tabs.\n *\n * Renders a wide modal with an optional sidebar listing pages. Each\n * `PreferencesPage` child becomes a navigation entry. Supports built-in\n * search when `searchable` is `true` (the default).\n *\n * Mirrors `AdwPreferencesDialog`.\n *\n * @example\n * ```tsx\n * <PreferencesDialog open={open} onClose={() => setOpen(false)}>\n * <PreferencesPage title=\"General\" iconName=\"preferences-system-symbolic\">\n * <PreferencesGroup title=\"Appearance\">\n * <BoxedList>\n * <SwitchRow title=\"Dark mode\" />\n * </BoxedList>\n * </PreferencesGroup>\n * </PreferencesPage>\n * </PreferencesDialog>\n * ```\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.PreferencesDialog.html\n */\nexport function PreferencesDialog({\n open,\n onClose,\n children,\n searchable = true,\n className,\n ...props\n}: PreferencesDialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const titleId = useId();\n\n const pages = Children.toArray(children).filter((c): c is ReactElement<PreferencesPageProps> =>\n isValidElement(c),\n ) as ReactElement<PreferencesPageProps>[];\n\n const [activeIndex, setActiveIndex] = useState(0);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Reset state when dialog opens\n useEffect(() => {\n if (open) {\n setActiveIndex(0);\n setSearchQuery('');\n // Focus search or first focusable after open animation\n const id = requestAnimationFrame(() => {\n if (searchable && searchRef.current) {\n searchRef.current.focus();\n } else {\n const first = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE);\n\n first?.focus();\n }\n });\n\n return () => cancelAnimationFrame(id);\n }\n }, [open, searchable]);\n\n // Close on Escape\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onClose();\n\n return;\n }\n\n trapFocus(e, dialogRef);\n },\n [onClose],\n );\n\n const multiPage = pages.length > 1;\n const activePage = pages[activeIndex] ?? pages[0];\n\n // Filter content by search query\n const query = searchQuery.trim().toLowerCase();\n\n if (!open) {\n return null;\n }\n\n return createPortal(\n <div\n className={styles.backdrop}\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n onClose();\n }\n }}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className={[styles.dialog, multiPage ? styles.dialogMulti : null, className]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {/* ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.closeBtn}\n onClick={onClose}\n aria-label=\"Close preferences\"\n >\n β\n </button>\n <span id={titleId} className={styles.title}>\n Preferences\n </span>\n {searchable && (\n <div className={styles.searchWrap}>\n <input\n ref={searchRef}\n type=\"search\"\n placeholder=\"Searchβ¦\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={styles.searchInput}\n aria-label=\"Search preferences\"\n />\n </div>\n )}\n </div>\n\n {/* ββ Body βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.body}>\n {/* Sidebar β only shown when there are multiple pages */}\n {multiPage && (\n <nav className={styles.sidebar} aria-label=\"Preferences pages\">\n <ul className={styles.navList}>\n {pages.map((page, i) => (\n <li key={i} role=\"presentation\">\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={i === activeIndex}\n className={[styles.navItem, i === activeIndex ? styles.navItemActive : null]\n .filter(Boolean)\n .join(' ')}\n onClick={() => setActiveIndex(i)}\n >\n {page.props.iconName && (\n <span\n className={[styles.navIcon, 'icon', page.props.iconName].join(' ')}\n aria-hidden=\"true\"\n />\n )}\n <span className={styles.navLabel}>{page.props.title}</span>\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )}\n\n {/* Page content */}\n <div className={styles.pageWrap}>\n {activePage &&\n cloneElement(activePage, {\n 'data-search-query': query || undefined,\n } as Partial<PreferencesPageProps>)}\n </div>\n </div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
-
export interface PreferencesDialogProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
2
|
+
export interface PreferencesDialogProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
3
3
|
/** Whether the dialog is open. */
|
|
4
4
|
open: boolean;
|
|
5
5
|
/** Called when the user requests to close the dialog. */
|
|
@@ -81,7 +81,6 @@ function m({ open: m, onClose: h, children: g, searchable: _ = !0, className: v,
|
|
|
81
81
|
className: e.sidebar,
|
|
82
82
|
"aria-label": "Preferences pages",
|
|
83
83
|
children: /* @__PURE__ */ u("ul", {
|
|
84
|
-
role: "tablist",
|
|
85
84
|
className: e.navList,
|
|
86
85
|
children: C.map((t, n) => /* @__PURE__ */ u("li", {
|
|
87
86
|
role: "presentation",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreferencesDialog.js","names":[],"sources":["../../../src/components/PreferencesDialog/PreferencesDialog.tsx"],"sourcesContent":["import {\n Children,\n cloneElement,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport styles from \"./PreferencesDialog.module.css\";\nimport type { PreferencesPageProps } from \"../PreferencesPage/PreferencesPage\";\n\n// βββ Focus trap βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction trapFocus(\n e: KeyboardEvent<HTMLDivElement>,\n ref: React.RefObject<HTMLDivElement | null>\n) {\n if (e.key !== \"Tab\") return;\n const focusable = Array.from(\n ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []\n );\n if (!focusable.length) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n}\n\n// βββ Types ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nexport interface PreferencesDialogProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Whether the dialog is open. */\n open: boolean;\n /** Called when the user requests to close the dialog. */\n onClose: () => void;\n /**\n * `PreferencesPage` children. Each page appears as a sidebar entry.\n * When only one page is provided the sidebar is hidden.\n */\n children?: ReactNode;\n /**\n * Whether to show a search bar in the header.\n * When `true` the user can filter group/row content by typing.\n * Defaults to `true`.\n */\n searchable?: boolean;\n}\n\n// βββ Component ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n/**\n * Multi-page settings dialog using `PreferencesPage` tabs.\n *\n * Renders a wide modal with an optional sidebar listing pages. Each\n * `PreferencesPage` child becomes a navigation entry. Supports built-in\n * search when `searchable` is `true` (the default).\n *\n * Mirrors `AdwPreferencesDialog`.\n *\n * @example\n * ```tsx\n * <PreferencesDialog open={open} onClose={() => setOpen(false)}>\n * <PreferencesPage title=\"General\" iconName=\"preferences-system-symbolic\">\n * <PreferencesGroup title=\"Appearance\">\n * <BoxedList>\n * <SwitchRow title=\"Dark mode\" />\n * </BoxedList>\n * </PreferencesGroup>\n * </PreferencesPage>\n * </PreferencesDialog>\n * ```\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.PreferencesDialog.html\n */\nexport function PreferencesDialog({\n open,\n onClose,\n children,\n searchable = true,\n className,\n ...props\n}: PreferencesDialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const titleId = useId();\n\n const pages = Children.toArray(children).filter(\n (c): c is ReactElement<PreferencesPageProps> =>\n isValidElement(c)\n ) as ReactElement<PreferencesPageProps>[];\n\n const [activeIndex, setActiveIndex] = useState(0);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // Reset state when dialog opens\n useEffect(() => {\n if (open) {\n setActiveIndex(0);\n setSearchQuery(\"\");\n // Focus search or first focusable after open animation\n const id = requestAnimationFrame(() => {\n if (searchable && searchRef.current) {\n searchRef.current.focus();\n } else {\n const first = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE);\n first?.focus();\n }\n });\n return () => cancelAnimationFrame(id);\n }\n }, [open, searchable]);\n\n // Close on Escape\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n onClose();\n return;\n }\n trapFocus(e, dialogRef);\n },\n [onClose]\n );\n\n const multiPage = pages.length > 1;\n const activePage = pages[activeIndex] ?? pages[0];\n\n // Filter content by search query\n const query = searchQuery.trim().toLowerCase();\n\n if (!open) return null;\n\n return createPortal(\n <div\n className={styles.backdrop}\n onClick={(e) => {\n if (e.target === e.currentTarget) onClose();\n }}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className={[\n styles.dialog,\n multiPage ? styles.dialogMulti : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {/* ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.closeBtn}\n onClick={onClose}\n aria-label=\"Close preferences\"\n >\n β\n </button>\n <span id={titleId} className={styles.title}>\n Preferences\n </span>\n {searchable && (\n <div className={styles.searchWrap}>\n <input\n ref={searchRef}\n type=\"search\"\n placeholder=\"Searchβ¦\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={styles.searchInput}\n aria-label=\"Search preferences\"\n />\n </div>\n )}\n </div>\n\n {/* ββ Body βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.body}>\n {/* Sidebar β only shown when there are multiple pages */}\n {multiPage && (\n <nav className={styles.sidebar} aria-label=\"Preferences pages\">\n <ul role=\"tablist\" className={styles.navList}>\n {pages.map((page, i) => (\n <li key={i} role=\"presentation\">\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={i === activeIndex}\n className={[\n styles.navItem,\n i === activeIndex ? styles.navItemActive : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n onClick={() => setActiveIndex(i)}\n >\n {page.props.iconName && (\n <span\n className={[\n styles.navIcon,\n \"icon\",\n page.props.iconName,\n ].join(\" \")}\n aria-hidden=\"true\"\n />\n )}\n <span className={styles.navLabel}>\n {page.props.title}\n </span>\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )}\n\n {/* Page content */}\n <div className={styles.pageWrap}>\n {activePage &&\n cloneElement(activePage, {\n \"data-search-query\": query || undefined,\n } as Partial<PreferencesPageProps>)}\n </div>\n </div>\n </div>\n </div>,\n document.body\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PreferencesDialog.js","names":[],"sources":["../../../src/components/PreferencesDialog/PreferencesDialog.tsx"],"sourcesContent":["import {\n Children,\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type RefObject,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport { createPortal } from 'react-dom';\n\nimport type { PreferencesPageProps } from '../PreferencesPage/PreferencesPage';\n\nimport styles from './PreferencesDialog.module.css';\n\n// βββ Focus trap βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst FOCUSABLE =\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction trapFocus(e: KeyboardEvent<HTMLDivElement>, ref: RefObject<HTMLDivElement | null>) {\n if (e.key !== 'Tab') {\n return;\n }\n\n const focusable = Array.from(ref.current?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []);\n\n if (!focusable.length) {\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n}\n\n// βββ Types ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nexport interface PreferencesDialogProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Whether the dialog is open. */\n open: boolean;\n /** Called when the user requests to close the dialog. */\n onClose: () => void;\n /**\n * `PreferencesPage` children. Each page appears as a sidebar entry.\n * When only one page is provided the sidebar is hidden.\n */\n children?: ReactNode;\n /**\n * Whether to show a search bar in the header.\n * When `true` the user can filter group/row content by typing.\n * Defaults to `true`.\n */\n searchable?: boolean;\n}\n\n// βββ Component ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\n/**\n * Multi-page settings dialog using `PreferencesPage` tabs.\n *\n * Renders a wide modal with an optional sidebar listing pages. Each\n * `PreferencesPage` child becomes a navigation entry. Supports built-in\n * search when `searchable` is `true` (the default).\n *\n * Mirrors `AdwPreferencesDialog`.\n *\n * @example\n * ```tsx\n * <PreferencesDialog open={open} onClose={() => setOpen(false)}>\n * <PreferencesPage title=\"General\" iconName=\"preferences-system-symbolic\">\n * <PreferencesGroup title=\"Appearance\">\n * <BoxedList>\n * <SwitchRow title=\"Dark mode\" />\n * </BoxedList>\n * </PreferencesGroup>\n * </PreferencesPage>\n * </PreferencesDialog>\n * ```\n *\n * @see https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.PreferencesDialog.html\n */\nexport function PreferencesDialog({\n open,\n onClose,\n children,\n searchable = true,\n className,\n ...props\n}: PreferencesDialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const titleId = useId();\n\n const pages = Children.toArray(children).filter((c): c is ReactElement<PreferencesPageProps> =>\n isValidElement(c),\n ) as ReactElement<PreferencesPageProps>[];\n\n const [activeIndex, setActiveIndex] = useState(0);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Reset state when dialog opens\n useEffect(() => {\n if (open) {\n setActiveIndex(0);\n setSearchQuery('');\n // Focus search or first focusable after open animation\n const id = requestAnimationFrame(() => {\n if (searchable && searchRef.current) {\n searchRef.current.focus();\n } else {\n const first = dialogRef.current?.querySelector<HTMLElement>(FOCUSABLE);\n\n first?.focus();\n }\n });\n\n return () => cancelAnimationFrame(id);\n }\n }, [open, searchable]);\n\n // Close on Escape\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onClose();\n\n return;\n }\n\n trapFocus(e, dialogRef);\n },\n [onClose],\n );\n\n const multiPage = pages.length > 1;\n const activePage = pages[activeIndex] ?? pages[0];\n\n // Filter content by search query\n const query = searchQuery.trim().toLowerCase();\n\n if (!open) {\n return null;\n }\n\n return createPortal(\n <div\n className={styles.backdrop}\n onClick={(e) => {\n if (e.target === e.currentTarget) {\n onClose();\n }\n }}\n role=\"presentation\"\n >\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className={[styles.dialog, multiPage ? styles.dialogMulti : null, className]\n .filter(Boolean)\n .join(' ')}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {/* ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.header}>\n <button\n type=\"button\"\n className={styles.closeBtn}\n onClick={onClose}\n aria-label=\"Close preferences\"\n >\n β\n </button>\n <span id={titleId} className={styles.title}>\n Preferences\n </span>\n {searchable && (\n <div className={styles.searchWrap}>\n <input\n ref={searchRef}\n type=\"search\"\n placeholder=\"Searchβ¦\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={styles.searchInput}\n aria-label=\"Search preferences\"\n />\n </div>\n )}\n </div>\n\n {/* ββ Body βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */}\n <div className={styles.body}>\n {/* Sidebar β only shown when there are multiple pages */}\n {multiPage && (\n <nav className={styles.sidebar} aria-label=\"Preferences pages\">\n <ul className={styles.navList}>\n {pages.map((page, i) => (\n <li key={i} role=\"presentation\">\n <button\n role=\"tab\"\n type=\"button\"\n aria-selected={i === activeIndex}\n className={[styles.navItem, i === activeIndex ? styles.navItemActive : null]\n .filter(Boolean)\n .join(' ')}\n onClick={() => setActiveIndex(i)}\n >\n {page.props.iconName && (\n <span\n className={[styles.navIcon, 'icon', page.props.iconName].join(' ')}\n aria-hidden=\"true\"\n />\n )}\n <span className={styles.navLabel}>{page.props.title}</span>\n </button>\n </li>\n ))}\n </ul>\n </nav>\n )}\n\n {/* Page content */}\n <div className={styles.pageWrap}>\n {activePage &&\n cloneElement(activePage, {\n 'data-search-query': query || undefined,\n } as Partial<PreferencesPageProps>)}\n </div>\n </div>\n </div>\n </div>,\n document.body,\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=`
|
|
1
|
+
var e=`_backdrop_1k5wp_3`,t=`_dialog_1k5wp_30`,n=`_dialogMulti_1k5wp_50`,r=`_header_1k5wp_67`,i=`_closeBtn_1k5wp_78`,a=`_title_1k5wp_108`,o=`_searchWrap_1k5wp_118`,s=`_searchInput_1k5wp_122`,c=`_body_1k5wp_151`,l=`_sidebar_1k5wp_160`,u=`_navList_1k5wp_168`,d=`_navItem_1k5wp_177`,f=`_navItemActive_1k5wp_198`,p=`_navIcon_1k5wp_213`,m=`_navLabel_1k5wp_219`,h=`_pageWrap_1k5wp_229`,g={backdrop:e,"backdrop-in":`_backdrop-in_1k5wp_1`,dialog:t,"dialog-in":`_dialog-in_1k5wp_1`,dialogMulti:n,header:r,closeBtn:i,title:a,searchWrap:o,searchInput:s,body:c,sidebar:l,navList:u,navItem:d,navItemActive:f,navIcon:p,navLabel:m,pageWrap:h};exports.default=g;
|
|
2
2
|
//# sourceMappingURL=PreferencesDialog.module.css.cjs.map
|