cursedbelt 5.40.0 → 5.45.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/dist/react/Toast.d.ts +12 -2
- package/dist/react/Toast.d.ts.map +1 -1
- package/dist/react/Toast.js +32 -3
- package/dist/react/Toast.js.map +1 -1
- package/dist/react/analytics/MetricDrilldown.js +1 -1
- package/dist/react/charts/AreaChart.d.ts.map +1 -1
- package/dist/react/charts/AreaChart.js +5 -5
- package/dist/react/charts/AreaChart.js.map +1 -1
- package/dist/react/charts/BarChart.d.ts.map +1 -1
- package/dist/react/charts/BarChart.js +3 -3
- package/dist/react/charts/BarChart.js.map +1 -1
- package/dist/react/charts/ChartCard.d.ts +53 -0
- package/dist/react/charts/ChartCard.d.ts.map +1 -0
- package/dist/react/charts/ChartCard.js +46 -0
- package/dist/react/charts/ChartCard.js.map +1 -0
- package/dist/react/charts/ChartFrame.d.ts +12 -5
- package/dist/react/charts/ChartFrame.d.ts.map +1 -1
- package/dist/react/charts/ChartFrame.js +12 -5
- package/dist/react/charts/ChartFrame.js.map +1 -1
- package/dist/react/charts/ChartLegend.js +1 -1
- package/dist/react/charts/ChartLegend.js.map +1 -1
- package/dist/react/charts/HeatmapChart.js +3 -3
- package/dist/react/charts/HeatmapChart.js.map +1 -1
- package/dist/react/charts/IntervalTimeline.js +1 -1
- package/dist/react/charts/IntervalTimeline.js.map +1 -1
- package/dist/react/charts/LineChart.d.ts.map +1 -1
- package/dist/react/charts/LineChart.js +3 -3
- package/dist/react/charts/LineChart.js.map +1 -1
- package/dist/react/charts/TimeSeriesChart.d.ts.map +1 -1
- package/dist/react/charts/TimeSeriesChart.js +6 -6
- package/dist/react/charts/TimeSeriesChart.js.map +1 -1
- package/dist/react/charts/chartBox.d.ts +46 -0
- package/dist/react/charts/chartBox.d.ts.map +1 -0
- package/dist/react/charts/chartBox.js +45 -0
- package/dist/react/charts/chartBox.js.map +1 -0
- package/dist/react/charts/index.d.ts +2 -0
- package/dist/react/charts/index.d.ts.map +1 -1
- package/dist/react/charts/index.js +2 -0
- package/dist/react/charts/index.js.map +1 -1
- package/dist/react/charts/shared.d.ts +13 -2
- package/dist/react/charts/shared.d.ts.map +1 -1
- package/dist/react/charts/shared.js +14 -3
- package/dist/react/charts/shared.js.map +1 -1
- package/dist/react/chat/Bubble.js +4 -4
- package/dist/react/chat/Bubble.js.map +1 -1
- package/dist/react/chat/MessageScroller.js +1 -1
- package/dist/react/chat/MessageScroller.js.map +1 -1
- package/dist/react/components/ActionBar.d.ts.map +1 -1
- package/dist/react/components/ActionBar.js +63 -1
- package/dist/react/components/ActionBar.js.map +1 -1
- package/dist/react/components/AddItemsMenu.js +1 -1
- package/dist/react/components/AddItemsMenu.js.map +1 -1
- package/dist/react/components/Alert.d.ts +16 -2
- package/dist/react/components/Alert.d.ts.map +1 -1
- package/dist/react/components/Alert.js +35 -2
- package/dist/react/components/Alert.js.map +1 -1
- package/dist/react/components/AppShell.d.ts +55 -33
- package/dist/react/components/AppShell.d.ts.map +1 -1
- package/dist/react/components/AppShell.js +121 -31
- package/dist/react/components/AppShell.js.map +1 -1
- package/dist/react/components/AsyncPanel.d.ts +21 -3
- package/dist/react/components/AsyncPanel.d.ts.map +1 -1
- package/dist/react/components/AsyncPanel.js +49 -5
- package/dist/react/components/AsyncPanel.js.map +1 -1
- package/dist/react/components/BannerLane.d.ts +32 -0
- package/dist/react/components/BannerLane.d.ts.map +1 -0
- package/dist/react/components/BannerLane.js +41 -0
- package/dist/react/components/BannerLane.js.map +1 -0
- package/dist/react/components/Button.d.ts.map +1 -1
- package/dist/react/components/Button.js +2 -1
- package/dist/react/components/Button.js.map +1 -1
- package/dist/react/components/ChipFilterStrip.js +1 -1
- package/dist/react/components/ChipFilterStrip.js.map +1 -1
- package/dist/react/components/ComboboxField.d.ts.map +1 -1
- package/dist/react/components/ComboboxField.js +14 -4
- package/dist/react/components/ComboboxField.js.map +1 -1
- package/dist/react/components/CommentThread.js +2 -2
- package/dist/react/components/CommentThread.js.map +1 -1
- package/dist/react/components/ConfirmDialog.js +1 -1
- package/dist/react/components/ConfirmDialog.js.map +1 -1
- package/dist/react/components/DataTable/DataTable.d.ts +18 -2
- package/dist/react/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/react/components/DataTable/DataTable.js +51 -12
- package/dist/react/components/DataTable/DataTable.js.map +1 -1
- package/dist/react/components/DataTable/Pagination.js +1 -1
- package/dist/react/components/DataTable/Pagination.js.map +1 -1
- package/dist/react/components/DataTable/RowActions.d.ts +7 -1
- package/dist/react/components/DataTable/RowActions.d.ts.map +1 -1
- package/dist/react/components/DataTable/RowActions.js +10 -3
- package/dist/react/components/DataTable/RowActions.js.map +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.js +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -1
- package/dist/react/components/DataTable/cells/CodeCell.js +1 -1
- package/dist/react/components/DataTable/cells/CodeCell.js.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.js +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
- package/dist/react/components/DataTable/index.d.ts +1 -1
- package/dist/react/components/DataTable/index.d.ts.map +1 -1
- package/dist/react/components/DataTable/index.js.map +1 -1
- package/dist/react/components/DataTable/types.d.ts +20 -0
- package/dist/react/components/DataTable/types.d.ts.map +1 -1
- package/dist/react/components/DataTable/types.js +22 -0
- package/dist/react/components/DataTable/types.js.map +1 -1
- package/dist/react/components/DateTimeField.d.ts.map +1 -1
- package/dist/react/components/DateTimeField.js +4 -1
- package/dist/react/components/DateTimeField.js.map +1 -1
- package/dist/react/components/DeleteButton.js +2 -0
- package/dist/react/components/DeleteButton.js.map +1 -1
- package/dist/react/components/Drawer.js +3 -3
- package/dist/react/components/Drawer.js.map +1 -1
- package/dist/react/components/DropdownMenu.d.ts +16 -0
- package/dist/react/components/DropdownMenu.d.ts.map +1 -1
- package/dist/react/components/DropdownMenu.js +22 -6
- package/dist/react/components/DropdownMenu.js.map +1 -1
- package/dist/react/components/EmptyState.d.ts +10 -2
- package/dist/react/components/EmptyState.d.ts.map +1 -1
- package/dist/react/components/EmptyState.js +10 -5
- package/dist/react/components/EmptyState.js.map +1 -1
- package/dist/react/components/EventTimeline.js +1 -1
- package/dist/react/components/EventTimeline.js.map +1 -1
- package/dist/react/components/FileDropZone.js +1 -1
- package/dist/react/components/FileDropZone.js.map +1 -1
- package/dist/react/components/Grid.d.ts +9 -1
- package/dist/react/components/Grid.d.ts.map +1 -1
- package/dist/react/components/Grid.js +20 -2
- package/dist/react/components/Grid.js.map +1 -1
- package/dist/react/components/Guide.d.ts +31 -0
- package/dist/react/components/Guide.d.ts.map +1 -0
- package/dist/react/components/Guide.js +18 -0
- package/dist/react/components/Guide.js.map +1 -0
- package/dist/react/components/InfoHintImpl.d.ts +0 -13
- package/dist/react/components/InfoHintImpl.d.ts.map +1 -1
- package/dist/react/components/InfoHintImpl.js +17 -1
- package/dist/react/components/InfoHintImpl.js.map +1 -1
- package/dist/react/components/InlineEditableText.js +1 -1
- package/dist/react/components/InlineEditableText.js.map +1 -1
- package/dist/react/components/IsolatedFrame.js +1 -1
- package/dist/react/components/IsolatedFrame.js.map +1 -1
- package/dist/react/components/ListToolbar.d.ts.map +1 -1
- package/dist/react/components/ListToolbar.js +2 -2
- package/dist/react/components/ListToolbar.js.map +1 -1
- package/dist/react/components/LogViewer.d.ts +26 -2
- package/dist/react/components/LogViewer.d.ts.map +1 -1
- package/dist/react/components/LogViewer.js +41 -26
- package/dist/react/components/LogViewer.js.map +1 -1
- package/dist/react/components/Modal.d.ts +5 -1
- package/dist/react/components/Modal.d.ts.map +1 -1
- package/dist/react/components/Modal.js +18 -8
- package/dist/react/components/Modal.js.map +1 -1
- package/dist/react/components/Page.d.ts +51 -7
- package/dist/react/components/Page.d.ts.map +1 -1
- package/dist/react/components/Page.js +53 -8
- package/dist/react/components/Page.js.map +1 -1
- package/dist/react/components/PageGuideButton.d.ts +11 -0
- package/dist/react/components/PageGuideButton.d.ts.map +1 -0
- package/dist/react/components/PageGuideButton.js +13 -0
- package/dist/react/components/PageGuideButton.js.map +1 -0
- package/dist/react/components/PanelSeparator.js +1 -1
- package/dist/react/components/PanelSeparator.js.map +1 -1
- package/dist/react/components/Popover.d.ts.map +1 -1
- package/dist/react/components/Popover.js +2 -1
- package/dist/react/components/Popover.js.map +1 -1
- package/dist/react/components/PromptDialog.js +1 -1
- package/dist/react/components/PromptDialog.js.map +1 -1
- package/dist/react/components/ScrollArea.d.ts +9 -1
- package/dist/react/components/ScrollArea.d.ts.map +1 -1
- package/dist/react/components/ScrollArea.js +9 -3
- package/dist/react/components/ScrollArea.js.map +1 -1
- package/dist/react/components/Section.d.ts +5 -2
- package/dist/react/components/Section.d.ts.map +1 -1
- package/dist/react/components/Section.js +5 -2
- package/dist/react/components/Section.js.map +1 -1
- package/dist/react/components/Skeleton.d.ts +19 -1
- package/dist/react/components/Skeleton.d.ts.map +1 -1
- package/dist/react/components/Skeleton.js +24 -2
- package/dist/react/components/Skeleton.js.map +1 -1
- package/dist/react/components/StatStrip.js +1 -1
- package/dist/react/components/StatStrip.js.map +1 -1
- package/dist/react/components/StatTile.d.ts +30 -3
- package/dist/react/components/StatTile.d.ts.map +1 -1
- package/dist/react/components/StatTile.js +35 -9
- package/dist/react/components/StatTile.js.map +1 -1
- package/dist/react/components/StatTileGrid.d.ts +10 -1
- package/dist/react/components/StatTileGrid.d.ts.map +1 -1
- package/dist/react/components/StatTileGrid.js +50 -33
- package/dist/react/components/StatTileGrid.js.map +1 -1
- package/dist/react/components/StatusPill.d.ts.map +1 -1
- package/dist/react/components/StatusPill.js +26 -1
- package/dist/react/components/StatusPill.js.map +1 -1
- package/dist/react/components/Surface.d.ts +1 -1
- package/dist/react/components/Surface.d.ts.map +1 -1
- package/dist/react/components/Surface.js +20 -11
- package/dist/react/components/Surface.js.map +1 -1
- package/dist/react/components/SwatchPicker.d.ts.map +1 -1
- package/dist/react/components/SwatchPicker.js +5 -1
- package/dist/react/components/SwatchPicker.js.map +1 -1
- package/dist/react/components/Switch.js +1 -1
- package/dist/react/components/Switch.js.map +1 -1
- package/dist/react/components/WidgetHeader.js +1 -1
- package/dist/react/components/WidgetHeader.js.map +1 -1
- package/dist/react/components/calendar/CalendarLegend.js +1 -1
- package/dist/react/components/calendar/CalendarLegend.js.map +1 -1
- package/dist/react/components/calendar/DayAgenda.js +1 -1
- package/dist/react/components/calendar/DayAgenda.js.map +1 -1
- package/dist/react/components/calendar/EventChip.js +1 -1
- package/dist/react/components/calendar/EventChip.js.map +1 -1
- package/dist/react/components/calendar/MonthGrid.js +1 -1
- package/dist/react/components/calendar/MonthGrid.js.map +1 -1
- package/dist/react/components/calendar/WeekView.js +2 -2
- package/dist/react/components/calendar/WeekView.js.map +1 -1
- package/dist/react/components/cardFrame.d.ts +16 -0
- package/dist/react/components/cardFrame.d.ts.map +1 -0
- package/dist/react/components/cardFrame.js +24 -0
- package/dist/react/components/cardFrame.js.map +1 -0
- package/dist/react/components/dialog.d.ts.map +1 -1
- package/dist/react/components/dialog.js +2 -1
- package/dist/react/components/dialog.js.map +1 -1
- package/dist/react/dashboard-grid/WidgetFrame.js +2 -2
- package/dist/react/dashboard-grid/WidgetFrame.js.map +1 -1
- package/dist/react/emoji/EmojiPicker.js +1 -1
- package/dist/react/emoji/EmojiPicker.js.map +1 -1
- package/dist/react/file-tree/FileTree.d.ts +8 -1
- package/dist/react/file-tree/FileTree.d.ts.map +1 -1
- package/dist/react/file-tree/FileTree.js +29 -4
- package/dist/react/file-tree/FileTree.js.map +1 -1
- package/dist/react/filter-rail/FilterRail.js +1 -1
- package/dist/react/filter-rail/FilterRail.js.map +1 -1
- package/dist/react/icons.js +1 -1
- package/dist/react/icons.js.map +1 -1
- package/dist/react/index.d.ts +8 -5
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/lib/menuSections.d.ts +8 -0
- package/dist/react/lib/menuSections.d.ts.map +1 -0
- package/dist/react/lib/menuSections.js +37 -0
- package/dist/react/lib/menuSections.js.map +1 -0
- package/dist/react/markdown/Markdown.js +2 -2
- package/dist/react/markdown/Markdown.js.map +1 -1
- package/dist/react/media/HoverScrubVideoThumb.js +1 -1
- package/dist/react/media/HoverScrubVideoThumb.js.map +1 -1
- package/dist/react/media/MaskPainter.js +1 -1
- package/dist/react/media/MediaUploadControl.js +1 -1
- package/dist/react/media/MediaUploadControl.js.map +1 -1
- package/dist/react/media/VideoTrimmer.js +1 -1
- package/dist/react/media/VideoTrimmer.js.map +1 -1
- package/dist/react/media/denseGallery.css +5 -1
- package/dist/react/namespace/NamespaceTargetCapsule.js +1 -1
- package/dist/react/namespace/NamespaceTargetCapsule.js.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.js +1 -1
- package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
- package/dist/react/nav/CommandBar.d.ts +7 -1
- package/dist/react/nav/CommandBar.d.ts.map +1 -1
- package/dist/react/nav/CommandBar.js +5 -3
- package/dist/react/nav/CommandBar.js.map +1 -1
- package/dist/react/nav/PlaceBar.d.ts.map +1 -1
- package/dist/react/nav/PlaceBar.js +7 -9
- package/dist/react/nav/PlaceBar.js.map +1 -1
- package/dist/react/nav/SideNav.d.ts +12 -2
- package/dist/react/nav/SideNav.d.ts.map +1 -1
- package/dist/react/nav/SideNav.js +42 -22
- package/dist/react/nav/SideNav.js.map +1 -1
- package/dist/react/nav/TopBar.d.ts +65 -31
- package/dist/react/nav/TopBar.d.ts.map +1 -1
- package/dist/react/nav/TopBar.js +59 -24
- package/dist/react/nav/TopBar.js.map +1 -1
- package/dist/react/nav/index.d.ts +1 -1
- package/dist/react/nav/index.d.ts.map +1 -1
- package/dist/react/nav/index.js +1 -1
- package/dist/react/nav/index.js.map +1 -1
- package/dist/react/nav/navShared.d.ts +10 -1
- package/dist/react/nav/navShared.d.ts.map +1 -1
- package/dist/react/nav/navShared.js +23 -0
- package/dist/react/nav/navShared.js.map +1 -1
- package/dist/react/notifications/NotificationFeed.js +2 -2
- package/dist/react/notifications/NotificationFeed.js.map +1 -1
- package/dist/react/palette/Command.d.ts.map +1 -1
- package/dist/react/palette/Command.js +1 -1
- package/dist/react/palette/Command.js.map +1 -1
- package/dist/react/palette/CommandPalette.d.ts +13 -1
- package/dist/react/palette/CommandPalette.d.ts.map +1 -1
- package/dist/react/palette/CommandPalette.js +44 -8
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/react/palette/commandSources.d.ts +57 -0
- package/dist/react/palette/commandSources.d.ts.map +1 -0
- package/dist/react/palette/commandSources.js +129 -0
- package/dist/react/palette/commandSources.js.map +1 -0
- package/dist/react/palette/index.d.ts +1 -0
- package/dist/react/palette/index.d.ts.map +1 -1
- package/dist/react/palette/index.js +1 -0
- package/dist/react/palette/index.js.map +1 -1
- package/dist/react/rich-text/RichTextEditor.js +1 -1
- package/dist/react/rich-text/RichTextEditor.js.map +1 -1
- package/dist/react/rich-text/RichTextToolbar.js +1 -1
- package/dist/react/rich-text/RichTextToolbar.js.map +1 -1
- package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
- package/dist/styles-areas/analytics.css +16 -16
- package/dist/styles-areas/auth.css +3 -3
- package/dist/styles-areas/calendar.css +6 -6
- package/dist/styles-areas/chart-table.css +1 -1
- package/dist/styles-areas/charts.css +3 -3
- package/dist/styles-areas/chat.css +7 -6
- package/dist/styles-areas/companion-link.css +2 -2
- package/dist/styles-areas/core.css +98 -89
- package/dist/styles-areas/dashboard-grid.css +4 -4
- package/dist/styles-areas/data-table.css +16 -16
- package/dist/styles-areas/disk-usage.css +5 -5
- package/dist/styles-areas/emoji.css +2 -2
- package/dist/styles-areas/fields.css +13 -14
- package/dist/styles-areas/filter-rail.css +4 -4
- package/dist/styles-areas/folder-tree.css +3 -3
- package/dist/styles-areas/markdown.css +2 -1
- package/dist/styles-areas/master-detail.css +3 -3
- package/dist/styles-areas/media-gallery.css +8 -8
- package/dist/styles-areas/media.css +12 -13
- package/dist/styles-areas/nav.css +28 -14
- package/dist/styles-areas/notifications.css +4 -4
- package/dist/styles-areas/overlays.css +4 -4
- package/dist/styles-areas/palette.css +4 -3
- package/dist/styles-areas/rich-text.css +3 -3
- package/dist/styles-areas/sharing.css +4 -3
- package/dist/styles-areas/stats.css +9 -8
- package/dist/styles-areas/test-report.css +3 -3
- package/dist/styles-areas/wizard.css +6 -5
- package/dist/styles-areas/workbench.css +10 -9
- package/dist/styles-areas/workbook-viewer.css +2 -2
- package/dist/styles-utilities.css +272 -187
- package/dist/testing/designAudit.d.ts.map +1 -1
- package/dist/testing/designAudit.js +4 -0
- package/dist/testing/designAudit.js.map +1 -1
- package/dist/testing/designBaseline.d.ts.map +1 -1
- package/dist/testing/designBaseline.js +4 -0
- package/dist/testing/designBaseline.js.map +1 -1
- package/dist/theme.css +103 -2
- package/package.json +3 -2
- package/scripts/guardrails-baseline.json +2 -1
- package/scripts/guardrailsEnforce.spec.ts +64 -0
- package/scripts/guardrailsEnforce.ts +65 -8
- package/scripts/styleAreas.ts +1 -0
- package/src/nodeTypesDeclared.spec.ts +47 -0
- package/src/react/Toast.spec.tsx +43 -0
- package/src/react/Toast.tsx +45 -2
- package/src/react/analytics/MetricDrilldown.tsx +1 -1
- package/src/react/charts/AreaChart.tsx +9 -8
- package/src/react/charts/BarChart.tsx +11 -10
- package/src/react/charts/ChartCard.tsx +146 -0
- package/src/react/charts/ChartFrame.tsx +28 -10
- package/src/react/charts/ChartLegend.tsx +1 -1
- package/src/react/charts/HeatmapChart.tsx +5 -5
- package/src/react/charts/IntervalTimeline.tsx +2 -2
- package/src/react/charts/LineChart.tsx +9 -8
- package/src/react/charts/TimeSeriesChart.tsx +11 -10
- package/src/react/charts/chartBox.spec.ts +40 -0
- package/src/react/charts/chartBox.ts +75 -0
- package/src/react/charts/index.ts +2 -0
- package/src/react/charts/shared.ts +16 -3
- package/src/react/chat/Bubble.tsx +5 -5
- package/src/react/chat/MessageScroller.tsx +1 -1
- package/src/react/components/ActionBar.spec.tsx +90 -0
- package/src/react/components/ActionBar.tsx +82 -2
- package/src/react/components/AddItemsMenu.tsx +1 -1
- package/src/react/components/Alert.spec.tsx +32 -2
- package/src/react/components/Alert.tsx +47 -3
- package/src/react/components/AppShell.spec.tsx +199 -13
- package/src/react/components/AppShell.tsx +235 -92
- package/src/react/components/AsyncPanel.spec.tsx +7 -1
- package/src/react/components/AsyncPanel.tsx +85 -5
- package/src/react/components/BannerLane.tsx +128 -0
- package/src/react/components/Button.tsx +2 -0
- package/src/react/components/ChipFilterStrip.tsx +1 -1
- package/src/react/components/ComboboxField.tsx +20 -3
- package/src/react/components/CommentThread.tsx +2 -2
- package/src/react/components/ConfirmDialog.tsx +1 -1
- package/src/react/components/DataTable/DataTable.tsx +80 -8
- package/src/react/components/DataTable/Pagination.tsx +1 -1
- package/src/react/components/DataTable/RowActions.tsx +55 -2
- package/src/react/components/DataTable/TableFilterBuilder.tsx +1 -1
- package/src/react/components/DataTable/cells/CodeCell.tsx +1 -1
- package/src/react/components/DataTable/cells/LinkCell.tsx +1 -1
- package/src/react/components/DataTable/index.ts +1 -0
- package/src/react/components/DataTable/numericColumn.spec.ts +19 -0
- package/src/react/components/DataTable/types.ts +36 -0
- package/src/react/components/DateTimeField.tsx +3 -1
- package/src/react/components/DeleteButton.tsx +3 -0
- package/src/react/components/Drawer.tsx +3 -3
- package/src/react/components/DropdownMenu.spec.tsx +55 -0
- package/src/react/components/DropdownMenu.tsx +73 -20
- package/src/react/components/EmptyState.tsx +26 -7
- package/src/react/components/EventTimeline.tsx +1 -1
- package/src/react/components/Field.width.spec.tsx +11 -0
- package/src/react/components/FileDropZone.tsx +1 -1
- package/src/react/components/Grid.spec.tsx +44 -0
- package/src/react/components/Grid.tsx +41 -11
- package/src/react/components/Guide.tsx +77 -0
- package/src/react/components/InfoHint.spec.tsx +21 -0
- package/src/react/components/InfoHintImpl.tsx +22 -1
- package/src/react/components/InlineEditableText.tsx +1 -1
- package/src/react/components/IsolatedFrame.tsx +1 -1
- package/src/react/components/ListToolbar.spec.tsx +12 -0
- package/src/react/components/ListToolbar.tsx +8 -5
- package/src/react/components/LogViewer.tsx +118 -18
- package/src/react/components/Modal.spec.tsx +17 -2
- package/src/react/components/Modal.tsx +25 -10
- package/src/react/components/MultiSelectField.spec.tsx +6 -0
- package/src/react/components/Page.spec.tsx +89 -5
- package/src/react/components/Page.tsx +100 -16
- package/src/react/components/PageGuideButton.tsx +42 -0
- package/src/react/components/PanelSeparator.tsx +1 -1
- package/src/react/components/Popover.tsx +3 -1
- package/src/react/components/PromptDialog.tsx +1 -1
- package/src/react/components/ScrollArea.spec.tsx +20 -0
- package/src/react/components/ScrollArea.tsx +19 -0
- package/src/react/components/Section.spec.tsx +82 -1
- package/src/react/components/Section.tsx +10 -4
- package/src/react/components/Skeleton.tsx +50 -2
- package/src/react/components/StatStrip.tsx +1 -1
- package/src/react/components/StatTile.tsx +84 -11
- package/src/react/components/StatTileGrid.spec.tsx +6 -1
- package/src/react/components/StatTileGrid.tsx +25 -0
- package/src/react/components/StatusPill.tsx +26 -1
- package/src/react/components/Surface.tsx +22 -14
- package/src/react/components/SwatchPicker.tsx +4 -0
- package/src/react/components/Switch.tsx +1 -1
- package/src/react/components/WidgetHeader.tsx +1 -1
- package/src/react/components/calendar/CalendarLegend.tsx +1 -1
- package/src/react/components/calendar/DayAgenda.tsx +1 -1
- package/src/react/components/calendar/EventChip.tsx +1 -1
- package/src/react/components/calendar/MonthGrid.tsx +1 -1
- package/src/react/components/calendar/WeekView.tsx +2 -2
- package/src/react/components/cardFrame.ts +28 -0
- package/src/react/components/dataDisplay.spec.tsx +176 -0
- package/src/react/components/dialog.tsx +4 -1
- package/src/react/dashboard-grid/WidgetFrame.tsx +2 -2
- package/src/react/emoji/EmojiPicker.tsx +1 -1
- package/src/react/file-tree/FileTree.spec.tsx +49 -0
- package/src/react/file-tree/FileTree.tsx +37 -4
- package/src/react/filter-rail/FilterRail.tsx +1 -1
- package/src/react/icons.tsx +1 -1
- package/src/react/index.ts +28 -3
- package/src/react/lib/menuSections.ts +33 -0
- package/src/react/markdown/Markdown.tsx +2 -2
- package/src/react/media/HoverScrubVideoThumb.tsx +2 -2
- package/src/react/media/MaskPainter.tsx +1 -1
- package/src/react/media/MediaUploadControl.tsx +1 -1
- package/src/react/media/VideoTrimmer.tsx +1 -1
- package/src/react/media/denseGallery.css +5 -1
- package/src/react/namespace/NamespaceTargetCapsule.tsx +1 -1
- package/src/react/nav/BreadcrumbTrail.tsx +2 -2
- package/src/react/nav/CommandBar.tsx +14 -3
- package/src/react/nav/PlaceBar.tsx +18 -8
- package/src/react/nav/SideNav.tsx +99 -17
- package/src/react/nav/TopBar.spec.tsx +78 -21
- package/src/react/nav/TopBar.tsx +270 -98
- package/src/react/nav/index.ts +8 -1
- package/src/react/nav/nav.spec.tsx +46 -2
- package/src/react/nav/navShared.tsx +23 -2
- package/src/react/notifications/NotificationFeed.tsx +2 -2
- package/src/react/palette/Command.tsx +1 -1
- package/src/react/palette/CommandPalette.spec.tsx +31 -0
- package/src/react/palette/CommandPalette.tsx +108 -11
- package/src/react/palette/commandSources.tsx +186 -0
- package/src/react/palette/index.ts +7 -0
- package/src/react/rich-text/RichTextEditor.tsx +1 -1
- package/src/react/rich-text/RichTextToolbar.tsx +1 -1
- package/src/styles-areas/analytics.css +16 -16
- package/src/styles-areas/auth.css +3 -3
- package/src/styles-areas/calendar.css +6 -6
- package/src/styles-areas/chart-table.css +1 -1
- package/src/styles-areas/charts.css +3 -3
- package/src/styles-areas/chat.css +7 -6
- package/src/styles-areas/companion-link.css +2 -2
- package/src/styles-areas/core.css +98 -89
- package/src/styles-areas/dashboard-grid.css +4 -4
- package/src/styles-areas/data-table.css +16 -16
- package/src/styles-areas/disk-usage.css +5 -5
- package/src/styles-areas/emoji.css +2 -2
- package/src/styles-areas/fields.css +13 -14
- package/src/styles-areas/filter-rail.css +4 -4
- package/src/styles-areas/folder-tree.css +3 -3
- package/src/styles-areas/markdown.css +2 -1
- package/src/styles-areas/master-detail.css +3 -3
- package/src/styles-areas/media-gallery.css +8 -8
- package/src/styles-areas/media.css +12 -13
- package/src/styles-areas/nav.css +28 -14
- package/src/styles-areas/notifications.css +4 -4
- package/src/styles-areas/overlays.css +4 -4
- package/src/styles-areas/palette.css +4 -3
- package/src/styles-areas/rich-text.css +3 -3
- package/src/styles-areas/sharing.css +4 -3
- package/src/styles-areas/stats.css +9 -8
- package/src/styles-areas/test-report.css +3 -3
- package/src/styles-areas/wizard.css +6 -5
- package/src/styles-areas/workbench.css +10 -9
- package/src/styles-areas/workbook-viewer.css +2 -2
- package/src/styles-utilities.css +272 -187
- package/src/testing/designAudit.ts +3 -0
- package/src/testing/designBaseline.ts +4 -0
- package/src/theme.css +103 -2
- package/src/themeDarkScopeAliases.spec.ts +65 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { AlertTriangle, CheckCircle, Info, X, XCircle } from 'lucide-react';
|
|
3
|
+
import { useState } from 'react';
|
|
3
4
|
import { cn } from '../lib/cn.js';
|
|
4
5
|
import { IconButton } from './IconButton.js';
|
|
5
6
|
/*
|
|
@@ -22,9 +23,41 @@ const DEFAULT_ICON = {
|
|
|
22
23
|
error: _jsx(XCircle, {}),
|
|
23
24
|
muted: _jsx(Info, {}),
|
|
24
25
|
};
|
|
25
|
-
|
|
26
|
+
/** The localStorage namespace for a dismissed `Alert`'s `dismissKey`. */
|
|
27
|
+
export const ALERT_DISMISS_STORAGE_PREFIX = 'cb:alert-dismissed:';
|
|
28
|
+
function readDismissed(key) {
|
|
29
|
+
if (!key)
|
|
30
|
+
return false;
|
|
31
|
+
try {
|
|
32
|
+
return globalThis.localStorage?.getItem(ALERT_DISMISS_STORAGE_PREFIX + key) !== null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false; // storage refused (a private window): the caveat shows, which is the safe side
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function writeDismissed(key) {
|
|
39
|
+
if (!key)
|
|
40
|
+
return;
|
|
41
|
+
try {
|
|
42
|
+
globalThis.localStorage?.setItem(ALERT_DISMISS_STORAGE_PREFIX + key, new Date().toISOString());
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Not persisted; it is still gone for this mount.
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function Alert({ tone = 'info', title, icon, actions, onDismiss, dismissLabel = 'Dismiss', dismissible = false, dismissKey, className, children, }) {
|
|
49
|
+
const [dismissed, setDismissed] = useState(() => dismissible && readDismissed(dismissKey));
|
|
50
|
+
if (dismissed)
|
|
51
|
+
return null;
|
|
52
|
+
const dismiss = dismissible
|
|
53
|
+
? () => {
|
|
54
|
+
writeDismissed(dismissKey);
|
|
55
|
+
setDismissed(true);
|
|
56
|
+
onDismiss?.();
|
|
57
|
+
}
|
|
58
|
+
: onDismiss;
|
|
26
59
|
return (_jsxs("div", {
|
|
27
60
|
// Errors are assertive (`alert`); the rest are polite live regions (`status`).
|
|
28
|
-
role: tone === 'error' ? 'alert' : 'status', className: cn('flex gap-3 rounded-lg border p-4', TONE[tone], className), children: [icon !== false && (_jsx("span", { className: 'alert-icon mt-0.5 shrink-0 [&_svg]:size-4', children: icon ?? DEFAULT_ICON[tone] })), _jsxs("div", { className: 'flex min-w-0 flex-1 flex-col gap-1', children: [title && _jsx("p", { className: 'wrap-anywhere text-sm font-medium text-foreground', children: title }), children && _jsx("div", { className: 'wrap-anywhere text-sm text-muted-foreground', children: children }), actions && _jsx("div", { className: 'mt-2 flex flex-wrap gap-2', children: actions })] }),
|
|
61
|
+
role: tone === 'error' ? 'alert' : 'status', className: cn('flex gap-3 rounded-lg border p-4', TONE[tone], className), children: [icon !== false && (_jsx("span", { className: 'alert-icon mt-0.5 shrink-0 [&_svg]:size-4', children: icon ?? DEFAULT_ICON[tone] })), _jsxs("div", { className: 'flex min-w-0 flex-1 flex-col gap-1', children: [title && _jsx("p", { className: 'wrap-anywhere text-sm font-medium text-foreground', children: title }), children && _jsx("div", { className: 'wrap-anywhere text-sm text-muted-foreground', children: children }), actions && _jsx("div", { className: 'mt-2 flex flex-wrap gap-2', children: actions })] }), dismiss && (_jsx(IconButton, { label: dismissLabel, onClick: dismiss, className: 'alert-icon h-auto min-h-0 w-auto shrink-0 rounded p-0.5 text-current hover:opacity-70 hover:bg-transparent [&_svg]:size-4', children: _jsx(X, {}) }))] }));
|
|
29
62
|
}
|
|
30
63
|
//# sourceMappingURL=Alert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../../src/react/components/Alert.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../../src/react/components/Alert.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
1
|
+
import { type ElementType, type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { type GateFn, type NavigationModel, type NavPreferences } from 'cursedbelt-core/navigation';
|
|
3
|
+
import { type IconResolver, type NavBadgeTone } from '../nav/navShared.js';
|
|
4
4
|
import { type AmbientBackdropProps } from './AmbientBackdrop.js';
|
|
5
|
+
import { type ShellBanner } from './BannerLane.js';
|
|
5
6
|
import { type ScrollAreaSpace } from './ScrollArea.js';
|
|
6
7
|
export interface AppShellProps {
|
|
7
8
|
/** Routed page content. Scrolls inside the single keyboard-safe `ScrollArea`. */
|
|
8
9
|
children: ReactNode;
|
|
9
10
|
/**
|
|
10
|
-
* The navigation model — the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The navigation model — the one registry every nav surface reads. The app passes it and
|
|
12
|
+
* the SHELL picks the pattern from the number of places (NAV-3):
|
|
13
|
+
*
|
|
14
|
+
* | places | ≥1024px | 768–1023px | <768px |
|
|
15
|
+
* |---|---|---|---|
|
|
16
|
+
* | 2–5 | labeled `TopBar` places in the header's center | same | `PlaceBar`, every place |
|
|
17
|
+
* | 6+ | `SideNav` with labeled sections, 240px | the 64px icon rail | `PlaceBar`, top 4 + More |
|
|
18
|
+
*
|
|
19
|
+
* Six or more places mount the ⌘K `CommandPalette` too (NAV-9). Omit for chromeless pages.
|
|
15
20
|
*/
|
|
16
21
|
nav?: NavigationModel;
|
|
17
22
|
/** Visibility gate (auth/role/ctgr) applied to the nav model. Default: allow all. */
|
|
@@ -34,8 +39,30 @@ export interface AppShellProps {
|
|
|
34
39
|
navBadgeTone?: NavBadgeTone;
|
|
35
40
|
/** Brand slot — top-left of the command spine (logo / app name). */
|
|
36
41
|
navHeader?: ReactNode;
|
|
37
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The sidebar's footer (NAV-13): the version, `BuildFreshness` and a Settings link, set in
|
|
44
|
+
* 12px muted type. Only a 6+-place shell has a sidebar; a 2–5-place app keeps these in
|
|
45
|
+
* Settings → About.
|
|
46
|
+
*/
|
|
38
47
|
navFooter?: ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* App-wide conditions — a sign-in broke, the Mac is asleep, the app is offline — as the ONE
|
|
50
|
+
* banner lane between the header and the page (NAV-10). One line each; two or more collapse
|
|
51
|
+
* into "N problems · View". Never a card inside the page.
|
|
52
|
+
*/
|
|
53
|
+
banners?: readonly ShellBanner[];
|
|
54
|
+
/**
|
|
55
|
+
* The header's height (NAV-1): `dense` 48px for a tool (station, desk, binary-server),
|
|
56
|
+
* `roomy` 64px for media and consumer apps. Unset, it reads `--header-h` (64px; 48px
|
|
57
|
+
* inside `.cb-dense`).
|
|
58
|
+
*/
|
|
59
|
+
density?: 'roomy' | 'dense';
|
|
60
|
+
/**
|
|
61
|
+
* Mount the shell's own ⌘K `CommandPalette` — every place preloaded, plus whatever pages
|
|
62
|
+
* contribute through `useCommandSource`. `'auto'` (default) mounts it for 6+ places
|
|
63
|
+
* (NAV-9). Ignored when the app renders its own through `palette`.
|
|
64
|
+
*/
|
|
65
|
+
commandPalette?: boolean | 'auto';
|
|
39
66
|
/**
|
|
40
67
|
* Universal capture (UX north-star §8.2) — wired to the command spine's capture
|
|
41
68
|
* hero (desktop) and the `PlaceBar`'s raised center FAB (mobile). Capture is a
|
|
@@ -72,7 +99,7 @@ export interface AppShellProps {
|
|
|
72
99
|
* in the tree is immaterial.
|
|
73
100
|
*/
|
|
74
101
|
palette?: ReactNode;
|
|
75
|
-
/** Max places in the mobile `PlaceBar` thumb zone
|
|
102
|
+
/** Max places in the mobile `PlaceBar` thumb zone; past it, `max - 1` places + More. Default 5. */
|
|
76
103
|
placeBarMax?: number;
|
|
77
104
|
/** PlaceBar caption policy (`'active'` | `'all'`). Pass `'all'` when place names
|
|
78
105
|
* are short or icons alone are ambiguous (two grid-glyph plugins side by side
|
|
@@ -100,42 +127,37 @@ export interface AppShellProps {
|
|
|
100
127
|
className?: string;
|
|
101
128
|
}
|
|
102
129
|
/**
|
|
103
|
-
* THE single application shell. One per app —
|
|
104
|
-
* (`
|
|
130
|
+
* THE single application shell. One per app — the frame every page sits in
|
|
131
|
+
* (`docs/design/shell-and-navigation.md`, NAV-1…NAV-14). The app passes ONE navigation
|
|
132
|
+
* model and the shell decides how to draw it, so no app can pick the wrong pattern:
|
|
105
133
|
*
|
|
106
|
-
* **
|
|
107
|
-
*
|
|
108
|
-
* -
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* place-set in the thumb zone around a raised center capture FAB (mobile is
|
|
112
|
-
* capture-forward, not tab-forward — §7).
|
|
113
|
-
* - The buried, invisible ⌘K palette + no capture → the first-class **`CommandBar`
|
|
114
|
-
* spine**: a visible command/search field (the co-equal second way to move) + a
|
|
115
|
-
* capture hero (universal capture, §8.2).
|
|
116
|
-
* - The avatar-in-nav → **account chrome** behind the avatar in the spine (not a door).
|
|
134
|
+
* - **2–5 places** → their labels in the header's center zone (NAV-2: destinations have
|
|
135
|
+
* words from 768px up), every place in the `PlaceBar` on a phone.
|
|
136
|
+
* - **6+ places** → a 240px `SideNav` in labeled sections at ≥1024px, the 64px icon rail
|
|
137
|
+
* at 768–1023px, the `PlaceBar` with the top 4 + More on a phone, and a ⌘K
|
|
138
|
+
* `CommandPalette` preloaded with every place (NAV-9).
|
|
117
139
|
*
|
|
118
|
-
*
|
|
119
|
-
* coverage test
|
|
120
|
-
*
|
|
140
|
+
* Kept from the shell before it (owner teardowns 2026-07-15, the UX north-star): the single
|
|
141
|
+
* `navigationModel` registry and its coverage test, per-user place prefs, badges, universal
|
|
142
|
+
* capture (the spine's hero on desktop, the `PlaceBar` FAB on a phone), and the
|
|
143
|
+
* keyboard-safe single `ScrollArea`. No hamburger drawer, ever.
|
|
121
144
|
*
|
|
122
145
|
* Layout model:
|
|
123
146
|
* ```
|
|
124
147
|
* <div h-dvh flex flex-col overflow-hidden> ← dvh excludes the mobile URL bar
|
|
125
|
-
* <header
|
|
126
|
-
* <
|
|
127
|
-
*
|
|
148
|
+
* <header h-[--header-h]> ← left: brand · center: places or ⌘K field · right: account
|
|
149
|
+
* <BannerLane /> ← NAV-10, only when there is a banner
|
|
150
|
+
* <div flex min-h-0 grow> ← sidebar + content row
|
|
151
|
+
* <aside md:flex lg:hidden w-16 /> ← 6+ places: the icon rail
|
|
152
|
+
* <aside lg:flex w-60 /> ← 6+ places: the sectioned SideNav
|
|
128
153
|
* <main><ScrollArea>{children}</ScrollArea></main> ← THE ONLY page scroll container
|
|
129
154
|
* </div>
|
|
130
155
|
* <div pb-[safe-area]> ← bottomDock + mobile PlaceBar
|
|
131
|
-
* {bottomDock}
|
|
132
|
-
* <PlaceBar md:hidden /> ← capture-forward bottom bar
|
|
133
|
-
* </div>
|
|
134
156
|
* </div>
|
|
135
157
|
* ```
|
|
136
158
|
*
|
|
137
159
|
* Keyboard model: `useKeyboardInset` (installed exactly once, here) writes
|
|
138
160
|
* `--keyboard-inset` onto `<html>`; `ScrollArea` reads it via CSS `calc()`.
|
|
139
161
|
*/
|
|
140
|
-
export declare function AppShell(
|
|
162
|
+
export declare function AppShell(props: AppShellProps): import("react").JSX.Element;
|
|
141
163
|
//# sourceMappingURL=AppShell.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAA2B,MAAM,OAAO,CAAC;AAC5F,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAAE,KAAK,YAAY,EAAkB,KAAK,YAAY,EAA0B,MAAM,qBAAqB,CAAC;AAOnH,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;;OAUG;IACH,GAAG,CAAC,EAAE,eAAe,CAAC;IAEtB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAE/B,iEAAiE;IACjE,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAElD,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC5C;0EACsE;IACtE,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B,oEAAoE;IACpE,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAEjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAE5B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAElC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,+EAA+E;IAC/E,eAAe,CAAC,EAAE,SAAS,CAAC;IAE5B;gEAC4D;IAC5D,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB,mGAAmG;IACnG,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;iFAE6E;IAC7E,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAElC,uFAAuF;IACvF,WAAW,CAAC,EAAE,eAAe,CAAC;IAE9B,sEAAsE;IACtE,SAAS,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAAC;IAEzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,+BAQ5C"}
|
|
@@ -1,66 +1,156 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef } from 'react';
|
|
3
|
+
import { allowAllGate, deriveSideNavDomains, } from 'cursedbelt-core/navigation';
|
|
2
4
|
import { useKeyboardInset } from '../hooks/useKeyboardInset.js';
|
|
3
5
|
import { cn } from '../lib/cn.js';
|
|
6
|
+
import { devWarnOnce } from '../lib/devWarn.js';
|
|
4
7
|
import { CommandBar } from '../nav/CommandBar.js';
|
|
8
|
+
import { isDomainActive, renderIcon, routeClick } from '../nav/navShared.js';
|
|
5
9
|
import { PlaceBar } from '../nav/PlaceBar.js';
|
|
6
10
|
import { SideNav } from '../nav/SideNav.js';
|
|
11
|
+
import { TopBarPlaces } from '../nav/TopBar.js';
|
|
12
|
+
import { CommandPalette } from '../palette/CommandPalette.js';
|
|
13
|
+
import { CommandSourceProvider, useCommandSources } from '../palette/commandSources.js';
|
|
14
|
+
import { useCommandPalette } from '../palette/useCommandPalette.js';
|
|
7
15
|
import { AmbientBackdrop } from './AmbientBackdrop.js';
|
|
16
|
+
import { BannerLane } from './BannerLane.js';
|
|
8
17
|
import { ScrollArea } from './ScrollArea.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
/** NAV-3's line: up to this many places ride a labeled top bar; past it, a sectioned sidebar. */
|
|
19
|
+
const TOP_BAR_MAX_PLACES = 5;
|
|
20
|
+
/** Past this many places, a sidebar with no sections is a wall (NAV-3: ≤7 items a section). */
|
|
21
|
+
const UNSECTIONED_MAX_PLACES = 7;
|
|
12
22
|
/**
|
|
13
|
-
* THE single application shell. One per app —
|
|
14
|
-
* (`
|
|
23
|
+
* THE single application shell. One per app — the frame every page sits in
|
|
24
|
+
* (`docs/design/shell-and-navigation.md`, NAV-1…NAV-14). The app passes ONE navigation
|
|
25
|
+
* model and the shell decides how to draw it, so no app can pick the wrong pattern:
|
|
15
26
|
*
|
|
16
|
-
* **
|
|
17
|
-
*
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* place-set in the thumb zone around a raised center capture FAB (mobile is
|
|
22
|
-
* capture-forward, not tab-forward — §7).
|
|
23
|
-
* - The buried, invisible ⌘K palette + no capture → the first-class **`CommandBar`
|
|
24
|
-
* spine**: a visible command/search field (the co-equal second way to move) + a
|
|
25
|
-
* capture hero (universal capture, §8.2).
|
|
26
|
-
* - The avatar-in-nav → **account chrome** behind the avatar in the spine (not a door).
|
|
27
|
+
* - **2–5 places** → their labels in the header's center zone (NAV-2: destinations have
|
|
28
|
+
* words from 768px up), every place in the `PlaceBar` on a phone.
|
|
29
|
+
* - **6+ places** → a 240px `SideNav` in labeled sections at ≥1024px, the 64px icon rail
|
|
30
|
+
* at 768–1023px, the `PlaceBar` with the top 4 + More on a phone, and a ⌘K
|
|
31
|
+
* `CommandPalette` preloaded with every place (NAV-9).
|
|
27
32
|
*
|
|
28
|
-
*
|
|
29
|
-
* coverage test
|
|
30
|
-
*
|
|
33
|
+
* Kept from the shell before it (owner teardowns 2026-07-15, the UX north-star): the single
|
|
34
|
+
* `navigationModel` registry and its coverage test, per-user place prefs, badges, universal
|
|
35
|
+
* capture (the spine's hero on desktop, the `PlaceBar` FAB on a phone), and the
|
|
36
|
+
* keyboard-safe single `ScrollArea`. No hamburger drawer, ever.
|
|
31
37
|
*
|
|
32
38
|
* Layout model:
|
|
33
39
|
* ```
|
|
34
40
|
* <div h-dvh flex flex-col overflow-hidden> ← dvh excludes the mobile URL bar
|
|
35
|
-
* <header
|
|
36
|
-
* <
|
|
37
|
-
*
|
|
41
|
+
* <header h-[--header-h]> ← left: brand · center: places or ⌘K field · right: account
|
|
42
|
+
* <BannerLane /> ← NAV-10, only when there is a banner
|
|
43
|
+
* <div flex min-h-0 grow> ← sidebar + content row
|
|
44
|
+
* <aside md:flex lg:hidden w-16 /> ← 6+ places: the icon rail
|
|
45
|
+
* <aside lg:flex w-60 /> ← 6+ places: the sectioned SideNav
|
|
38
46
|
* <main><ScrollArea>{children}</ScrollArea></main> ← THE ONLY page scroll container
|
|
39
47
|
* </div>
|
|
40
48
|
* <div pb-[safe-area]> ← bottomDock + mobile PlaceBar
|
|
41
|
-
* {bottomDock}
|
|
42
|
-
* <PlaceBar md:hidden /> ← capture-forward bottom bar
|
|
43
|
-
* </div>
|
|
44
49
|
* </div>
|
|
45
50
|
* ```
|
|
46
51
|
*
|
|
47
52
|
* Keyboard model: `useKeyboardInset` (installed exactly once, here) writes
|
|
48
53
|
* `--keyboard-inset` onto `<html>`; `ScrollArea` reads it via CSS `calc()`.
|
|
49
54
|
*/
|
|
50
|
-
export function AppShell(
|
|
55
|
+
export function AppShell(props) {
|
|
56
|
+
// The provider sits ABOVE the shell, so a page anywhere in `children` can contribute to the
|
|
57
|
+
// palette the shell mounts, and the shell can read what they contributed.
|
|
58
|
+
return (_jsx(CommandSourceProvider, { children: _jsx(Shell, { ...props }) }));
|
|
59
|
+
}
|
|
60
|
+
function Shell({ children, nav, navGate = allowAllGate, activeHref, onNavigate, navLinkComponent, resolveIcon, navPrefs, onNavPrefsChange, navBadges, navBadgeTone, navHeader, navFooter, banners, density, commandPalette = 'auto', onCapture, captureLabel, onOpenCommand, commandLabel, commandHint, commandBarExtra, account, bottomDock, palette, placeBarMax = 5, placeBarLabels = 'active', scrollSpace = 'default', scrollRef, ambient, className, }) {
|
|
51
61
|
useKeyboardInset();
|
|
52
|
-
const
|
|
62
|
+
const places = nav ? deriveSideNavDomains(nav, navGate) : [];
|
|
63
|
+
const pattern = !nav ? 'none' : places.length <= TOP_BAR_MAX_PLACES ? 'top' : 'side';
|
|
64
|
+
if (pattern === 'side' && places.length > UNSECTIONED_MAX_PLACES && !places.some((d) => d.section)) {
|
|
65
|
+
devWarnOnce('AppShell:unsectioned', `cursedbelt: <AppShell> was given ${places.length} places and no sections. NAV-3 wants 2–5 labeled sections ` +
|
|
66
|
+
'of ≤7 places each — give each NavDomain a `section` ("Operate", "Insight", "Limits", "Records").');
|
|
67
|
+
}
|
|
68
|
+
// NAV-9: the shell's own palette, unless the app renders one.
|
|
69
|
+
const ownPalette = !palette && Boolean(nav) && (commandPalette === 'auto' ? pattern === 'side' : commandPalette);
|
|
70
|
+
const paletteControls = useCommandPalette({ enabled: ownPalette });
|
|
71
|
+
const sources = useCommandSources();
|
|
72
|
+
const openCommand = onOpenCommand ?? (ownPalette ? paletteControls.toggle : undefined);
|
|
73
|
+
const navigate = (path) => {
|
|
74
|
+
if (onNavigate)
|
|
75
|
+
onNavigate(path);
|
|
76
|
+
else
|
|
77
|
+
window.location.assign(path);
|
|
78
|
+
};
|
|
79
|
+
const showSpine = Boolean(nav || navHeader || account || openCommand || onCapture || commandBarExtra);
|
|
53
80
|
const showBottom = Boolean(bottomDock || nav);
|
|
81
|
+
const bottomChromeRef = usePublishedBottomChrome(showBottom);
|
|
54
82
|
// Chrome that lets the field through. The rails/spine keep their own directional
|
|
55
83
|
// border either way — only the FILL changes, so the layout is byte-identical and
|
|
56
84
|
// an app can flip `ambient` on and off without anything reflowing.
|
|
57
85
|
const chrome = ambient ? 'cb-glass-chrome' : 'bg-background';
|
|
58
|
-
|
|
86
|
+
const commandBar = (_jsx(CommandBar
|
|
87
|
+
// The search field is capped and centered: a 2000px-wide input reads as a form, not a
|
|
88
|
+
// header (Linear and GitHub cap theirs the same way).
|
|
89
|
+
, {
|
|
90
|
+
// The search field is capped and centered: a 2000px-wide input reads as a form, not a
|
|
91
|
+
// header (Linear and GitHub cap theirs the same way).
|
|
92
|
+
className: pattern === 'top' ? 'shrink-0' : 'min-w-0 max-w-2xl flex-1', compact: pattern === 'top', onCapture: onCapture, captureLabel: captureLabel,
|
|
93
|
+
// On mobile the PlaceBar FAB owns capture — don't duplicate it in the spine.
|
|
94
|
+
captureDesktopOnly: Boolean(nav), onOpenCommand: openCommand, commandPlaceholder: commandLabel, commandHint: commandHint, extra: commandBarExtra }));
|
|
95
|
+
const sideNavProps = {
|
|
96
|
+
model: nav,
|
|
97
|
+
gate: navGate,
|
|
98
|
+
activeHref,
|
|
99
|
+
onNavigate,
|
|
100
|
+
linkComponent: navLinkComponent,
|
|
101
|
+
resolveIcon,
|
|
102
|
+
prefs: navPrefs,
|
|
103
|
+
badges: navBadges,
|
|
104
|
+
badgeTone: navBadgeTone,
|
|
105
|
+
footer: navFooter,
|
|
106
|
+
};
|
|
107
|
+
return (_jsxs("div", { "data-cb-appshell": '', "data-cb-nav-pattern": pattern, className: cn('flex h-dvh flex-col overflow-hidden bg-background text-foreground',
|
|
59
108
|
// `isolation: isolate` is load-bearing, not decoration: the blobs blend with
|
|
60
109
|
// `mix-blend-mode: screen`, and without a stacking context here they would
|
|
61
110
|
// blend against whatever is painted behind the app instead of against it.
|
|
62
|
-
ambient && 'cb-ambient-host', className), children: [ambient ? (_jsx(AmbientBackdrop, { position: 'absolute', ...(ambient === true ? {} : ambient) })) : null, showSpine && (_jsxs("header", { "data-cb-appheader": '', className: cn('relative z-30 flex shrink-0 items-center gap-3 border-b border-border px-3
|
|
63
|
-
|
|
64
|
-
|
|
111
|
+
ambient && 'cb-ambient-host', className), children: [ambient ? (_jsx(AmbientBackdrop, { position: 'absolute', ...(ambient === true ? {} : ambient) })) : null, showSpine && (_jsxs("header", { "data-cb-appheader": '', "data-cb-density": density, className: cn('relative z-30 flex shrink-0 items-center gap-3 border-b border-border px-3 md:px-6', density === 'dense'
|
|
112
|
+
? 'h-[var(--header-h-dense)]'
|
|
113
|
+
: density === 'roomy'
|
|
114
|
+
? 'h-[var(--header-h-roomy)]'
|
|
115
|
+
: 'h-[var(--header-h)]', ambient && chrome), children: [_jsx("div", { "data-cb-header-zone": 'left', className: 'flex shrink-0 items-center', children: navHeader }), _jsx("div", { "data-cb-header-zone": 'center', className: 'flex h-full min-w-0 flex-1 items-center justify-center', children: pattern === 'top' ? (_jsx(TopBarPlaces
|
|
116
|
+
// Below 768px the PlaceBar carries every place (NAV-14), so the header doesn't.
|
|
117
|
+
, {
|
|
118
|
+
// Below 768px the PlaceBar carries every place (NAV-14), so the header doesn't.
|
|
119
|
+
phonePlaces: 'none', linkComponent: navLinkComponent, items: places.map((d) => ({
|
|
120
|
+
id: d.id,
|
|
121
|
+
label: d.label,
|
|
122
|
+
icon: renderIcon(resolveIcon, d.icon),
|
|
123
|
+
href: d.path,
|
|
124
|
+
active: isDomainActive(d, activeHref),
|
|
125
|
+
badge: navBadges?.[d.id],
|
|
126
|
+
badgeTone: navBadgeTone,
|
|
127
|
+
unavailable: d.hostLimit && d.hostLimit.navigable !== true ? d.hostLimit.reason : undefined,
|
|
128
|
+
linkProps: navLinkComponent ? undefined : { onClick: routeClick(d.path, onNavigate) },
|
|
129
|
+
})) })) : (commandBar) }), (pattern === 'top' || account) && (_jsxs("div", { "data-cb-header-zone": 'right', className: 'flex shrink-0 items-center gap-2', children: [pattern === 'top' ? commandBar : null, account && (_jsx("div", { "data-cb-account": '', className: 'shrink-0', children: account }))] }))] })), banners && banners.length > 0 ? _jsx(BannerLane, { banners: banners, className: cn(ambient && chrome) }) : null, _jsxs("div", { className: 'relative flex min-h-0 grow overflow-hidden', children: [pattern === 'side' && (_jsxs(_Fragment, { children: [_jsx("aside", { "data-cb-nav-rail": '', "data-cb-nav-collapsed": '', className: cn('hidden w-[var(--rail-w-collapsed)] border-r border-border md:flex md:shrink-0 md:flex-col lg:hidden', chrome), children: _jsx(SideNav, { ...sideNavProps, collapsed: true }) }), _jsx("aside", { "data-cb-nav-rail": '', className: cn('hidden w-[var(--rail-w)] border-r border-border lg:flex lg:shrink-0 lg:flex-col', chrome), children: _jsx(SideNav, { ...sideNavProps, onPrefsChange: onNavPrefsChange }) })] })), _jsx("main", { className: 'flex min-h-0 min-w-0 grow flex-col', children: _jsx(ScrollArea, { space: scrollSpace, scrollRef: scrollRef, children: children }) })] }), showBottom && (_jsxs("div", { ref: bottomChromeRef, className: 'shrink-0 pb-[env(safe-area-inset-bottom,0px)]', children: [bottomDock && _jsx("div", { className: 'border-t border-border', children: bottomDock }), nav && (_jsx(PlaceBar, { className: cn('border-t border-border md:hidden', ambient && chrome), model: nav, gate: navGate, activeHref: activeHref, onNavigate: onNavigate, linkComponent: navLinkComponent, resolveIcon: resolveIcon, badges: navBadges, badgeTone: navBadgeTone, onCapture: onCapture, captureLabel: captureLabel, max: placeBarMax, labels: placeBarLabels }))] })), palette, ownPalette && nav ? (_jsx(CommandPalette, { model: nav, gate: navGate, open: paletteControls.open, onOpenChange: paletteControls.setOpen, onNavigate: navigate, resolveIcon: resolveIcon, currentPath: activeHref, places: true, sources: sources })) : null] }));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Publishes the bottom chrome's height (dock + `PlaceBar` + safe area) as
|
|
133
|
+
* `--cb-bottom-chrome-h` on the root, so what floats over the page — the `Toaster`'s stack
|
|
134
|
+
* (OVL-9) — rises above the navigation instead of covering it. A `PlaceBar` hidden at `md` up
|
|
135
|
+
* measures 0, so the desktop stack drops back to the corner by itself.
|
|
136
|
+
*/
|
|
137
|
+
function usePublishedBottomChrome(shown) {
|
|
138
|
+
const ref = useRef(null);
|
|
139
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `shown` mounts or drops the element the ref points at.
|
|
140
|
+
useLayoutEffect(() => {
|
|
141
|
+
const el = ref.current;
|
|
142
|
+
const root = document.documentElement;
|
|
143
|
+
if (!el)
|
|
144
|
+
return;
|
|
145
|
+
const publish = () => root.style.setProperty('--cb-bottom-chrome-h', `${el.offsetHeight}px`);
|
|
146
|
+
publish();
|
|
147
|
+
const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(publish);
|
|
148
|
+
observer?.observe(el);
|
|
149
|
+
return () => {
|
|
150
|
+
observer?.disconnect();
|
|
151
|
+
root.style.removeProperty('--cb-bottom-chrome-h');
|
|
152
|
+
};
|
|
153
|
+
}, [shown]);
|
|
154
|
+
return ref;
|
|
65
155
|
}
|
|
66
156
|
//# sourceMappingURL=AppShell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.js","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"AppShell.js","sourceRoot":"","sources":["../../../src/react/components/AppShell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type SkeletonVariant } from './Skeleton.js';
|
|
2
3
|
export interface AsyncPanelProps {
|
|
3
4
|
loading?: boolean;
|
|
4
5
|
/** Anything truthy renders the degraded state; an Error's message is used. */
|
|
@@ -8,8 +9,23 @@ export interface AsyncPanelProps {
|
|
|
8
9
|
/** Copy for the empty state. */
|
|
9
10
|
emptyTitle?: ReactNode;
|
|
10
11
|
emptyDescription?: ReactNode;
|
|
11
|
-
/** Rows of skeleton to show while loading. Default 3. */
|
|
12
|
+
/** Rows (or tiles) of skeleton to show while loading. Default 3. */
|
|
12
13
|
skeletonRows?: number;
|
|
14
|
+
/**
|
|
15
|
+
* The SHAPE of the first-load skeleton (STA-1): `rows` for a list or table, `tiles` for a
|
|
16
|
+
* stat strip, `chart` for a chart frame at the chart's own height. Default `rows`.
|
|
17
|
+
*/
|
|
18
|
+
skeleton?: SkeletonVariant;
|
|
19
|
+
/**
|
|
20
|
+
* A refetch is in flight while the panel already shows data (STA-2). The data stays and a
|
|
21
|
+
* quiet "Updating…" replaces the freshness stamp — the panel never blanks to a skeleton on
|
|
22
|
+
* every poll. `loading` after the first content behaves the same way on its own.
|
|
23
|
+
*/
|
|
24
|
+
refreshing?: boolean;
|
|
25
|
+
/** When the shown data was fetched — rendered as "Updated 12s ago" (STA-2, STA-8). */
|
|
26
|
+
updatedAt?: number | Date | null;
|
|
27
|
+
/** Past this age the stamp turns amber and says so ("No update for 5m", STA-8). */
|
|
28
|
+
staleAfterMs?: number;
|
|
13
29
|
/**
|
|
14
30
|
* Names the failing section in its error message ("AWS cost is unavailable").
|
|
15
31
|
* Without it the reader gets "Something went wrong" on a page of twelve
|
|
@@ -20,6 +36,8 @@ export interface AsyncPanelProps {
|
|
|
20
36
|
onRetryAction?: ReactNode;
|
|
21
37
|
children: ReactNode;
|
|
22
38
|
}
|
|
39
|
+
/** "just now", "12s ago", "3m ago", "2h ago", "4d ago" — the freshness stamp's wording. */
|
|
40
|
+
export declare function ageLabel(ms: number): string;
|
|
23
41
|
/**
|
|
24
42
|
* The per-section error envelope: one panel's failure degrades that panel, never
|
|
25
43
|
* the page.
|
|
@@ -35,5 +53,5 @@ export interface AsyncPanelProps {
|
|
|
35
53
|
* query, a `{ok:false}` section), which is the common case. Wrap it in an
|
|
36
54
|
* `ErrorBoundary` as well if the child can also throw during render.
|
|
37
55
|
*/
|
|
38
|
-
export declare function AsyncPanel({ loading, error, empty, emptyTitle, emptyDescription, skeletonRows, label, onRetryAction, children, }: AsyncPanelProps): import("react").JSX.Element;
|
|
56
|
+
export declare function AsyncPanel({ loading, error, empty, emptyTitle, emptyDescription, skeletonRows, skeleton, refreshing, updatedAt, staleAfterMs, label, onRetryAction, children, }: AsyncPanelProps): import("react").JSX.Element;
|
|
39
57
|
//# sourceMappingURL=AsyncPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsyncPanel.d.ts","sourceRoot":"","sources":["../../../src/react/components/AsyncPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AsyncPanel.d.ts","sourceRoot":"","sources":["../../../src/react/components/AsyncPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,2FAA2F;AAC3F,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAS3C;AA6CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,KAAK,EACL,UAA8B,EAC9B,gBAAgB,EAChB,YAAgB,EAChB,QAAiB,EACjB,UAAkB,EAClB,SAAS,EACT,YAAY,EACZ,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE,eAAe,+BAiCjB"}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
3
|
import { Alert } from './Alert.js';
|
|
3
4
|
import { EmptyState } from './EmptyState.js';
|
|
4
|
-
import {
|
|
5
|
+
import { ContentSkeleton } from './Skeleton.js';
|
|
6
|
+
/** "just now", "12s ago", "3m ago", "2h ago", "4d ago" — the freshness stamp's wording. */
|
|
7
|
+
export function ageLabel(ms) {
|
|
8
|
+
if (!Number.isFinite(ms) || ms < 5_000)
|
|
9
|
+
return 'just now';
|
|
10
|
+
const s = Math.floor(ms / 1000);
|
|
11
|
+
if (s < 60)
|
|
12
|
+
return `${s}s ago`;
|
|
13
|
+
const m = Math.floor(s / 60);
|
|
14
|
+
if (m < 60)
|
|
15
|
+
return `${m}m ago`;
|
|
16
|
+
const h = Math.floor(m / 60);
|
|
17
|
+
if (h < 48)
|
|
18
|
+
return `${h}h ago`;
|
|
19
|
+
return `${Math.floor(h / 24)}d ago`;
|
|
20
|
+
}
|
|
21
|
+
/** Re-render on a slow tick so an age keeps reading true without a refetch. */
|
|
22
|
+
function useNow(active, everyMs = 10_000) {
|
|
23
|
+
const [now, setNow] = useState(() => Date.now());
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!active)
|
|
26
|
+
return;
|
|
27
|
+
const id = setInterval(() => setNow(Date.now()), everyMs);
|
|
28
|
+
return () => clearInterval(id);
|
|
29
|
+
}, [active, everyMs]);
|
|
30
|
+
return now;
|
|
31
|
+
}
|
|
32
|
+
function Freshness({ refreshing, updatedAt, staleAfterMs, }) {
|
|
33
|
+
const at = updatedAt == null ? null : typeof updatedAt === 'number' ? updatedAt : updatedAt.getTime();
|
|
34
|
+
const now = useNow(at != null);
|
|
35
|
+
if (!refreshing && at == null)
|
|
36
|
+
return null;
|
|
37
|
+
const age = at == null ? 0 : Math.max(0, now - at);
|
|
38
|
+
const stale = !refreshing && staleAfterMs != null && at != null && age > staleAfterMs;
|
|
39
|
+
return (_jsx("p", { "data-cb-freshness": refreshing ? 'updating' : stale ? 'stale' : 'fresh', "aria-live": 'polite', className: stale ? 'text-right text-xs tabular-nums text-warning' : 'text-right text-xs tabular-nums text-muted-foreground', children: refreshing ? 'Updating…' : stale ? `No update for ${ageLabel(age).replace(' ago', '')}` : `Updated ${ageLabel(age)}` }));
|
|
40
|
+
}
|
|
5
41
|
const messageOf = (error) => {
|
|
6
42
|
if (error instanceof Error)
|
|
7
43
|
return error.message;
|
|
@@ -26,15 +62,23 @@ const messageOf = (error) => {
|
|
|
26
62
|
* query, a `{ok:false}` section), which is the common case. Wrap it in an
|
|
27
63
|
* `ErrorBoundary` as well if the child can also throw during render.
|
|
28
64
|
*/
|
|
29
|
-
export function AsyncPanel({ loading, error, empty, emptyTitle = 'Nothing to show', emptyDescription, skeletonRows = 3, label, onRetryAction, children, }) {
|
|
30
|
-
|
|
31
|
-
|
|
65
|
+
export function AsyncPanel({ loading, error, empty, emptyTitle = 'Nothing to show', emptyDescription, skeletonRows = 3, skeleton = 'rows', refreshing = false, updatedAt, staleAfterMs, label, onRetryAction, children, }) {
|
|
66
|
+
// STA-2: once the panel has shown its content, a later `loading` is a REFRESH — the content
|
|
67
|
+
// stays on screen. Only the first load draws the skeleton.
|
|
68
|
+
const shownContent = useRef(false);
|
|
69
|
+
if (loading && !shownContent.current) {
|
|
70
|
+
return _jsx(ContentSkeleton, { variant: skeleton, count: skeletonRows });
|
|
71
|
+
}
|
|
32
72
|
if (error) {
|
|
33
73
|
return (_jsxs(Alert, { tone: 'warning', ...(onRetryAction ? { action: onRetryAction } : {}), children: [label ? `${label} is unavailable — ` : '', messageOf(error)] }));
|
|
34
74
|
}
|
|
35
75
|
if (empty) {
|
|
36
76
|
return (_jsx(EmptyState, { title: emptyTitle, ...(emptyDescription ? { description: emptyDescription } : {}), compact: true }));
|
|
37
77
|
}
|
|
38
|
-
|
|
78
|
+
shownContent.current = true;
|
|
79
|
+
const busy = refreshing || loading === true;
|
|
80
|
+
if (!busy && updatedAt == null)
|
|
81
|
+
return _jsx(_Fragment, { children: children });
|
|
82
|
+
return (_jsxs("div", { className: 'flex min-w-0 flex-col gap-2', "aria-busy": busy || undefined, children: [_jsx(Freshness, { refreshing: busy, updatedAt: updatedAt, staleAfterMs: staleAfterMs }), children] }));
|
|
39
83
|
}
|
|
40
84
|
//# sourceMappingURL=AsyncPanel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsyncPanel.js","sourceRoot":"","sources":["../../../src/react/components/AsyncPanel.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"AsyncPanel.js","sourceRoot":"","sources":["../../../src/react/components/AsyncPanel.tsx"],"names":[],"mappings":"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"}
|