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
|
@@ -11,7 +11,7 @@ import { Drawer } from '../components/Drawer.js';
|
|
|
11
11
|
import { IconButton } from '../components/IconButton.js';
|
|
12
12
|
import { cn } from '../lib/cn.js';
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
isDomainActive,
|
|
15
15
|
NAV_BADGE_TONE,
|
|
16
16
|
type NavBadgeTone,
|
|
17
17
|
NavLink,
|
|
@@ -168,9 +168,10 @@ export function PlaceBar({
|
|
|
168
168
|
onClick={() => setMoreOpen(true)}
|
|
169
169
|
className={cn(
|
|
170
170
|
'relative flex min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-md px-1 py-1.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
171
|
-
overflowActive ? 'text-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
171
|
+
overflowActive ? 'bg-accent/10 text-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
172
172
|
)}
|
|
173
173
|
>
|
|
174
|
+
{overflowActive && <ActiveBar />}
|
|
174
175
|
{/* Accent tints the icon only โ see the PlaceTab comment above (cbux-101). */}
|
|
175
176
|
<span
|
|
176
177
|
className='relative grid size-6 place-items-center [&_svg]:size-5'
|
|
@@ -244,11 +245,6 @@ export function PlaceBar({
|
|
|
244
245
|
);
|
|
245
246
|
}
|
|
246
247
|
|
|
247
|
-
/** A place is active when the route is its landing or lives within it (rail-consistent). */
|
|
248
|
-
function isDomainActive(domain: NavDomain, activeHref: string | undefined): boolean {
|
|
249
|
-
if (isPathWithin(domain.path, activeHref)) return true;
|
|
250
|
-
return domain.groups.some((g) => g.items.some((it) => isPathWithin(it.path, activeHref)));
|
|
251
|
-
}
|
|
252
248
|
|
|
253
249
|
interface PlaceTabProps extends NavNavigationProps {
|
|
254
250
|
place: NavDomain;
|
|
@@ -292,9 +288,12 @@ function PlaceTab({
|
|
|
292
288
|
ariaLabel={place.label}
|
|
293
289
|
className={cn(
|
|
294
290
|
'relative flex min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-md px-1 py-1.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
295
|
-
active ? 'text-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
291
|
+
active ? 'bg-accent/10 text-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
296
292
|
)}
|
|
297
293
|
>
|
|
294
|
+
{/* NAV-6 on a bottom bar: its leading edge is the top one, facing the page. With the
|
|
295
|
+
tint and the foreground caption that is three marks โ never color alone. */}
|
|
296
|
+
{active && <ActiveBar />}
|
|
298
297
|
{/* The accent only ever tints the icon (graphical, 3:1 floor โ axe doesn't
|
|
299
298
|
score it as text) โ never the label. `navAccent`/`--accent-solid` stays
|
|
300
299
|
saturated in both modes for white-on-solid-fill use; as real label text
|
|
@@ -333,3 +332,14 @@ function PlaceTab({
|
|
|
333
332
|
</NavLink>
|
|
334
333
|
);
|
|
335
334
|
}
|
|
335
|
+
|
|
336
|
+
/** The 3px accent bar across the top of the current tab (NAV-6). */
|
|
337
|
+
function ActiveBar() {
|
|
338
|
+
return (
|
|
339
|
+
<span
|
|
340
|
+
aria-hidden='true'
|
|
341
|
+
data-cb-active-indicator=''
|
|
342
|
+
className='absolute inset-x-3 top-0 h-[var(--indicator-w)] rounded-full bg-accent-solid'
|
|
343
|
+
/>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
@@ -2,10 +2,12 @@ import { Fragment, type ReactNode, Suspense, useState } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
allowAllGate,
|
|
4
4
|
CURRENT_NAV_PREFS_VERSION,
|
|
5
|
+
deriveDomainItems,
|
|
5
6
|
deriveSideNavDomains,
|
|
6
7
|
type GateFn,
|
|
7
8
|
type NavDomain,
|
|
8
9
|
type NavigationModel,
|
|
10
|
+
type NavItem,
|
|
9
11
|
type NavPreferences,
|
|
10
12
|
} from 'cursedbelt-core/navigation';
|
|
11
13
|
import { DisclosureButton } from '../components/DisclosureButton.js';
|
|
@@ -15,6 +17,7 @@ import { Tooltip } from '../components/Tooltip.js';
|
|
|
15
17
|
import type { DragItemApi } from '../hooks/dragShared.js';
|
|
16
18
|
import { cn } from '../lib/cn.js';
|
|
17
19
|
import {
|
|
20
|
+
isDomainActive,
|
|
18
21
|
isPathWithin,
|
|
19
22
|
NAV_BADGE_TONE,
|
|
20
23
|
type NavBadgeTone,
|
|
@@ -76,8 +79,18 @@ export interface SideNavProps extends NavNavigationProps {
|
|
|
76
79
|
badgeTone?: NavBadgeTone;
|
|
77
80
|
/** App slot above the list (logo / brand). */
|
|
78
81
|
header?: ReactNode;
|
|
79
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* App slot below the list โ the version, `BuildFreshness` and a Settings link (NAV-13). Set
|
|
84
|
+
* in 12px muted type, under a 1px rule; a tool has no marketing footer anywhere else. Not
|
|
85
|
+
* drawn in the `collapsed` icon rail, which is 64px wide.
|
|
86
|
+
*/
|
|
80
87
|
footer?: ReactNode;
|
|
88
|
+
/**
|
|
89
|
+
* Show the ACTIVE place's own items beneath it, each label aligned under the parent's label
|
|
90
|
+
* text (NAV-7) โ so a reader sees where they are inside a place without a second nav.
|
|
91
|
+
* Default `true`. Never in the icon rail, which has no labels to align to.
|
|
92
|
+
*/
|
|
93
|
+
expandActive?: boolean;
|
|
81
94
|
className?: string;
|
|
82
95
|
}
|
|
83
96
|
|
|
@@ -109,6 +122,7 @@ export function SideNav({
|
|
|
109
122
|
badgeTone = 'alert',
|
|
110
123
|
header,
|
|
111
124
|
footer,
|
|
125
|
+
expandActive = true,
|
|
112
126
|
className,
|
|
113
127
|
}: SideNavProps) {
|
|
114
128
|
const domains = deriveSideNavDomains(model, gate);
|
|
@@ -159,11 +173,18 @@ export function SideNav({
|
|
|
159
173
|
sections.sort((a, b) => Number(b.section === undefined) - Number(a.section === undefined));
|
|
160
174
|
}
|
|
161
175
|
|
|
162
|
-
const renderRow = (domain: NavDomain, drag?: DragItemApi): ReactNode =>
|
|
176
|
+
const renderRow = (domain: NavDomain, drag?: DragItemApi): ReactNode => {
|
|
177
|
+
const active = isDomainActive(domain, activeHref);
|
|
178
|
+
const children = active && expandActive && !collapsed ? deriveDomainItems(domain, gate) : [];
|
|
179
|
+
const activeChild = children.find((it) => isPathWithin(it.path, activeHref));
|
|
180
|
+
const row = (
|
|
163
181
|
<DomainRow
|
|
164
182
|
key={domain.id}
|
|
165
183
|
domain={domain}
|
|
166
|
-
active={
|
|
184
|
+
active={active}
|
|
185
|
+
// When a child is the current page, IT carries the bar and the tint; the place keeps
|
|
186
|
+
// its foreground label so the reader still sees which place they are inside.
|
|
187
|
+
activeIsChild={Boolean(activeChild)}
|
|
167
188
|
color={prefs?.colors?.[domain.id]}
|
|
168
189
|
badge={badges?.[domain.id]}
|
|
169
190
|
badgeTone={badgeTone}
|
|
@@ -179,11 +200,26 @@ export function SideNav({
|
|
|
179
200
|
}}
|
|
180
201
|
{...navProps}
|
|
181
202
|
/>
|
|
182
|
-
|
|
203
|
+
);
|
|
204
|
+
if (children.length === 0) return row;
|
|
205
|
+
return (
|
|
206
|
+
<Fragment key={domain.id}>
|
|
207
|
+
{row}
|
|
208
|
+
<ul data-cb-sidenav-children='' className='mt-0.5 space-y-0.5'>
|
|
209
|
+
{children.map((item) => (
|
|
210
|
+
<li key={item.id}>
|
|
211
|
+
<ChildRow item={item} active={item === activeChild} {...navProps} />
|
|
212
|
+
</li>
|
|
213
|
+
))}
|
|
214
|
+
</ul>
|
|
215
|
+
</Fragment>
|
|
216
|
+
);
|
|
217
|
+
};
|
|
183
218
|
|
|
184
219
|
return (
|
|
185
220
|
<nav
|
|
186
221
|
data-cb-sidenav=''
|
|
222
|
+
data-cb-nav-collapsed={collapsed ? '' : undefined}
|
|
187
223
|
aria-label='Primary'
|
|
188
224
|
className={cn('flex h-full flex-col', collapsed ? 'w-16' : 'w-full', className)}
|
|
189
225
|
>
|
|
@@ -256,8 +292,10 @@ export function SideNav({
|
|
|
256
292
|
)}
|
|
257
293
|
</ScrollArea>
|
|
258
294
|
|
|
259
|
-
{
|
|
260
|
-
|
|
295
|
+
{/* The footer is words in a 240px column (NAV-13); the 64px icon rail has no room for
|
|
296
|
+
them, so it leaves them to the expanded rail and Settings. */}
|
|
297
|
+
{((footer && !collapsed) || (canCustomize && hiddenDomains.length > 0)) && (
|
|
298
|
+
<div data-cb-sidenav-footer='' className='shrink-0 space-y-2 border-t border-border px-3 py-3 text-xs text-muted-foreground'>
|
|
261
299
|
{canCustomize && hiddenDomains.length > 0 && (
|
|
262
300
|
<Suspense fallback={null}>
|
|
263
301
|
<RestoreHiddenMenu
|
|
@@ -267,22 +305,19 @@ export function SideNav({
|
|
|
267
305
|
/>
|
|
268
306
|
</Suspense>
|
|
269
307
|
)}
|
|
270
|
-
{footer}
|
|
308
|
+
{collapsed ? null : footer}
|
|
271
309
|
</div>
|
|
272
310
|
)}
|
|
273
311
|
</nav>
|
|
274
312
|
);
|
|
275
313
|
}
|
|
276
314
|
|
|
277
|
-
/** A domain is active when the route is its landing or lives within it. */
|
|
278
|
-
function isDomainActive(domain: NavDomain, activeHref: string | undefined): boolean {
|
|
279
|
-
if (isPathWithin(domain.path, activeHref)) return true;
|
|
280
|
-
return domain.groups.some((g) => g.items.some((it) => isPathWithin(it.path, activeHref)));
|
|
281
|
-
}
|
|
282
315
|
|
|
283
316
|
interface DomainRowProps extends NavNavigationProps {
|
|
284
317
|
domain: NavDomain;
|
|
285
318
|
active: boolean;
|
|
319
|
+
/** The current page is one of this place's items, shown beneath it. */
|
|
320
|
+
activeIsChild?: boolean;
|
|
286
321
|
color?: string;
|
|
287
322
|
badge?: number | string;
|
|
288
323
|
badgeTone: NavBadgeTone;
|
|
@@ -296,6 +331,7 @@ interface DomainRowProps extends NavNavigationProps {
|
|
|
296
331
|
function DomainRow({
|
|
297
332
|
domain,
|
|
298
333
|
active,
|
|
334
|
+
activeIsChild = false,
|
|
299
335
|
color,
|
|
300
336
|
badge,
|
|
301
337
|
badgeTone,
|
|
@@ -327,7 +363,7 @@ function DomainRow({
|
|
|
327
363
|
linkComponent={linkComponent}
|
|
328
364
|
onNavigate={onNavigate}
|
|
329
365
|
onAfterNavigate={onAfterNavigate}
|
|
330
|
-
ariaCurrent={active ? 'page' : undefined}
|
|
366
|
+
ariaCurrent={active && !activeIsChild ? 'page' : undefined}
|
|
331
367
|
disabled={limited}
|
|
332
368
|
// When there IS a host limit the wrapper below carries the richer hint, so the
|
|
333
369
|
// link must not open a second, nested one.
|
|
@@ -345,7 +381,13 @@ function DomainRow({
|
|
|
345
381
|
collapsed
|
|
346
382
|
? `size-10 justify-center ${TAP_TARGET}`
|
|
347
383
|
: `w-full gap-3 px-3 py-2 ${TAP_TARGET_HEIGHT}`,
|
|
348
|
-
|
|
384
|
+
// NAV-6: the current place is marked three ways โ the bar below, this tint, and a
|
|
385
|
+
// foreground label against the muted ones around it. Color alone fails.
|
|
386
|
+
active && !activeIsChild
|
|
387
|
+
? 'bg-accent/10 text-foreground'
|
|
388
|
+
: active
|
|
389
|
+
? 'text-foreground hover:bg-muted'
|
|
390
|
+
: 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
349
391
|
)}
|
|
350
392
|
>
|
|
351
393
|
{/* Active accent bar โ colored by the per-row override or theme accent. The
|
|
@@ -359,12 +401,13 @@ function DomainRow({
|
|
|
359
401
|
caught a domain green at 2.67:1 on the dark-mode muted background);
|
|
360
402
|
the label stays on the guaranteed-contrast `text-foreground` token
|
|
361
403
|
regardless of which accent a domain picks. */}
|
|
362
|
-
{active && (
|
|
404
|
+
{active && !activeIsChild && (
|
|
363
405
|
<span
|
|
364
406
|
aria-hidden='true'
|
|
407
|
+
data-cb-active-indicator=''
|
|
365
408
|
className={cn(
|
|
366
|
-
'absolute left-0 rounded-full',
|
|
367
|
-
collapsed ? 'inset-y-1
|
|
409
|
+
'absolute left-0 w-[var(--indicator-w)] rounded-full',
|
|
410
|
+
collapsed ? 'inset-y-1' : 'inset-y-1.5',
|
|
368
411
|
)}
|
|
369
412
|
style={{ backgroundColor: accent }}
|
|
370
413
|
/>
|
|
@@ -432,3 +475,42 @@ function DomainRow({
|
|
|
432
475
|
</div>
|
|
433
476
|
);
|
|
434
477
|
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* One of the active place's items (NAV-7). Its label starts exactly under the parent's label:
|
|
481
|
+
* the parent row's `px-3` + its 20px icon + its `gap-3` is 44px, so the child's padding is 44px
|
|
482
|
+
* (`pl-11`) and its text lands on the same x. Marked like the place when it is the current page.
|
|
483
|
+
*/
|
|
484
|
+
function ChildRow({
|
|
485
|
+
item,
|
|
486
|
+
active,
|
|
487
|
+
linkComponent,
|
|
488
|
+
onNavigate,
|
|
489
|
+
onAfterNavigate,
|
|
490
|
+
}: NavNavigationProps & { item: NavItem; active: boolean }) {
|
|
491
|
+
return (
|
|
492
|
+
<NavLink
|
|
493
|
+
path={item.path}
|
|
494
|
+
linkComponent={linkComponent}
|
|
495
|
+
onNavigate={onNavigate}
|
|
496
|
+
onAfterNavigate={onAfterNavigate}
|
|
497
|
+
ariaCurrent={active ? 'page' : undefined}
|
|
498
|
+
className={cn(
|
|
499
|
+
'relative flex w-full items-center rounded-md py-1.5 pl-11 pr-3 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
500
|
+
TAP_TARGET_HEIGHT,
|
|
501
|
+
active ? 'bg-accent/10 font-medium text-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground',
|
|
502
|
+
)}
|
|
503
|
+
>
|
|
504
|
+
{active && (
|
|
505
|
+
<span
|
|
506
|
+
aria-hidden='true'
|
|
507
|
+
data-cb-active-indicator=''
|
|
508
|
+
className='absolute inset-y-1.5 left-0 w-[var(--indicator-w)] rounded-full bg-accent-solid'
|
|
509
|
+
/>
|
|
510
|
+
)}
|
|
511
|
+
<span data-cb-nav-child-label='' className='min-w-0 flex-1 truncate text-left'>
|
|
512
|
+
{item.label}
|
|
513
|
+
</span>
|
|
514
|
+
</NavLink>
|
|
515
|
+
);
|
|
516
|
+
}
|
|
@@ -13,34 +13,89 @@ const items: TopBarItem[] = [
|
|
|
13
13
|
|
|
14
14
|
const brand = { icon: <Glyph name='brand' />, label: 'Music', href: '/' };
|
|
15
15
|
|
|
16
|
-
describe('TopBar โ
|
|
17
|
-
test('๐ด an item paints its
|
|
16
|
+
describe('TopBar โ destinations have words (NAV-2, owner review 2026-10-01)', () => {
|
|
17
|
+
test('๐ด an item paints its icon AND its label from md up; the label is its accessible name', () => {
|
|
18
18
|
const { getByRole } = render(<TopBar brand={brand} items={items} />);
|
|
19
19
|
const link = getByRole('link', { name: 'Downloads' });
|
|
20
20
|
expect(link.querySelector('[data-glyph="downloads"]')).not.toBeNull();
|
|
21
|
-
|
|
22
|
-
expect(
|
|
21
|
+
const word = Array.from(link.querySelectorAll('span')).find((s) => s.textContent === 'Downloads');
|
|
22
|
+
expect(word?.className).toContain('hidden');
|
|
23
|
+
expect(word?.className).toContain('md:inline');
|
|
23
24
|
expect(link.getAttribute('href')).toBe('/downloads');
|
|
24
25
|
});
|
|
25
26
|
|
|
26
|
-
test('
|
|
27
|
+
test('a router nav is marked primary for the design audit; an iconOnly utility bar is not', () => {
|
|
28
|
+
const { container } = render(<TopBar brand={brand} items={items} />);
|
|
29
|
+
const nav = container.querySelector('[data-cb-topbar-nav]') as HTMLElement;
|
|
30
|
+
expect(nav.hasAttribute('data-cb-primary-nav')).toBe(true);
|
|
31
|
+
cleanup();
|
|
32
|
+
const utility = render(<TopBar brand={brand} items={items} iconOnly />);
|
|
33
|
+
const bar = utility.container.querySelector('[data-cb-topbar-nav]') as HTMLElement;
|
|
34
|
+
expect(bar.hasAttribute('data-cb-primary-nav')).toBe(false);
|
|
35
|
+
expect(bar.hasAttribute('data-cb-nav-utility')).toBe(true);
|
|
36
|
+
// A utility bar paints glyphs only, at every width.
|
|
37
|
+
expect(utility.getByRole('link', { name: 'Downloads' }).textContent).toBe('');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('๐ด the active place is marked three ways (NAV-6): bar, tint, foreground โ and aria-current', () => {
|
|
27
41
|
const { getByRole } = render(<TopBar brand={brand} items={items} />);
|
|
28
|
-
|
|
29
|
-
expect(
|
|
42
|
+
const active = getByRole('link', { name: 'Library' });
|
|
43
|
+
expect(active.getAttribute('aria-current')).toBe('page');
|
|
44
|
+
expect(active.querySelector('[data-cb-active-indicator]')).not.toBeNull();
|
|
45
|
+
expect(active.className).toContain('bg-accent/10');
|
|
46
|
+
expect(active.className).toContain('text-foreground');
|
|
47
|
+
const idle = getByRole('link', { name: 'Downloads' });
|
|
48
|
+
expect(idle.getAttribute('aria-current')).toBeNull();
|
|
49
|
+
expect(idle.querySelector('[data-cb-active-indicator]')).toBeNull();
|
|
50
|
+
expect(idle.className).toContain('text-muted-foreground');
|
|
30
51
|
});
|
|
31
52
|
|
|
32
|
-
test('
|
|
33
|
-
const
|
|
34
|
-
const { getByRole } = render(<TopBar brand={brand} items={
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
40
|
-
|
|
53
|
+
test('๐ด a count is never hidden: beside the word from md up, on the glyph\'s corner below, and in the name', () => {
|
|
54
|
+
const counted: TopBarItem[] = [items[0] as TopBarItem, { ...(items[1] as TopBarItem), badge: 1234 }];
|
|
55
|
+
const { getByRole } = render(<TopBar brand={brand} items={counted} />);
|
|
56
|
+
// Read as part of the name, so a screen reader hears the figure the eye sees.
|
|
57
|
+
const link = getByRole('link', { name: 'Downloads ยท 99+' });
|
|
58
|
+
const badge = link.querySelector('[data-cb-nav-badge]') as HTMLElement;
|
|
59
|
+
expect(badge.textContent).toBe('99+');
|
|
60
|
+
expect(badge.className).not.toContain('hidden');
|
|
61
|
+
expect(badge.className).toContain('max-md:absolute');
|
|
41
62
|
cleanup();
|
|
42
|
-
const
|
|
43
|
-
|
|
63
|
+
const utility = render(<TopBar brand={brand} items={counted} iconOnly />);
|
|
64
|
+
const corner = utility.getByRole('link', { name: 'Downloads ยท 99+' }).querySelector('[data-cb-nav-badge]') as HTMLElement;
|
|
65
|
+
expect(corner.className).toContain('absolute');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('header geometry (NAV-1): the --header-h token, a 1px bottom border, three zones', () => {
|
|
69
|
+
const { container } = render(<TopBar brand={brand} items={items} trailing={<span>x</span>} />);
|
|
70
|
+
const bar = container.querySelector('[data-cb-topbar]') as HTMLElement;
|
|
71
|
+
expect(bar.className).toContain('h-[var(--header-h)]');
|
|
72
|
+
expect(bar.className).toContain('border-b');
|
|
73
|
+
expect(bar.className).not.toContain('shadow');
|
|
74
|
+
const zones = Array.from(bar.children).map((z) => z.getAttribute('data-cb-topbar-zone'));
|
|
75
|
+
expect(zones).toEqual(['left', 'center', 'right']);
|
|
76
|
+
cleanup();
|
|
77
|
+
const dense = render(<TopBar brand={brand} items={items} density='dense' />);
|
|
78
|
+
expect((dense.container.querySelector('[data-cb-topbar]') as HTMLElement).className).toContain(
|
|
79
|
+
'h-[var(--header-h-dense)]',
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("phonePlaces='none' hands the places to a PlaceBar below md", () => {
|
|
84
|
+
const { container } = render(<TopBar brand={brand} items={items} phonePlaces='none' />);
|
|
85
|
+
expect((container.querySelector('[data-cb-topbar-nav]') as HTMLElement).className).toContain('max-md:hidden');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('six or more places warn in dev โ NAV-3 puts them in a sectioned SideNav', () => {
|
|
89
|
+
const warn = console.warn;
|
|
90
|
+
const said: string[] = [];
|
|
91
|
+
console.warn = (m: string) => said.push(m);
|
|
92
|
+
try {
|
|
93
|
+
const six = Array.from({ length: 6 }, (_, i) => ({ ...items[1], id: `p${i}`, href: `/p${i}` }));
|
|
94
|
+
render(<TopBar brand={{ ...brand, label: 'Six-place app' }} items={six} />);
|
|
95
|
+
} finally {
|
|
96
|
+
console.warn = warn;
|
|
97
|
+
}
|
|
98
|
+
expect(said.some((m) => m.includes('NAV-3'))).toBe(true);
|
|
44
99
|
});
|
|
45
100
|
|
|
46
101
|
test('๐ด the row cannot widen the page: clamped, and the places scroll inside themselves', () => {
|
|
@@ -55,15 +110,17 @@ describe('TopBar โ icons, not words (owner, 2026-09-25)', () => {
|
|
|
55
110
|
// Brand and trailing controls never shrink โ the account menu stays reachable.
|
|
56
111
|
const brandLink = container.querySelector('[data-cb-topbar-brand]') as HTMLElement;
|
|
57
112
|
expect(brandLink.className).toContain('shrink-0');
|
|
58
|
-
|
|
113
|
+
const right = container.querySelector('[data-cb-topbar-zone="right"]') as HTMLElement;
|
|
114
|
+
expect(right.querySelector('[data-trailing]')).not.toBeNull();
|
|
115
|
+
expect(right.className).toContain('shrink-0');
|
|
59
116
|
});
|
|
60
117
|
|
|
61
118
|
test('a leading control sits BEFORE the brand and never shrinks โ the phone sidebar button', () => {
|
|
62
119
|
const { container } = render(
|
|
63
120
|
<TopBar brand={brand} items={items} leading={<span data-leading=''>โฐ</span>} />,
|
|
64
121
|
);
|
|
65
|
-
const
|
|
66
|
-
const first =
|
|
122
|
+
const left = container.querySelector('[data-cb-topbar-zone="left"]') as HTMLElement;
|
|
123
|
+
const first = left.firstElementChild as HTMLElement;
|
|
67
124
|
expect(first.querySelector('[data-leading]')).not.toBeNull();
|
|
68
125
|
expect(first.className).toContain('shrink-0');
|
|
69
126
|
expect(first.nextElementSibling?.hasAttribute('data-cb-topbar-brand')).toBe(true);
|