@lar-works/design-system 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/actions/Button.d.ts +39 -1
- package/dist/actions/Button.js +39 -9
- package/dist/actions/Button.js.map +1 -1
- package/dist/actions/ButtonLink.d.ts +5 -1
- package/dist/actions/ButtonLink.js +28 -2
- package/dist/actions/ButtonLink.js.map +1 -1
- package/dist/actions/ButtonRecipes.js +7 -0
- package/dist/actions/ButtonRecipes.js.map +1 -0
- package/dist/actions/IconButton.d.ts +2 -2
- package/dist/actions/IconButton.js +1 -1
- package/dist/actions/IconButton.js.map +1 -1
- package/dist/actions/ThemeSwitch.js +1 -1
- package/dist/board/ActivityLine.d.ts +36 -0
- package/dist/board/ActivityLine.js +144 -0
- package/dist/board/ActivityLine.js.map +1 -0
- package/dist/board/ActivityTrack.d.ts +11 -0
- package/dist/board/ActivityTrack.js +25 -0
- package/dist/board/ActivityTrack.js.map +1 -0
- package/dist/board/AddItem.d.ts +82 -0
- package/dist/board/AddItem.js +185 -0
- package/dist/board/AddItem.js.map +1 -0
- package/dist/board/Archive.d.ts +21 -0
- package/dist/board/Archive.js +63 -0
- package/dist/board/Archive.js.map +1 -0
- package/dist/board/Attention.d.ts +66 -0
- package/dist/board/Attention.js +122 -0
- package/dist/board/Attention.js.map +1 -0
- package/dist/board/BoardShell.d.ts +16 -0
- package/dist/board/BoardShell.js +35 -0
- package/dist/board/BoardShell.js.map +1 -0
- package/dist/board/BoardTitleBar.d.ts +50 -0
- package/dist/board/BoardTitleBar.js +125 -0
- package/dist/board/BoardTitleBar.js.map +1 -0
- package/dist/board/ButtonKinds.d.ts +24 -0
- package/dist/board/ButtonKinds.js +19 -0
- package/dist/board/ButtonKinds.js.map +1 -0
- package/dist/board/Cleanup.d.ts +8 -0
- package/dist/board/Cleanup.js +15 -0
- package/dist/board/Cleanup.js.map +1 -0
- package/dist/board/Counters.d.ts +101 -0
- package/dist/board/Counters.js +202 -0
- package/dist/board/Counters.js.map +1 -0
- package/dist/board/DataAttributes.d.ts +6 -0
- package/dist/board/Dependencies.d.ts +17 -0
- package/dist/board/Dependencies.js +44 -0
- package/dist/board/Dependencies.js.map +1 -0
- package/dist/board/Desk.d.ts +52 -0
- package/dist/board/Desk.js +130 -0
- package/dist/board/Desk.js.map +1 -0
- package/dist/board/Dossier.d.ts +100 -0
- package/dist/board/Dossier.js +194 -0
- package/dist/board/Dossier.js.map +1 -0
- package/dist/board/Filters.d.ts +33 -0
- package/dist/board/Filters.js +64 -0
- package/dist/board/Filters.js.map +1 -0
- package/dist/board/ItemDetails.d.ts +167 -0
- package/dist/board/ItemDetails.js +339 -0
- package/dist/board/ItemDetails.js.map +1 -0
- package/dist/board/ItemDialog.d.ts +73 -0
- package/dist/board/ItemDialog.js +140 -0
- package/dist/board/ItemDialog.js.map +1 -0
- package/dist/board/ItemParts.d.ts +42 -0
- package/dist/board/ItemParts.js +82 -0
- package/dist/board/ItemParts.js.map +1 -0
- package/dist/board/ItemProgress.d.ts +56 -0
- package/dist/board/ItemProgress.js +138 -0
- package/dist/board/ItemProgress.js.map +1 -0
- package/dist/board/List.d.ts +65 -0
- package/dist/board/List.js +118 -0
- package/dist/board/List.js.map +1 -0
- package/dist/board/LoadingScreen.d.ts +38 -0
- package/dist/board/LoadingScreen.js +74 -0
- package/dist/board/LoadingScreen.js.map +1 -0
- package/dist/board/NeedsYou.d.ts +13 -0
- package/dist/board/NeedsYou.js +31 -0
- package/dist/board/NeedsYou.js.map +1 -0
- package/dist/board/Onboarding.d.ts +53 -0
- package/dist/board/Onboarding.js +122 -0
- package/dist/board/Onboarding.js.map +1 -0
- package/dist/board/PartsList.d.ts +60 -0
- package/dist/board/PartsList.js +115 -0
- package/dist/board/PartsList.js.map +1 -0
- package/dist/board/ProjectIcon.d.ts +51 -0
- package/dist/board/ProjectIcon.js +120 -0
- package/dist/board/ProjectIcon.js.map +1 -0
- package/dist/board/PullRequests.d.ts +43 -0
- package/dist/board/PullRequests.js +83 -0
- package/dist/board/PullRequests.js.map +1 -0
- package/dist/board/RowStyles.js +14 -0
- package/dist/board/RowStyles.js.map +1 -0
- package/dist/board/Settings.d.ts +54 -0
- package/dist/board/Settings.js +112 -0
- package/dist/board/Settings.js.map +1 -0
- package/dist/board/Slices.d.ts +32 -0
- package/dist/board/Slices.js +88 -0
- package/dist/board/Slices.js.map +1 -0
- package/dist/board/SourceIcon.d.ts +12 -0
- package/dist/board/SourceIcon.js +24 -0
- package/dist/board/SourceIcon.js.map +1 -0
- package/dist/board/StagePane.d.ts +43 -0
- package/dist/board/StagePane.js +97 -0
- package/dist/board/StagePane.js.map +1 -0
- package/dist/board/StageRow.d.ts +141 -0
- package/dist/board/StageRow.js +287 -0
- package/dist/board/StageRow.js.map +1 -0
- package/dist/board/StageTrack.d.ts +18 -0
- package/dist/board/StageTrack.js +38 -0
- package/dist/board/StageTrack.js.map +1 -0
- package/dist/board/StartControls.d.ts +30 -0
- package/dist/board/StartControls.js +51 -0
- package/dist/board/StartControls.js.map +1 -0
- package/dist/board/StatusColors.d.ts +5 -0
- package/dist/board/StatusColors.js +17 -0
- package/dist/board/StatusColors.js.map +1 -0
- package/dist/board/StatusGlyph.d.ts +18 -0
- package/dist/board/StatusGlyph.js +51 -0
- package/dist/board/StatusGlyph.js.map +1 -0
- package/dist/board/Threads.d.ts +13 -0
- package/dist/board/Threads.js +35 -0
- package/dist/board/Threads.js.map +1 -0
- package/dist/board/TrackerLabels.d.ts +27 -0
- package/dist/board/TrackerLabels.js +56 -0
- package/dist/board/TrackerLabels.js.map +1 -0
- package/dist/board/UpdatePill.d.ts +52 -0
- package/dist/board/UpdatePill.js +188 -0
- package/dist/board/UpdatePill.js.map +1 -0
- package/dist/board/Vocabulary.d.ts +56 -0
- package/dist/board/Vocabulary.js +104 -0
- package/dist/board/Vocabulary.js.map +1 -0
- package/dist/board/Warnings.d.ts +35 -0
- package/dist/board/Warnings.js +85 -0
- package/dist/board/Warnings.js.map +1 -0
- package/dist/board/WorkMap.d.ts +136 -0
- package/dist/board/WorkMap.js +274 -0
- package/dist/board/WorkMap.js.map +1 -0
- package/dist/board/index.d.ts +42 -0
- package/dist/collections/CollectionState.d.ts +10 -1
- package/dist/collections/CollectionState.js +12 -5
- package/dist/collections/CollectionState.js.map +1 -1
- package/dist/collections/ResultList.js +1 -1
- package/dist/collections/ScrollRow.js +1 -1
- package/dist/collections/VirtualList.js +1 -1
- package/dist/display/Avatar.d.ts +5 -2
- package/dist/display/Avatar.js +2 -2
- package/dist/display/Avatar.js.map +1 -1
- package/dist/display/Badge.d.ts +6 -1
- package/dist/display/Badge.js +9 -4
- package/dist/display/Badge.js.map +1 -1
- package/dist/display/CheckList.js +1 -1
- package/dist/display/Comment.d.ts +12 -0
- package/dist/display/Comment.js +39 -0
- package/dist/display/Comment.js.map +1 -0
- package/dist/display/CopyButton.d.ts +10 -2
- package/dist/display/CopyButton.js +29 -16
- package/dist/display/CopyButton.js.map +1 -1
- package/dist/display/Diagram.d.ts +17 -0
- package/dist/display/Diagram.js +49 -0
- package/dist/display/Diagram.js.map +1 -0
- package/dist/display/ImagePicker.js +1 -1
- package/dist/display/InfoBox.js +2 -2
- package/dist/display/InsetPanel.d.ts +3 -1
- package/dist/display/InsetPanel.js +7 -4
- package/dist/display/InsetPanel.js.map +1 -1
- package/dist/display/ItemAction.js +2 -2
- package/dist/display/LabelChip.d.ts +26 -0
- package/dist/display/LabelChip.js +41 -0
- package/dist/display/LabelChip.js.map +1 -0
- package/dist/display/LabelTint.js +60 -0
- package/dist/display/LabelTint.js.map +1 -0
- package/dist/display/Person.d.ts +5 -0
- package/dist/display/Person.js +19 -0
- package/dist/display/Person.js.map +1 -0
- package/dist/display/PropertySheet.js +1 -1
- package/dist/display/RadioChoice.d.ts +9 -2
- package/dist/display/RadioChoice.js +5 -1
- package/dist/display/RadioChoice.js.map +1 -1
- package/dist/display/RatingLink.js +1 -1
- package/dist/display/RichText.d.ts +12 -0
- package/dist/display/RichText.js +94 -0
- package/dist/display/RichText.js.map +1 -0
- package/dist/display/RowList.js +1 -1
- package/dist/display/index.d.ts +6 -1
- package/dist/feedback/Alert.js +1 -1
- package/dist/feedback/AsyncState.js +1 -1
- package/dist/feedback/DismissButton.d.ts +12 -0
- package/dist/feedback/DismissButton.js +20 -0
- package/dist/feedback/DismissButton.js.map +1 -0
- package/dist/feedback/ErrorNotification.js +2 -0
- package/dist/feedback/ErrorNotification.js.map +1 -1
- package/dist/feedback/FormResult.d.ts +16 -0
- package/dist/feedback/FormResult.js +30 -0
- package/dist/feedback/FormResult.js.map +1 -0
- package/dist/feedback/LiveRegion.d.ts +7 -0
- package/dist/feedback/LiveRegion.js +15 -0
- package/dist/feedback/LiveRegion.js.map +1 -0
- package/dist/feedback/Loading.d.ts +19 -0
- package/dist/feedback/Loading.js +63 -0
- package/dist/feedback/Loading.js.map +1 -0
- package/dist/feedback/Notifications.d.ts +35 -1
- package/dist/feedback/Notifications.js +196 -4
- package/dist/feedback/Notifications.js.map +1 -1
- package/dist/feedback/Progress.d.ts +15 -0
- package/dist/feedback/Progress.js +38 -0
- package/dist/feedback/Progress.js.map +1 -0
- package/dist/feedback/ProgressStatusRow.js +1 -1
- package/dist/feedback/StatusIndicator.d.ts +6 -1
- package/dist/feedback/StatusIndicator.js +19 -5
- package/dist/feedback/StatusIndicator.js.map +1 -1
- package/dist/feedback/index.d.ts +8 -4
- package/dist/forms/Checkbox.js +1 -1
- package/dist/forms/ColorSwatches.d.ts +21 -0
- package/dist/forms/ColorSwatches.js +26 -0
- package/dist/forms/ColorSwatches.js.map +1 -0
- package/dist/forms/FormSection.d.ts +68 -6
- package/dist/forms/FormSection.js +139 -8
- package/dist/forms/FormSection.js.map +1 -1
- package/dist/forms/HiddenField.d.ts +6 -0
- package/dist/forms/HiddenField.js +13 -0
- package/dist/forms/HiddenField.js.map +1 -0
- package/dist/forms/Input.d.ts +12 -2
- package/dist/forms/Input.js +10 -3
- package/dist/forms/Input.js.map +1 -1
- package/dist/forms/LabelPicker.d.ts +43 -0
- package/dist/forms/LabelPicker.js +107 -0
- package/dist/forms/LabelPicker.js.map +1 -0
- package/dist/forms/MarkdownEditor.d.ts +21 -0
- package/dist/forms/MarkdownEditor.js +175 -0
- package/dist/forms/MarkdownEditor.js.map +1 -0
- package/dist/forms/MarkdownToolbar.js +204 -0
- package/dist/forms/MarkdownToolbar.js.map +1 -0
- package/dist/forms/OptionSelect.d.ts +30 -9
- package/dist/forms/OptionSelect.js +53 -13
- package/dist/forms/OptionSelect.js.map +1 -1
- package/dist/forms/Select.d.ts +4 -1
- package/dist/forms/Select.js +3 -1
- package/dist/forms/Select.js.map +1 -1
- package/dist/forms/Switch.d.ts +4 -1
- package/dist/forms/Switch.js +5 -2
- package/dist/forms/Switch.js.map +1 -1
- package/dist/forms/TagInput.js +1 -1
- package/dist/forms/index.d.ts +7 -3
- package/dist/foundations/AmbientMotion.d.ts +2 -0
- package/dist/foundations/AmbientMotion.js +39 -0
- package/dist/foundations/AmbientMotion.js.map +1 -0
- package/dist/foundations/DesignSystemProvider.d.ts +34 -0
- package/dist/foundations/DesignSystemProvider.js +26 -1
- package/dist/foundations/DesignSystemProvider.js.map +1 -1
- package/dist/foundations/index.d.ts +2 -1
- package/dist/icons/BrandIcons.d.ts +8 -2
- package/dist/icons/BrandIcons.js +14 -3
- package/dist/icons/BrandIcons.js.map +1 -1
- package/dist/icons/dynamic.d.ts +2 -0
- package/dist/icons/dynamic.js +1 -0
- package/dist/icons/index.d.ts +2 -2
- package/dist/icons/index.js +1 -1
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +71 -10
- package/dist/index.js +78 -21
- package/dist/layout/Site.js +1 -1
- package/dist/layout/TitleBar.js +1 -1
- package/dist/layout/index.d.ts +2 -2
- package/dist/layout/index.js +3 -3
- package/dist/layout/toolbar/CommandPaletteTrigger.d.ts +17 -2
- package/dist/layout/toolbar/CommandPaletteTrigger.js +89 -6
- package/dist/layout/toolbar/CommandPaletteTrigger.js.map +1 -1
- package/dist/layout/toolbar/TriggerFit.js +56 -0
- package/dist/layout/toolbar/TriggerFit.js.map +1 -0
- package/dist/navigation/CollectionBrowseSelector.js +1 -1
- package/dist/navigation/CollectionViewToggle.d.ts +26 -0
- package/dist/navigation/CollectionViewToggle.js +54 -23
- package/dist/navigation/CollectionViewToggle.js.map +1 -1
- package/dist/navigation/DrilldownBrowseSelector.js +1 -1
- package/dist/navigation/FolderSelector.js +2 -2
- package/dist/navigation/SortMenu.d.ts +10 -0
- package/dist/navigation/SortMenu.js +33 -0
- package/dist/navigation/SortMenu.js.map +1 -0
- package/dist/navigation/index.d.ts +3 -2
- package/dist/overlays/CommandPalette.d.ts +38 -4
- package/dist/overlays/CommandPalette.js +140 -54
- package/dist/overlays/CommandPalette.js.map +1 -1
- package/dist/overlays/Drawer.js +1 -1
- package/dist/overlays/DropdownMenu.d.ts +7 -1
- package/dist/overlays/DropdownMenu.js +13 -2
- package/dist/overlays/DropdownMenu.js.map +1 -1
- package/dist/overlays/HelpTip.d.ts +8 -0
- package/dist/overlays/HelpTip.js +29 -0
- package/dist/overlays/HelpTip.js.map +1 -0
- package/dist/overlays/ImageViewer.js +2 -2
- package/dist/overlays/Modal.d.ts +5 -0
- package/dist/overlays/Modal.js +17 -2
- package/dist/overlays/Modal.js.map +1 -1
- package/dist/overlays/ModalExpandButton.d.ts +18 -0
- package/dist/overlays/ModalExpandButton.js +43 -0
- package/dist/overlays/ModalExpandButton.js.map +1 -0
- package/dist/overlays/Popover.d.ts +2 -1
- package/dist/overlays/Popover.js +1 -0
- package/dist/overlays/Popover.js.map +1 -1
- package/dist/overlays/index.d.ts +4 -2
- package/dist/showcase/Cards.js +1 -1
- package/dist/showcase/FeatureRow.js +1 -1
- package/dist/showcase/PhotoSearchConcept.js +1 -1
- package/dist/showcase/ProductBand.js +1 -1
- package/dist/showcase/Status.js +1 -1
- package/dist/typography/Code.d.ts +18 -0
- package/dist/typography/Code.js +24 -0
- package/dist/typography/Code.js.map +1 -0
- package/dist/typography/Link.d.ts +7 -2
- package/dist/typography/Link.js +15 -5
- package/dist/typography/Link.js.map +1 -1
- package/dist/typography/Typography.d.ts +19 -1
- package/dist/typography/Typography.js +11 -3
- package/dist/typography/Typography.js.map +1 -1
- package/dist/typography/index.d.ts +3 -3
- package/package.json +26 -3
- package/src/actions/Button.tsx +78 -11
- package/src/actions/ButtonLink.tsx +34 -0
- package/src/actions/ButtonRecipes.ts +10 -0
- package/src/actions/IconButton.tsx +7 -4
- package/src/board/ActivityLine.tsx +176 -0
- package/src/board/ActivityTrack.tsx +23 -0
- package/src/board/AddItem.tsx +259 -0
- package/src/board/Archive.tsx +75 -0
- package/src/board/Attention.tsx +135 -0
- package/src/board/BoardShell.tsx +30 -0
- package/src/board/BoardTitleBar.tsx +167 -0
- package/src/board/ButtonKinds.ts +32 -0
- package/src/board/Cleanup.tsx +19 -0
- package/src/board/Counters.tsx +224 -0
- package/src/board/DataAttributes.ts +3 -0
- package/src/board/Dependencies.tsx +49 -0
- package/src/board/Desk.tsx +155 -0
- package/src/board/Dossier.tsx +262 -0
- package/src/board/Filters.tsx +85 -0
- package/src/board/ItemDetails.tsx +435 -0
- package/src/board/ItemDialog.tsx +179 -0
- package/src/board/ItemParts.tsx +128 -0
- package/src/board/ItemProgress.tsx +164 -0
- package/src/board/List.tsx +154 -0
- package/src/board/LoadingScreen.tsx +78 -0
- package/src/board/NeedsYou.tsx +30 -0
- package/src/board/Onboarding.tsx +124 -0
- package/src/board/PartsList.tsx +160 -0
- package/src/board/ProjectIcon.tsx +172 -0
- package/src/board/PullRequests.tsx +106 -0
- package/src/board/RowStyles.ts +17 -0
- package/src/board/Settings.tsx +124 -0
- package/src/board/Slices.tsx +103 -0
- package/src/board/SourceIcon.tsx +33 -0
- package/src/board/StagePane.tsx +128 -0
- package/src/board/StageRow.tsx +320 -0
- package/src/board/StageTrack.tsx +61 -0
- package/src/board/StartControls.tsx +77 -0
- package/src/board/StatusColors.ts +28 -0
- package/src/board/StatusGlyph.tsx +70 -0
- package/src/board/Threads.tsx +38 -0
- package/src/board/TrackerLabels.tsx +75 -0
- package/src/board/UpdatePill.tsx +222 -0
- package/src/board/Vocabulary.tsx +155 -0
- package/src/board/Warnings.tsx +83 -0
- package/src/board/WorkMap.tsx +436 -0
- package/src/board/base.css +121 -0
- package/src/board/button-kinds.css +8 -0
- package/src/board/index.ts +224 -0
- package/src/board/items.css +75 -0
- package/src/board/loading-screen.css +171 -0
- package/src/board/rows.css +180 -0
- package/src/board/title-bar.css +56 -0
- package/src/board/tokens.css +52 -0
- package/src/board.css +19 -0
- package/src/collections/CollectionState.tsx +20 -7
- package/src/display/Avatar.tsx +6 -3
- package/src/display/Badge.tsx +25 -3
- package/src/display/Comment.tsx +26 -0
- package/src/display/CopyButton.tsx +48 -18
- package/src/display/Diagram.tsx +59 -0
- package/src/display/InsetPanel.tsx +4 -1
- package/src/display/LabelChip.tsx +73 -0
- package/src/display/LabelTint.ts +72 -0
- package/src/display/Person.tsx +11 -0
- package/src/display/RadioChoice.tsx +11 -2
- package/src/display/RichText.tsx +114 -0
- package/src/display/index.ts +5 -0
- package/src/feedback/DismissButton.tsx +28 -0
- package/src/feedback/ErrorNotification.ts +3 -0
- package/src/feedback/FormResult.tsx +50 -0
- package/src/feedback/LiveRegion.tsx +10 -0
- package/src/feedback/Loading.tsx +75 -0
- package/src/feedback/Notifications.tsx +267 -2
- package/src/feedback/Progress.tsx +44 -0
- package/src/feedback/StatusIndicator.tsx +34 -3
- package/src/feedback/index.ts +12 -2
- package/src/forms/ColorSwatches.tsx +50 -0
- package/src/forms/FormSection.tsx +245 -10
- package/src/forms/HiddenField.tsx +4 -0
- package/src/forms/Input.tsx +26 -4
- package/src/forms/LabelPicker.tsx +140 -0
- package/src/forms/MarkdownEditor.tsx +283 -0
- package/src/forms/MarkdownToolbar.tsx +267 -0
- package/src/forms/OptionSelect.tsx +110 -25
- package/src/forms/Select.tsx +20 -13
- package/src/forms/Switch.tsx +16 -2
- package/src/forms/index.ts +16 -2
- package/src/foundations/AmbientMotion.ts +51 -0
- package/src/foundations/DesignSystemProvider.tsx +19 -0
- package/src/foundations/index.ts +1 -0
- package/src/foundations/theme.css +64 -0
- package/src/icons/BrandIcons.tsx +12 -3
- package/src/icons/dynamic.ts +4 -0
- package/src/icons/index.ts +1 -1
- package/src/index.ts +2 -1
- package/src/layout/index.ts +1 -1
- package/src/layout/toolbar/CommandPaletteTrigger.tsx +187 -31
- package/src/layout/toolbar/TriggerFit.ts +84 -0
- package/src/navigation/CollectionViewToggle.tsx +94 -24
- package/src/navigation/SortMenu.tsx +41 -0
- package/src/navigation/index.ts +2 -1
- package/src/overlays/CommandPalette.tsx +190 -60
- package/src/overlays/DropdownMenu.tsx +12 -1
- package/src/overlays/HelpTip.tsx +29 -0
- package/src/overlays/Modal.tsx +23 -0
- package/src/overlays/ModalExpandButton.tsx +48 -0
- package/src/overlays/Popover.tsx +3 -1
- package/src/overlays/index.ts +9 -1
- package/src/showcase.css +6 -0
- package/src/styles.css +9 -1
- package/src/typography/Code.tsx +24 -0
- package/src/typography/Link.tsx +19 -10
- package/src/typography/Typography.tsx +25 -2
- package/src/typography/index.ts +1 -1
- package/dist/feedback/index.js +0 -11
- package/dist/typography/index.js +0 -4
|
@@ -1,53 +1,209 @@
|
|
|
1
1
|
import { SearchIcon } from 'lucide-react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type CSSProperties,
|
|
4
|
+
forwardRef,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
type Ref,
|
|
7
|
+
useEffect,
|
|
8
|
+
useEffectEvent,
|
|
9
|
+
useImperativeHandle,
|
|
10
|
+
useRef,
|
|
11
|
+
} from 'react';
|
|
3
12
|
|
|
4
13
|
import { Kbd } from '../../display/Kbd';
|
|
5
14
|
import { tabbable } from '../../foundations/KeyboardFocus';
|
|
6
15
|
import { applePlatform, isShortcut } from '../../foundations/KeyboardShortcut';
|
|
16
|
+
import { fitTrigger, useTriggerRoom } from './TriggerFit';
|
|
17
|
+
|
|
18
|
+
/** What narrows the palette, shown in the trigger as a small chip. */
|
|
19
|
+
export interface CommandPaletteTriggerToken {
|
|
20
|
+
id: string;
|
|
21
|
+
label: string;
|
|
22
|
+
/** An icon or colour mark before the label. */
|
|
23
|
+
leading?: ReactNode;
|
|
24
|
+
/** A lar-brand app hue that colours the chip, as a kind's badge. */
|
|
25
|
+
hue?: number;
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
interface CommandPaletteTriggerProps {
|
|
9
29
|
label: string;
|
|
10
30
|
onOpen: () => void;
|
|
11
31
|
/** Key that opens the palette from anywhere, pressed with ⌘ on Apple devices and Ctrl elsewhere. */
|
|
12
32
|
shortcut: string;
|
|
33
|
+
/** What narrows the palette now, such as filters. With tokens, the trigger measures its own room: the chips go
|
|
34
|
+
* into a count from the last, then it folds to its icon. */
|
|
35
|
+
tokens?: readonly CommandPaletteTriggerToken[];
|
|
36
|
+
/** The accessible name's addition while tokens show, such as "filtered by bug, docs". */
|
|
37
|
+
filterLabel?: (labels: readonly string[]) => string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const chip =
|
|
41
|
+
'inline-flex h-5 shrink-0 items-center gap-1 rounded-sm bg-base-200 px-1 text-2xs font-medium text-base-800 dark:bg-base-300 dark:text-base-content [&_svg]:size-3';
|
|
42
|
+
|
|
43
|
+
function TokenChip({ token }: { token: CommandPaletteTriggerToken }) {
|
|
44
|
+
const hued = token.hue !== undefined;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<span
|
|
48
|
+
title={token.label}
|
|
49
|
+
className={`${chip} ${hued ? 'kind-badge!' : ''}`}
|
|
50
|
+
style={hued ? ({ '--lar-kind-hue': token.hue } as CSSProperties) : undefined}
|
|
51
|
+
>
|
|
52
|
+
{token.leading}
|
|
53
|
+
<span className="max-w-32 min-w-0 truncate">{token.label}</span>
|
|
54
|
+
</span>
|
|
55
|
+
);
|
|
13
56
|
}
|
|
14
57
|
|
|
15
58
|
/** The title bar's way into the command palette: a quiet field-like button with its shortcut, folding to its
|
|
16
|
-
* icon when the title bar is narrow. */
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
59
|
+
* icon when the title bar is narrow. With tokens, it also says what narrows the palette. */
|
|
60
|
+
export const CommandPaletteTrigger = forwardRef<HTMLButtonElement, CommandPaletteTriggerProps>(
|
|
61
|
+
({ label, onOpen, shortcut, tokens, filterLabel }, ref) => {
|
|
62
|
+
const button = useRef<HTMLButtonElement>(null);
|
|
63
|
+
const openFromShortcut = useEffectEvent((event: KeyboardEvent) => {
|
|
64
|
+
// An open dialog hides the page behind it, the trigger included.
|
|
65
|
+
if (!isShortcut(event, shortcut) || button.current?.closest('[aria-hidden="true"]')) return;
|
|
66
|
+
|
|
67
|
+
event.preventDefault();
|
|
68
|
+
onOpen();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
useImperativeHandle(ref, () => button.current!);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const listener = (event: KeyboardEvent) => openFromShortcut(event);
|
|
74
|
+
|
|
75
|
+
document.addEventListener('keydown', listener);
|
|
76
|
+
|
|
77
|
+
return () => document.removeEventListener('keydown', listener);
|
|
78
|
+
}, []);
|
|
22
79
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
80
|
+
const keys = `${applePlatform ? 'Meta' : 'Control'}+${shortcut.toUpperCase()}`;
|
|
81
|
+
const hint = applePlatform ? `⌘${shortcut.toUpperCase()}` : `Ctrl ${shortcut.toUpperCase()}`;
|
|
26
82
|
|
|
27
|
-
|
|
28
|
-
|
|
83
|
+
if (tokens)
|
|
84
|
+
return (
|
|
85
|
+
<FittedTrigger
|
|
86
|
+
button={button}
|
|
87
|
+
label={label}
|
|
88
|
+
onOpen={onOpen}
|
|
89
|
+
tokens={tokens}
|
|
90
|
+
filterLabel={filterLabel}
|
|
91
|
+
keys={keys}
|
|
92
|
+
hint={hint}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
29
95
|
|
|
30
|
-
|
|
96
|
+
return (
|
|
97
|
+
<button
|
|
98
|
+
{...tabbable}
|
|
99
|
+
ref={button}
|
|
100
|
+
type="button"
|
|
101
|
+
aria-label={label}
|
|
102
|
+
aria-haspopup="dialog"
|
|
103
|
+
aria-keyshortcuts={keys}
|
|
104
|
+
onClick={onOpen}
|
|
105
|
+
className="text-base-600 hover:bg-base-200 hover:text-base-content focus-visible:outline-primary @2xl:border-base-300 @2xl:bg-base-100 @2xl:hover:border-base-400 @2xl:hover:bg-base-100 dark:@2xl:bg-base-200 flex size-7 items-center justify-center gap-2 rounded-lg text-sm transition-colors focus-visible:outline-2 @2xl:w-56 @2xl:justify-start @2xl:border @2xl:px-2.5 [&>svg]:size-4 [&>svg]:shrink-0"
|
|
106
|
+
>
|
|
107
|
+
<SearchIcon />
|
|
108
|
+
<span className="hidden flex-1 text-left @2xl:inline">{label}</span>
|
|
109
|
+
<span className="hidden pointer-fine:@2xl:inline">
|
|
110
|
+
<Kbd>{hint}</Kbd>
|
|
111
|
+
</span>
|
|
112
|
+
</button>
|
|
113
|
+
);
|
|
114
|
+
},
|
|
115
|
+
);
|
|
31
116
|
|
|
32
|
-
|
|
33
|
-
|
|
117
|
+
CommandPaletteTrigger.displayName = 'CommandPaletteTrigger';
|
|
118
|
+
|
|
119
|
+
/** The trigger with tokens, up to 26rem wide: it measures its room and the chips in a hidden copy, then shows what
|
|
120
|
+
* fits (TriggerFit.ts). */
|
|
121
|
+
function FittedTrigger({
|
|
122
|
+
button,
|
|
123
|
+
label,
|
|
124
|
+
onOpen,
|
|
125
|
+
tokens,
|
|
126
|
+
filterLabel,
|
|
127
|
+
keys,
|
|
128
|
+
hint,
|
|
129
|
+
}: {
|
|
130
|
+
button: Ref<HTMLButtonElement>;
|
|
131
|
+
label: string;
|
|
132
|
+
onOpen: () => void;
|
|
133
|
+
tokens: readonly CommandPaletteTriggerToken[];
|
|
134
|
+
filterLabel?: (labels: readonly string[]) => string;
|
|
135
|
+
keys: string;
|
|
136
|
+
hint: string;
|
|
137
|
+
}) {
|
|
138
|
+
const wrapper = useRef<HTMLDivElement>(null);
|
|
139
|
+
const ghost = useRef<HTMLDivElement>(null);
|
|
140
|
+
const { room, widths } = useTriggerRoom(wrapper, ghost, tokens.map(({ id }) => id).join());
|
|
141
|
+
const { shown, keyHint, folded, width } = fitTrigger(room, widths);
|
|
142
|
+
const hidden = tokens.slice(shown);
|
|
143
|
+
const labels = tokens.map((token) => token.label);
|
|
34
144
|
|
|
35
145
|
return (
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
146
|
+
<div ref={wrapper} className="relative ml-auto flex max-w-[26rem] min-w-0 flex-1 justify-end">
|
|
147
|
+
<div
|
|
148
|
+
ref={ghost}
|
|
149
|
+
aria-hidden="true"
|
|
150
|
+
className="invisible absolute right-0 flex h-0 w-max gap-1 overflow-hidden"
|
|
151
|
+
>
|
|
152
|
+
{tokens.map((token) => (
|
|
153
|
+
<TokenChip key={token.id} token={token} />
|
|
154
|
+
))}
|
|
155
|
+
</div>
|
|
156
|
+
<button
|
|
157
|
+
{...tabbable}
|
|
158
|
+
ref={button}
|
|
159
|
+
type="button"
|
|
160
|
+
data-search-field
|
|
161
|
+
data-folded={folded || undefined}
|
|
162
|
+
aria-haspopup="dialog"
|
|
163
|
+
aria-keyshortcuts={keys}
|
|
164
|
+
aria-label={tokens.length && filterLabel ? `${label}, ${filterLabel(labels)}` : label}
|
|
165
|
+
onClick={onOpen}
|
|
166
|
+
style={folded ? undefined : { width }}
|
|
167
|
+
className={`text-base-700 focus-visible:outline-primary relative flex h-7 shrink-0 cursor-pointer items-center rounded-lg text-xs transition-colors focus-visible:outline-2 ${
|
|
168
|
+
folded
|
|
169
|
+
? 'hover:bg-base-200 hover:text-base-content dark:hover:bg-base-300 w-7 justify-center'
|
|
170
|
+
: 'border-base-300 bg-base-100 hover:border-base-400 dark:bg-base-200 gap-1 border pr-2 pl-1.5'
|
|
171
|
+
}`}
|
|
172
|
+
>
|
|
173
|
+
<SearchIcon aria-hidden="true" className={`shrink-0 ${folded ? 'size-4' : 'mr-0.5 size-3.5'}`} />
|
|
174
|
+
{folded ? (
|
|
175
|
+
tokens.length > 0 && (
|
|
176
|
+
<span
|
|
177
|
+
data-search-count
|
|
178
|
+
className="bg-primary text-2xs text-primary-content absolute -top-0.5 -right-0.5 grid h-3.5 min-w-3.5 place-items-center rounded-full px-0.5 leading-none font-semibold tabular-nums"
|
|
179
|
+
>
|
|
180
|
+
{tokens.length}
|
|
181
|
+
</span>
|
|
182
|
+
)
|
|
183
|
+
) : (
|
|
184
|
+
<>
|
|
185
|
+
{tokens.slice(0, shown).map((token) => (
|
|
186
|
+
<TokenChip key={token.id} token={token} />
|
|
187
|
+
))}
|
|
188
|
+
{hidden.length > 0 && (
|
|
189
|
+
<span
|
|
190
|
+
data-search-count
|
|
191
|
+
title={hidden.map((token) => token.label).join(', ')}
|
|
192
|
+
className={`${chip} tabular-nums`}
|
|
193
|
+
>
|
|
194
|
+
{shown > 0 ? '+' : ''}
|
|
195
|
+
{hidden.length}
|
|
196
|
+
</span>
|
|
197
|
+
)}
|
|
198
|
+
<span className="ml-0.5 min-w-0 flex-1 truncate text-left">{label}</span>
|
|
199
|
+
{keyHint && (
|
|
200
|
+
<span className="shrink-0 pointer-coarse:hidden">
|
|
201
|
+
<Kbd>{hint}</Kbd>
|
|
202
|
+
</span>
|
|
203
|
+
)}
|
|
204
|
+
</>
|
|
205
|
+
)}
|
|
206
|
+
</button>
|
|
207
|
+
</div>
|
|
52
208
|
);
|
|
53
209
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// What the command palette trigger shows, with tokens, in the room it has. Tokens go from the last, into a count,
|
|
2
|
+
// while the word Search and the count still fit; the key hint shows only with every token and room to spare; below the
|
|
3
|
+
// word's room, or on the narrowest title bar, the field folds to its magnifier with a count. Widths are in pixels, in
|
|
4
|
+
// the field's `text-xs`.
|
|
5
|
+
import { type RefObject, useLayoutEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
/** The field's left padding, magnifier, gap and right padding. */
|
|
8
|
+
const CHROME = 34;
|
|
9
|
+
const SEARCH_WORD = 42;
|
|
10
|
+
const COUNT = 24;
|
|
11
|
+
const KEY_HINT = 34;
|
|
12
|
+
const GAP = 4;
|
|
13
|
+
/** lar-server's trigger width, which the field keeps until its tokens ask for more. */
|
|
14
|
+
const MIN_WIDTH = 224;
|
|
15
|
+
/** Up to this title bar width, the smallest phones', the field folds. Its row there still has room for the word, as the
|
|
16
|
+
* bar gives its actions their own row, so the room alone would never fold it. */
|
|
17
|
+
const NARROWEST_BAR = 340;
|
|
18
|
+
|
|
19
|
+
interface FieldRoom {
|
|
20
|
+
/** What the field may fill. */
|
|
21
|
+
field: number;
|
|
22
|
+
/** The title bar's width. */
|
|
23
|
+
bar: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TriggerFit {
|
|
27
|
+
/** How many tokens show; the rest are in the count. */
|
|
28
|
+
shown: number;
|
|
29
|
+
keyHint: boolean;
|
|
30
|
+
folded: boolean;
|
|
31
|
+
width: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function fitTrigger({ field: room, bar }: FieldRoom, tokenWidths: readonly number[]): TriggerFit {
|
|
35
|
+
const tokens = (count: number) => tokenWidths.slice(0, count).reduce((sum, width) => sum + width + GAP, 0);
|
|
36
|
+
const used = (count: number) =>
|
|
37
|
+
CHROME + SEARCH_WORD + tokens(count) + (count < tokenWidths.length ? COUNT + GAP : 0);
|
|
38
|
+
let shown = tokenWidths.length;
|
|
39
|
+
|
|
40
|
+
while (shown > 0 && used(shown) > room) shown--;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
shown,
|
|
44
|
+
keyHint: shown === tokenWidths.length && used(shown) + KEY_HINT + GAP <= room,
|
|
45
|
+
folded: bar <= NARROWEST_BAR || used(shown) > room,
|
|
46
|
+
width: Math.min(room, Math.max(MIN_WIDTH, used(tokenWidths.length) + KEY_HINT + GAP)),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The room in `wrapper` and the title bar holding it, and each child's width in `ghost`, which draws every token out of
|
|
51
|
+
* sight to be measured. */
|
|
52
|
+
export function useTriggerRoom(
|
|
53
|
+
wrapper: RefObject<HTMLElement | null>,
|
|
54
|
+
ghost: RefObject<HTMLElement | null>,
|
|
55
|
+
tokens: string,
|
|
56
|
+
) {
|
|
57
|
+
const [room, setRoom] = useState({ field: 0, bar: 0 });
|
|
58
|
+
const [widths, setWidths] = useState<number[]>([]);
|
|
59
|
+
|
|
60
|
+
useLayoutEffect(() => {
|
|
61
|
+
const measure = () => {
|
|
62
|
+
setRoom({
|
|
63
|
+
field: wrapper.current!.getBoundingClientRect().width,
|
|
64
|
+
bar: (wrapper.current!.closest('header') ?? wrapper.current!).getBoundingClientRect().width,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const next = [...ghost.current!.children].map((child) => (child as HTMLElement).offsetWidth);
|
|
68
|
+
|
|
69
|
+
setWidths((now) => (now.join() === next.join() ? now : next));
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
measure();
|
|
73
|
+
|
|
74
|
+
// The ghost resizes too when a late web font changes the tokens' widths.
|
|
75
|
+
const observer = new ResizeObserver(measure);
|
|
76
|
+
|
|
77
|
+
observer.observe(wrapper.current!);
|
|
78
|
+
observer.observe(ghost.current!);
|
|
79
|
+
|
|
80
|
+
return () => observer.disconnect();
|
|
81
|
+
}, [wrapper, ghost, tokens]);
|
|
82
|
+
|
|
83
|
+
return { room, widths };
|
|
84
|
+
}
|
|
@@ -1,9 +1,82 @@
|
|
|
1
1
|
import { LayoutGridIcon, TableIcon } from 'lucide-react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
import { IconButton } from '../actions/IconButton';
|
|
5
|
+
import { tabbable } from '../foundations/KeyboardFocus';
|
|
4
6
|
|
|
5
7
|
export type CollectionView = 'grid' | 'table';
|
|
6
8
|
|
|
9
|
+
/** One way of drawing a view, as ViewToggle offers it: its icon, named by its label (or, as `text`, its label alone).
|
|
10
|
+
* `attributes` are `data-*` markers for its button, such as the pane it shows. */
|
|
11
|
+
export interface ViewToggleOption<V extends string> {
|
|
12
|
+
value: V;
|
|
13
|
+
label: string;
|
|
14
|
+
icon?: ReactNode;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
attributes?: { [name: `data-${string}`]: string };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A group of icon buttons that picks one way of drawing a view, the picked one raised. `compact` draws 24px buttons with
|
|
21
|
+
* 14px icons, for a row's line. As `text`, each button is its label in small type, such as a dialog's panes in its
|
|
22
|
+
* header.
|
|
23
|
+
*/
|
|
24
|
+
export function ViewToggle<V extends string>({
|
|
25
|
+
label,
|
|
26
|
+
options,
|
|
27
|
+
value,
|
|
28
|
+
onChange,
|
|
29
|
+
compact = false,
|
|
30
|
+
presentation = 'icons',
|
|
31
|
+
}: {
|
|
32
|
+
/** Names the group; with none, the group is named by its options alone. */
|
|
33
|
+
label?: string;
|
|
34
|
+
options: readonly ViewToggleOption<V>[];
|
|
35
|
+
value: V;
|
|
36
|
+
onChange: (view: V) => void;
|
|
37
|
+
compact?: boolean;
|
|
38
|
+
presentation?: 'icons' | 'text';
|
|
39
|
+
}) {
|
|
40
|
+
if (presentation === 'text')
|
|
41
|
+
return (
|
|
42
|
+
<div role="group" aria-label={label} className="bg-base-200 flex gap-0.5 rounded-lg p-0.5">
|
|
43
|
+
{options.map((option) => (
|
|
44
|
+
<button
|
|
45
|
+
key={option.value}
|
|
46
|
+
{...tabbable}
|
|
47
|
+
{...option.attributes}
|
|
48
|
+
type="button"
|
|
49
|
+
aria-pressed={value === option.value}
|
|
50
|
+
disabled={option.disabled}
|
|
51
|
+
onClick={() => onChange(option.value)}
|
|
52
|
+
className={`focus-visible:ring-primary h-7 rounded-md px-2.5 text-xs font-medium outline-none focus-visible:ring-2 ${value === option.value ? 'bg-base-100 text-base-content shadow-sm' : 'hover:text-base-content text-(--muted-foreground)'}`}
|
|
53
|
+
>
|
|
54
|
+
{option.label}
|
|
55
|
+
</button>
|
|
56
|
+
))}
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div role="group" aria-label={label} className="bg-base-200/70 flex gap-0.5 rounded-lg p-0.5">
|
|
62
|
+
{options.map((option) => (
|
|
63
|
+
<IconButton
|
|
64
|
+
key={option.value}
|
|
65
|
+
{...option.attributes}
|
|
66
|
+
aria-label={option.label}
|
|
67
|
+
aria-pressed={value === option.value}
|
|
68
|
+
disabled={option.disabled}
|
|
69
|
+
icon={option.icon}
|
|
70
|
+
title={option.label}
|
|
71
|
+
className={buttonClasses(value === option.value, compact)}
|
|
72
|
+
onClick={() => onChange(option.value)}
|
|
73
|
+
tone="neutral"
|
|
74
|
+
/>
|
|
75
|
+
))}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
7
80
|
interface CollectionViewToggleProps {
|
|
8
81
|
disabledViews?: readonly CollectionView[];
|
|
9
82
|
gridLabel: string;
|
|
@@ -22,31 +95,28 @@ export function CollectionViewToggle({
|
|
|
22
95
|
value,
|
|
23
96
|
}: CollectionViewToggleProps) {
|
|
24
97
|
return (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
tone="neutral"
|
|
45
|
-
/>
|
|
46
|
-
</div>
|
|
98
|
+
<ViewToggle
|
|
99
|
+
label={label}
|
|
100
|
+
value={value}
|
|
101
|
+
onChange={onChange}
|
|
102
|
+
options={[
|
|
103
|
+
{
|
|
104
|
+
value: 'grid',
|
|
105
|
+
label: gridLabel,
|
|
106
|
+
icon: <LayoutGridIcon />,
|
|
107
|
+
disabled: disabledViews.includes('grid'),
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
value: 'table',
|
|
111
|
+
label: tableLabel,
|
|
112
|
+
icon: <TableIcon />,
|
|
113
|
+
disabled: disabledViews.includes('table'),
|
|
114
|
+
},
|
|
115
|
+
]}
|
|
116
|
+
/>
|
|
47
117
|
);
|
|
48
118
|
}
|
|
49
119
|
|
|
50
|
-
function buttonClasses(active: boolean): string {
|
|
51
|
-
return
|
|
120
|
+
function buttonClasses(active: boolean, compact: boolean): string {
|
|
121
|
+
return `${compact ? 'size-6 **:data-[slot=icon]:size-3.5' : 'size-8'} p-0 ${active ? 'bg-base-100 text-base-content shadow-sm' : 'text-base-600'}`;
|
|
52
122
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ChevronDownIcon } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
import { Button } from '../actions/Button';
|
|
4
|
+
import { DropdownMenu } from '../overlays/DropdownMenu';
|
|
5
|
+
|
|
6
|
+
/** A menu of the ways a list sorts, its button naming the current one. */
|
|
7
|
+
export function SortMenu<Value extends string>({
|
|
8
|
+
value,
|
|
9
|
+
options,
|
|
10
|
+
onChange,
|
|
11
|
+
}: {
|
|
12
|
+
value: Value;
|
|
13
|
+
options: readonly { value: Value; label: string }[];
|
|
14
|
+
onChange: (value: Value) => void;
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<DropdownMenu>
|
|
18
|
+
<DropdownMenu.Trigger asChild>
|
|
19
|
+
<Button variant="secondary" compact rightIcon={<ChevronDownIcon />}>
|
|
20
|
+
{options.find((option) => option.value === value)?.label}
|
|
21
|
+
</Button>
|
|
22
|
+
</DropdownMenu.Trigger>
|
|
23
|
+
<DropdownMenu.Content align="end">
|
|
24
|
+
<DropdownMenu.RadioGroup
|
|
25
|
+
value={value}
|
|
26
|
+
onValueChange={(next) => {
|
|
27
|
+
const picked = options.find((option) => option.value === next);
|
|
28
|
+
|
|
29
|
+
if (picked) onChange(picked.value);
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
{options.map((option) => (
|
|
33
|
+
<DropdownMenu.RadioItem key={option.value} value={option.value}>
|
|
34
|
+
{option.label}
|
|
35
|
+
</DropdownMenu.RadioItem>
|
|
36
|
+
))}
|
|
37
|
+
</DropdownMenu.RadioGroup>
|
|
38
|
+
</DropdownMenu.Content>
|
|
39
|
+
</DropdownMenu>
|
|
40
|
+
);
|
|
41
|
+
}
|
package/src/navigation/index.ts
CHANGED
|
@@ -5,11 +5,12 @@ export {
|
|
|
5
5
|
CollectionBrowseSelector,
|
|
6
6
|
CollectionBrowseTrigger,
|
|
7
7
|
} from './CollectionBrowseSelector';
|
|
8
|
-
export { type CollectionView, CollectionViewToggle } from './CollectionViewToggle';
|
|
8
|
+
export { type CollectionView, CollectionViewToggle, ViewToggle, type ViewToggleOption } from './CollectionViewToggle';
|
|
9
9
|
export {
|
|
10
10
|
type DrilldownBrowseGroup,
|
|
11
11
|
type DrilldownBrowseItem,
|
|
12
12
|
DrilldownBrowseSelector,
|
|
13
13
|
} from './DrilldownBrowseSelector';
|
|
14
14
|
export { FolderSelector, type FolderSelectorOption, type FolderSelectorProps } from './FolderSelector';
|
|
15
|
+
export { SortMenu } from './SortMenu';
|
|
15
16
|
export { ViewTabs, type ViewTabsItem } from './ViewTabs';
|