cursedbelt 5.40.0 → 5.45.1
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/canvas-hud/CanvasMinimap.d.ts +32 -0
- package/dist/react/canvas-hud/CanvasMinimap.d.ts.map +1 -0
- package/dist/react/canvas-hud/CanvasMinimap.js +32 -0
- package/dist/react/canvas-hud/CanvasMinimap.js.map +1 -0
- package/dist/react/canvas-hud/CanvasNodeMenu.d.ts +34 -0
- package/dist/react/canvas-hud/CanvasNodeMenu.d.ts.map +1 -0
- package/dist/react/canvas-hud/CanvasNodeMenu.js +21 -0
- package/dist/react/canvas-hud/CanvasNodeMenu.js.map +1 -0
- package/dist/react/canvas-hud/CanvasSearchField.d.ts +27 -0
- package/dist/react/canvas-hud/CanvasSearchField.d.ts.map +1 -0
- package/dist/react/canvas-hud/CanvasSearchField.js +35 -0
- package/dist/react/canvas-hud/CanvasSearchField.js.map +1 -0
- package/dist/react/canvas-hud/HudControls.d.ts +43 -0
- package/dist/react/canvas-hud/HudControls.d.ts.map +1 -0
- package/dist/react/canvas-hud/HudControls.js +22 -0
- package/dist/react/canvas-hud/HudControls.js.map +1 -0
- package/dist/react/canvas-hud/index.d.ts +13 -0
- package/dist/react/canvas-hud/index.d.ts.map +1 -0
- package/dist/react/canvas-hud/index.js +7 -0
- package/dist/react/canvas-hud/index.js.map +1 -0
- package/dist/react/canvas-hud/useCanvasWheel.d.ts +41 -0
- package/dist/react/canvas-hud/useCanvasWheel.d.ts.map +1 -0
- package/dist/react/canvas-hud/useCanvasWheel.js +65 -0
- package/dist/react/canvas-hud/useCanvasWheel.js.map +1 -0
- package/dist/react/canvas-hud/viewport.d.ts +68 -0
- package/dist/react/canvas-hud/viewport.d.ts.map +1 -0
- package/dist/react/canvas-hud/viewport.js +77 -0
- package/dist/react/canvas-hud/viewport.js.map +1 -0
- 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 +141 -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 +50 -6
- 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/Checkbox.d.ts.map +1 -1
- package/dist/react/components/Checkbox.js +7 -2
- package/dist/react/components/Checkbox.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/Field.d.ts.map +1 -1
- package/dist/react/components/Field.js +4 -1
- package/dist/react/components/Field.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 +52 -0
- package/dist/react/components/PageGuideButton.js.map +1 -0
- package/dist/react/components/PageGuidePopover.d.ts +14 -0
- package/dist/react/components/PageGuidePopover.d.ts.map +1 -0
- package/dist/react/components/PageGuidePopover.js +25 -0
- package/dist/react/components/PageGuidePopover.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/TagsInput.d.ts.map +1 -1
- package/dist/react/components/TagsInput.js +3 -1
- package/dist/react/components/TagsInput.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/folder-tree/FolderPicker.d.ts.map +1 -1
- package/dist/react/folder-tree/FolderPicker.js +5 -1
- package/dist/react/folder-tree/FolderPicker.js.map +1 -1
- package/dist/react/icons.d.ts +28 -0
- package/dist/react/icons.d.ts.map +1 -1
- package/dist/react/icons.js +29 -1
- package/dist/react/icons.js.map +1 -1
- package/dist/react/index.d.ts +9 -6
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +6 -3
- 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/lib/whenIdle.d.ts +7 -0
- package/dist/react/lib/whenIdle.d.ts.map +1 -0
- package/dist/react/lib/whenIdle.js +14 -0
- package/dist/react/lib/whenIdle.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/DenseGalleryShell.d.ts +7 -1
- package/dist/react/media/DenseGalleryShell.d.ts.map +1 -1
- package/dist/react/media/DenseGalleryShell.js +3 -3
- package/dist/react/media/DenseGalleryShell.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 +96 -1
- package/dist/react/media-gallery/MediaGallery.d.ts +5 -2
- package/dist/react/media-gallery/MediaGallery.d.ts.map +1 -1
- package/dist/react/media-gallery/MediaGallery.js +1 -1
- package/dist/react/media-gallery/MediaGallery.js.map +1 -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 +2 -2
- package/dist/styles-areas/calendar.css +5 -6
- package/dist/styles-areas/canvas-hud.css +30 -0
- 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 +99 -90
- 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 +6 -6
- package/dist/styles-areas/layout-engine.css +4 -4
- package/dist/styles-areas/markdown.css +2 -1
- package/dist/styles-areas/master-detail.css +3 -3
- package/dist/styles-areas/media-gallery.css +7 -6
- 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 +5 -4
- 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 +4 -4
- 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 +296 -190
- 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 +10 -2
- package/scripts/generateAreaStyles.ts +3 -1
- package/scripts/guardrails-baseline.json +2 -1
- package/scripts/guardrailsEnforce.spec.ts +64 -0
- package/scripts/guardrailsEnforce.ts +65 -8
- package/scripts/styleAreas.ts +89 -6
- package/src/bundlerOnlyEntries.spec.ts +25 -8
- 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/canvas-hud/CanvasMinimap.tsx +88 -0
- package/src/react/canvas-hud/CanvasNodeMenu.tsx +91 -0
- package/src/react/canvas-hud/CanvasSearchField.tsx +91 -0
- package/src/react/canvas-hud/HudControls.spec.tsx +160 -0
- package/src/react/canvas-hud/HudControls.tsx +128 -0
- package/src/react/canvas-hud/index.ts +33 -0
- package/src/react/canvas-hud/useCanvasWheel.ts +99 -0
- package/src/react/canvas-hud/viewport.spec.ts +105 -0
- package/src/react/canvas-hud/viewport.ts +124 -0
- 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 +254 -92
- package/src/react/components/AsyncPanel.spec.tsx +17 -1
- package/src/react/components/AsyncPanel.tsx +88 -6
- package/src/react/components/BannerLane.tsx +128 -0
- package/src/react/components/Button.tsx +2 -0
- package/src/react/components/Checkbox.spec.tsx +18 -0
- package/src/react/components/Checkbox.tsx +8 -5
- 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.spec.tsx +3 -2
- package/src/react/components/Field.tsx +7 -4
- package/src/react/components/Field.width.spec.tsx +14 -3
- 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.spec.tsx +39 -0
- package/src/react/components/PageGuideButton.tsx +110 -0
- package/src/react/components/PageGuidePopover.tsx +52 -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/TagsInput.spec.tsx +8 -0
- package/src/react/components/TagsInput.tsx +3 -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/components/entryChunks.graph.spec.ts +89 -0
- 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/folder-tree/FolderPicker.spec.tsx +8 -0
- package/src/react/folder-tree/FolderPicker.tsx +4 -1
- package/src/react/icons.spec.ts +21 -1
- package/src/react/icons.tsx +136 -2
- package/src/react/index.ts +38 -3
- package/src/react/lib/menuSections.ts +33 -0
- package/src/react/lib/whenIdle.ts +13 -0
- package/src/react/markdown/Markdown.tsx +2 -2
- package/src/react/media/DenseGalleryShell.tsx +20 -4
- 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 +96 -1
- package/src/react/media-gallery/MediaGallery.spec.tsx +26 -0
- package/src/react/media-gallery/MediaGallery.tsx +10 -3
- 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 +2 -2
- package/src/styles-areas/calendar.css +5 -6
- package/src/styles-areas/canvas-hud.css +30 -0
- 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 +99 -90
- 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 +6 -6
- package/src/styles-areas/layout-engine.css +4 -4
- package/src/styles-areas/markdown.css +2 -1
- package/src/styles-areas/master-detail.css +3 -3
- package/src/styles-areas/media-gallery.css +7 -6
- 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 +5 -4
- 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 +4 -4
- 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 +296 -190
- package/src/stylesAreas.spec.ts +17 -0
- 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
|
);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join, relative } from 'node:path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What an app's entry chunk must NOT carry. Forge task 2533: AppShell keeps its ⌘K palette off
|
|
7
|
+
* it; task 2535: `Page`'s header keeps its ⓘ guide popover off it. Whatever a module reaches
|
|
8
|
+
* through STATIC imports lands in the chunk that imports it, so this walks AppShell's static
|
|
9
|
+
* graph (Bun's own scanner — type-only imports and `import()` excluded) and refuses the palette
|
|
10
|
+
* body and the packages only it needs. A dynamic `import()` is the split, and is not followed.
|
|
11
|
+
*/
|
|
12
|
+
const SRC = join(import.meta.dir, '..', '..');
|
|
13
|
+
// One per loader: a `.ts` file's `<const T>` generic is not JSX, and a TSX parse refuses it.
|
|
14
|
+
const transpilers = { ts: new Bun.Transpiler({ loader: 'ts' }), tsx: new Bun.Transpiler({ loader: 'tsx' }) };
|
|
15
|
+
|
|
16
|
+
function resolveLocal(from: string, spec: string): string | null {
|
|
17
|
+
const base = join(dirname(from), spec.replace(/\.js$/, ''));
|
|
18
|
+
for (const candidate of [`${base}.ts`, `${base}.tsx`, join(base, 'index.ts'), join(base, 'index.tsx')]) {
|
|
19
|
+
if (existsSync(candidate)) return candidate;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function staticGraph(entry: string): { files: Set<string>; packages: Set<string> } {
|
|
25
|
+
const files = new Set<string>();
|
|
26
|
+
const packages = new Set<string>();
|
|
27
|
+
const queue = [entry];
|
|
28
|
+
while (queue.length > 0) {
|
|
29
|
+
const file = queue.pop() as string;
|
|
30
|
+
if (files.has(file)) continue;
|
|
31
|
+
files.add(file);
|
|
32
|
+
for (const { path, kind } of transpilers[file.endsWith('.tsx') ? 'tsx' : 'ts'].scanImports(readFileSync(file, 'utf8'))) {
|
|
33
|
+
if (kind !== 'import-statement') continue;
|
|
34
|
+
if (!path.startsWith('.')) {
|
|
35
|
+
packages.add(path);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const next = resolveLocal(file, path);
|
|
39
|
+
if (next) queue.push(next);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { files, packages };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('AppShell static graph', () => {
|
|
46
|
+
const { files, packages } = staticGraph(join(SRC, 'react', 'components', 'AppShell.tsx'));
|
|
47
|
+
const local = [...files].map((f) => relative(SRC, f));
|
|
48
|
+
|
|
49
|
+
test('the walker sees the shell itself and what it draws on every page', () => {
|
|
50
|
+
expect(local).toContain('react/components/AppShell.tsx');
|
|
51
|
+
expect(local).toContain('react/palette/useCommandPalette.ts');
|
|
52
|
+
expect(local).toContain('react/nav/SideNav.tsx');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('🔴 the command palette body is not in it — it is fetched on idle or first open', () => {
|
|
56
|
+
expect(local).not.toContain('react/palette/CommandPalette.tsx');
|
|
57
|
+
expect(local).not.toContain('react/palette/Command.tsx');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('🔴 neither are the packages only the palette needs', () => {
|
|
61
|
+
// `cursedbelt-core/palette/hotkeys` stays: it is the ⌘K binding `useCommandPalette` registers.
|
|
62
|
+
const palettePackages = [...packages].filter(
|
|
63
|
+
(p) => p === 'cmdk' || p.startsWith('@leeoniya/ufuzzy') || p === 'cursedbelt-core/palette/fuzzy-rank',
|
|
64
|
+
);
|
|
65
|
+
expect(palettePackages).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('Page static graph', () => {
|
|
70
|
+
const { files, packages } = staticGraph(join(SRC, 'react', 'components', 'Page.tsx'));
|
|
71
|
+
const local = [...files].map((f) => relative(SRC, f));
|
|
72
|
+
|
|
73
|
+
test('the walker sees the page and its guide trigger', () => {
|
|
74
|
+
expect(local).toContain('react/components/Page.tsx');
|
|
75
|
+
expect(local).toContain('react/components/PageGuideButton.tsx');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('🔴 the guide popover is not in it — it is fetched on idle or on the first hover, focus or press', () => {
|
|
79
|
+
expect(local).not.toContain('react/components/PageGuidePopover.tsx');
|
|
80
|
+
expect(local).not.toContain('react/components/Popover.tsx');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('🔴 neither is the positioning engine a closed popover does not need', () => {
|
|
84
|
+
const floating = [...packages].filter(
|
|
85
|
+
(p) => p.startsWith('@radix-ui/react-popover') || p.startsWith('@radix-ui/react-popper') || p.startsWith('@floating-ui/'),
|
|
86
|
+
);
|
|
87
|
+
expect(floating).toEqual([]);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -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
|
|
@@ -18,6 +18,14 @@ function Harness({ initial = [] as string[] }: { initial?: string[] }) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
describe("FolderPicker", () => {
|
|
21
|
+
test("the trigger is a field at the locked control height, not a hand-padded box (FND-4)", () => {
|
|
22
|
+
const { container } = render(<Harness />);
|
|
23
|
+
const cls = (container.querySelector("button[aria-expanded]")?.getAttribute("class") ?? "").split(/\s+/);
|
|
24
|
+
expect(cls).toContain("h-[var(--control-h-md)]");
|
|
25
|
+
expect(cls).toContain("border-field-border");
|
|
26
|
+
expect(cls).not.toContain("py-1.5");
|
|
27
|
+
});
|
|
28
|
+
|
|
21
29
|
test("every existing-folder option is labeled with its FULL breadcrumb path", () => {
|
|
22
30
|
const { getByLabelText, queryByLabelText } = render(<Harness />);
|
|
23
31
|
fireEvent.click(getByLabelText("Folder")); // open the panel
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import { useState } from "react";
|
|
16
16
|
import { Button } from "../components/Button.js";
|
|
17
17
|
import { Input } from "../components/Input.js";
|
|
18
|
+
import { fieldControlClass } from "../lib/field.js";
|
|
18
19
|
import { FolderBreadcrumb } from "./FolderBreadcrumb.js";
|
|
19
20
|
import { formatFolderPath, isValidFolderName, normalizeFolderName } from "cursedbelt-core/folder-tree/path";
|
|
20
21
|
import { type FolderNode, flattenFolderTree } from "cursedbelt-core/folder-tree/tree";
|
|
@@ -102,7 +103,9 @@ export function FolderPicker({
|
|
|
102
103
|
type="button"
|
|
103
104
|
aria-label={ariaLabel}
|
|
104
105
|
aria-expanded={open}
|
|
105
|
-
|
|
106
|
+
// The shared field chrome at the locked control height, so the trigger lines up with
|
|
107
|
+
// an Input or TagsInput beside it (FND-4); it was hand-padded to 34px in its own colours.
|
|
108
|
+
className={`${fieldControlClass("md")} flex items-center justify-between gap-2 text-left`}
|
|
106
109
|
onClick={() => (open ? close() : setOpen(true))}
|
|
107
110
|
>
|
|
108
111
|
<span className="min-w-0 truncate">{selectedLabel}</span>
|
package/src/react/icons.spec.ts
CHANGED
|
@@ -3,10 +3,20 @@ import { render } from '@testing-library/react';
|
|
|
3
3
|
import {
|
|
4
4
|
createIconMapRegistry,
|
|
5
5
|
DynamicIcon,
|
|
6
|
+
IconAdd,
|
|
7
|
+
IconArchive,
|
|
8
|
+
IconCopies,
|
|
9
|
+
IconFullscreen,
|
|
10
|
+
IconFullscreenExit,
|
|
11
|
+
IconGrid,
|
|
12
|
+
IconMore,
|
|
13
|
+
IconRefresh,
|
|
6
14
|
IconRegistry,
|
|
15
|
+
IconScissors,
|
|
7
16
|
IconSearch,
|
|
8
17
|
IconSidebar,
|
|
9
18
|
IconTable,
|
|
19
|
+
IconTrash,
|
|
10
20
|
} from './icons.js';
|
|
11
21
|
|
|
12
22
|
describe('createIconMapRegistry', () => {
|
|
@@ -72,11 +82,21 @@ describe('DynamicIcon with no iconMap', () => {
|
|
|
72
82
|
describe('hand-drawn icons', () => {
|
|
73
83
|
// Dependency-free SVG components (not routed through IconToken/lucide) shared by
|
|
74
84
|
// hosts that don't carry lucide-react — collections and desk used to hand-roll
|
|
75
|
-
// these
|
|
85
|
+
// these locally; see tasks 2382 and 2473.
|
|
76
86
|
test.each([
|
|
77
87
|
['IconSidebar', IconSidebar],
|
|
78
88
|
['IconSearch', IconSearch],
|
|
79
89
|
['IconTable', IconTable],
|
|
90
|
+
['IconAdd', IconAdd],
|
|
91
|
+
['IconMore', IconMore],
|
|
92
|
+
['IconFullscreen', IconFullscreen],
|
|
93
|
+
['IconFullscreenExit', IconFullscreenExit],
|
|
94
|
+
['IconRefresh', IconRefresh],
|
|
95
|
+
['IconGrid', IconGrid],
|
|
96
|
+
['IconTrash', IconTrash],
|
|
97
|
+
['IconCopies', IconCopies],
|
|
98
|
+
['IconArchive', IconArchive],
|
|
99
|
+
['IconScissors', IconScissors],
|
|
80
100
|
] as const)('%s renders a sized svg with no lucide dependency', (_name, Icon) => {
|
|
81
101
|
const { container } = render(Icon({ size: 24, className: 'test-class' }));
|
|
82
102
|
const svg = container.querySelector('svg');
|