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
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { afterEach, beforeAll, describe, expect, spyOn, test } from 'bun:test';
|
|
2
|
+
import { act, cleanup, fireEvent, render, waitFor } from '@testing-library/react';
|
|
3
|
+
import { AsyncPanel } from './AsyncPanel.js';
|
|
4
|
+
import { DataTable, preloadDataTableParts } from './DataTable/DataTable.js';
|
|
5
|
+
import type { ColDef } from './DataTable/types.js';
|
|
6
|
+
import { EmptyState } from './EmptyState.js';
|
|
7
|
+
import { LogViewer } from './LogViewer.js';
|
|
8
|
+
import { STATUS_ATTENTION_TONE } from './StatusPill.js';
|
|
9
|
+
import { StatTile } from './StatTile.js';
|
|
10
|
+
import { StatTileGrid } from './StatTileGrid.js';
|
|
11
|
+
|
|
12
|
+
// Task 2464's unit half — what happy-dom can decide, through the components alone (the pure
|
|
13
|
+
// helpers are specced beside them: `DataTable/numericColumn.spec.ts`, `charts/chartBox.spec.ts`,
|
|
14
|
+
// `StatTileGrid.spec.tsx`, `AsyncPanel.spec.tsx`). Layout (fit at 2560, chart resize, the log's
|
|
15
|
+
// follow pause) is measured in `e2e/data-display.spec.ts`.
|
|
16
|
+
|
|
17
|
+
beforeAll(preloadDataTableParts);
|
|
18
|
+
afterEach(cleanup);
|
|
19
|
+
|
|
20
|
+
interface Row extends Record<string, unknown> {
|
|
21
|
+
step: string;
|
|
22
|
+
runs: number;
|
|
23
|
+
code: string;
|
|
24
|
+
}
|
|
25
|
+
const ROWS: Row[] = [
|
|
26
|
+
{ step: 'gate', runs: 2472, code: '41' },
|
|
27
|
+
{ step: 'prove-red', runs: 531, code: '7' },
|
|
28
|
+
];
|
|
29
|
+
const COLUMNS: ColDef<Row>[] = [
|
|
30
|
+
{ key: 'step', label: 'Step', type: 'text' },
|
|
31
|
+
{ key: 'runs', label: 'Runs', type: 'number' },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
describe('DAT-1 · numeric columns', () => {
|
|
35
|
+
test('numeric header and cells stack digits; the warning fires once in dev', () => {
|
|
36
|
+
const warn = spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
37
|
+
const { container } = render(
|
|
38
|
+
<DataTable<Row> columns={[...COLUMNS, { key: 'code', label: 'Code', type: 'text' }]} data={ROWS} hidePagination />,
|
|
39
|
+
);
|
|
40
|
+
const th = [...container.querySelectorAll('thead th')].find((n) => n.textContent?.includes('Runs'));
|
|
41
|
+
expect(th?.className).toContain('tabular-nums');
|
|
42
|
+
const cells = container.querySelectorAll('tbody tr:first-child td');
|
|
43
|
+
expect(cells[1]?.className).toContain('tabular-nums');
|
|
44
|
+
expect(cells[0]?.className).not.toContain('tabular-nums');
|
|
45
|
+
expect(warn.mock.calls.some(([m]) => String(m).includes('"code"'))).toBe(true);
|
|
46
|
+
warn.mockRestore();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('DAT-3 / DAT-5 · fit and the row action', () => {
|
|
51
|
+
test('`fit` marks the table and drops the full-width rule', () => {
|
|
52
|
+
const { container } = render(<DataTable<Row> columns={COLUMNS} data={ROWS} fit hidePagination />);
|
|
53
|
+
const table = container.querySelector('table');
|
|
54
|
+
expect(table?.getAttribute('data-cb-table-fit')).toBe('true');
|
|
55
|
+
expect(table?.className.split(' ')).not.toContain('w-full');
|
|
56
|
+
expect(table?.className).toContain('w-auto');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('one inline action where the row returns one, none where it returns null', () => {
|
|
60
|
+
const { container } = render(
|
|
61
|
+
<DataTable<Row>
|
|
62
|
+
columns={COLUMNS}
|
|
63
|
+
data={ROWS}
|
|
64
|
+
hidePagination
|
|
65
|
+
rowAction={(r) => (r.runs > 1000 ? { label: 'Retry', onClick: () => undefined } : null)}
|
|
66
|
+
/>,
|
|
67
|
+
);
|
|
68
|
+
const rows = container.querySelectorAll('tbody tr');
|
|
69
|
+
expect(rows[0]?.textContent).toContain('Retry');
|
|
70
|
+
expect(rows[1]?.textContent).not.toContain('Retry');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('a right-click opens the row menu only where the row has one', () => {
|
|
74
|
+
const { container } = render(
|
|
75
|
+
<DataTable<Row> columns={COLUMNS} data={ROWS} hidePagination rowMenu={() => [{ key: 'o', label: 'Open', onClick: () => undefined }]} />,
|
|
76
|
+
);
|
|
77
|
+
const row = container.querySelector('tbody tr') as HTMLElement;
|
|
78
|
+
const event = new MouseEvent('contextmenu', { bubbles: true, cancelable: true });
|
|
79
|
+
act(() => {
|
|
80
|
+
row.dispatchEvent(event);
|
|
81
|
+
});
|
|
82
|
+
expect(event.defaultPrevented).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('STA-3 · filtered to nothing', () => {
|
|
87
|
+
test('EmptyState `onClearFilters` is the filtered variant with its own verb', () => {
|
|
88
|
+
let cleared = 0;
|
|
89
|
+
const { getByText, container } = render(<EmptyState onClearFilters={() => cleared++} />);
|
|
90
|
+
expect(getByText('No matches')).toBeDefined();
|
|
91
|
+
expect(container.querySelector('[data-cb-empty-state]')?.getAttribute('data-cb-empty-state')).toBe('filtered');
|
|
92
|
+
fireEvent.click(getByText('Clear filters'));
|
|
93
|
+
expect(cleared).toBe(1);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('a DataTable searched to nothing offers Clear filters, which brings the rows back', async () => {
|
|
97
|
+
const { container, getByText } = render(<DataTable<Row> columns={COLUMNS} data={ROWS} hidePagination />);
|
|
98
|
+
const input = container.querySelector('input') as HTMLInputElement;
|
|
99
|
+
fireEvent.change(input, { target: { value: 'zzz-nothing' } });
|
|
100
|
+
await waitFor(() => expect(getByText('Clear filters')).toBeDefined());
|
|
101
|
+
fireEvent.click(getByText('Clear filters'));
|
|
102
|
+
await waitFor(() => expect(container.querySelectorAll('tbody tr').length).toBe(2));
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('an empty dataset is NOT the filtered variant', () => {
|
|
106
|
+
const { container } = render(<DataTable<Row> columns={COLUMNS} data={[]} hidePagination />);
|
|
107
|
+
expect(container.textContent).toContain('No results');
|
|
108
|
+
expect(container.textContent).not.toContain('Clear filters');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('DAT-8 / DAT-9 · StatTile', () => {
|
|
113
|
+
test('one value size per grid — the longest value sets it for every tile', () => {
|
|
114
|
+
const { container } = render(
|
|
115
|
+
<StatTileGrid>
|
|
116
|
+
<StatTile label='a' value='21' />
|
|
117
|
+
<StatTile label='b' value='61h 20m' />
|
|
118
|
+
<StatTile label='c' value='Executing now' />
|
|
119
|
+
</StatTileGrid>,
|
|
120
|
+
);
|
|
121
|
+
const sizes = [...container.querySelectorAll('[data-cb-stat-size]')].map((n) => n.getAttribute('data-cb-stat-size'));
|
|
122
|
+
expect(sizes).toEqual(['sm', 'sm', 'sm']);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('a budget past its max reads as the real percentage, in the critical tone', () => {
|
|
126
|
+
const { container, getByText } = render(
|
|
127
|
+
<StatTile label='DO' value='1.11M' budget={{ used: 1.11, max: 1, verb: 'of the allowance', window: 'Oct' }} />,
|
|
128
|
+
);
|
|
129
|
+
expect(getByText('111% of the allowance')).toBeDefined();
|
|
130
|
+
expect(container.querySelector('[data-cb-stat-budget]')?.getAttribute('data-cb-stat-budget')).toBe('critical');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('STA-1 / STA-2 · AsyncPanel', () => {
|
|
135
|
+
test('first load is a skeleton of the content\'s shape', () => {
|
|
136
|
+
const { container } = render(
|
|
137
|
+
<AsyncPanel loading skeleton='tiles'>
|
|
138
|
+
<p>never</p>
|
|
139
|
+
</AsyncPanel>,
|
|
140
|
+
);
|
|
141
|
+
expect(container.querySelector('[data-cb-skeleton="tiles"]')).not.toBeNull();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('a refetch keeps the data on screen and says it is updating', () => {
|
|
145
|
+
const { getByText, rerender, container } = render(
|
|
146
|
+
<AsyncPanel updatedAt={Date.now() - 12_000}>
|
|
147
|
+
<p>the goods</p>
|
|
148
|
+
</AsyncPanel>,
|
|
149
|
+
);
|
|
150
|
+
expect(container.querySelector('[data-cb-freshness]')?.getAttribute('data-cb-freshness')).toBe('fresh');
|
|
151
|
+
rerender(
|
|
152
|
+
<AsyncPanel loading updatedAt={Date.now() - 12_000}>
|
|
153
|
+
<p>the goods</p>
|
|
154
|
+
</AsyncPanel>,
|
|
155
|
+
);
|
|
156
|
+
expect(getByText('the goods')).toBeDefined();
|
|
157
|
+
expect(getByText('Updating…')).toBeDefined();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('DAT-4 / DAT-13 · status and the log', () => {
|
|
162
|
+
test('the operator vocabulary of station and roms is rationed, not neutral', () => {
|
|
163
|
+
expect(STATUS_ATTENTION_TONE.interrupted).toBe('error');
|
|
164
|
+
expect(STATUS_ATTENTION_TONE['not-answering']).toBe('error');
|
|
165
|
+
expect(STATUS_ATTENTION_TONE.stale).toBe('warning');
|
|
166
|
+
expect(STATUS_ATTENTION_TONE.transcoding).toBe('success');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('a log with a stream draws the header strip and no empty toolbar row', () => {
|
|
170
|
+
const { container, getByText } = render(
|
|
171
|
+
<LogViewer text={'a\nb'} stream='Batch B1' age='3m' openFullLog={{ href: '#x' }} filterable={false} />,
|
|
172
|
+
);
|
|
173
|
+
expect(container.querySelector('[data-cb-log-header]')?.textContent).toContain('Batch B1');
|
|
174
|
+
expect(getByText(/Open full log/)).toBeDefined();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
2
2
|
import { type ComponentPropsWithoutRef, forwardRef, useEffect } from 'react';
|
|
3
3
|
import { cn } from '../lib/cn.js';
|
|
4
|
+
import { CardFrameContext } from './cardFrame.js';
|
|
4
5
|
import { useFloatingContainer } from '../lib/floatingContainer.js';
|
|
5
6
|
import { noteDialogOpen } from '../lib/openDialogs.js';
|
|
6
7
|
|
|
@@ -115,7 +116,9 @@ export const DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
|
115
116
|
{...props}
|
|
116
117
|
>
|
|
117
118
|
<CountsAsOpen />
|
|
118
|
-
{
|
|
119
|
+
{/* A dialog floats: what it holds starts a fresh stack of container levels, even
|
|
120
|
+
when it was opened from inside a card (React context crosses the portal). */}
|
|
121
|
+
<CardFrameContext.Provider value={false}>{children}</CardFrameContext.Provider>
|
|
119
122
|
</DialogPrimitive.Content>
|
|
120
123
|
</DialogPortal>
|
|
121
124
|
);
|
|
@@ -84,9 +84,9 @@ export function WidgetFrame({
|
|
|
84
84
|
</>
|
|
85
85
|
}
|
|
86
86
|
className={cn(
|
|
87
|
-
'dashboard-drag-handle h-auto min-h-
|
|
87
|
+
'dashboard-drag-handle h-auto min-h-11 cursor-grab select-none active:cursor-grabbing',
|
|
88
88
|
onKeyDown !== undefined &&
|
|
89
|
-
'focus-visible:outline focus-visible:outline-2 focus-visible
|
|
89
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring',
|
|
90
90
|
)}
|
|
91
91
|
{...(onKeyDown !== undefined && {
|
|
92
92
|
tabIndex: 0,
|
|
@@ -673,6 +673,55 @@ describe('where you are', () => {
|
|
|
673
673
|
view.rerender(<FileTree nodes={TREE} selectedId='dinos' onSelect={() => undefined} />);
|
|
674
674
|
expect(scrolled).toEqual([]);
|
|
675
675
|
});
|
|
676
|
+
|
|
677
|
+
test('a changed revealKey reveals the SAME selection again; an unchanged one does not', () => {
|
|
678
|
+
const scrolled: string[] = [];
|
|
679
|
+
const props = { nodes: TREE, onSelect: () => undefined, selectedId: 'dinos' };
|
|
680
|
+
const view = render(<FileTree {...props} revealKey={0} />);
|
|
681
|
+
for (const row of screen.getAllByRole('treeitem') as HTMLElement[]) {
|
|
682
|
+
row.scrollIntoView = () => scrolled.push((row.textContent ?? '').trim());
|
|
683
|
+
row.getBoundingClientRect = () => ({ top: 900, bottom: 920 }) as DOMRect;
|
|
684
|
+
}
|
|
685
|
+
(view.container.querySelector('.cbft-scroll') as HTMLElement).getBoundingClientRect = () =>
|
|
686
|
+
({ top: 0, bottom: 400 }) as DOMRect;
|
|
687
|
+
view.rerender(<FileTree {...props} revealKey={0} />);
|
|
688
|
+
expect(scrolled).toEqual([]);
|
|
689
|
+
view.rerender(<FileTree {...props} revealKey={1} />);
|
|
690
|
+
expect(scrolled).toEqual(['Dinos']);
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
test('🔴 under scroll="host" the HOST scroller is the frame, not the tree drawn at full height', () => {
|
|
694
|
+
// music's rail: the tree is laid out at its natural height inside the rail's scroller, so
|
|
695
|
+
// its own frame holds every row and measuring against it never scrolled a revealed row
|
|
696
|
+
// into view (owner, 2026-10-01: "the file tree does not open to it").
|
|
697
|
+
const scrolled: string[] = [];
|
|
698
|
+
const host = document.createElement('div');
|
|
699
|
+
host.style.overflowY = 'auto';
|
|
700
|
+
document.body.append(host);
|
|
701
|
+
host.getBoundingClientRect = () => ({ top: 0, bottom: 400 }) as DOMRect;
|
|
702
|
+
const props = { nodes: TREE, onSelect: () => undefined, scroll: 'host' as const };
|
|
703
|
+
const view = render(<FileTree {...props} selectedId={null} />, { container: host });
|
|
704
|
+
try {
|
|
705
|
+
// The tree's own box spans every row — exactly what made the old check a no-op.
|
|
706
|
+
(host.querySelector('.cbft-scroll') as HTMLElement).getBoundingClientRect = () =>
|
|
707
|
+
({ top: 0, bottom: 2000 }) as DOMRect;
|
|
708
|
+
for (const row of screen.getAllByRole('treeitem') as HTMLElement[]) {
|
|
709
|
+
row.scrollIntoView = () => scrolled.push((row.textContent ?? '').trim());
|
|
710
|
+
row.getBoundingClientRect = () => ({ top: 900, bottom: 920 }) as DOMRect;
|
|
711
|
+
}
|
|
712
|
+
view.rerender(<FileTree {...props} selectedId='dinos' />);
|
|
713
|
+
expect(scrolled).toEqual(['Dinos']);
|
|
714
|
+
|
|
715
|
+
// …and a row the host already shows still does not jump.
|
|
716
|
+
for (const row of screen.getAllByRole('treeitem') as HTMLElement[])
|
|
717
|
+
row.getBoundingClientRect = () => ({ top: 10, bottom: 32 }) as DOMRect;
|
|
718
|
+
view.rerender(<FileTree {...props} selectedId='simpsons' />);
|
|
719
|
+
expect(scrolled).toEqual(['Dinos']);
|
|
720
|
+
} finally {
|
|
721
|
+
view.unmount();
|
|
722
|
+
host.remove();
|
|
723
|
+
}
|
|
724
|
+
});
|
|
676
725
|
});
|
|
677
726
|
|
|
678
727
|
/**
|
|
@@ -365,6 +365,13 @@ export interface FileTreeProps {
|
|
|
365
365
|
* Wire it to whatever decides the fetch plan, never to the stored collapse.
|
|
366
366
|
*/
|
|
367
367
|
onRevealExpand?: (ids: readonly string[]) => void;
|
|
368
|
+
/**
|
|
369
|
+
* Change it to reveal the selection AGAIN — VS Code's *Reveal in Explorer* on the file that
|
|
370
|
+
* is already selected. The reveal otherwise fires once per {@link selectedId}, so a "show me
|
|
371
|
+
* where it is" button pressed after the reader scrolled away or shut its folder did nothing.
|
|
372
|
+
* Any value; only a change counts. Omit it and nothing differs.
|
|
373
|
+
*/
|
|
374
|
+
revealKey?: unknown;
|
|
368
375
|
|
|
369
376
|
/**
|
|
370
377
|
* The rows kept in a section of their own ABOVE the folders — *"pin open files where they
|
|
@@ -809,6 +816,7 @@ export function FileTree({
|
|
|
809
816
|
onCollapsedChange,
|
|
810
817
|
expandOnReveal = false,
|
|
811
818
|
onRevealExpand,
|
|
819
|
+
revealKey,
|
|
812
820
|
pinnedIds,
|
|
813
821
|
onPinnedChange,
|
|
814
822
|
pinnedLabel = 'Pinned',
|
|
@@ -1327,7 +1335,9 @@ export function FileTree({
|
|
|
1327
1335
|
announceReveal.current = onRevealExpand;
|
|
1328
1336
|
}, [revealShut, onRevealExpand]);
|
|
1329
1337
|
/** The selection an expanding reveal has already fired for — see limit 1 below. */
|
|
1330
|
-
const revealedFor = useRef<string | null>(null);
|
|
1338
|
+
const revealedFor = useRef<string | null | undefined>(null);
|
|
1339
|
+
/** The {@link FileTreeProps.revealKey} last honoured — a change re-arms `revealedFor`. */
|
|
1340
|
+
const revealedKey = useRef(revealKey);
|
|
1331
1341
|
|
|
1332
1342
|
/**
|
|
1333
1343
|
* Bring the selected row into view — the explorer's *reveal*.
|
|
@@ -1384,10 +1394,14 @@ export function FileTree({
|
|
|
1384
1394
|
* expansion returns without scrolling and the re-render it causes is what lands the scroll.
|
|
1385
1395
|
* What it must NOT be is the trigger for expanding again — that is `revealedFor`, below.
|
|
1386
1396
|
*/
|
|
1387
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: `selectedId`
|
|
1397
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: `selectedId` and `revealKey` are the triggers; `drag` is a guard and not a trigger; `revealOpened` is the second pass — see just above.
|
|
1388
1398
|
useEffect(() => {
|
|
1389
1399
|
const scroller = scrollRef.current;
|
|
1390
1400
|
if (!scroller || drag?.active) return;
|
|
1401
|
+
if (revealedKey.current !== revealKey) {
|
|
1402
|
+
revealedKey.current = revealKey;
|
|
1403
|
+
revealedFor.current = undefined;
|
|
1404
|
+
}
|
|
1391
1405
|
/*
|
|
1392
1406
|
* Once per selection, whatever it finds — the ref moves even when there is nothing shut to
|
|
1393
1407
|
* open, so a later hand-shut of one of these folders cannot be undone by this effect.
|
|
@@ -1408,12 +1422,19 @@ export function FileTree({
|
|
|
1408
1422
|
scroller.querySelector<HTMLElement>('.cbft-row[data-holds-open]');
|
|
1409
1423
|
if (!row?.scrollIntoView) return;
|
|
1410
1424
|
const box = row.getBoundingClientRect();
|
|
1411
|
-
|
|
1425
|
+
/*
|
|
1426
|
+
* 🔴 Under `scroll='host'` the tree's own frame is NOT what clips it: it is drawn at full
|
|
1427
|
+
* height, so every row is always "inside" it and this check returned before scrolling —
|
|
1428
|
+
* a reveal in music's rail opened the folders and lit the row eight hundred pixels below
|
|
1429
|
+
* the fold (owner, 2026-10-01: *"the file tree does not open to it"*). The frame that
|
|
1430
|
+
* decides "already visible" is the host's scroller.
|
|
1431
|
+
*/
|
|
1432
|
+
const frame = (scroll === 'host' ? hostScroller(scroller) : scroller).getBoundingClientRect();
|
|
1412
1433
|
if (box.top >= frame.top && box.bottom <= frame.bottom) return;
|
|
1413
1434
|
// `nearest` on both axes: the least movement that makes the row visible, and no sideways
|
|
1414
1435
|
// travel in a list that does not scroll sideways.
|
|
1415
1436
|
row.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
1416
|
-
}, [selectedId, revealOpened]);
|
|
1437
|
+
}, [selectedId, revealOpened, revealKey]);
|
|
1417
1438
|
|
|
1418
1439
|
// ── The drag ──────────────────────────────────────────────────────────────────────────
|
|
1419
1440
|
|
|
@@ -3249,3 +3270,15 @@ function nameOf(nodes: readonly FileTreeNode[], id: string): string {
|
|
|
3249
3270
|
}
|
|
3250
3271
|
return '';
|
|
3251
3272
|
}
|
|
3273
|
+
|
|
3274
|
+
/**
|
|
3275
|
+
* The element that actually clips a `scroll='host'` tree: its nearest ancestor that scrolls
|
|
3276
|
+
* vertically, or the document's scroller when nothing between here and the root does.
|
|
3277
|
+
*/
|
|
3278
|
+
function hostScroller(from: HTMLElement): Element {
|
|
3279
|
+
for (let node = from.parentElement; node; node = node.parentElement) {
|
|
3280
|
+
const overflow = getComputedStyle(node).overflowY;
|
|
3281
|
+
if (overflow === 'auto' || overflow === 'scroll' || overflow === 'overlay') return node;
|
|
3282
|
+
}
|
|
3283
|
+
return document.scrollingElement ?? document.documentElement;
|
|
3284
|
+
}
|
|
@@ -443,7 +443,7 @@ function FilterRailRow({
|
|
|
443
443
|
// Outlined rather than filled, so the row's own SELECTED paint stays readable
|
|
444
444
|
// underneath it — a row can be both the current one and the drop target.
|
|
445
445
|
item.dropActive &&
|
|
446
|
-
'outline outline-2 outline-dashed outline-offset-
|
|
446
|
+
'outline outline-2 outline-dashed -outline-offset-2 outline-accent bg-accent/10',
|
|
447
447
|
)}
|
|
448
448
|
// A collapsed rail has no room to indent, and a 14rem-wide column has no room to
|
|
449
449
|
// indent far — the step is deliberately small and it stops growing at depth 6, so a
|
package/src/react/icons.tsx
CHANGED
|
@@ -331,7 +331,7 @@ export function DynamicIcon({ token, iconMap, className }: DynamicIconProps) {
|
|
|
331
331
|
className={cn(
|
|
332
332
|
// guardrails-ignore micro-typography-floor: 0.6em is RELATIVE to the avatar box —
|
|
333
333
|
// it scales with the circle rather than sitting at a fixed sub-floor size.
|
|
334
|
-
'inline-flex shrink-0 items-center justify-center overflow-hidden text-[
|
|
334
|
+
'inline-flex shrink-0 items-center justify-center overflow-hidden text-[length:var(--text-glyph-relative)] font-semibold uppercase leading-none',
|
|
335
335
|
className,
|
|
336
336
|
)}
|
|
337
337
|
data-icon={token}
|
package/src/react/index.ts
CHANGED
|
@@ -116,6 +116,7 @@ export {
|
|
|
116
116
|
type AmbientIntensity,
|
|
117
117
|
} from './components/AmbientBackdrop.js';
|
|
118
118
|
export { AppShell, type AppShellProps } from './components/AppShell.js';
|
|
119
|
+
export { BannerLane, type BannerLaneProps, type ShellBanner } from './components/BannerLane.js';
|
|
119
120
|
export { AuthGate, type AuthGateProps, notifyUnauthorized } from './AuthGate.js';
|
|
120
121
|
export { AutocompleteField, type AutocompleteProps } from './components/Autocomplete.js';
|
|
121
122
|
export { AutoGrowTextarea, type AutoGrowTextareaProps } from './components/AutoGrowTextarea.js';
|
|
@@ -289,6 +290,7 @@ export {
|
|
|
289
290
|
type TableViewMode,
|
|
290
291
|
TableViewToggle,
|
|
291
292
|
type DataTableHandle,
|
|
293
|
+
type DataTableRowAction,
|
|
292
294
|
type DataTableRowProps,
|
|
293
295
|
type DataTableSelectAll,
|
|
294
296
|
type DataTableServerWindow,
|
|
@@ -463,10 +465,19 @@ export { OtpInput, type OtpInputProps } from './components/OtpInput.js';
|
|
|
463
465
|
export {
|
|
464
466
|
Page,
|
|
465
467
|
PageContainer,
|
|
468
|
+
type PageContainerProps,
|
|
466
469
|
PageHeader,
|
|
467
470
|
type PageHeaderProps,
|
|
471
|
+
type PageWidth,
|
|
468
472
|
ReadableColumn,
|
|
469
473
|
} from './components/Page.js';
|
|
474
|
+
export {
|
|
475
|
+
GuideRoute,
|
|
476
|
+
type GuideRouteProps,
|
|
477
|
+
GuideSection,
|
|
478
|
+
type GuideSectionProps,
|
|
479
|
+
} from './components/Guide.js';
|
|
480
|
+
export { PageGuideButton, type PageGuideButtonProps } from './components/PageGuideButton.js';
|
|
470
481
|
export { PathText, type PathTextProps } from './components/PathText.js';
|
|
471
482
|
export { TruncatedText, type TruncatedTextProps } from './components/TruncatedText.js';
|
|
472
483
|
export { UnstyledButton, type UnstyledButtonProps } from './components/UnstyledButton.js';
|
|
@@ -500,7 +511,7 @@ export {
|
|
|
500
511
|
} from './components/ResponsiveWorkbench.js';
|
|
501
512
|
export { RevealAction, type RevealActionProps } from './components/RevealAction.js';
|
|
502
513
|
export { REVEAL_ON_HOVER } from './components/revealOnHover.js';
|
|
503
|
-
export { ScrollArea, type ScrollAreaProps, type ScrollAreaSpace } from './components/ScrollArea.js';
|
|
514
|
+
export { ScrollArea, type ScrollAreaHeight, type ScrollAreaProps, type ScrollAreaSpace } from './components/ScrollArea.js';
|
|
504
515
|
export { ScrollToTopButton } from './components/ScrollToTopButton.js';
|
|
505
516
|
export {
|
|
506
517
|
SaveIndicator,
|
|
@@ -530,7 +541,15 @@ export {
|
|
|
530
541
|
type SelectGroup,
|
|
531
542
|
type SelectOption,
|
|
532
543
|
} from './components/SelectField.js';
|
|
533
|
-
export {
|
|
544
|
+
export {
|
|
545
|
+
ContentSkeleton,
|
|
546
|
+
Skeleton,
|
|
547
|
+
SkeletonChart,
|
|
548
|
+
SkeletonList,
|
|
549
|
+
type SkeletonListProps,
|
|
550
|
+
SkeletonTiles,
|
|
551
|
+
type SkeletonVariant,
|
|
552
|
+
} from './components/Skeleton.js';
|
|
534
553
|
export {
|
|
535
554
|
RangeSlider,
|
|
536
555
|
type RangeSliderProps,
|
|
@@ -578,7 +597,13 @@ export {
|
|
|
578
597
|
} from './components/SplitPane.js';
|
|
579
598
|
export { Sparkline, type SparklineProps } from './components/Sparkline.js';
|
|
580
599
|
export { StatStrip, type StatStripItem, type StatStripProps } from './components/StatStrip.js';
|
|
581
|
-
export {
|
|
600
|
+
export {
|
|
601
|
+
StatTile,
|
|
602
|
+
type StatTileBudget,
|
|
603
|
+
type StatTileProps,
|
|
604
|
+
type StatTileTone,
|
|
605
|
+
type StatValueSize,
|
|
606
|
+
} from './components/StatTile.js';
|
|
582
607
|
export {
|
|
583
608
|
ThresholdMeter,
|
|
584
609
|
type ThresholdMeterProps,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DropdownMenuAction, DropdownMenuItem } from '../components/DropdownMenu.js';
|
|
2
|
+
|
|
3
|
+
// Kept out of `DropdownMenu.tsx` so the `./react/dropdown-menu` subpath does not export it.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* OVL-7's order: the caller's sections (split at its dividers, then by `group`), and every
|
|
7
|
+
* destructive action pulled out into one last section, so "Delete" is never between "Rename"
|
|
8
|
+
* and "Duplicate" and never sits by accident under the pointer's resting place.
|
|
9
|
+
*/
|
|
10
|
+
export function arrangeMenuItems(items: readonly DropdownMenuItem[]): DropdownMenuAction[][] {
|
|
11
|
+
const sections: DropdownMenuAction[][] = [];
|
|
12
|
+
const destructive: DropdownMenuAction[] = [];
|
|
13
|
+
let run: DropdownMenuAction[] = [];
|
|
14
|
+
const flush = () => {
|
|
15
|
+
const byGroup = new Map<string, DropdownMenuAction[]>();
|
|
16
|
+
for (const item of run) {
|
|
17
|
+
const key = item.group ?? '';
|
|
18
|
+
const list = byGroup.get(key);
|
|
19
|
+
if (list) list.push(item);
|
|
20
|
+
else byGroup.set(key, [item]);
|
|
21
|
+
}
|
|
22
|
+
sections.push(...byGroup.values());
|
|
23
|
+
run = [];
|
|
24
|
+
};
|
|
25
|
+
for (const item of items) {
|
|
26
|
+
if (item.divider) flush();
|
|
27
|
+
else if (item.destructive) destructive.push(item);
|
|
28
|
+
else run.push(item);
|
|
29
|
+
}
|
|
30
|
+
flush();
|
|
31
|
+
if (destructive.length) sections.push(destructive);
|
|
32
|
+
return sections.filter((section) => section.length > 0);
|
|
33
|
+
}
|
|
@@ -23,7 +23,7 @@ function renderInline(nodes: InlineNode[], keyPrefix: string): ReactNode[] {
|
|
|
23
23
|
return <em key={key}>{renderInline(node.children, key)}</em>;
|
|
24
24
|
case 'code':
|
|
25
25
|
return (
|
|
26
|
-
<code key={key} className='rounded bg-black/10 px-1 py-0.5 font-mono text-[
|
|
26
|
+
<code key={key} className='rounded bg-black/10 px-1 py-0.5 font-mono text-[length:var(--text-code-inline)] dark:bg-white/10'>
|
|
27
27
|
{node.value}
|
|
28
28
|
</code>
|
|
29
29
|
);
|
|
@@ -67,7 +67,7 @@ function renderBlock(block: BlockNode, key: string): ReactNode {
|
|
|
67
67
|
<pre
|
|
68
68
|
// guardrails-ignore no-raw-overflow: horizontal-only scroll sized to the code
|
|
69
69
|
// block's own content, not a keyboard-aware vertical page region.
|
|
70
|
-
className='overflow-x-auto rounded-md bg-black/10 p-2 pr-9 font-mono text-[
|
|
70
|
+
className='overflow-x-auto rounded-md bg-black/10 p-2 pr-9 font-mono text-[length:var(--text-code-block)] leading-snug dark:bg-white/10'
|
|
71
71
|
>
|
|
72
72
|
<code>{block.code}</code>
|
|
73
73
|
</pre>
|
|
@@ -265,8 +265,8 @@ export function HoverScrubVideoThumb({
|
|
|
265
265
|
*/}
|
|
266
266
|
{!previewing && !posterFailed && video.posterUrl ? (
|
|
267
267
|
<span className='pointer-events-none absolute inset-0 flex items-center justify-center'>
|
|
268
|
-
<span className='flex size-9 items-center justify-center rounded-full bg-black/55 text-white shadow-sm backdrop-blur-
|
|
269
|
-
<Play aria-hidden className='size-4 translate-x-
|
|
268
|
+
<span className='flex size-9 items-center justify-center rounded-full bg-black/55 text-white shadow-sm backdrop-blur-xs'>
|
|
269
|
+
<Play aria-hidden className='size-4 translate-x-px' />
|
|
270
270
|
</span>
|
|
271
271
|
</span>
|
|
272
272
|
) : null}
|
|
@@ -173,7 +173,7 @@ export function VideoTrimmer({
|
|
|
173
173
|
<video
|
|
174
174
|
ref={videoRef}
|
|
175
175
|
src={src}
|
|
176
|
-
className='mx-auto max-h-[
|
|
176
|
+
className='mx-auto max-h-[var(--media-max-h)] w-full bg-black'
|
|
177
177
|
playsInline
|
|
178
178
|
preload='metadata'
|
|
179
179
|
crossOrigin='anonymous'
|
|
@@ -32,7 +32,11 @@
|
|
|
32
32
|
.cbgd-search {
|
|
33
33
|
margin-left: auto;
|
|
34
34
|
width: min(360px, 50%);
|
|
35
|
-
|
|
35
|
+
/* The order pills' 28px, so the header row is one control height (FND-4); the phone rule
|
|
36
|
+
* below raises both to 44px together. */
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
height: 28px;
|
|
39
|
+
padding: 0 12px;
|
|
36
40
|
border-radius: 18px;
|
|
37
41
|
border: 1px solid var(--border);
|
|
38
42
|
background: var(--muted);
|
|
@@ -116,7 +116,7 @@ export function NamespaceTargetCapsule({
|
|
|
116
116
|
data-testid="namespace-target-capsule"
|
|
117
117
|
>
|
|
118
118
|
<span aria-hidden className={cn('inline-block size-2.5 shrink-0 rounded-full', dot.className)} style={dot.style} />
|
|
119
|
-
<span className="max-w-
|
|
119
|
+
<span className="max-w-40 truncate">{selected?.label ?? 'General'}</span>
|
|
120
120
|
<ChevronDown className="size-3 shrink-0 opacity-60" />
|
|
121
121
|
</Button>
|
|
122
122
|
}
|
|
@@ -500,7 +500,7 @@ const Crumb = memo(function Crumb({
|
|
|
500
500
|
typeof node.label === 'string' ? (
|
|
501
501
|
<TruncatedText
|
|
502
502
|
as='span'
|
|
503
|
-
className={cn(isLeaf ? 'max-w-
|
|
503
|
+
className={cn(isLeaf ? 'max-w-80' : 'max-w-48', hideLabel && 'hidden')}
|
|
504
504
|
{...(isRoot ? { 'data-cb-crumb-rootlabel': '' } : {})}
|
|
505
505
|
>
|
|
506
506
|
{node.label}
|
|
@@ -520,7 +520,7 @@ const Crumb = memo(function Crumb({
|
|
|
520
520
|
<span
|
|
521
521
|
className={cn(
|
|
522
522
|
'inline-flex min-w-0 items-center [&>*]:min-w-0',
|
|
523
|
-
isLeaf ? 'max-w-
|
|
523
|
+
isLeaf ? 'max-w-80' : 'max-w-48',
|
|
524
524
|
hideLabel && 'hidden',
|
|
525
525
|
)}
|
|
526
526
|
>
|
|
@@ -30,6 +30,12 @@ export interface CommandBarProps {
|
|
|
30
30
|
* `PlaceBar` owns capture via its raised center FAB, so capture isn't duplicated.
|
|
31
31
|
*/
|
|
32
32
|
captureDesktopOnly?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The command trigger as a square ⌘K button instead of a field — for a header whose
|
|
35
|
+
* center zone holds the places (a 2–5-place `AppShell`), where the trigger sits in the
|
|
36
|
+
* locked right zone and must not compete with them for width.
|
|
37
|
+
*/
|
|
38
|
+
compact?: boolean;
|
|
33
39
|
className?: string;
|
|
34
40
|
}
|
|
35
41
|
|
|
@@ -52,6 +58,7 @@ export function CommandBar({
|
|
|
52
58
|
commandHint = '⌘K',
|
|
53
59
|
extra,
|
|
54
60
|
captureDesktopOnly = false,
|
|
61
|
+
compact = false,
|
|
55
62
|
className,
|
|
56
63
|
}: CommandBarProps) {
|
|
57
64
|
return (
|
|
@@ -63,6 +70,8 @@ export function CommandBar({
|
|
|
63
70
|
data-cb-command-trigger=''
|
|
64
71
|
onClick={onOpenCommand}
|
|
65
72
|
aria-keyshortcuts='Meta+K Control+K'
|
|
73
|
+
// The square trigger paints no words, so it is named by them.
|
|
74
|
+
aria-label={compact ? commandPlaceholder : undefined}
|
|
66
75
|
leftIcon={<Search className='size-4 shrink-0' aria-hidden='true' />}
|
|
67
76
|
className={cn(
|
|
68
77
|
'group h-10 min-w-0 flex-1 justify-start gap-2 rounded-lg border border-border bg-surface px-3 font-normal text-muted-foreground hover:border-foreground/20',
|
|
@@ -72,16 +81,18 @@ export function CommandBar({
|
|
|
72
81
|
// `pointer-coarse:min-w-11` alongside it: the collapsed `w-10` square is
|
|
73
82
|
// a mouse-fine 40px, short of the 44px touch floor on a coarse pointer
|
|
74
83
|
// (owner orch-host 390px teardown — measured 40×44).
|
|
75
|
-
|
|
84
|
+
compact
|
|
85
|
+
? 'w-10 flex-none justify-center px-0 pointer-coarse:min-w-11'
|
|
86
|
+
: 'max-sm:w-10 max-sm:flex-none max-sm:justify-center max-sm:px-0 pointer-coarse:min-w-11',
|
|
76
87
|
)}
|
|
77
88
|
>
|
|
78
89
|
{/* Below sm the field can be squeezed by spine meta (badges/pills) — a
|
|
79
90
|
truncated placeholder fragment ("S..") reads broken, so the text
|
|
80
91
|
yields entirely and the trigger collapses to the icon button above. */}
|
|
81
|
-
<span className='hidden min-w-0 flex-1 truncate text-left text-sm sm:inline'>
|
|
92
|
+
<span className={cn('hidden min-w-0 flex-1 truncate text-left text-sm', !compact && 'sm:inline')}>
|
|
82
93
|
{commandPlaceholder}
|
|
83
94
|
</span>
|
|
84
|
-
{commandHint != null && (
|
|
95
|
+
{commandHint != null && !compact && (
|
|
85
96
|
<kbd className='hidden shrink-0 items-center rounded border border-border bg-background px-1.5 py-0.5 font-sans text-xs text-muted-foreground sm:inline-flex'>
|
|
86
97
|
{commandHint}
|
|
87
98
|
</kbd>
|