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
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HTMLAttributes, useRef } from 'react';
|
|
2
|
+
import { chartHeight } from '../charts/chartBox.js';
|
|
3
|
+
import { useElementSize } from '../hooks/useResizeObserver.js';
|
|
2
4
|
import { cn } from '../lib/cn.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
@@ -57,7 +59,7 @@ export interface SkeletonListProps {
|
|
|
57
59
|
* (used as `QueryBoundary`'s loading fallback). */
|
|
58
60
|
export function SkeletonList({ rows = 6, className }: SkeletonListProps) {
|
|
59
61
|
return (
|
|
60
|
-
<div className={cn('flex flex-col gap-3', className)} aria-hidden>
|
|
62
|
+
<div className={cn('flex flex-col gap-3', className)} aria-hidden data-cb-skeleton='rows'>
|
|
61
63
|
{Array.from({ length: rows }).map((_, i) => (
|
|
62
64
|
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-length skeleton placeholder rows that never reorder
|
|
63
65
|
<Skeleton key={`skeleton-row-${i}`} className='h-14' />
|
|
@@ -65,3 +67,49 @@ export function SkeletonList({ rows = 6, className }: SkeletonListProps) {
|
|
|
65
67
|
</div>
|
|
66
68
|
);
|
|
67
69
|
}
|
|
70
|
+
|
|
71
|
+
/** A strip of stat-tile placeholders — the shape of a `StatTileGrid` (label, value, sub). */
|
|
72
|
+
export function SkeletonTiles({ tiles = 4, className }: { tiles?: number; className?: string }) {
|
|
73
|
+
return (
|
|
74
|
+
<div className={cn('grid grid-cols-2 gap-3 md:grid-cols-4', className)} aria-hidden data-cb-skeleton='tiles'>
|
|
75
|
+
{Array.from({ length: tiles }).map((_, i) => (
|
|
76
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-length skeleton placeholder tiles that never reorder
|
|
77
|
+
<div key={`skeleton-tile-${i}`} className='flex flex-col gap-2 rounded-lg border border-border p-3'>
|
|
78
|
+
<Skeleton className='h-3 w-1/2' />
|
|
79
|
+
<Skeleton className='h-8 w-2/3' />
|
|
80
|
+
<Skeleton className='h-3 w-3/4' />
|
|
81
|
+
</div>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** A chart frame's placeholder at the height the chart will take at this width (CHT-9) —
|
|
88
|
+
* the same `chartHeight` the frame uses, so nothing moves when the chart lands. */
|
|
89
|
+
export function SkeletonChart({ className }: { className?: string }) {
|
|
90
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
91
|
+
const { width } = useElementSize(ref, { layout: true });
|
|
92
|
+
return (
|
|
93
|
+
<div ref={ref} className={cn('w-full', className)} aria-hidden data-cb-skeleton='chart'>
|
|
94
|
+
<Skeleton className='w-full rounded-md' style={{ height: chartHeight(width) }} />
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type SkeletonVariant = 'rows' | 'tiles' | 'chart';
|
|
100
|
+
|
|
101
|
+
/** The skeleton shaped like the content it stands in for (STA-1) — rows, tiles or a chart. */
|
|
102
|
+
export function ContentSkeleton({
|
|
103
|
+
variant = 'rows',
|
|
104
|
+
count,
|
|
105
|
+
className,
|
|
106
|
+
}: {
|
|
107
|
+
variant?: SkeletonVariant;
|
|
108
|
+
/** Rows or tiles to draw. */
|
|
109
|
+
count?: number;
|
|
110
|
+
className?: string;
|
|
111
|
+
}) {
|
|
112
|
+
if (variant === 'tiles') return <SkeletonTiles tiles={count} className={className} />;
|
|
113
|
+
if (variant === 'chart') return <SkeletonChart className={className} />;
|
|
114
|
+
return <SkeletonList rows={count} className={className} />;
|
|
115
|
+
}
|
|
@@ -111,7 +111,7 @@ export function StatStrip({ items, orientation = 'horizontal', flat = false, cla
|
|
|
111
111
|
const interactive = item.onClick !== undefined;
|
|
112
112
|
const itemClass = cn(
|
|
113
113
|
'group/stat flex min-w-0 flex-col gap-0.5 text-left',
|
|
114
|
-
horizontal ? 'min-w-
|
|
114
|
+
horizontal ? 'min-w-34 flex-1 shrink-0 px-3 py-2 first:pl-1 last:pr-1' : 'px-1 py-2.5',
|
|
115
115
|
interactive &&
|
|
116
116
|
'cursor-pointer rounded-sm transition-colors hover:bg-accent/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
117
117
|
);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Info } from 'lucide-react';
|
|
2
|
-
import type
|
|
2
|
+
import { createContext, type ReactNode, useContext } from 'react';
|
|
3
3
|
import { cn } from '../lib/cn.js';
|
|
4
4
|
import { CopyButton } from './CopyButton.js';
|
|
5
5
|
import { Sparkline } from './Sparkline.js';
|
|
6
6
|
import { TruncatedText } from './TruncatedText.js';
|
|
7
7
|
import { Tooltip } from './Tooltip.js';
|
|
8
8
|
import { TAP_TARGET_ALWAYS } from '../lib/tapTarget.js';
|
|
9
|
+
import { Progress as ProgressBar } from './Progress.js';
|
|
10
|
+
import { type ThresholdTone, thresholdToneOf } from './ThresholdMeter.js';
|
|
9
11
|
|
|
10
12
|
interface Progress {
|
|
11
13
|
value: number;
|
|
@@ -28,6 +30,45 @@ const TONE_BAR: Record<StatTileTone, string> = {
|
|
|
28
30
|
neutral: 'bg-border-strong',
|
|
29
31
|
};
|
|
30
32
|
|
|
33
|
+
/**
|
|
34
|
+
* A budget (DAT-9): a quota, a time window or money, drawn as the tile's big value with its
|
|
35
|
+
* meter DIRECTLY underneath and the window it covers at 12px. The color turns at the
|
|
36
|
+
* thresholds — warning, then critical — and the readout says in words what the color means
|
|
37
|
+
* ("60% used"), so the color is never the only signal.
|
|
38
|
+
*/
|
|
39
|
+
export interface StatTileBudget {
|
|
40
|
+
/** Consumed, in the same unit as `max`. */
|
|
41
|
+
used: number;
|
|
42
|
+
max: number;
|
|
43
|
+
/** The window the budget covers — "Sep 30 21:01 → Oct 1 02:01". */
|
|
44
|
+
window?: ReactNode;
|
|
45
|
+
/** Fractions of `max` (0–1) where the color turns. Default 0.85 / 0.95, as `ThresholdMeter`. */
|
|
46
|
+
thresholds?: { warning: number; critical: number };
|
|
47
|
+
/** The words beside the percentage. Default `used`. */
|
|
48
|
+
verb?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const BUDGET_BAR: Record<ThresholdTone, string> = {
|
|
52
|
+
ok: 'bg-accent-solid',
|
|
53
|
+
warning: 'bg-warning',
|
|
54
|
+
critical: 'bg-destructive',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const BUDGET_TEXT: Record<ThresholdTone, string> = {
|
|
58
|
+
ok: 'text-muted-foreground',
|
|
59
|
+
warning: 'text-warning',
|
|
60
|
+
critical: 'text-destructive',
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type StatValueSize = 'sm' | 'md' | 'lg';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The value size a {@link StatTileGrid} imposes on every tile in it (DAT-8: tiles in a row
|
|
67
|
+
* share ONE value size). `null` outside a grid — a lone tile sizes itself.
|
|
68
|
+
*/
|
|
69
|
+
const GridValueSize = createContext<StatValueSize | null>(null);
|
|
70
|
+
export const StatTileValueSizeProvider = GridValueSize.Provider;
|
|
71
|
+
|
|
31
72
|
export interface StatTileProps {
|
|
32
73
|
label: string;
|
|
33
74
|
value: ReactNode;
|
|
@@ -45,7 +86,9 @@ export interface StatTileProps {
|
|
|
45
86
|
* status-word tiles ("Running" / "Executing" / "Off") must share ONE size — the
|
|
46
87
|
* auto scale would render them at three different sizes purely by string length.
|
|
47
88
|
*/
|
|
48
|
-
valueSize?:
|
|
89
|
+
valueSize?: StatValueSize;
|
|
90
|
+
/** Draw the tile as a budget — see {@link StatTileBudget}. Replaces `progress`. */
|
|
91
|
+
budget?: StatTileBudget;
|
|
49
92
|
/**
|
|
50
93
|
* Makes the WHOLE tile a click target — {@link StatTileGrid} reads this off its
|
|
51
94
|
* child and turns that cell's card into the pressable surface (hover border
|
|
@@ -147,12 +190,13 @@ function defaultCopyText(label: string, value: ReactNode, sub: ReactNode): strin
|
|
|
147
190
|
return tail.length > 0 ? `${head} (${tail})` : head;
|
|
148
191
|
}
|
|
149
192
|
|
|
150
|
-
|
|
151
|
-
|
|
193
|
+
/** The size a value would pick ON ITS OWN — by length, so "Executing" never overflows a
|
|
194
|
+
* tile that "42" fits. {@link StatTileGrid} takes the smallest across its tiles. */
|
|
195
|
+
export function statValueSize(value: ReactNode): StatValueSize {
|
|
152
196
|
const s = typeof value === 'string' ? value : typeof value === 'number' ? String(value) : '';
|
|
153
|
-
if (s.length > 12) return '
|
|
154
|
-
if (s.length > 7) return '
|
|
155
|
-
return '
|
|
197
|
+
if (s.length > 12) return 'sm';
|
|
198
|
+
if (s.length > 7) return 'md';
|
|
199
|
+
return 'lg';
|
|
156
200
|
}
|
|
157
201
|
|
|
158
202
|
/**
|
|
@@ -178,7 +222,15 @@ export function StatTile({
|
|
|
178
222
|
help,
|
|
179
223
|
copyValue,
|
|
180
224
|
delta,
|
|
225
|
+
budget,
|
|
181
226
|
}: StatTileProps) {
|
|
227
|
+
const gridSize = useContext(GridValueSize);
|
|
228
|
+
const size = valueSize ?? gridSize ?? statValueSize(value);
|
|
229
|
+
const budgetRatio = budget && budget.max > 0 ? Math.min(1, Math.max(0, budget.used / budget.max)) : null;
|
|
230
|
+
const budgetTone = budgetRatio == null ? null : thresholdToneOf(budgetRatio, budget?.thresholds);
|
|
231
|
+
// The BAR stops at full; the words do not — 1.11M of a 1M allowance is "111% used", and a
|
|
232
|
+
// readout clamped to 100% would hide exactly the overrun the tile exists to show.
|
|
233
|
+
const budgetPercent = budget && budget.max > 0 ? Math.round((budget.used / budget.max) * 100) : 0;
|
|
182
234
|
const pct =
|
|
183
235
|
progress && progress.max > 0 ? Math.round((progress.value / progress.max) * 100) : null;
|
|
184
236
|
const body = (
|
|
@@ -238,9 +290,11 @@ export function StatTile({
|
|
|
238
290
|
</div>
|
|
239
291
|
<div
|
|
240
292
|
className={cn(
|
|
241
|
-
|
|
293
|
+
VALUE_SIZE[size],
|
|
242
294
|
'min-w-0 break-words font-semibold leading-tight tabular-nums',
|
|
295
|
+
budgetTone && budgetTone !== 'ok' && BUDGET_TEXT[budgetTone],
|
|
243
296
|
)}
|
|
297
|
+
data-cb-stat-size={size}
|
|
244
298
|
style={color ? { color } : undefined}
|
|
245
299
|
>
|
|
246
300
|
{value}
|
|
@@ -251,7 +305,7 @@ export function StatTile({
|
|
|
251
305
|
className={cn('shrink-0 tabular-nums font-medium', DELTA_CLASS[delta.direction ?? 'flat'])}
|
|
252
306
|
>
|
|
253
307
|
{/* guardrails-ignore micro-typography-floor: an aria-hidden ▲/▼ delta arrow, not text */}
|
|
254
|
-
<span aria-hidden className='mr-0.5 text-[
|
|
308
|
+
<span aria-hidden className='mr-0.5 text-[length:var(--text-glyph)]'>
|
|
255
309
|
{TREND_GLYPH[delta.trend ?? 'flat']}
|
|
256
310
|
</span>
|
|
257
311
|
{delta.value}
|
|
@@ -270,8 +324,27 @@ export function StatTile({
|
|
|
270
324
|
</div>
|
|
271
325
|
</Tooltip>
|
|
272
326
|
) : null}
|
|
327
|
+
{budget && budgetRatio != null && budgetTone ? (
|
|
328
|
+
<div className='flex min-w-0 flex-col gap-1' data-cb-stat-budget={budgetTone}>
|
|
329
|
+
<ProgressBar
|
|
330
|
+
value={budgetRatio * 100}
|
|
331
|
+
max={100}
|
|
332
|
+
size='sm'
|
|
333
|
+
indicatorClassName={BUDGET_BAR[budgetTone]}
|
|
334
|
+
aria-label={`${label}: ${budgetPercent}% ${budget.verb ?? 'used'}`}
|
|
335
|
+
/>
|
|
336
|
+
<div className='flex min-w-0 items-baseline justify-between gap-2 text-xs'>
|
|
337
|
+
<span className={cn('shrink-0 tabular-nums font-medium', BUDGET_TEXT[budgetTone])}>
|
|
338
|
+
{`${budgetPercent}% ${budget.verb ?? 'used'}`}
|
|
339
|
+
</span>
|
|
340
|
+
{budget.window ? (
|
|
341
|
+
<span className='min-w-0 truncate text-muted-foreground tabular-nums'>{budget.window}</span>
|
|
342
|
+
) : null}
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
) : null}
|
|
273
346
|
{spark ? <Sparkline data={spark} /> : null}
|
|
274
|
-
{progress && pct != null ? (
|
|
347
|
+
{!budget && progress && pct != null ? (
|
|
275
348
|
<div>
|
|
276
349
|
<div className='h-1.5 w-full overflow-hidden rounded-full bg-muted'>
|
|
277
350
|
<div
|
|
@@ -288,7 +361,7 @@ export function StatTile({
|
|
|
288
361
|
);
|
|
289
362
|
if (!tone) return body;
|
|
290
363
|
return (
|
|
291
|
-
<div className='flex min-w-0 gap-
|
|
364
|
+
<div className='flex min-w-0 gap-3' data-tone={tone}>
|
|
292
365
|
<span aria-hidden className={cn('w-1 shrink-0 self-stretch rounded-full', TONE_BAR[tone])} />
|
|
293
366
|
{body}
|
|
294
367
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { afterEach, describe, expect, test } from 'bun:test';
|
|
2
2
|
import { cleanup, render } from '@testing-library/react';
|
|
3
3
|
import { StatTile } from './StatTile.js';
|
|
4
|
-
import { StatTileGrid } from './StatTileGrid.js';
|
|
4
|
+
import { StatTileGrid, gridValueSize } from './StatTileGrid.js';
|
|
5
5
|
|
|
6
6
|
afterEach(cleanup);
|
|
7
7
|
|
|
@@ -85,4 +85,9 @@ describe('fill', () => {
|
|
|
85
85
|
expect(grid.style.gridTemplateColumns).toContain('auto-fit');
|
|
86
86
|
expect(grid.style.gridTemplateColumns).not.toContain('auto-fill');
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
test('gridValueSize skips a tile that fixes its own size', () => {
|
|
90
|
+
expect(gridValueSize([<StatTile key='1' label='a' value='1' />, <StatTile key='2' label='b' value='a long value here' valueSize='lg' />])).toBe('lg');
|
|
91
|
+
});
|
|
92
|
+
|
|
88
93
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Children, isValidElement, type KeyboardEvent, type ReactNode } from 'react';
|
|
2
2
|
import { cn } from '../lib/cn.js';
|
|
3
3
|
import { pressWithoutSelection } from '../lib/selection.js';
|
|
4
|
+
import { type StatValueSize, StatTileValueSizeProvider, statValueSize } from './StatTile.js';
|
|
4
5
|
import { Surface } from './Surface.js';
|
|
5
6
|
|
|
6
7
|
export interface StatTileGridProps {
|
|
@@ -27,9 +28,29 @@ export interface StatTileGridProps {
|
|
|
27
28
|
* provides a surface (a dashboard widget frame, a padded panel).
|
|
28
29
|
*/
|
|
29
30
|
flat?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The ONE value size every tile in the grid uses (DAT-8). Default: the smallest any tile's
|
|
33
|
+
* value would pick on its own, so "Executing" and "42" sit at the same size instead of
|
|
34
|
+
* three sizes by string length. A tile's own `valueSize` still wins for that tile.
|
|
35
|
+
*/
|
|
36
|
+
valueSize?: StatValueSize;
|
|
30
37
|
className?: string;
|
|
31
38
|
}
|
|
32
39
|
|
|
40
|
+
const SIZE_RANK: Record<StatValueSize, number> = { sm: 0, md: 1, lg: 2 };
|
|
41
|
+
|
|
42
|
+
/** The smallest auto size across the grid's tiles — exported for its spec. */
|
|
43
|
+
export function gridValueSize(children: ReactNode): StatValueSize {
|
|
44
|
+
let size: StatValueSize = 'lg';
|
|
45
|
+
Children.forEach(children, (child) => {
|
|
46
|
+
if (!isValidElement<{ value?: ReactNode; valueSize?: StatValueSize }>(child)) return;
|
|
47
|
+
if (child.props.valueSize || !('value' in (child.props as object))) return;
|
|
48
|
+
const own = statValueSize(child.props.value);
|
|
49
|
+
if (SIZE_RANK[own] < SIZE_RANK[size]) size = own;
|
|
50
|
+
});
|
|
51
|
+
return size;
|
|
52
|
+
}
|
|
53
|
+
|
|
33
54
|
/** A child (normally a {@link StatTile}) may declare itself pressable — the grid
|
|
34
55
|
* owns the card chrome, so the grid is what turns the WHOLE cell into the click
|
|
35
56
|
* target (Fitts's law: the entire card, not just the text inside it). */
|
|
@@ -56,13 +77,16 @@ export function StatTileGrid({
|
|
|
56
77
|
minTileWidth = '10.5rem',
|
|
57
78
|
fill = false,
|
|
58
79
|
flat = false,
|
|
80
|
+
valueSize,
|
|
59
81
|
className,
|
|
60
82
|
}: StatTileGridProps) {
|
|
83
|
+
const size = valueSize ?? gridValueSize(children);
|
|
61
84
|
// `min(<w>, 100%)` keeps a single narrow container from overflowing horizontally;
|
|
62
85
|
// `auto-fill` (not `auto-fit`) holds cells near minTileWidth instead of ballooning
|
|
63
86
|
// a short strip into comically wide tiles.
|
|
64
87
|
const columns = `repeat(${fill ? 'auto-fit' : 'auto-fill'}, minmax(min(${minTileWidth}, 100%), 1fr))`;
|
|
65
88
|
return (
|
|
89
|
+
<StatTileValueSizeProvider value={size}>
|
|
66
90
|
<div className={cn('grid gap-3', className)} style={{ gridTemplateColumns: columns }}>
|
|
67
91
|
{Children.map(children, (child) => {
|
|
68
92
|
if (child == null || child === false) return null;
|
|
@@ -107,5 +131,6 @@ export function StatTileGrid({
|
|
|
107
131
|
);
|
|
108
132
|
})}
|
|
109
133
|
</div>
|
|
134
|
+
</StatTileValueSizeProvider>
|
|
110
135
|
);
|
|
111
136
|
}
|
|
@@ -65,6 +65,14 @@ export const STATUS_ATTENTION_TONE: Record<string, BadgeTone> = {
|
|
|
65
65
|
dispatched: 'success',
|
|
66
66
|
claimed: 'success',
|
|
67
67
|
active: 'success',
|
|
68
|
+
// The live states station's and roms' jobs report (forge task 2464, DAT-4): a copy, a
|
|
69
|
+
// cipher pass and a download are work in flight, the same reading as `running`.
|
|
70
|
+
downloading: 'success',
|
|
71
|
+
uploading: 'success',
|
|
72
|
+
encrypting: 'success',
|
|
73
|
+
transcoding: 'success',
|
|
74
|
+
deploying: 'success',
|
|
75
|
+
building: 'success',
|
|
68
76
|
// Broken — demands the owner
|
|
69
77
|
error: 'error',
|
|
70
78
|
failed: 'error',
|
|
@@ -72,12 +80,29 @@ export const STATUS_ATTENTION_TONE: Record<string, BadgeTone> = {
|
|
|
72
80
|
offline: 'error',
|
|
73
81
|
rejected: 'error',
|
|
74
82
|
vanished: 'error',
|
|
83
|
+
// A job that stopped part-way and a record the reader cannot open are broken too — station's
|
|
84
|
+
// backup and cipher cards, its data audit (`failing`, `uncovered`, `unscheduled`) and its
|
|
85
|
+
// reach probe (`not-answering`, `looping`, `no-address`).
|
|
86
|
+
interrupted: 'error',
|
|
87
|
+
unreadable: 'error',
|
|
88
|
+
failing: 'error',
|
|
89
|
+
uncovered: 'error',
|
|
90
|
+
unscheduled: 'error',
|
|
91
|
+
'not-answering': 'error',
|
|
92
|
+
looping: 'error',
|
|
93
|
+
'no-address': 'error',
|
|
75
94
|
// Held / degraded — waiting on a person or a recovery
|
|
76
95
|
paused: 'warning',
|
|
77
96
|
degraded: 'warning',
|
|
78
97
|
unhealthy: 'warning',
|
|
79
98
|
parked: 'warning',
|
|
80
99
|
on_hold: 'warning',
|
|
100
|
+
blocked: 'warning',
|
|
101
|
+
// Stale and half-watched: it still works, and it has stopped being checked.
|
|
102
|
+
stale: 'warning',
|
|
103
|
+
unwatched: 'warning',
|
|
104
|
+
'watchdog-stale': 'warning',
|
|
105
|
+
unauditable: 'warning',
|
|
81
106
|
};
|
|
82
107
|
|
|
83
108
|
/** Statuses whose dot breathes (a slow pulse): live processes, plus `crashed` —
|
|
@@ -131,7 +156,7 @@ export function StatusPill({
|
|
|
131
156
|
<span
|
|
132
157
|
aria-hidden
|
|
133
158
|
className={cn(
|
|
134
|
-
'size-0 shrink-0 border-x-4 border-b-[
|
|
159
|
+
'size-0 shrink-0 border-x-4 border-b-[length:var(--status-glyph-h)] border-x-transparent border-b-current',
|
|
135
160
|
LIVE_STATUSES.has(status) && 'animate-pulse motion-reduce:animate-none',
|
|
136
161
|
)}
|
|
137
162
|
/>
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { Slot } from '@radix-ui/react-slot';
|
|
2
2
|
import type { HTMLAttributes, Ref } from 'react';
|
|
3
3
|
import { cn } from '../lib/cn.js';
|
|
4
|
+
import { CardFrameContext, useCardNestingWarning } from './cardFrame.js';
|
|
4
5
|
|
|
5
|
-
// Elevation is meaning (flat | raised | overlay), not decoration.
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// Elevation is meaning (flat | raised | overlay), not decoration. FND-11 (task 2461):
|
|
7
|
+
// an IN-FLOW card is anchored by its 1px border and carries no drop shadow — shadows
|
|
8
|
+
// belong to floating layers only, so `overlay` is the one level with one. Dark mode
|
|
9
|
+
// still reads `raised` through a lighter background; all via tokens, so the same
|
|
10
|
+
// class is correct in every theme with no `dark:` color literals.
|
|
9
11
|
const ELEVATION = {
|
|
10
12
|
flat: 'bg-surface border border-border shadow-none',
|
|
11
13
|
raised: cn(
|
|
12
|
-
'bg-card border border-border shadow-
|
|
13
|
-
// `interactive` opts a raised surface into
|
|
14
|
-
//
|
|
15
|
-
|
|
14
|
+
'bg-card border border-border shadow-none dark:bg-card-raised',
|
|
15
|
+
// `interactive` opts a raised surface into hover feedback (clickable cards): the
|
|
16
|
+
// edge strengthens, transitioned at the motion token. No lift and no shadow — an
|
|
17
|
+
// in-flow card does not float (FND-11).
|
|
18
|
+
'data-[interactive=true]:transition-colors data-[interactive=true]:duration-[var(--duration-base)]',
|
|
16
19
|
'data-[interactive=true]:ease-[var(--ease-out)]',
|
|
17
|
-
'data-[interactive=true]:hover:
|
|
18
|
-
'data-[interactive=true]:hover:-translate-y-0.5',
|
|
20
|
+
'data-[interactive=true]:hover:border-border-strong',
|
|
19
21
|
),
|
|
20
22
|
overlay: 'bg-popover border border-border shadow-overlay dark:bg-card-overlay',
|
|
21
23
|
// `glass` is elevation with the ambient field showing THROUGH it — the panel
|
|
@@ -23,8 +25,8 @@ const ELEVATION = {
|
|
|
23
25
|
// come from the `--glass-*` tokens (theme.css), so it is a legitimate choice under
|
|
24
26
|
// ANY theme: in the default light theme those resolve to a near-opaque white frost
|
|
25
27
|
// (glass over white is white), which is why this is safe to reach for without
|
|
26
|
-
// asking whether the app opted into a theme.
|
|
27
|
-
// `raised
|
|
28
|
+
// asking whether the app opted into a theme. Its hover feedback is a lift, not
|
|
29
|
+
// `raised`'s border swap — a glass edge that thickens on hover reads as a
|
|
28
30
|
// rendering artifact rather than as feedback.
|
|
29
31
|
glass: cn(
|
|
30
32
|
'cb-glass',
|
|
@@ -51,7 +53,7 @@ export interface SurfaceProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
51
53
|
pad?: keyof typeof PAD;
|
|
52
54
|
/** Corner radius on the token scale (larger surface → larger radius). */
|
|
53
55
|
radius?: keyof typeof RADIUS;
|
|
54
|
-
/** Enable
|
|
56
|
+
/** Enable hover feedback on a `raised` or `glass` surface (clickable cards). No-op on flat/overlay. */
|
|
55
57
|
interactive?: boolean;
|
|
56
58
|
/** Render as the child element (Radix Slot) — e.g. `<Surface asChild><Link …/></Surface>`. */
|
|
57
59
|
asChild?: boolean;
|
|
@@ -75,11 +77,17 @@ export function Surface({
|
|
|
75
77
|
...rest
|
|
76
78
|
}: SurfaceProps) {
|
|
77
79
|
const Comp = asChild ? Slot : 'div';
|
|
78
|
-
|
|
80
|
+
// A sheet floats above the page and starts a fresh stack of levels (it provides
|
|
81
|
+
// `false`); every other Surface is an in-flow box, and a box inside it is the
|
|
82
|
+
// fourth level (LAY-5).
|
|
83
|
+
const isCard = level !== 'overlay';
|
|
84
|
+
useCardNestingWarning(isCard, 'Surface');
|
|
85
|
+
const el = (
|
|
79
86
|
<Comp
|
|
80
87
|
data-interactive={interactive || undefined}
|
|
81
88
|
className={cn(ELEVATION[level], PAD[pad], RADIUS[radius], className)}
|
|
82
89
|
{...rest}
|
|
83
90
|
/>
|
|
84
91
|
);
|
|
92
|
+
return <CardFrameContext.Provider value={isCard}>{el}</CardFrameContext.Provider>;
|
|
85
93
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as RadioGroup from '@radix-ui/react-radio-group';
|
|
2
2
|
import { Check } from 'lucide-react';
|
|
3
3
|
import { cn } from '../lib/cn.js';
|
|
4
|
+
import { TAP_TARGET_SQUARE } from '../lib/tapTarget.js';
|
|
4
5
|
|
|
5
6
|
export interface SwatchOption<T extends string = string> {
|
|
6
7
|
/** Stable value reported by `onChange` (an id, an index-as-string, a hex…). */
|
|
@@ -61,6 +62,9 @@ export function SwatchPicker<T extends string = string>({
|
|
|
61
62
|
className={cn(
|
|
62
63
|
'inline-flex items-center justify-center rounded-full border border-border/40 transition-transform',
|
|
63
64
|
SIZE[size],
|
|
65
|
+
// A finger needs 44px (DESIGN.md §5): the swatch itself grows on a coarse pointer, since
|
|
66
|
+
// the colour IS the button. A 28px one failed e2e/touch-targets (forge task 2514).
|
|
67
|
+
TAP_TARGET_SQUARE,
|
|
64
68
|
'hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1',
|
|
65
69
|
'data-[state=checked]:ring-2 data-[state=checked]:ring-foreground data-[state=checked]:ring-offset-1',
|
|
66
70
|
'disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:scale-100',
|
|
@@ -45,7 +45,7 @@ export function Switch({ className, label, labelClassName, showState, id: idProp
|
|
|
45
45
|
// never changes, so the previous hit-slop technique read as still-40×24 and
|
|
46
46
|
// kept failing orch-host's task-sources mobile scan (owner teardown,
|
|
47
47
|
// 2026-07-17 — the "cc"/"co"/etc. processing toggles all measured 40×24).
|
|
48
|
-
'pointer-coarse:h-11 pointer-coarse:w-
|
|
48
|
+
'pointer-coarse:h-11 pointer-coarse:w-18',
|
|
49
49
|
className,
|
|
50
50
|
)}
|
|
51
51
|
{...props}
|
|
@@ -22,6 +22,14 @@ const typeAndEnter = (input: HTMLInputElement, text: string) => {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
describe('TagsInput', () => {
|
|
25
|
+
test('the empty row fits the control height beside an Input — py-1, not the 38px py-1.5 (FND-4)', () => {
|
|
26
|
+
const { container } = render(<TagsInput value={[]} onChange={() => {}} aria-label='Tags' />);
|
|
27
|
+
const cls = (container.firstElementChild?.getAttribute('class') ?? '').split(/\s+/);
|
|
28
|
+
expect(cls).toContain('min-h-[var(--control-h-md)]');
|
|
29
|
+
expect(cls).toContain('py-1');
|
|
30
|
+
expect(cls).not.toContain('py-1.5');
|
|
31
|
+
});
|
|
32
|
+
|
|
25
33
|
test('adds 3 tags then removes the middle one → ["a","c"]', () => {
|
|
26
34
|
const { container, getByLabelText } = render(<Controlled />);
|
|
27
35
|
const input = container.querySelector('input') as HTMLInputElement;
|
|
@@ -98,8 +98,10 @@ export function TagsInput({
|
|
|
98
98
|
<div
|
|
99
99
|
aria-invalid={ariaInvalid}
|
|
100
100
|
className={cn(
|
|
101
|
+
// `py-1`, not `py-1.5`: the empty row is a 20px line + 8px + 2px border, under the min-height, so it
|
|
102
|
+
// sits at exactly the control height beside an Input; `py-1.5` made it 38px next to a 36px one (FND-4).
|
|
101
103
|
// guardrails-ignore control-height-tokens: min-height chip-wrapping row (not fixed) — py- clears wrapped lines
|
|
102
|
-
'flex w-full flex-wrap items-center gap-1.5 rounded-field border border-field-border bg-field-bg px-2 py-1
|
|
104
|
+
'flex w-full flex-wrap items-center gap-1.5 rounded-field border border-field-border bg-field-bg px-2 py-1 transition focus-within:border-field-ring focus-within:ring-2 focus-within:ring-field-ring/30 aria-[invalid=true]:border-field-error',
|
|
103
105
|
CONTROL_MIN_HEIGHT_CLASS[size],
|
|
104
106
|
disabled && 'cursor-not-allowed opacity-50',
|
|
105
107
|
className,
|
|
@@ -68,7 +68,7 @@ export function WidgetHeader({
|
|
|
68
68
|
narrow (phone) header — without a clip boundary here, that excess
|
|
69
69
|
visually spilled rightward on top of the actions cluster instead of
|
|
70
70
|
being contained at this cluster's own edge. */}
|
|
71
|
-
<div className='flex min-w-
|
|
71
|
+
<div className='flex min-w-20 flex-1 items-center gap-2 overflow-hidden'>
|
|
72
72
|
{icon != null && (
|
|
73
73
|
<span aria-hidden className='shrink-0 text-muted-foreground [&_svg]:size-4'>
|
|
74
74
|
{icon}
|
|
@@ -50,7 +50,7 @@ export function CalendarLegend({
|
|
|
50
50
|
onClick={() => onToggle?.(cal.id)}
|
|
51
51
|
tooltip={`${isHidden ? 'Show' : 'Hide'} ${cal.name}`}
|
|
52
52
|
className={cn(
|
|
53
|
-
'h-auto min-h-
|
|
53
|
+
'h-auto min-h-11 rounded-full border-border px-3 py-1.5 font-medium text-foreground',
|
|
54
54
|
isHidden && 'opacity-40 hover:opacity-70',
|
|
55
55
|
)}
|
|
56
56
|
>
|
|
@@ -130,7 +130,7 @@ function AgendaItem({ occurrence, color, calendarName, onSelect }: AgendaItemPro
|
|
|
130
130
|
onClick={() => onSelect(occurrence)}
|
|
131
131
|
tooltip={event.title}
|
|
132
132
|
className={cn(
|
|
133
|
-
'h-auto min-h-
|
|
133
|
+
'h-auto min-h-11 w-full items-center justify-start gap-3 rounded-lg',
|
|
134
134
|
'border border-border px-3 py-2 text-left font-normal',
|
|
135
135
|
'text-sm hover:border-border/80 hover:bg-muted/40',
|
|
136
136
|
)}
|
|
@@ -41,7 +41,7 @@ export function EventChip({ occurrence, onClick, color }: EventChipProps) {
|
|
|
41
41
|
aria-label={label}
|
|
42
42
|
className={cn(
|
|
43
43
|
'flex w-full min-w-0 truncate rounded px-1 py-0.5 text-left text-caption leading-tight',
|
|
44
|
-
'min-h-
|
|
44
|
+
'min-h-11 sm:min-h-0',
|
|
45
45
|
'flex-col gap-0 sm:flex-row sm:items-center sm:gap-1 sm:px-1.5 sm:text-xs',
|
|
46
46
|
chip,
|
|
47
47
|
done && 'line-through opacity-60',
|
|
@@ -116,7 +116,7 @@ export function MonthGrid({
|
|
|
116
116
|
// designer's "Rigid Border Trapping" — a full-strength line on all four
|
|
117
117
|
// sides of 42 boxes reads as the wireframe it is, and the events inside
|
|
118
118
|
// lose. The OUTER frame keeps full strength so the grid still has an edge.
|
|
119
|
-
'group flex min-h-
|
|
119
|
+
'group flex min-h-28 min-w-0 flex-col gap-1 overflow-hidden border-b border-r border-border/40 p-1 last:border-r-0',
|
|
120
120
|
'sm:min-h-24',
|
|
121
121
|
clickable && 'cursor-pointer hover:bg-muted/30',
|
|
122
122
|
// Out-of-month days are the SAME grid, half-present: a tint plus a muted
|
|
@@ -96,7 +96,7 @@ export function WeekView({
|
|
|
96
96
|
key={dayKey}
|
|
97
97
|
onClick={() => onSelectDay(day)}
|
|
98
98
|
className={cn(
|
|
99
|
-
'group flex min-h-
|
|
99
|
+
'group flex min-h-40 min-w-0 cursor-pointer flex-col gap-1 overflow-hidden',
|
|
100
100
|
'border-r border-border p-1 last:border-r-0',
|
|
101
101
|
'hover:bg-muted/30',
|
|
102
102
|
dayKey === today && 'bg-accent/5',
|
|
@@ -110,7 +110,7 @@ export function WeekView({
|
|
|
110
110
|
onSelectDay(day);
|
|
111
111
|
}}
|
|
112
112
|
className={cn(
|
|
113
|
-
'h-auto min-h-
|
|
113
|
+
'h-auto min-h-11 w-auto min-w-11 rounded p-1.5 text-muted-foreground',
|
|
114
114
|
'opacity-0 transition-opacity hover:bg-muted hover:text-foreground',
|
|
115
115
|
'focus:opacity-100 group-hover:opacity-100',
|
|
116
116
|
TAP_TARGET_ALWAYS,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import { devWarnOnce } from '../lib/devWarn.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether the element being rendered already sits inside an in-flow card — a
|
|
6
|
+
* `Surface` other than an overlay, or a `Section variant="card"`.
|
|
7
|
+
*
|
|
8
|
+
* `docs/design/page-layout.md` LAY-5: three levels of container, never four — the
|
|
9
|
+
* canvas, one card for a region, then groups separated by whitespace or a rule. A
|
|
10
|
+
* card inside a card is the fourth level. It is an authoring mistake, not a runtime
|
|
11
|
+
* error, so it warns once in dev rather than throwing (task 2461).
|
|
12
|
+
*
|
|
13
|
+
* An overlay (a Modal's sheet) does not count: a card group inside a dialog is the
|
|
14
|
+
* vault new-entry case `Section`'s `card` variant exists for.
|
|
15
|
+
*/
|
|
16
|
+
export const CardFrameContext = createContext(false);
|
|
17
|
+
|
|
18
|
+
/** Warn once (dev only) when a card renders inside another card. */
|
|
19
|
+
export function useCardNestingWarning(isCard: boolean, who: string): void {
|
|
20
|
+
const inCard = useContext(CardFrameContext);
|
|
21
|
+
if (isCard && inCard) {
|
|
22
|
+
devWarnOnce(
|
|
23
|
+
`card-in-card:${who}`,
|
|
24
|
+
`cursedbelt: a ${who} card is nested inside another card — a box inside a box (docs/design/page-layout.md LAY-5). ` +
|
|
25
|
+
'Separate the groups inside a card with whitespace or a rule: use the default cardless Section.',
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|