@lar-works/design-system 0.2.1 → 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/styles.css +3 -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
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
// A dossier's Work map: lanes of parts placed left to right by what they wait on, arrows between them, the end-to-end
|
|
2
|
+
// check, and finished history folded into one group below. The board lays it out; these draw it at the given places.
|
|
3
|
+
|
|
4
|
+
import { ChevronDownIcon, ChevronRightIcon, FlaskConicalIcon, HammerIcon, LightbulbIcon } from 'lucide-react';
|
|
5
|
+
import type { ReactNode, Ref } from 'react';
|
|
6
|
+
|
|
7
|
+
import { Tooltip, TooltipPopup, TooltipTrigger } from '../overlays/Tooltip';
|
|
8
|
+
|
|
9
|
+
/** The map's frame, which scrolls sideways when the map is wider; `frameRef` measures its width. */
|
|
10
|
+
export function WorkMapFrame({ frameRef, children }: { frameRef?: Ref<HTMLDivElement>; children: ReactNode }) {
|
|
11
|
+
return (
|
|
12
|
+
<div
|
|
13
|
+
ref={frameRef}
|
|
14
|
+
className="overflow-x-auto rounded-lg border border-(--border) bg-(--background)"
|
|
15
|
+
data-work-map
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The map's drawing area, `width` by `height` pixels, which places what it holds absolutely. */
|
|
23
|
+
export function MapCanvas({ width, height, children }: { width: number; height: number; children: ReactNode }) {
|
|
24
|
+
return (
|
|
25
|
+
<div className="relative" style={{ width, height }} data-map-canvas>
|
|
26
|
+
{children}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A lane's band across the map, banded on odd `index`es, with its `name` in a label that stays in view as the map
|
|
32
|
+
* scrolls. */
|
|
33
|
+
export function MapBand({
|
|
34
|
+
index,
|
|
35
|
+
top,
|
|
36
|
+
height,
|
|
37
|
+
width,
|
|
38
|
+
labelWidth,
|
|
39
|
+
children,
|
|
40
|
+
}: {
|
|
41
|
+
index: number;
|
|
42
|
+
top: number;
|
|
43
|
+
height: number;
|
|
44
|
+
width: number;
|
|
45
|
+
labelWidth: number;
|
|
46
|
+
children: ReactNode;
|
|
47
|
+
}) {
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
className={`absolute left-0 ${index ? 'border-t border-(--border)' : ''} ${index % 2 ? 'bg-[color-mix(in_srgb,var(--muted)_50%,transparent)]' : ''}`}
|
|
51
|
+
style={{ top, height, width }}
|
|
52
|
+
>
|
|
53
|
+
<div
|
|
54
|
+
className="sticky left-0 flex h-full flex-col justify-center gap-0.5 bg-[color-mix(in_srgb,var(--background)_85%,transparent)] px-3"
|
|
55
|
+
style={{ width: labelWidth }}
|
|
56
|
+
>
|
|
57
|
+
<span className="flex min-w-0 items-center gap-1.5 text-xs font-medium">{children}</span>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** A lane's name with its icon: the decisions' lane, or the dossier's own repository's builds. */
|
|
64
|
+
export function MapLaneName({ lane, children }: { lane: 'decisions' | 'builds'; children: string }) {
|
|
65
|
+
const Icon = lane === 'decisions' ? LightbulbIcon : HammerIcon;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<>
|
|
69
|
+
<Icon className="size-3.5 text-(--muted-foreground)" />
|
|
70
|
+
{children}
|
|
71
|
+
</>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** An arrow from one part to another: `d` is its line; a `done` one is solid in the done colour. `lit` draws it bold
|
|
76
|
+
* while either end is hovered, and `dim` faint while another is. */
|
|
77
|
+
export interface MapEdge {
|
|
78
|
+
key: string;
|
|
79
|
+
d: string;
|
|
80
|
+
done: boolean;
|
|
81
|
+
lit: boolean;
|
|
82
|
+
dim: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The map's arrows, under its parts. `markerId` is unique to the map. */
|
|
86
|
+
export function MapEdges({
|
|
87
|
+
width,
|
|
88
|
+
height,
|
|
89
|
+
markerId,
|
|
90
|
+
edges,
|
|
91
|
+
}: {
|
|
92
|
+
width: number;
|
|
93
|
+
height: number;
|
|
94
|
+
markerId: string;
|
|
95
|
+
edges: MapEdge[];
|
|
96
|
+
}) {
|
|
97
|
+
return (
|
|
98
|
+
<svg className="pointer-events-none absolute inset-0" width={width} height={height} aria-hidden="true">
|
|
99
|
+
<defs>
|
|
100
|
+
{['done', 'open'].map((k) => (
|
|
101
|
+
<marker
|
|
102
|
+
key={k}
|
|
103
|
+
id={`${markerId}-${k}`}
|
|
104
|
+
viewBox="0 0 8 8"
|
|
105
|
+
refX="7"
|
|
106
|
+
refY="4"
|
|
107
|
+
markerWidth="7"
|
|
108
|
+
markerHeight="7"
|
|
109
|
+
orient="auto"
|
|
110
|
+
>
|
|
111
|
+
<path d="M0 0 8 4 0 8z" fill={k === 'done' ? 'var(--st-done)' : 'var(--muted-foreground)'} />
|
|
112
|
+
</marker>
|
|
113
|
+
))}
|
|
114
|
+
</defs>
|
|
115
|
+
{edges.map((e) => (
|
|
116
|
+
<path
|
|
117
|
+
key={e.key}
|
|
118
|
+
d={e.d}
|
|
119
|
+
fill="none"
|
|
120
|
+
data-edge={e.key}
|
|
121
|
+
stroke={e.done ? 'var(--st-done)' : 'var(--muted-foreground)'}
|
|
122
|
+
strokeWidth={e.lit ? 2.5 : 1.5}
|
|
123
|
+
strokeDasharray={e.done ? undefined : '5 4'}
|
|
124
|
+
opacity={e.dim ? 0.2 : e.done ? 0.7 : 0.9}
|
|
125
|
+
markerEnd={`url(#${markerId}-${e.done ? 'done' : 'open'})`}
|
|
126
|
+
/>
|
|
127
|
+
))}
|
|
128
|
+
</svg>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** An arrow's label, at `left`/`top` and at most `maxWidth` wide: a button that opens what it stands for, its tooltip
|
|
133
|
+
* naming them (`names`). */
|
|
134
|
+
export function MapEdgeLabel({
|
|
135
|
+
edge,
|
|
136
|
+
label,
|
|
137
|
+
names,
|
|
138
|
+
left,
|
|
139
|
+
top,
|
|
140
|
+
maxWidth,
|
|
141
|
+
onOpen,
|
|
142
|
+
}: {
|
|
143
|
+
edge: string;
|
|
144
|
+
label: string;
|
|
145
|
+
names: string;
|
|
146
|
+
left: number;
|
|
147
|
+
top: number;
|
|
148
|
+
maxWidth: number;
|
|
149
|
+
onOpen: () => void;
|
|
150
|
+
}) {
|
|
151
|
+
return (
|
|
152
|
+
<Tooltip>
|
|
153
|
+
<TooltipTrigger asChild>
|
|
154
|
+
<button
|
|
155
|
+
type="button"
|
|
156
|
+
aria-label={`${label}: ${names}`}
|
|
157
|
+
onClick={onOpen}
|
|
158
|
+
data-edge-label={edge}
|
|
159
|
+
className="absolute truncate rounded text-left text-[11px] leading-3.5 text-(--muted-foreground) hover:text-(--foreground) hover:underline focus-visible:outline-2 focus-visible:outline-(--primary)"
|
|
160
|
+
style={{ left, top, maxWidth }}
|
|
161
|
+
>
|
|
162
|
+
{label}
|
|
163
|
+
</button>
|
|
164
|
+
</TooltipTrigger>
|
|
165
|
+
<TooltipPopup side="top">{names}</TooltipPopup>
|
|
166
|
+
</Tooltip>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** A node's place on the map, faint while `dim`; hovering it lights its arrows. */
|
|
171
|
+
export function MapNode({
|
|
172
|
+
left,
|
|
173
|
+
top,
|
|
174
|
+
dim,
|
|
175
|
+
onHover,
|
|
176
|
+
children,
|
|
177
|
+
}: {
|
|
178
|
+
left: number;
|
|
179
|
+
top: number;
|
|
180
|
+
dim: boolean;
|
|
181
|
+
onHover: (hovered: boolean) => void;
|
|
182
|
+
children: ReactNode;
|
|
183
|
+
}) {
|
|
184
|
+
return (
|
|
185
|
+
<div
|
|
186
|
+
className={`absolute transition-opacity ${dim ? 'opacity-40' : ''}`}
|
|
187
|
+
style={{ left, top }}
|
|
188
|
+
onMouseEnter={() => onHover(true)}
|
|
189
|
+
onMouseLeave={() => onHover(false)}
|
|
190
|
+
>
|
|
191
|
+
{children}
|
|
192
|
+
</div>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** The group finished history folds into, across the map at `top`: a button with its `glyph` and `text` that shows or
|
|
197
|
+
* hides the finished parts, saying which it does. */
|
|
198
|
+
export function MapHistoryGroup({
|
|
199
|
+
open,
|
|
200
|
+
top,
|
|
201
|
+
height,
|
|
202
|
+
dim,
|
|
203
|
+
glyph,
|
|
204
|
+
text,
|
|
205
|
+
showLabel,
|
|
206
|
+
hideLabel,
|
|
207
|
+
onToggle,
|
|
208
|
+
onHover,
|
|
209
|
+
}: {
|
|
210
|
+
open: boolean;
|
|
211
|
+
top: number;
|
|
212
|
+
height: number;
|
|
213
|
+
dim: boolean;
|
|
214
|
+
glyph: ReactNode;
|
|
215
|
+
text: string;
|
|
216
|
+
showLabel: string;
|
|
217
|
+
hideLabel: string;
|
|
218
|
+
onToggle: () => void;
|
|
219
|
+
onHover: (hovered: boolean) => void;
|
|
220
|
+
}) {
|
|
221
|
+
return (
|
|
222
|
+
<button
|
|
223
|
+
type="button"
|
|
224
|
+
aria-expanded={open}
|
|
225
|
+
onClick={onToggle}
|
|
226
|
+
data-map-history
|
|
227
|
+
onMouseEnter={() => onHover(true)}
|
|
228
|
+
onMouseLeave={() => onHover(false)}
|
|
229
|
+
className={`absolute flex items-center gap-2 rounded-lg border border-(--border) bg-(--card) px-2.5 text-left text-xs shadow-xs transition-opacity hover:bg-(--accent) focus-visible:outline-2 focus-visible:outline-(--primary) ${dim ? 'opacity-40' : ''}`}
|
|
230
|
+
style={{ left: 12, right: 12, top, height }}
|
|
231
|
+
>
|
|
232
|
+
{glyph}
|
|
233
|
+
<span className="min-w-0 truncate font-medium">{text}</span>
|
|
234
|
+
<span className="inline-flex shrink-0 items-center gap-1 text-(--muted-foreground)">
|
|
235
|
+
{open ? (
|
|
236
|
+
<>
|
|
237
|
+
{hideLabel}
|
|
238
|
+
<ChevronDownIcon className="size-3.5" />
|
|
239
|
+
</>
|
|
240
|
+
) : (
|
|
241
|
+
<>
|
|
242
|
+
{showLabel}
|
|
243
|
+
<ChevronRightIcon className="size-3.5" />
|
|
244
|
+
</>
|
|
245
|
+
)}
|
|
246
|
+
</span>
|
|
247
|
+
</button>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** The finished parts under the map, `width` wide, one HistoryRow each. */
|
|
252
|
+
export function MapHistoryList({ width, children }: { width: number; children: ReactNode }) {
|
|
253
|
+
return (
|
|
254
|
+
<ol
|
|
255
|
+
className="m-0 grid list-none grid-cols-[repeat(auto-fill,minmax(min(100%,28rem),1fr))] gap-x-4 gap-y-1 px-3 pb-3"
|
|
256
|
+
style={{ width }}
|
|
257
|
+
data-map-history-parts
|
|
258
|
+
>
|
|
259
|
+
{children}
|
|
260
|
+
</ol>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** A finished part as one row of the history: its glyph, kind, title opening it, what it followed, and at its right its
|
|
265
|
+
* repository, pull requests and thread. */
|
|
266
|
+
export function HistoryRow({
|
|
267
|
+
id,
|
|
268
|
+
glyph,
|
|
269
|
+
kind,
|
|
270
|
+
name,
|
|
271
|
+
onOpen,
|
|
272
|
+
title,
|
|
273
|
+
after,
|
|
274
|
+
afterTitle,
|
|
275
|
+
side,
|
|
276
|
+
}: {
|
|
277
|
+
id: string;
|
|
278
|
+
glyph: ReactNode;
|
|
279
|
+
kind: ReactNode;
|
|
280
|
+
/** The part's full name, for its title's tooltip. */
|
|
281
|
+
name: string;
|
|
282
|
+
onOpen: () => void;
|
|
283
|
+
title: ReactNode;
|
|
284
|
+
after?: string | undefined;
|
|
285
|
+
afterTitle?: string | undefined;
|
|
286
|
+
side: ReactNode;
|
|
287
|
+
}) {
|
|
288
|
+
return (
|
|
289
|
+
<li
|
|
290
|
+
className="flex min-h-12 min-w-0 items-center gap-3 rounded-md px-3 text-[13px] hover:bg-(--soft)"
|
|
291
|
+
data-history-part={id}
|
|
292
|
+
>
|
|
293
|
+
{glyph}
|
|
294
|
+
<span className="w-22 shrink-0">{kind}</span>
|
|
295
|
+
<button
|
|
296
|
+
type="button"
|
|
297
|
+
onClick={onOpen}
|
|
298
|
+
title={name}
|
|
299
|
+
className="min-w-0 truncate rounded text-left hover:underline focus-visible:outline-2 focus-visible:outline-(--primary)"
|
|
300
|
+
>
|
|
301
|
+
{title}
|
|
302
|
+
</button>
|
|
303
|
+
{after && (
|
|
304
|
+
<span
|
|
305
|
+
className="min-w-0 shrink-[1000] truncate text-[11px] text-(--muted-foreground)"
|
|
306
|
+
title={afterTitle}
|
|
307
|
+
>
|
|
308
|
+
{after}
|
|
309
|
+
</span>
|
|
310
|
+
)}
|
|
311
|
+
<span className="ml-auto flex shrink-0 items-center gap-2 text-[11px] text-(--muted-foreground)">
|
|
312
|
+
{side}
|
|
313
|
+
</span>
|
|
314
|
+
</li>
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const NODE_TONE = {
|
|
319
|
+
default: 'border-(--border)',
|
|
320
|
+
asks: 'border-[color-mix(in_srgb,var(--warning)_45%,var(--border))] shadow-[inset_3px_0_0_var(--warning)]',
|
|
321
|
+
waits: 'border-dashed border-(--input)',
|
|
322
|
+
} as const;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* A part on the map, `width` by `height`: a card that opens it (`openLabel` names the button, `title` says it all),
|
|
326
|
+
* with its `source` in the corner, a `head` line (kind, repository, fields) with its `action` at the right, its title,
|
|
327
|
+
* its `glyph` and `facts`, and its `slices` along the bottom. It `asks` (an answer from you) or `waits` (on other work)
|
|
328
|
+
* in its border's tone, and is ringed while `picked`.
|
|
329
|
+
*/
|
|
330
|
+
export function MapPartNode({
|
|
331
|
+
id,
|
|
332
|
+
width,
|
|
333
|
+
height,
|
|
334
|
+
tone = 'default',
|
|
335
|
+
picked,
|
|
336
|
+
openLabel,
|
|
337
|
+
title,
|
|
338
|
+
onOpen,
|
|
339
|
+
source,
|
|
340
|
+
head,
|
|
341
|
+
action,
|
|
342
|
+
name,
|
|
343
|
+
glyph,
|
|
344
|
+
facts,
|
|
345
|
+
slices,
|
|
346
|
+
}: {
|
|
347
|
+
id: string;
|
|
348
|
+
width: number;
|
|
349
|
+
height: number;
|
|
350
|
+
tone?: keyof typeof NODE_TONE;
|
|
351
|
+
picked: boolean;
|
|
352
|
+
openLabel: string;
|
|
353
|
+
title: string;
|
|
354
|
+
onOpen: () => void;
|
|
355
|
+
source: ReactNode;
|
|
356
|
+
head: ReactNode;
|
|
357
|
+
action?: ReactNode;
|
|
358
|
+
name: ReactNode;
|
|
359
|
+
glyph: ReactNode;
|
|
360
|
+
facts: string;
|
|
361
|
+
slices?: ReactNode;
|
|
362
|
+
}) {
|
|
363
|
+
return (
|
|
364
|
+
<div
|
|
365
|
+
style={{ width, height }}
|
|
366
|
+
data-map-part={id}
|
|
367
|
+
className={`relative flex flex-col gap-1 overflow-hidden rounded-lg border bg-(--card) px-2.5 py-2 text-left shadow-xs ${NODE_TONE[tone]} ${picked ? 'ring-2 ring-(--primary) ring-offset-1 ring-offset-(--card)' : ''}`}
|
|
368
|
+
>
|
|
369
|
+
<button
|
|
370
|
+
type="button"
|
|
371
|
+
aria-label={openLabel}
|
|
372
|
+
title={title}
|
|
373
|
+
onClick={onOpen}
|
|
374
|
+
className="absolute inset-0 rounded-lg hover:bg-[color-mix(in_srgb,var(--accent)_60%,transparent)] focus-visible:outline-2 focus-visible:outline-(--primary)"
|
|
375
|
+
/>
|
|
376
|
+
{source}
|
|
377
|
+
<span
|
|
378
|
+
className="pointer-events-none relative flex min-h-6 min-w-0 items-center gap-1.5 pr-5 text-[11px] text-(--muted-foreground)"
|
|
379
|
+
data-map-head
|
|
380
|
+
>
|
|
381
|
+
{head}
|
|
382
|
+
{action && <span className="pointer-events-auto ml-auto shrink-0">{action}</span>}
|
|
383
|
+
</span>
|
|
384
|
+
<span className="pointer-events-none relative line-clamp-2 text-[13px] leading-snug font-medium">
|
|
385
|
+
{name}
|
|
386
|
+
</span>
|
|
387
|
+
<span className="pointer-events-none relative mt-auto flex min-w-0 items-center gap-1.5 text-xs">
|
|
388
|
+
{glyph}
|
|
389
|
+
<span className="min-w-0 flex-1 truncate" data-map-facts>
|
|
390
|
+
{facts}
|
|
391
|
+
</span>
|
|
392
|
+
</span>
|
|
393
|
+
{slices && <span className="pointer-events-none absolute inset-x-2.5 bottom-0.5">{slices}</span>}
|
|
394
|
+
</div>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/** The end-to-end check at the end of the map, `width` by `height`: its `label`, title, then its `glyph` and `steps`
|
|
399
|
+
* (how many, and what it comes after), which `stepsTitle` says in full. */
|
|
400
|
+
export function MapCheckNode({
|
|
401
|
+
width,
|
|
402
|
+
height,
|
|
403
|
+
label,
|
|
404
|
+
title,
|
|
405
|
+
glyph,
|
|
406
|
+
steps,
|
|
407
|
+
stepsTitle,
|
|
408
|
+
}: {
|
|
409
|
+
width: number;
|
|
410
|
+
height: number;
|
|
411
|
+
label: string;
|
|
412
|
+
title: string;
|
|
413
|
+
glyph: ReactNode;
|
|
414
|
+
steps: string;
|
|
415
|
+
stepsTitle?: string | undefined;
|
|
416
|
+
}) {
|
|
417
|
+
return (
|
|
418
|
+
<div
|
|
419
|
+
style={{ width, height }}
|
|
420
|
+
data-map-check
|
|
421
|
+
className="flex flex-col gap-1 rounded-lg border-2 border-dashed border-(--input) bg-(--card) px-2.5 py-2 shadow-xs"
|
|
422
|
+
>
|
|
423
|
+
<span className="flex items-center gap-1.5 text-[11px] text-(--muted-foreground)">
|
|
424
|
+
<FlaskConicalIcon className="size-3.5" />
|
|
425
|
+
{label}
|
|
426
|
+
</span>
|
|
427
|
+
<span className="line-clamp-2 text-[13px] leading-snug font-medium">{title}</span>
|
|
428
|
+
<span className="mt-auto flex min-w-0 items-center gap-1.5 text-xs">
|
|
429
|
+
{glyph}
|
|
430
|
+
<span className="min-w-0 truncate" title={stepsTitle}>
|
|
431
|
+
{steps}
|
|
432
|
+
</span>
|
|
433
|
+
</span>
|
|
434
|
+
</div>
|
|
435
|
+
);
|
|
436
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/* The board app's base styles: a bare border takes the theme's border colour and an outline the primary's, links keep
|
|
2
|
+
their underline, inline code is small mono, and the one focus ring is the primary's. */
|
|
3
|
+
@layer base {
|
|
4
|
+
* {
|
|
5
|
+
@apply border-border outline-primary/50;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/* Tailwind's base styles take links' underline; these put it back. In the base layer, so a link styled as a
|
|
9
|
+
button keeps its button's text colour. */
|
|
10
|
+
a {
|
|
11
|
+
color: inherit;
|
|
12
|
+
text-decoration: underline;
|
|
13
|
+
}
|
|
14
|
+
a[data-slot='button'] {
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
}
|
|
17
|
+
a:hover {
|
|
18
|
+
text-decoration-thickness: --spacing(0.5);
|
|
19
|
+
}
|
|
20
|
+
/* So a design-system control's outline-none wins and its own focus ring is the only one. */
|
|
21
|
+
:focus-visible {
|
|
22
|
+
outline: --spacing(0.5) solid var(--ring);
|
|
23
|
+
outline-offset: --spacing(0.5);
|
|
24
|
+
border-radius: var(--radius-sm);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
code {
|
|
29
|
+
font: var(--text-xs) var(--font-mono);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.sr-only {
|
|
33
|
+
position: absolute;
|
|
34
|
+
width: --spacing(0.25);
|
|
35
|
+
height: --spacing(0.25);
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
clip-path: inset(50%);
|
|
38
|
+
white-space: nowrap;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* The design system's Button, ninna-ui's, takes no pointer events while disabled; one that says why keeps them, so
|
|
42
|
+
its title shows. */
|
|
43
|
+
button:disabled[title] {
|
|
44
|
+
pointer-events: auto;
|
|
45
|
+
cursor: not-allowed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* The board app's window drags by its title bar; the design system's Modal, its overlay and its content, which cover
|
|
49
|
+
the bar, must not, so a click over the bar while a modal is open reaches the page. */
|
|
50
|
+
[data-slot='modal-overlay'],
|
|
51
|
+
[data-slot='modal-content'] {
|
|
52
|
+
-webkit-app-region: no-drag;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Status icons animate during agent work: a running build's glyph spins, and the glyphs, slices and part bars of work
|
|
56
|
+
at a pace of its own pulse. 24 steps per half-cycle: 30 updates/s for these tiny indicators, independent of display
|
|
57
|
+
refresh rate. */
|
|
58
|
+
@keyframes status-spin {
|
|
59
|
+
to {
|
|
60
|
+
transform: rotate(360deg);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
.status-spin {
|
|
64
|
+
animation: status-spin 2.4s steps(72) infinite;
|
|
65
|
+
}
|
|
66
|
+
@keyframes status-pulse {
|
|
67
|
+
50% {
|
|
68
|
+
opacity: 0.35;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
.status-pulse {
|
|
72
|
+
animation: status-pulse 1.6s steps(24) infinite;
|
|
73
|
+
}
|
|
74
|
+
@media (prefers-reduced-motion: reduce) {
|
|
75
|
+
.status-spin,
|
|
76
|
+
.status-pulse {
|
|
77
|
+
animation: none;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* An activity's sweep across its track. 30 updates/s lets the compositor skip unchanged frames on high-refresh
|
|
82
|
+
displays. */
|
|
83
|
+
@keyframes activity-sweep {
|
|
84
|
+
from {
|
|
85
|
+
transform: translateX(-100%);
|
|
86
|
+
}
|
|
87
|
+
to {
|
|
88
|
+
transform: translateX(300%);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
.activity-sweep {
|
|
92
|
+
animation: activity-sweep 1.8s steps(54) infinite;
|
|
93
|
+
}
|
|
94
|
+
@media (prefers-reduced-motion: reduce) {
|
|
95
|
+
.activity-sweep {
|
|
96
|
+
animation: none;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Each loop behind an open blurred overlay stops repainting that blur. Ninna-ui portals every overlay as a child of
|
|
101
|
+
body in opening order, so this covers the board and lower modals and leaves the topmost modal and anything opened
|
|
102
|
+
from it. The toaster mounts earlier but sits above every dialog. Named animations only: a one-shot entrance starts
|
|
103
|
+
at opacity 0, so pausing it would hide what it enters. The title bar's refreshed ping is the one one-shot here: it
|
|
104
|
+
starts visible at opacity 0.6 and repaints the blur for 1.2 s on each landed read, and it finishes once the modal
|
|
105
|
+
closes. */
|
|
106
|
+
body
|
|
107
|
+
> :not([data-slot='toaster']):has(~ [data-slot$='-overlay'][data-state='open'])
|
|
108
|
+
:is(
|
|
109
|
+
.status-spin,
|
|
110
|
+
.status-pulse,
|
|
111
|
+
.activity-sweep,
|
|
112
|
+
.animate-spin,
|
|
113
|
+
.motion-safe\:animate-spin,
|
|
114
|
+
.animate-pulse,
|
|
115
|
+
[data-ping]
|
|
116
|
+
) {
|
|
117
|
+
animation-play-state: paused;
|
|
118
|
+
}
|
|
119
|
+
body > :not([data-slot='toaster']):has(~ [data-slot$='-overlay'][data-state='open']) .lar-skeleton::before {
|
|
120
|
+
animation-play-state: paused;
|
|
121
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* The board's button kinds (ButtonKinds.ts) are the compact Button, and an icon-only one is the Button's `iconOnly`.
|
|
2
|
+
Unlayered, so it wins over the Modal's own utilities. */
|
|
3
|
+
|
|
4
|
+
/* The design system's Modal's Close: 28 px square, like every icon-only button on the board. */
|
|
5
|
+
[data-slot='modal-close'] {
|
|
6
|
+
width: --spacing(7);
|
|
7
|
+
height: --spacing(7);
|
|
8
|
+
}
|