cursedbelt 5.87.0 → 5.89.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/looks.css +4 -4
- package/dist/react/Toast.js +2 -2
- package/dist/react/Toast.js.map +1 -1
- package/dist/react/VirtualCardGrid.d.ts +1 -1
- package/dist/react/VirtualCardGrid.js +1 -1
- package/dist/react/activity-bar/ActivityBar.d.ts +2 -2
- package/dist/react/activity-bar/ActivityBar.js +1 -1
- package/dist/react/activity-bar/activityBar.css +4 -4
- package/dist/react/analytics/AnalyticsPanel.d.ts +1 -1
- package/dist/react/analytics/AnalyticsPanel.js +1 -1
- package/dist/react/canvas-hud/CanvasMinimap.d.ts +1 -1
- package/dist/react/canvas-hud/HudControls.d.ts +2 -2
- package/dist/react/canvas-hud/alignment.d.ts +2 -2
- package/dist/react/canvas-hud/alignment.js +3 -3
- package/dist/react/canvas-hud/alignment.js.map +1 -1
- package/dist/react/canvas-hud/viewport.d.ts +1 -1
- package/dist/react/canvas-hud/viewport.js +1 -1
- package/dist/react/charts/BarChart.d.ts +2 -2
- package/dist/react/charts/HeatmapChart.d.ts +1 -1
- package/dist/react/charts/HeatmapChart.js +1 -1
- package/dist/react/charts/IntervalTimeline.d.ts +2 -2
- package/dist/react/charts/IntervalTimeline.d.ts.map +1 -1
- package/dist/react/charts/categorical.d.ts +11 -11
- package/dist/react/charts/categorical.js +9 -9
- package/dist/react/charts/categorical.js.map +1 -1
- package/dist/react/charts/ink.d.ts +5 -5
- package/dist/react/charts/ink.js +5 -5
- package/dist/react/charts/tokens.d.ts +1 -1
- package/dist/react/charts/tokens.js +1 -1
- package/dist/react/chat/Bubble.js +1 -1
- package/dist/react/chat/Bubble.js.map +1 -1
- package/dist/react/chat/DateMarker.js +1 -1
- package/dist/react/chat/MessageComposer.d.ts +1 -1
- package/dist/react/chat/types.d.ts +1 -1
- package/dist/react/chat/usePresence.d.ts +2 -2
- package/dist/react/chat/usePresence.js +1 -1
- package/dist/react/code-editor/markdownRules.js +1 -1
- package/dist/react/code-editor/markdownRules.js.map +1 -1
- package/dist/react/components/Badge.js +1 -1
- package/dist/react/components/Badge.js.map +1 -1
- package/dist/react/components/Button.js +5 -5
- package/dist/react/components/Button.js.map +1 -1
- package/dist/react/components/ChartTablePanel.js +1 -1
- package/dist/react/components/ChartTablePanel.js.map +1 -1
- package/dist/react/components/Checkbox.js +2 -2
- package/dist/react/components/Checkbox.js.map +1 -1
- package/dist/react/components/ChoiceGroup.d.ts +1 -1
- package/dist/react/components/ChoiceGroup.js +1 -1
- package/dist/react/components/CodeChip.d.ts +1 -1
- package/dist/react/components/CodeChip.js +1 -1
- package/dist/react/components/ColorSwatches.d.ts +10 -10
- package/dist/react/components/ColorSwatches.d.ts.map +1 -1
- package/dist/react/components/ColorSwatches.js +10 -10
- package/dist/react/components/ColorSwatches.js.map +1 -1
- package/dist/react/components/DataTable/DataTable.d.ts +2 -2
- package/dist/react/components/DataTable/DataTable.js +8 -8
- package/dist/react/components/DataTable/DataTable.js.map +1 -1
- package/dist/react/components/DataTable/SearchBox.js +2 -2
- package/dist/react/components/DataTable/SortHeader.js +1 -1
- package/dist/react/components/DataTable/SortHeader.js.map +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.js +1 -1
- package/dist/react/components/DropdownMenu.js +1 -1
- package/dist/react/components/Field.d.ts +1 -1
- package/dist/react/components/FormPreviewLayout.d.ts +1 -1
- package/dist/react/components/FormPreviewLayout.js +1 -1
- package/dist/react/components/Heat.d.ts +6 -6
- package/dist/react/components/Heat.js +1 -1
- package/dist/react/components/IconPicker.d.ts +8 -8
- package/dist/react/components/IconPicker.d.ts.map +1 -1
- package/dist/react/components/IconPicker.js +6 -6
- package/dist/react/components/IconPicker.js.map +1 -1
- package/dist/react/components/InfoHint.d.ts +1 -1
- package/dist/react/components/InfoHint.js +1 -1
- package/dist/react/components/InheritBadge.js +2 -2
- package/dist/react/components/ListToolbar.d.ts +1 -1
- package/dist/react/components/ListToolbar.js +1 -1
- package/dist/react/components/Menu.d.ts +1 -1
- package/dist/react/components/Menu.d.ts.map +1 -1
- package/dist/react/components/Modal.js +5 -5
- package/dist/react/components/Modal.js.map +1 -1
- package/dist/react/components/Page.d.ts +1 -1
- package/dist/react/components/Page.js +1 -1
- package/dist/react/components/PaneSplit.d.ts +1 -1
- package/dist/react/components/PathText.d.ts +1 -1
- package/dist/react/components/PathText.js +1 -1
- package/dist/react/components/Popover.d.ts +1 -1
- package/dist/react/components/PropertyList.d.ts +1 -1
- package/dist/react/components/PropertyList.js +1 -1
- package/dist/react/components/PropertyPicker.d.ts +2 -2
- package/dist/react/components/PropertyPicker.js +2 -2
- package/dist/react/components/RatingField.js +1 -1
- package/dist/react/components/RatingField.js.map +1 -1
- package/dist/react/components/SaveIndicator.d.ts +2 -2
- package/dist/react/components/SaveIndicator.js +2 -2
- package/dist/react/components/SearchInput.d.ts +1 -1
- package/dist/react/components/SearchInput.d.ts.map +1 -1
- package/dist/react/components/SecretInput.d.ts +1 -1
- package/dist/react/components/Section.d.ts +1 -1
- package/dist/react/components/SectionNav.d.ts +3 -3
- package/dist/react/components/SectionNav.d.ts.map +1 -1
- package/dist/react/components/SectionNav.js +2 -2
- package/dist/react/components/Slider.js +1 -1
- package/dist/react/components/StarRating.js +1 -1
- package/dist/react/components/SwatchPicker.d.ts +6 -6
- package/dist/react/components/SwatchPicker.d.ts.map +1 -1
- package/dist/react/components/SwatchPicker.js +3 -3
- package/dist/react/components/SwatchPicker.js.map +1 -1
- package/dist/react/components/Tooltip.js +1 -1
- package/dist/react/components/TreeView.js +1 -1
- package/dist/react/components/TreeView.js.map +1 -1
- package/dist/react/components/TruncatedText.d.ts +1 -1
- package/dist/react/components/TruncatedText.js +1 -1
- package/dist/react/components/UnstyledButton.d.ts +2 -2
- package/dist/react/components/UnstyledButton.js +2 -2
- package/dist/react/components/auth/AuthCard.js +1 -1
- package/dist/react/components/auth/AuthCard.js.map +1 -1
- package/dist/react/components/buildFreshness.css +2 -2
- package/dist/react/components/calendar/MonthGrid.js +2 -2
- package/dist/react/components/calendar/MonthGrid.js.map +1 -1
- package/dist/react/components/calendar/colorUtils.js +2 -2
- package/dist/react/components/dialog.js +1 -1
- package/dist/react/components/fieldErrorText.d.ts +1 -1
- package/dist/react/components/fieldErrorText.js +1 -1
- package/dist/react/components/paneSplit.css +1 -1
- package/dist/react/components/sharing/ShareEditor.d.ts +5 -1
- package/dist/react/components/sharing/ShareEditor.d.ts.map +1 -1
- package/dist/react/components/sharing/ShareEditor.js +2 -2
- package/dist/react/components/sharing/ShareEditor.js.map +1 -1
- package/dist/react/deep-link/links.d.ts +1 -1
- package/dist/react/deep-link/resume.js +1 -1
- package/dist/react/diff-viewer/DiffViewer.css +1 -1
- package/dist/react/file-tree/FileTree.d.ts +9 -9
- package/dist/react/file-tree/FileTree.js +13 -13
- package/dist/react/file-tree/FileTree.js.map +1 -1
- package/dist/react/file-tree/FolderViewMenus.d.ts +3 -3
- package/dist/react/file-tree/FolderViewMenus.d.ts.map +1 -1
- package/dist/react/file-tree/FolderViewMenus.js +1 -1
- package/dist/react/file-tree/FolderViewMenus.js.map +1 -1
- package/dist/react/file-tree/fileTree.css +14 -14
- package/dist/react/file-tree/fileTreeSelection.d.ts +3 -3
- package/dist/react/file-tree/fileTreeSelection.js +4 -4
- package/dist/react/file-tree/folderView.d.ts +3 -3
- package/dist/react/file-tree/folderView.d.ts.map +1 -1
- package/dist/react/file-tree/folderView.js +3 -3
- package/dist/react/file-tree/folderView.js.map +1 -1
- package/dist/react/filter-rail/FilterRail.d.ts +3 -3
- package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
- package/dist/react/filter-rail/FilterRail.js +1 -1
- package/dist/react/filter-rail/RailSection.d.ts +1 -1
- package/dist/react/filter-rail/railResize.d.ts +1 -1
- package/dist/react/filter-rail/railResize.js +1 -1
- package/dist/react/folder-tree/FolderBreadcrumb.d.ts +1 -1
- package/dist/react/folder-tree/NewFolderControl.js +1 -1
- package/dist/react/hooks/keyboardDnd.d.ts +1 -1
- package/dist/react/hooks/keyboardDnd.d.ts.map +1 -1
- package/dist/react/hooks/keyboardDnd.js +2 -2
- package/dist/react/hooks/keyboardDnd.js.map +1 -1
- package/dist/react/hooks/pointerDnd.d.ts +2 -2
- package/dist/react/hooks/pointerDnd.d.ts.map +1 -1
- package/dist/react/hooks/pointerDnd.js +1 -1
- package/dist/react/hooks/usePointerDrag.d.ts +2 -2
- package/dist/react/icons.d.ts +16 -9
- package/dist/react/icons.d.ts.map +1 -1
- package/dist/react/icons.js +17 -10
- package/dist/react/icons.js.map +1 -1
- package/dist/react/layoutEngine/LayoutRenderer.js +1 -1
- package/dist/react/layoutEngine/LayoutRenderer.js.map +1 -1
- package/dist/react/lib/cn.d.ts +3 -3
- package/dist/react/lib/cn.js +4 -4
- package/dist/react/lib/field.d.ts +1 -1
- package/dist/react/lib/floatingContainer.d.ts +1 -1
- package/dist/react/lib/floatingContainer.js +1 -1
- package/dist/react/lib/floatingStyles.d.ts +1 -1
- package/dist/react/lib/floatingStyles.js +2 -2
- package/dist/react/lib/floatingStyles.js.map +1 -1
- package/dist/react/lib/hoverIntent.d.ts +6 -6
- package/dist/react/lib/hoverIntent.js +6 -6
- package/dist/react/lib/infoHint.d.ts +1 -1
- package/dist/react/lib/infoHint.js +1 -1
- package/dist/react/lib/overlayMotion.d.ts +1 -1
- package/dist/react/lib/overlayMotion.d.ts.map +1 -1
- package/dist/react/lib/overlayMotion.js +1 -1
- package/dist/react/lib/overlayMotion.js.map +1 -1
- package/dist/react/lib/press.d.ts +1 -1
- package/dist/react/lib/press.js +1 -1
- package/dist/react/lib/selectField.d.ts +2 -2
- package/dist/react/lib/selectField.d.ts.map +1 -1
- package/dist/react/lib/selectField.js +2 -2
- package/dist/react/lib/selectField.js.map +1 -1
- package/dist/react/look/AppearanceMenu.d.ts +1 -1
- package/dist/react/look/AppearanceMenu.js +1 -1
- package/dist/react/look/LookPicker.d.ts +3 -3
- package/dist/react/look/LookPicker.js +3 -3
- package/dist/react/look/lookStore.d.ts +1 -1
- package/dist/react/look/lookStore.js +4 -4
- package/dist/react/look/lookStore.js.map +1 -1
- package/dist/react/master-lock/MasterLockDialog.js +2 -2
- package/dist/react/master-lock/MasterLockDialog.js.map +1 -1
- package/dist/react/master-lock/MasterLockProvider.d.ts +1 -1
- package/dist/react/media/DenseGalleryShell.d.ts +3 -3
- package/dist/react/media/FocusViewer.js +3 -3
- package/dist/react/media/FocusViewer.js.map +1 -1
- package/dist/react/media/FrameGrabber.js +3 -3
- package/dist/react/media/FrameGrabber.js.map +1 -1
- package/dist/react/media/HoverScrubVideoThumb.d.ts +1 -1
- package/dist/react/media/HoverScrubVideoThumb.js +1 -1
- package/dist/react/media/HoverScrubVideoThumb.js.map +1 -1
- package/dist/react/media/MediaCell.d.ts +1 -1
- package/dist/react/media/MediaCell.js +1 -1
- package/dist/react/media/MediaResize.d.ts +1 -1
- package/dist/react/media/MediaThumb.d.ts +1 -1
- package/dist/react/media/PictureControls.d.ts +1 -1
- package/dist/react/media/PictureControls.js +2 -2
- package/dist/react/media/PictureControls.js.map +1 -1
- package/dist/react/media/PictureEditor.js +2 -2
- package/dist/react/media/PictureEditor.js.map +1 -1
- package/dist/react/media/PlayerStrip.d.ts +4 -4
- package/dist/react/media/PlayerStrip.d.ts.map +1 -1
- package/dist/react/media/PlayerStrip.js +2 -2
- package/dist/react/media/VideoPlayer.d.ts +3 -3
- package/dist/react/media/VideoPlayer.js +5 -5
- package/dist/react/media/VideoTurner.js +1 -1
- package/dist/react/media/VideoTurner.js.map +1 -1
- package/dist/react/media/VirtualizedRows.d.ts +1 -1
- package/dist/react/media/denseGallery.css +7 -7
- package/dist/react/media/focusViewer.css +2 -2
- package/dist/react/media/gifEncode.d.ts +4 -4
- package/dist/react/media/gifEncode.d.ts.map +1 -1
- package/dist/react/media/gifEncode.js +8 -8
- package/dist/react/media/gifEncode.js.map +1 -1
- package/dist/react/media/gifRecord.js +1 -1
- package/dist/react/media/gifRecord.js.map +1 -1
- package/dist/react/media/hlsSource.js +2 -2
- package/dist/react/media/hlsSource.js.map +1 -1
- package/dist/react/media/mediaResize.css +3 -3
- package/dist/react/media/pictureEdit.d.ts +1 -1
- package/dist/react/media/pictureEdit.js +4 -4
- package/dist/react/media/pictureEdit.js.map +1 -1
- package/dist/react/media/pictureEditor.css +6 -6
- package/dist/react/media/playerSpaceKey.js +3 -3
- package/dist/react/media/playerStrip.css +11 -11
- package/dist/react/media/posterFraming.d.ts +2 -2
- package/dist/react/media/posterFraming.d.ts.map +1 -1
- package/dist/react/media/posterFraming.js +4 -4
- package/dist/react/media/posterFraming.js.map +1 -1
- package/dist/react/media/sourceFault.d.ts +2 -2
- package/dist/react/media/sourceFault.js +1 -1
- package/dist/react/media/stageResize.d.ts +1 -1
- package/dist/react/media/stageResize.js +1 -1
- package/dist/react/media/surfaceGesture.d.ts +1 -1
- package/dist/react/media/surfaceGesture.js +1 -1
- package/dist/react/media/types.d.ts +1 -1
- package/dist/react/media/videoChapterEditor.css +1 -1
- package/dist/react/media/videoChapters.d.ts +1 -1
- package/dist/react/media/videoChapters.js +1 -1
- package/dist/react/media/videoCutEditor.css +2 -2
- package/dist/react/media/videoEnhance.d.ts +2 -2
- package/dist/react/media/videoEnhance.js +2 -2
- package/dist/react/media/videoPoster.d.ts +3 -3
- package/dist/react/media/videoPoster.d.ts.map +1 -1
- package/dist/react/media/videoPoster.js +4 -4
- package/dist/react/media/videoPoster.js.map +1 -1
- package/dist/react/media/videoRegion.d.ts +8 -8
- package/dist/react/media/videoRegion.js +8 -8
- package/dist/react/media-gallery/MediaGallery.d.ts +2 -2
- package/dist/react/media-gallery/MediaGallery.d.ts.map +1 -1
- package/dist/react/media-gallery/MediaGallery.js +17 -17
- package/dist/react/media-gallery/MediaGallery.js.map +1 -1
- package/dist/react/media-gallery/MediaMetaEditor.js +1 -1
- package/dist/react/media-gallery/galleryDeepLink.d.ts +1 -1
- package/dist/react/media-gallery/galleryDeepLink.js +2 -2
- package/dist/react/media-gallery/galleryItemMedia.d.ts +1 -1
- package/dist/react/media-gallery/galleryItemMedia.js +1 -1
- package/dist/react/media-gallery/galleryReturn.d.ts +1 -1
- package/dist/react/media-gallery/galleryReturn.js +2 -2
- package/dist/react/media-gallery/mediaGallery.css +10 -10
- package/dist/react/media-gallery/mediaGalleryModel.d.ts +1 -1
- package/dist/react/media-gallery/mediaGalleryModel.js +1 -1
- package/dist/react/media-gallery/playbackPreferences.d.ts +3 -3
- package/dist/react/media-gallery/playbackPreferences.js +2 -2
- package/dist/react/media-gallery/playbackRun.d.ts +1 -1
- package/dist/react/media-gallery/playbackRun.js +1 -1
- package/dist/react/media-gallery/preferenceSync.js +1 -1
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts +1 -1
- package/dist/react/nav/BreadcrumbTrail.d.ts +1 -1
- package/dist/react/nav/BreadcrumbTrail.js +1 -1
- package/dist/react/nav/Breadcrumbs.d.ts +1 -1
- package/dist/react/nav/Breadcrumbs.js +1 -1
- package/dist/react/nav/HeaderSearch.d.ts +3 -3
- package/dist/react/nav/HeaderSearch.d.ts.map +1 -1
- package/dist/react/nav/HeaderSearch.js +2 -2
- package/dist/react/nav/PlaceBar.d.ts +1 -1
- package/dist/react/nav/PlaceBar.js +2 -2
- package/dist/react/nav/SearchResults.d.ts +2 -2
- package/dist/react/nav/SearchResults.d.ts.map +1 -1
- package/dist/react/nav/SearchResults.js +1 -1
- package/dist/react/nav/TopBar.js +1 -1
- package/dist/react/nav/breadcrumbStore.js +1 -1
- package/dist/react/nav/navShared.d.ts +1 -1
- package/dist/react/palette/CommandPalette.js +1 -1
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/react/pdf-viewer/PdfPage.js +1 -1
- package/dist/react/pdf-viewer/PdfPage.js.map +1 -1
- package/dist/react/spreadsheet/SpreadsheetGrid.d.ts +1 -1
- package/dist/react/spreadsheet/useGlideTheme.js +2 -2
- package/dist/react/workbook-viewer/WorkbookViewer.js +1 -1
- package/dist/react/workbook-viewer/WorkbookViewer.js.map +1 -1
- package/dist/styles-areas/notifications.css +1 -1
- package/dist/styles-static.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/testing/designAudit.d.ts +2 -2
- package/dist/testing/designAudit.js +3 -3
- package/dist/testing/designAudit.js.map +1 -1
- package/dist/testing/phoneRules.d.ts +4 -4
- package/dist/testing/phoneRules.js +4 -4
- package/dist/testing/phoneRules.js.map +1 -1
- package/dist/theme.css +10 -10
- package/package.json +1 -1
- package/scripts/attributesForwarded.ts +1 -1
- package/scripts/checkAreaStyles.ts +2 -2
- package/scripts/cssRules.ts +2 -2
- package/scripts/demoCoverage.ts +1 -1
- package/scripts/demoServer.ts +1 -1
- package/scripts/generateStaticStyles.ts +1 -1
- package/scripts/guardrailsEnforce.spec.ts +14 -14
- package/scripts/guardrailsEnforce.ts +25 -25
- package/scripts/paths.ts +1 -1
- package/scripts/styleAreas.ts +2 -2
- package/scripts/testTmpRoot.ts +1 -1
- package/src/buildIsStaged.spec.ts +1 -1
- package/src/iframesMakeNoRealRequest.spec.ts +1 -1
- package/src/looks.css +4 -4
- package/src/looks.spec.ts +3 -3
- package/src/namedSubpathsResolve.spec.ts +2 -2
- package/src/publishShape.spec.ts +1 -1
- package/src/react/Toast.spec.tsx +1 -1
- package/src/react/Toast.tsx +2 -2
- package/src/react/VirtualCardGrid.spec.tsx +1 -1
- package/src/react/VirtualCardGrid.tsx +3 -3
- package/src/react/activity-bar/ActivityBar.spec.tsx +2 -2
- package/src/react/activity-bar/ActivityBar.tsx +4 -4
- package/src/react/activity-bar/activityBar.css +4 -4
- package/src/react/analytics/AnalyticsPanel.tsx +1 -1
- package/src/react/canvas-hud/CanvasMinimap.tsx +1 -1
- package/src/react/canvas-hud/HudControls.spec.tsx +1 -1
- package/src/react/canvas-hud/HudControls.tsx +2 -2
- package/src/react/canvas-hud/alignment.spec.tsx +4 -4
- package/src/react/canvas-hud/alignment.ts +3 -3
- package/src/react/canvas-hud/viewport.spec.ts +1 -1
- package/src/react/canvas-hud/viewport.ts +1 -1
- package/src/react/charts/BarChart.tsx +2 -2
- package/src/react/charts/HeatmapChart.spec.ts +1 -1
- package/src/react/charts/HeatmapChart.tsx +1 -1
- package/src/react/charts/IntervalTimeline.color.spec.tsx +6 -6
- package/src/react/charts/IntervalTimeline.tsx +2 -2
- package/src/react/charts/Treemap.tsx +1 -1
- package/src/react/charts/accentCollision.spec.ts +1 -1
- package/src/react/charts/categorical.spec.ts +3 -3
- package/src/react/charts/categorical.ts +12 -12
- package/src/react/charts/ink.spec.ts +1 -1
- package/src/react/charts/ink.ts +5 -5
- package/src/react/charts/tokens.ts +1 -1
- package/src/react/chat/Bubble.tsx +1 -1
- package/src/react/chat/DateMarker.tsx +2 -2
- package/src/react/chat/MessageComposer.tsx +1 -1
- package/src/react/chat/PresenceRoster.tsx +2 -2
- package/src/react/chat/types.ts +1 -1
- package/src/react/chat/usePresence.ts +2 -2
- package/src/react/code-editor/markdownRules.ts +1 -1
- package/src/react/components/AvatarStack.spec.tsx +2 -2
- package/src/react/components/AvatarStack.tsx +2 -2
- package/src/react/components/Badge.capsule.spec.ts +6 -6
- package/src/react/components/Badge.tsx +1 -1
- package/src/react/components/Button.spec.tsx +1 -1
- package/src/react/components/Button.tsx +5 -5
- package/src/react/components/ChartTablePanel.tsx +1 -1
- package/src/react/components/Checkbox.spec.tsx +2 -2
- package/src/react/components/Checkbox.tsx +2 -2
- package/src/react/components/ChoiceGroup.tsx +1 -1
- package/src/react/components/CodeChip.spec.tsx +1 -1
- package/src/react/components/CodeChip.tsx +1 -1
- package/src/react/components/ColorSwatches.spec.tsx +9 -9
- package/src/react/components/ColorSwatches.tsx +16 -16
- package/src/react/components/CommentThread.tsx +1 -1
- package/src/react/components/ConnectionHealer.tsx +1 -1
- package/src/react/components/DataTable/DataTable.spec.tsx +2 -2
- package/src/react/components/DataTable/DataTable.tsx +10 -10
- package/src/react/components/DataTable/SearchBox.tsx +2 -2
- package/src/react/components/DataTable/SortHeader.tsx +1 -1
- package/src/react/components/DataTable/TableFilterBuilder.tsx +1 -1
- package/src/react/components/DataTable/selection.spec.tsx +1 -1
- package/src/react/components/DataTable/virtualize.spec.tsx +1 -1
- package/src/react/components/DropdownMenu.tsx +1 -1
- package/src/react/components/Field.tsx +1 -1
- package/src/react/components/FormPreviewLayout.tsx +1 -1
- package/src/react/components/Heat.spec.tsx +1 -1
- package/src/react/components/Heat.tsx +6 -6
- package/src/react/components/IconPicker.spec.tsx +1 -1
- package/src/react/components/IconPicker.tsx +9 -9
- package/src/react/components/InfoHint.spec.tsx +2 -2
- package/src/react/components/InfoHint.tsx +1 -1
- package/src/react/components/InheritBadge.tsx +2 -2
- package/src/react/components/IsolatedFrame.tsx +1 -1
- package/src/react/components/ListToolbar.tsx +1 -1
- package/src/react/components/Menu.tsx +1 -1
- package/src/react/components/Modal.tsx +5 -5
- package/src/react/components/Page.spec.tsx +1 -1
- package/src/react/components/Page.tsx +2 -2
- package/src/react/components/PaneSplit.tsx +1 -1
- package/src/react/components/PathText.tsx +1 -1
- package/src/react/components/PointerDrag.spec.tsx +1 -1
- package/src/react/components/Popover.spec.tsx +2 -2
- package/src/react/components/Popover.tsx +1 -1
- package/src/react/components/PropertyList.tsx +1 -1
- package/src/react/components/PropertyPicker.tsx +2 -2
- package/src/react/components/RatingField.tsx +1 -1
- package/src/react/components/SaveIndicator.tsx +2 -2
- package/src/react/components/SearchInput.tsx +1 -1
- package/src/react/components/SecretInput.tsx +1 -1
- package/src/react/components/Section.tsx +1 -1
- package/src/react/components/SectionNav.spec.tsx +3 -3
- package/src/react/components/SectionNav.tsx +3 -3
- package/src/react/components/SelectField.spec.tsx +1 -1
- package/src/react/components/Slider.tsx +1 -1
- package/src/react/components/StarRating.spec.tsx +4 -4
- package/src/react/components/StarRating.tsx +3 -3
- package/src/react/components/SwatchPicker.spec.tsx +4 -4
- package/src/react/components/SwatchPicker.tsx +9 -9
- package/src/react/components/Tooltip.spec.tsx +3 -3
- package/src/react/components/Tooltip.tsx +1 -1
- package/src/react/components/TreeView.tsx +1 -1
- package/src/react/components/TruncatedText.tsx +1 -1
- package/src/react/components/UnstyledButton.tsx +2 -2
- package/src/react/components/auth/AuthCard.tsx +1 -1
- package/src/react/components/buildFreshness.css +2 -2
- package/src/react/components/calendar/EventChip.spec.tsx +2 -2
- package/src/react/components/calendar/MonthGrid.tsx +2 -2
- package/src/react/components/calendar/colorUtils.ts +2 -2
- package/src/react/components/dialog.tsx +1 -1
- package/src/react/components/fieldErrorText.tsx +1 -1
- package/src/react/components/paneSplit.css +1 -1
- package/src/react/components/sharing/ShareEditor.spec.tsx +15 -0
- package/src/react/components/sharing/ShareEditor.tsx +14 -3
- package/src/react/deep-link/links.spec.ts +1 -1
- package/src/react/deep-link/links.ts +1 -1
- package/src/react/deep-link/resume.spec.tsx +1 -1
- package/src/react/deep-link/resume.ts +1 -1
- package/src/react/diff-viewer/DiffViewer.css +1 -1
- package/src/react/file-tree/FileTree.spec.tsx +13 -13
- package/src/react/file-tree/FileTree.tsx +22 -22
- package/src/react/file-tree/FolderViewMenus.tsx +3 -3
- package/src/react/file-tree/FolderViewPanels.tsx +1 -1
- package/src/react/file-tree/fileTree.css +14 -14
- package/src/react/file-tree/fileTreeGeometry.spec.ts +5 -5
- package/src/react/file-tree/fileTreeSelection.ts +4 -4
- package/src/react/file-tree/folderView.spec.ts +1 -1
- package/src/react/file-tree/folderView.ts +3 -3
- package/src/react/filter-rail/FilterRail.spec.tsx +1 -1
- package/src/react/filter-rail/FilterRail.tsx +4 -4
- package/src/react/filter-rail/RailSection.spec.tsx +2 -2
- package/src/react/filter-rail/RailSection.tsx +1 -1
- package/src/react/filter-rail/railResize.tsx +1 -1
- package/src/react/folder-tree/FolderBreadcrumb.tsx +1 -1
- package/src/react/folder-tree/NewFolderControl.tsx +1 -1
- package/src/react/hooks/keyboardDnd.spec.tsx +1 -1
- package/src/react/hooks/keyboardDnd.tsx +2 -2
- package/src/react/hooks/pointerDnd.spec.ts +3 -3
- package/src/react/hooks/pointerDnd.ts +2 -2
- package/src/react/hooks/useOutsidePress.spec.tsx +1 -1
- package/src/react/hooks/usePointerDrag.ts +2 -2
- package/src/react/icons.tsx +18 -11
- package/src/react/keep-awake/keepAwakeEngine.spec.ts +1 -1
- package/src/react/layoutEngine/LayoutConfigDialog.tsx +1 -1
- package/src/react/layoutEngine/LayoutRenderer.tsx +1 -1
- package/src/react/layoutEngine/gridClasses.spec.ts +3 -3
- package/src/react/lib/cn.spec.ts +1 -1
- package/src/react/lib/cn.ts +4 -4
- package/src/react/lib/directUpload.spec.ts +1 -1
- package/src/react/lib/field.ts +1 -1
- package/src/react/lib/floatingContainer.ts +1 -1
- package/src/react/lib/floatingStyles.spec.ts +1 -1
- package/src/react/lib/floatingStyles.ts +2 -2
- package/src/react/lib/hoverIntent.ts +6 -6
- package/src/react/lib/infoHint.ts +1 -1
- package/src/react/lib/overlayMotion.ts +1 -1
- package/src/react/lib/press.ts +1 -1
- package/src/react/lib/selectField.ts +2 -2
- package/src/react/lib/zodResolver.ts +1 -1
- package/src/react/look/AppearanceMenu.tsx +1 -1
- package/src/react/look/LookPicker.tsx +3 -3
- package/src/react/look/lookStore.ts +4 -4
- package/src/react/markdown/MarkdownDoc.spec.tsx +1 -1
- package/src/react/master-detail/MasterDetail.tsx +1 -1
- package/src/react/master-lock/MasterLockDialog.tsx +2 -2
- package/src/react/master-lock/MasterLockProvider.spec.tsx +1 -1
- package/src/react/master-lock/MasterLockProvider.tsx +1 -1
- package/src/react/media/DenseGalleryShell.tsx +3 -3
- package/src/react/media/FocusViewer.tsx +3 -3
- package/src/react/media/FrameGrabber.spec.tsx +2 -2
- package/src/react/media/FrameGrabber.tsx +3 -3
- package/src/react/media/HoverScrubVideoThumb.tsx +3 -3
- package/src/react/media/MediaCell.tsx +1 -1
- package/src/react/media/MediaResize.spec.tsx +4 -4
- package/src/react/media/MediaResize.tsx +1 -1
- package/src/react/media/MediaThumb.tsx +1 -1
- package/src/react/media/PictureControls.tsx +2 -2
- package/src/react/media/PictureEditor.tsx +2 -2
- package/src/react/media/PlayerStrip.tsx +9 -9
- package/src/react/media/VideoChapterEditor.tsx +1 -1
- package/src/react/media/VideoCutEditor.spec.tsx +1 -1
- package/src/react/media/VideoCutEditor.tsx +1 -1
- package/src/react/media/VideoPlayer.spec.tsx +7 -7
- package/src/react/media/VideoPlayer.tsx +6 -6
- package/src/react/media/VideoTurner.tsx +1 -1
- package/src/react/media/VirtualizedRows.tsx +1 -1
- package/src/react/media/denseGallery.css +7 -7
- package/src/react/media/focusViewer.css +2 -2
- package/src/react/media/focusViewer.css.spec.ts +1 -1
- package/src/react/media/gifEncode.spec.ts +2 -2
- package/src/react/media/gifEncode.ts +9 -9
- package/src/react/media/gifRecord.ts +1 -1
- package/src/react/media/hlsSource.recovery.spec.ts +2 -2
- package/src/react/media/hlsSource.spec.ts +1 -1
- package/src/react/media/hlsSource.ts +2 -2
- package/src/react/media/mediaResize.css +3 -3
- package/src/react/media/pictureEdit.spec.ts +5 -5
- package/src/react/media/pictureEdit.ts +4 -4
- package/src/react/media/pictureEditor.css +6 -6
- package/src/react/media/playerSpaceKey.ts +3 -3
- package/src/react/media/playerStrip.css +11 -11
- package/src/react/media/playerStrip.spec.tsx +17 -13
- package/src/react/media/posterFraming.spec.ts +4 -4
- package/src/react/media/posterFraming.ts +5 -5
- package/src/react/media/sourceFault.tsx +2 -2
- package/src/react/media/stageResize.ts +1 -1
- package/src/react/media/surfaceGesture.ts +1 -1
- package/src/react/media/types.ts +1 -1
- package/src/react/media/videoChapterEditor.css +1 -1
- package/src/react/media/videoChapters.spec.ts +1 -1
- package/src/react/media/videoChapters.ts +1 -1
- package/src/react/media/videoCutEditor.css +2 -2
- package/src/react/media/videoEnhance.spec.ts +1 -1
- package/src/react/media/videoEnhance.ts +2 -2
- package/src/react/media/videoPoster.spec.ts +3 -3
- package/src/react/media/videoPoster.ts +5 -5
- package/src/react/media/videoRegion.spec.ts +7 -7
- package/src/react/media/videoRegion.ts +8 -8
- package/src/react/media-gallery/GalleryTable.tsx +1 -1
- package/src/react/media-gallery/MediaGallery.spec.tsx +11 -11
- package/src/react/media-gallery/MediaGallery.tsx +23 -23
- package/src/react/media-gallery/MediaMetaEditor.tsx +1 -1
- package/src/react/media-gallery/galleryDeepLink.ts +2 -2
- package/src/react/media-gallery/galleryItemMedia.spec.tsx +1 -1
- package/src/react/media-gallery/galleryItemMedia.tsx +1 -1
- package/src/react/media-gallery/galleryReturn.ts +2 -2
- package/src/react/media-gallery/mediaGallery.css +10 -10
- package/src/react/media-gallery/mediaGalleryModel.ts +1 -1
- package/src/react/media-gallery/playbackPreferences.ts +3 -3
- package/src/react/media-gallery/playbackRun.spec.ts +1 -1
- package/src/react/media-gallery/playbackRun.ts +1 -1
- package/src/react/media-gallery/preferenceSync.ts +1 -1
- package/src/react/namespace/NamespaceTargetCapsule.tsx +1 -1
- package/src/react/nav/BreadcrumbTrail.tsx +1 -1
- package/src/react/nav/Breadcrumbs.tsx +1 -1
- package/src/react/nav/HeaderSearch.tsx +3 -3
- package/src/react/nav/PlaceBar.spec.tsx +4 -4
- package/src/react/nav/PlaceBar.tsx +4 -4
- package/src/react/nav/SearchResults.tsx +2 -2
- package/src/react/nav/TopBar.spec.tsx +1 -1
- package/src/react/nav/TopBar.tsx +1 -1
- package/src/react/nav/breadcrumbStore.ts +1 -1
- package/src/react/nav/breadcrumbSystem.spec.tsx +1 -1
- package/src/react/nav/navShared.tsx +1 -1
- package/src/react/palette/CommandPalette.spec.tsx +1 -1
- package/src/react/palette/CommandPalette.tsx +1 -1
- package/src/react/pdf-viewer/PdfPage.tsx +1 -1
- package/src/react/spreadsheet/SpreadsheetGrid.tsx +1 -1
- package/src/react/spreadsheet/useGlideTheme.ts +2 -2
- package/src/react/workbook-viewer/WorkbookViewer.tsx +1 -1
- package/src/shippedFilesAreTracked.spec.ts +2 -2
- package/src/styles-areas/notifications.css +1 -1
- package/src/styles-static.css +1 -1
- package/src/styles.css +1 -1
- package/src/stylesAreas.spec.ts +1 -1
- package/src/stylesStaticMatches.spec.ts +2 -2
- package/src/stylesUtilitiesMatches.spec.ts +4 -4
- package/src/testing/designAudit.ts +4 -4
- package/src/testing/phoneRules.spec.ts +1 -1
- package/src/testing/phoneRules.ts +7 -7
- package/src/theme.css +10 -10
- package/src/themeColorsResolve.spec.ts +5 -5
- package/src/themeDarkScopeAliases.spec.ts +1 -1
- package/src/verifyGraph.spec.ts +1 -1
|
@@ -132,7 +132,7 @@ describe('the gesture', () => {
|
|
|
132
132
|
|
|
133
133
|
describe('🔴 it is visible at rest — the reported failure', () => {
|
|
134
134
|
test('the bar grip is not painted in --border', () => {
|
|
135
|
-
// The whole 2026-08-25 report. `--border` is the
|
|
135
|
+
// The whole 2026-08-25 report. `--border` is the color of a hairline nobody is meant to
|
|
136
136
|
// look at; the grip has to be findable without hovering the exact 22px it occupies.
|
|
137
137
|
const grip = ruleBody('.cbmr-bar-grip');
|
|
138
138
|
expect(grip).toContain('--muted-foreground');
|
|
@@ -141,7 +141,7 @@ describe('🔴 it is visible at rest — the reported failure', () => {
|
|
|
141
141
|
|
|
142
142
|
test('the corner draws its glyph at rest, not on hover', () => {
|
|
143
143
|
// A rule that only sets `stroke` inside `:hover` is the invisible-affordance bug wearing
|
|
144
|
-
// a different
|
|
144
|
+
// a different color, so the at-rest rule must carry the ink itself.
|
|
145
145
|
expect(ruleBody('.cbmr-corner-glyph')).toContain('stroke:');
|
|
146
146
|
});
|
|
147
147
|
|
|
@@ -271,7 +271,7 @@ describe('🔴 every cb media player offers the gesture', () => {
|
|
|
271
271
|
const source = readFileSync(join(import.meta.dir, file), 'utf8');
|
|
272
272
|
expect(source).toContain('MediaResizeCorner');
|
|
273
273
|
expect(source).toContain('MediaResizeBar');
|
|
274
|
-
// From the shared hook, never a second hand-rolled copy of the pointer
|
|
274
|
+
// From the shared hook, never a second hand-rolled copy of the pointer math — the
|
|
275
275
|
// drift this file exists to prevent.
|
|
276
276
|
expect(source).toContain('useMediaResize');
|
|
277
277
|
/*
|
|
@@ -290,7 +290,7 @@ describe('🔴 every cb media player offers the gesture', () => {
|
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
test('no player hand-rolls the resize
|
|
293
|
+
test('no player hand-rolls the resize math it could share', () => {
|
|
294
294
|
// Narrow on purpose: `FocusViewer` legitimately captures a pointer for its timeline
|
|
295
295
|
// scrub and its marquee. What must not come back is a second copy of the CLAMP, which
|
|
296
296
|
// is the piece that carries the "thumbnails stay visible" rule.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* to make it bigger. A gesture that exists on one of two players reads, from the app, as
|
|
15
15
|
* a gesture that does not exist.
|
|
16
16
|
* 2. **You could not see it.** The handle was a 4px bar in `--border` that only brightened
|
|
17
|
-
* on hover,
|
|
17
|
+
* on hover, centered under the frame. The ask said *"dragging the corner"*, and there was
|
|
18
18
|
* nothing in the corner. An affordance nobody finds has the same value as an absent one,
|
|
19
19
|
* which is why the fix is not "document the bar".
|
|
20
20
|
*
|
|
@@ -55,7 +55,7 @@ export interface MediaThumbProps {
|
|
|
55
55
|
format?: string;
|
|
56
56
|
/**
|
|
57
57
|
* Stable hue (0–360) for the drawn mark, so the same artist/owner/album keeps the same
|
|
58
|
-
*
|
|
58
|
+
* color and a wall of placeholders still reads as organized. Omit for neutral.
|
|
59
59
|
*/
|
|
60
60
|
hue?: number;
|
|
61
61
|
className?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Brightness / contrast /
|
|
2
|
+
* Brightness / contrast / color — the ONE control, wherever a picture is shown.
|
|
3
3
|
*
|
|
4
4
|
* 🔴 cursedbelt's since 2026-08-20 (unit 15). It was already the one control for three
|
|
5
5
|
* surfaces INSIDE apps/collections; the lift makes it the one control for the fleet, which
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
const FIELDS = [
|
|
38
38
|
["brightness", "Brightness"],
|
|
39
39
|
["contrast", "Contrast"],
|
|
40
|
-
["saturation", "
|
|
40
|
+
["saturation", "Color"],
|
|
41
41
|
] as const;
|
|
42
42
|
|
|
43
43
|
export interface PictureControlsProps {
|
|
@@ -292,7 +292,7 @@ export function PictureEditor({
|
|
|
292
292
|
<Tooltip content={hint} key={label}>
|
|
293
293
|
<button
|
|
294
294
|
// guardrails-ignore no-raw-action-button: toolbar pill styled by this module's own
|
|
295
|
-
// plain CSS, matching the gallery's `.cbgd-order-btn`
|
|
295
|
+
// plain CSS, matching the gallery's `.cbgd-order-btn` neighbors.
|
|
296
296
|
type='button'
|
|
297
297
|
className={cn(RAW_BUTTON, 'cbpe-btn')}
|
|
298
298
|
onClick={onClick}
|
|
@@ -582,7 +582,7 @@ export function PictureEditor({
|
|
|
582
582
|
[
|
|
583
583
|
['brightness', 'Brightness'],
|
|
584
584
|
['contrast', 'Contrast'],
|
|
585
|
-
['saturation', '
|
|
585
|
+
['saturation', 'Color'],
|
|
586
586
|
] as const
|
|
587
587
|
).map(([key, label]) => (
|
|
588
588
|
<label className='cbpe-slider' key={key}>
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
* *"the buttons like back and forward and volume look tiny to me"*, and *"completely remove
|
|
25
25
|
* the opaque gray square containers around the back and forward arrows"*. There were no
|
|
26
26
|
* containers. The old strip drew its transport with the EMOJI characters ⏮ ⏭ 🔁 🔊, and the
|
|
27
|
-
* system emoji font renders those two as a
|
|
27
|
+
* system emoji font renders those two as a gray rounded square with black arrows inside it —
|
|
28
28
|
* so the "container" was a glyph, at whatever size the font felt like, and no amount of CSS
|
|
29
29
|
* could have removed it. Every control here is a lucide vector at a uniform 2px stroke, so
|
|
30
|
-
* "
|
|
30
|
+
* "normalize vector stroke weights" and "delete the gray squares" are the same one change.
|
|
31
31
|
*
|
|
32
32
|
* ── Hit targets ─────────────────────────────────────────────────────────────────────────
|
|
33
33
|
* `DESIGN.md` §5 requires 44×44 and wins over the owner's own "at least 40x40" here, which
|
|
@@ -64,7 +64,7 @@ import { RAW_BUTTON } from '../lib/cn.js';
|
|
|
64
64
|
export type PlayerStripRepeat = "off" | "one" | "all";
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
* One app-supplied control — a
|
|
67
|
+
* One app-supplied control — a favorite, a tag, a delete, a queue, a lyrics sheet.
|
|
68
68
|
*
|
|
69
69
|
* 🔴 The reason the strip takes these rather than hard-coding them: the owner's other
|
|
70
70
|
* report against this same bar is *"I want the bottom row … to have clear icons to delete or
|
|
@@ -88,9 +88,9 @@ export interface PlayerStripAction {
|
|
|
88
88
|
* strip; one star that opens them does, at every width.
|
|
89
89
|
*/
|
|
90
90
|
popover?: React.ReactNode;
|
|
91
|
-
/** Drawn in the accent — the "this track IS a
|
|
91
|
+
/** Drawn in the accent — the "this track IS a favorite" state. */
|
|
92
92
|
active?: boolean;
|
|
93
|
-
/** Drawn in the destructive
|
|
93
|
+
/** Drawn in the destructive color on hover. For delete, and nothing else. */
|
|
94
94
|
danger?: boolean;
|
|
95
95
|
disabled?: boolean;
|
|
96
96
|
}
|
|
@@ -132,7 +132,7 @@ export interface PlayerStripProps {
|
|
|
132
132
|
* How many track actions stand as buttons; the rest go behind one `⋯` menu (DAT-5). An
|
|
133
133
|
* action with a `popover` always stands, since a menu item cannot hold a panel. Default:
|
|
134
134
|
* all of them. Six 44px buttons beside the title left it four letters wide at 1440
|
|
135
|
-
* (music, forge task 2475) — the metadata column is a fixed share of a strip whose
|
|
135
|
+
* (music, forge task 2475) — the metadata column is a fixed share of a strip whose center
|
|
136
136
|
* is pinned to the window, so every standing button is taken from the title.
|
|
137
137
|
*/
|
|
138
138
|
inlineActions?: number;
|
|
@@ -411,7 +411,7 @@ export function PlayerStrip({
|
|
|
411
411
|
* future — is visible, and an invisible native range over the whole band.
|
|
412
412
|
*
|
|
413
413
|
* 🔴 `aria-hidden` + `tabIndex={-1}` is deliberate: this is a redundant POINTER
|
|
414
|
-
* affordance for the
|
|
414
|
+
* affordance for the labeled scrubber in the same strip. Two "Seek" sliders in the
|
|
415
415
|
* tab order is a worse screen-reader experience, not a better one.
|
|
416
416
|
*/}
|
|
417
417
|
{seekLine ? (
|
|
@@ -445,7 +445,7 @@ export function PlayerStrip({
|
|
|
445
445
|
<div className="cbps__meta">
|
|
446
446
|
{onReveal ? (
|
|
447
447
|
/* 🔴 The full title and artist, not only what the button DOES. The metadata
|
|
448
|
-
column is a fixed share of a strip whose
|
|
448
|
+
column is a fixed share of a strip whose center is pinned to the window, so
|
|
449
449
|
a long title truncates on a laptop however the columns are balanced — see
|
|
450
450
|
`.cbps__timeline` in the stylesheet for the measurement. The hover is where
|
|
451
451
|
the whole name lives. */
|
|
@@ -469,7 +469,7 @@ export function PlayerStrip({
|
|
|
469
469
|
<ActionButtons actions={trackActions} inline={inlineActions} />
|
|
470
470
|
</div>
|
|
471
471
|
|
|
472
|
-
{/* ──
|
|
472
|
+
{/* ── Center: the controls, over the timeline ────────────────────────────────── */}
|
|
473
473
|
<div className="cbps__centre">
|
|
474
474
|
<div className="cbps__transport">
|
|
475
475
|
{onShuffleChange ? (
|
|
@@ -296,7 +296,7 @@ export function VideoChapterEditor({
|
|
|
296
296
|
/>
|
|
297
297
|
}
|
|
298
298
|
>
|
|
299
|
-
{/* A `<fieldset>`, not a `<div>` with a role: this really is one
|
|
299
|
+
{/* A `<fieldset>`, not a `<div>` with a role: this really is one labeled set of controls
|
|
300
300
|
over one clip, and the native element is what makes a key handler on the container
|
|
301
301
|
legitimate rather than a shortcut hidden on a static box. */}
|
|
302
302
|
<fieldset
|
|
@@ -62,7 +62,7 @@ describe('cut, then mark a piece out', () => {
|
|
|
62
62
|
expect(only.tagName).toBe('BUTTON');
|
|
63
63
|
expect(only.getAttribute('aria-pressed')).toBe('false');
|
|
64
64
|
expect(only.getAttribute('aria-label')).toContain('Remove');
|
|
65
|
-
// The list names itself, so the strip is not an
|
|
65
|
+
// The list names itself, so the strip is not an unlabeled row of stripes.
|
|
66
66
|
expect(document.querySelector('.cbvc-strip')?.getAttribute('aria-label')).toBeTruthy();
|
|
67
67
|
});
|
|
68
68
|
|
|
@@ -277,7 +277,7 @@ export function VideoCutEditor({
|
|
|
277
277
|
/>
|
|
278
278
|
}
|
|
279
279
|
>
|
|
280
|
-
{/* A `<fieldset>`, not a `<div>` with a role: this really is one
|
|
280
|
+
{/* A `<fieldset>`, not a `<div>` with a role: this really is one labeled set of
|
|
281
281
|
controls over one clip, and the native element is what makes a key handler on the
|
|
282
282
|
container legitimate rather than a shortcut hidden on a static box. The keys are in
|
|
283
283
|
the label so they are discoverable without hovering for a tooltip. */}
|
|
@@ -58,7 +58,7 @@ describe('VideoPlayer sizing', () => {
|
|
|
58
58
|
*
|
|
59
59
|
* Fullscreen is the HOST `<div>`'s `onDoubleClick` now, decided by `isSurfaceControl` — see
|
|
60
60
|
* `toggleFullscreenOnSurfaceDoubleClick` and `surfaceGesture.spec.ts`. The single-click
|
|
61
|
-
* gesture stays a gesture: `toggle:paused` over the
|
|
61
|
+
* gesture stays a gesture: `toggle:paused` over the center band is what it is for, and
|
|
62
62
|
* Vidstack already declines it over the controls.
|
|
63
63
|
*/
|
|
64
64
|
test('the surface keeps ONE gesture — play/pause; fullscreen moved to the host', () => {
|
|
@@ -354,7 +354,7 @@ describe('a restored session volume', () => {
|
|
|
354
354
|
* over a remembered volume. The session volume reaches for no web store at all — see
|
|
355
355
|
* `SessionVolume`, which is also why a refresh returns him to mute — so there is nothing
|
|
356
356
|
* here to be denied. Asserted rather than assumed: the day somebody moves it onto
|
|
357
|
-
* `localStorage`/`sessionStorage` without the `try` its
|
|
357
|
+
* `localStorage`/`sessionStorage` without the `try` its neighbors carry, this reds.
|
|
358
358
|
*/
|
|
359
359
|
const original = Object.getOwnPropertyDescriptor(globalThis, 'sessionStorage');
|
|
360
360
|
Object.defineProperty(globalThis, 'sessionStorage', {
|
|
@@ -384,7 +384,7 @@ describe('a restored session volume', () => {
|
|
|
384
384
|
* its own `TimeSlider` and exposes none of its props.
|
|
385
385
|
*
|
|
386
386
|
* The test drives the hook with the event the slider actually dispatches rather than with a
|
|
387
|
-
* real drag: happy-dom has no layout, so a
|
|
387
|
+
* real drag: happy-dom has no layout, so a synthesized pointer sequence over a slider whose
|
|
388
388
|
* `getBoundingClientRect` is all zeroes would compute a position of `NaN` and assert nothing.
|
|
389
389
|
* The e2e half — an actual drag in Chromium — belongs in a consumer's browser smoke.
|
|
390
390
|
*/
|
|
@@ -464,7 +464,7 @@ describe('useLiveScrub — the picture follows the scrub bar', () => {
|
|
|
464
464
|
* The owner's report was *"the play/pause button and the video time section are missing
|
|
465
465
|
* from the player"* in `apps/family`, whose MediaDetail dialog gives the player roughly
|
|
466
466
|
* 400px inside a `max-h-[40vh]` box. Vidstack's own default (`width < 576 or height < 380`)
|
|
467
|
-
* calls that a phone, takes `data-sm`, swaps the bar's play button for a
|
|
467
|
+
* calls that a phone, takes `data-sm`, swaps the bar's play button for a centered overlay and
|
|
468
468
|
* hides `.vds-start-duration` outright once playback starts.
|
|
469
469
|
*
|
|
470
470
|
* These assert the two sizes the decision exists to separate. They are arithmetic on purpose
|
|
@@ -535,7 +535,7 @@ describe('the video layout keeps its controls at dialog size', () => {
|
|
|
535
535
|
*
|
|
536
536
|
* happy-dom does not run Vidstack's layout, so the slots are asserted as the DATA they are —
|
|
537
537
|
* `stepSlots` is exported for exactly that reason — plus one rendered check that the buttons
|
|
538
|
-
* are real,
|
|
538
|
+
* are real, labeled and wired.
|
|
539
539
|
*/
|
|
540
540
|
describe('⏮ / ⏭ section ride beside the chapters menu, in every layout', () => {
|
|
541
541
|
test('a video with sections gets the pair in both layouts; one without gets nothing', () => {
|
|
@@ -552,7 +552,7 @@ describe('🔴 stepping rides inside the player, so it survives fullscreen', ()
|
|
|
552
552
|
const slots = stepSlots(() => undefined, true);
|
|
553
553
|
expect(slots).not.toBeUndefined();
|
|
554
554
|
// The large layout is the desktop bar with the cog; `smallLayout` is the touch one,
|
|
555
|
-
// where the play button becomes a
|
|
555
|
+
// where the play button becomes a center overlay. Leaving the pair out of `smallLayout`
|
|
556
556
|
// deletes stepping on precisely the devices that cannot press ⇧←.
|
|
557
557
|
for (const layout of [slots, slots?.smallLayout, slots?.largeLayout]) {
|
|
558
558
|
expect(layout?.beforePlayButton, 'no Previous beside play').toBeTruthy();
|
|
@@ -564,7 +564,7 @@ describe('🔴 stepping rides inside the player, so it survives fullscreen', ()
|
|
|
564
564
|
expect(stepSlots(undefined, true)).toBeUndefined();
|
|
565
565
|
});
|
|
566
566
|
|
|
567
|
-
test('the buttons are
|
|
567
|
+
test('the buttons are labeled, disable-able and call back with -1 / 1', () => {
|
|
568
568
|
/*
|
|
569
569
|
* 🔴 Read off the SLOT ELEMENTS, not off a render.
|
|
570
570
|
*
|
|
@@ -266,7 +266,7 @@ function StepGlyph({ delta }: { delta: -1 | 1 }) {
|
|
|
266
266
|
* `beforePlayButton` / `afterPlayButton` rather than `beforeSettingsMenu`: the cog names the
|
|
267
267
|
* BAR the owner meant, and inside that bar Prev-Play-Next is the arrangement every player he
|
|
268
268
|
* has ever used puts them in. Both layouts get the same pair — `smallLayout` is the touch
|
|
269
|
-
* bar, where the play button becomes a
|
|
269
|
+
* bar, where the play button becomes a center overlay, and leaving it out would delete the
|
|
270
270
|
* controls again on exactly the devices that cannot press ⇧←.
|
|
271
271
|
*/
|
|
272
272
|
export function stepSlots(
|
|
@@ -323,7 +323,7 @@ function FillWindowGlyph({ active }: { active: boolean }) {
|
|
|
323
323
|
* screen icon in the video player itself."* Full-window mode hides everything around the
|
|
324
324
|
* picture — the titlebar's toggle included, below the fold — so the way out has to ride on
|
|
325
325
|
* the one chrome that is always over the picture. And it sits beside fullscreen because the
|
|
326
|
-
* two are the same kind of choice (how big), the arrangement every player with a
|
|
326
|
+
* two are the same kind of choice (how big), the arrangement every player with a theater
|
|
327
327
|
* mode uses.
|
|
328
328
|
*/
|
|
329
329
|
function fillWindowSlots(
|
|
@@ -358,7 +358,7 @@ function fillWindowSlots(
|
|
|
358
358
|
* a media query. Below it, the layout takes `data-sm` and:
|
|
359
359
|
*
|
|
360
360
|
* - the control bar's play button is replaced by one big round overlay button
|
|
361
|
-
* (`.vds-video-layout[data-sm] .vds-controls .vds-play-button` — 45px,
|
|
361
|
+
* (`.vds-video-layout[data-sm] .vds-controls .vds-play-button` — 45px, centered), and
|
|
362
362
|
* - the time readout becomes `.vds-start-duration`, which the stylesheet hides outright
|
|
363
363
|
* the moment playback starts (`[data-started] … .vds-start-duration .vds-time`).
|
|
364
364
|
*
|
|
@@ -508,7 +508,7 @@ export function resolveAutoplay(opts: {
|
|
|
508
508
|
* misconfiguration and there is no prop for it — `DefaultVideoLayout` builds its own
|
|
509
509
|
* `TimeSlider` and exposes none of its props to us.
|
|
510
510
|
*
|
|
511
|
-
* So we
|
|
511
|
+
* So we honor the drag ourselves: every `media-seeking-request` becomes a real seek. The
|
|
512
512
|
* slider already throttles them to one per 100ms (`seekingRequestThrottle`), which is what
|
|
513
513
|
* keeps a drag across a two-hour film from queuing hundreds of seeks, and the first one
|
|
514
514
|
* fires on POINTERDOWN — which is the *"click on a further ahead spot … and the video
|
|
@@ -812,7 +812,7 @@ export function VideoPlayer({
|
|
|
812
812
|
`<div>`'s `onDoubleClick` above, because a gesture is hit-tested against the
|
|
813
813
|
player and the layout's three `pointer-events: auto` control bands meant the
|
|
814
814
|
owner's double-click did nothing across the top and bottom of the picture. The
|
|
815
|
-
single-click gesture stays a gesture: `toggle:paused` over the
|
|
815
|
+
single-click gesture stays a gesture: `toggle:paused` over the center band is
|
|
816
816
|
exactly what it is for, and Vidstack already declines it over the controls. */}
|
|
817
817
|
<Gesture className='vds-gesture' event='pointerup' action='toggle:paused' />
|
|
818
818
|
<ChaptersTrack chapters={video.chapters} />
|
|
@@ -856,7 +856,7 @@ export function VideoPlayer({
|
|
|
856
856
|
* ── 🔴 Why this is a component and not three lines inside the player ──────────────────
|
|
857
857
|
* Because a chapter cue needs an END, and the only place the clip's real length is known is
|
|
858
858
|
* INSIDE the player. `PlayableVideo.durationSeconds` is optional and frequently absent — and
|
|
859
|
-
* where it is present it is whatever the app's
|
|
859
|
+
* where it is present it is whatever the app's catalog recorded, which is routinely rounded
|
|
860
860
|
* to the second. Building the cues from that would put every divider a fraction out on the one
|
|
861
861
|
* surface where they are compared against the picture, and would draw nothing at all for the
|
|
862
862
|
* ordinary video whose row has no duration on it. `useMediaState('duration')` is the decoder's
|
|
@@ -203,7 +203,7 @@ export function VideoTurner({
|
|
|
203
203
|
<Tooltip content='A quarter turn anticlockwise'>
|
|
204
204
|
<button
|
|
205
205
|
// guardrails-ignore no-raw-action-button: toolbar pill styled by this module's own
|
|
206
|
-
// plain CSS, matching the picture editor's `.cbpe-btn`
|
|
206
|
+
// plain CSS, matching the picture editor's `.cbpe-btn` neighbors.
|
|
207
207
|
type='button'
|
|
208
208
|
className={cn(RAW_BUTTON, 'cbpe-btn')}
|
|
209
209
|
onClick={() => setEdit((e) => rotate(e, -1))}
|
|
@@ -14,7 +14,7 @@ export interface VirtualizedRowsProps {
|
|
|
14
14
|
onDelete?: (item: MediaItem) => void;
|
|
15
15
|
/**
|
|
16
16
|
* Explicit scroll container for virtualization. When omitted (undefined) or null,
|
|
17
|
-
* the
|
|
17
|
+
* the catalog virtualizes against window scroll. An app embedding the catalog
|
|
18
18
|
* inside a bounded `ScrollArea` passes its viewport element so only visible rows mount.
|
|
19
19
|
*/
|
|
20
20
|
scrollRoot?: HTMLElement | null;
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
* A `<label>` wrapping a `<select>`, shaped as one more action pill so the actions row stays
|
|
117
117
|
* the single cohesive line `DESIGN.md` §2 requires rather than growing a second, differently
|
|
118
118
|
* styled control. `min-height` matches `.cbgd-order-btn` exactly — a control one pixel taller
|
|
119
|
-
* than its
|
|
119
|
+
* than its neighbors is what makes a toolbar look assembled rather than designed.
|
|
120
120
|
*
|
|
121
121
|
* The label is 12px, not 11: `DESIGN.md` §4 states a 12px FLOOR for secondary metadata and
|
|
122
122
|
* wins on every conflict. */
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
* construction, and no single constant could have been right for all of them.
|
|
346
346
|
* 2. **The height varied per TILE.** The second line renders only when the item has tags
|
|
347
347
|
* or a size (`GalleryMeta`), so a tile without either was 13px shorter than its
|
|
348
|
-
*
|
|
348
|
+
* neighbor — visible in the owner's screenshot as document cards sitting at different
|
|
349
349
|
* heights within one row.
|
|
350
350
|
*
|
|
351
351
|
* So the block is now exactly `CBGD_META_HEIGHT` tall whatever it contains:
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
* 🔴 The third line is the created date, added 2026-08-14 at the owner's request. It grew this
|
|
360
360
|
* block from 46 to 59, which is exactly the change the warning below is about: the date is
|
|
361
361
|
* OPTIONAL per item (`createdAt` may be missing), so had the height stayed fixed at 46 the
|
|
362
|
-
* tiles with a date would have overlapped their
|
|
362
|
+
* tiles with a date would have overlapped their neighbors — the same bug, from the same
|
|
363
363
|
* cause, that the paragraphs above describe. The block is sized for all three lines whether or
|
|
364
364
|
* not a given tile fills them.
|
|
365
365
|
*
|
|
@@ -492,7 +492,7 @@
|
|
|
492
492
|
*
|
|
493
493
|
* This was a flex ROW with `justify-content: center`, from when the frame was its only
|
|
494
494
|
* child. The resize bar landed on 2026-08-25 as a second child, and a second item in a
|
|
495
|
-
*
|
|
495
|
+
* centered row does not go UNDER the first — it goes BESIDE it. So the grip was drawn to the
|
|
496
496
|
* right of the picture, level with its top, which is what *"cb media players should allow
|
|
497
497
|
* dragging to resize … but it is not there"* was actually describing: it was there, and it
|
|
498
498
|
* was not where a person would ever look for it.
|
|
@@ -505,7 +505,7 @@
|
|
|
505
505
|
* that had nothing to do with it, and `e2e/stage-layout.spec.ts` was measurably red on main
|
|
506
506
|
* because of it.
|
|
507
507
|
*
|
|
508
|
-
* Stacked, each child gets the full row and
|
|
508
|
+
* Stacked, each child gets the full row and centers itself on its own `margin-inline: auto`,
|
|
509
509
|
* so neither can move the other. Do not put this back to a row.
|
|
510
510
|
*/
|
|
511
511
|
.cbgd-watch-player {
|
|
@@ -634,7 +634,7 @@
|
|
|
634
634
|
* of the window. This may mean I have to scroll to see anything under the video at all …
|
|
635
635
|
* and that is ok."* So the detail view covers the whole window (`fixed`, over the app's own
|
|
636
636
|
* toolstrip, sidebar and activity column — none of which this module could otherwise reach),
|
|
637
|
-
* stays the scroll container the related grid
|
|
637
|
+
* stays the scroll container the related grid virtualizes against, and the frame is exactly
|
|
638
638
|
* one window tall and wide. The stage letterboxes inside it as it always does, which is what
|
|
639
639
|
* keeps the aspect ratio and every edge of the picture on screen.
|
|
640
640
|
*
|
|
@@ -684,7 +684,7 @@
|
|
|
684
684
|
opacity: 0.6;
|
|
685
685
|
transition: opacity 120ms ease;
|
|
686
686
|
}
|
|
687
|
-
/* Solid, because what is under it is a picture of any
|
|
687
|
+
/* Solid, because what is under it is a picture of any color. */
|
|
688
688
|
.cbgd-full-exit .cbgd-order-btn {
|
|
689
689
|
background: var(--background);
|
|
690
690
|
color: var(--foreground);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `--text-muted`, `--accent`, `--border` — the first three are theme.css's compatibility
|
|
11
11
|
* aliases for `--background`/`--card-raised`/`--muted-foreground`). It came out of
|
|
12
12
|
* apps/collections, which already read them from the shared theme, so the lift needed no
|
|
13
|
-
*
|
|
13
|
+
* color decisions at all. `theme.tokens.test.ts` is what keeps that true.
|
|
14
14
|
*/
|
|
15
15
|
/* ── The focus viewer ────────────────────────────────────────────────────────────────
|
|
16
16
|
*
|
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
font-size: var(--text-caption);
|
|
205
205
|
font-variant-numeric: tabular-nums;
|
|
206
206
|
/* A SCRIM over arbitrary photograph bytes. There is no theme surface behind this label
|
|
207
|
-
— the backdrop is whatever frame was captured — so a token would be a
|
|
207
|
+
— the backdrop is whatever frame was captured — so a token would be a color chosen
|
|
208
208
|
against a background it will never sit on. White on a black wash is the only pair
|
|
209
209
|
that holds contrast over every possible still.
|
|
210
210
|
guardrails-ignore no-hardcoded-colors: scrim over photo bytes, see above */
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* Every unit test still passed, because none of the arithmetic was wrong; `regionLayout` had
|
|
20
20
|
* dutifully returned `widthPct: 500`. The failure lived entirely in whether the browser
|
|
21
|
-
*
|
|
21
|
+
* honored it. That is what makes it worth a structural check: the escape hatch looks like a
|
|
22
22
|
* redundant line to anyone tidying the stylesheet, and deleting it reintroduces a bug whose
|
|
23
23
|
* symptom (a black viewer) points nowhere near the cause.
|
|
24
24
|
*
|
|
@@ -110,7 +110,7 @@ const paint = (w: number, h: number, at: (x: number, y: number) => [number, numb
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
describe('the GIF encoder', () => {
|
|
113
|
-
test('🔴 a frame of a few flat
|
|
113
|
+
test('🔴 a frame of a few flat colors comes back pixel for pixel, looping forever', () => {
|
|
114
114
|
const colours: [number, number, number][] = [
|
|
115
115
|
[255, 0, 0],
|
|
116
116
|
[0, 128, 255],
|
|
@@ -143,7 +143,7 @@ describe('the GIF encoder', () => {
|
|
|
143
143
|
expect(palette.length).toBe(256 * 3);
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
test('a gradient with more than 256
|
|
146
|
+
test('a gradient with more than 256 colors keeps every pixel within a few levels of the truth', () => {
|
|
147
147
|
const rgba = paint(256, 64, (x, y) => [x, (y * 4) & 255, 255 - x]);
|
|
148
148
|
const { palette, indices } = quantizeFrame(rgba);
|
|
149
149
|
let worst = 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ── A looping GIF, encoded in the browser ────────────────────────────────────────────
|
|
2
2
|
// Owner, 2026-10-11: *"In collections and the cb media player in general allow making a
|
|
3
3
|
// looping gif out of a section of a video."* This is the encoder that ask needs, and only
|
|
4
|
-
// that: GIF89a, a local 256-
|
|
4
|
+
// that: GIF89a, a local 256-color palette per frame, the NETSCAPE2.0 loop block, LZW.
|
|
5
5
|
//
|
|
6
6
|
// 🔴 Written here rather than taken as a dependency. The media entry's heavy libraries are
|
|
7
7
|
// OPTIONAL peers an app has to install and dedupe (see `index.ts`), and the encoder this
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// a global palette would need every frame in memory first — 300 frames of 640×360 RGBA is
|
|
15
15
|
// 276 MB. Each frame is quantized, written and dropped.
|
|
16
16
|
|
|
17
|
-
/** The
|
|
17
|
+
/** The colors one frame is reduced to, and each pixel's index into them. */
|
|
18
18
|
export interface QuantizedFrame {
|
|
19
19
|
/** `r,g,b` triples — at most 256 of them. */
|
|
20
20
|
palette: Uint8Array;
|
|
@@ -26,13 +26,13 @@ const BINS = 1 << 15; // 5 bits a channel
|
|
|
26
26
|
const binOf = (r: number, g: number, b: number): number => ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Median-cut an RGBA frame to at most `maxColors`
|
|
29
|
+
* Median-cut an RGBA frame to at most `maxColors` colors.
|
|
30
30
|
*
|
|
31
31
|
* Pixels are first counted into 32,768 bins (5 bits a channel) holding their true 8-bit
|
|
32
32
|
* sums, so a palette entry is the real average of what it stands for rather than a bin's
|
|
33
33
|
* corner. The box split is the one with the most pixels × widest channel, at its weighted
|
|
34
34
|
* median — the textbook cut, which keeps a big flat sky from eating every entry. A frame with
|
|
35
|
-
* no more than `maxColors` distinct binned
|
|
35
|
+
* no more than `maxColors` distinct binned colors keeps them all.
|
|
36
36
|
*/
|
|
37
37
|
export function quantizeFrame(rgba: Uint8Array | Uint8ClampedArray, maxColors = 256): QuantizedFrame {
|
|
38
38
|
const pixels = rgba.length >> 2;
|
|
@@ -87,7 +87,7 @@ export function quantizeFrame(rgba: Uint8Array | Uint8ClampedArray, maxColors =
|
|
|
87
87
|
pick = i;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
if (pick < 0) break; // every box is one
|
|
90
|
+
if (pick < 0) break; // every box is one color
|
|
91
91
|
const box = boxes[pick] as Box;
|
|
92
92
|
const { c } = box;
|
|
93
93
|
box.bins.sort((a, b) => channel(a, c) - channel(b, c));
|
|
@@ -118,7 +118,7 @@ export function quantizeFrame(rgba: Uint8Array | Uint8ClampedArray, maxColors =
|
|
|
118
118
|
palette[entry * 3 + 2] = Math.round(b / n);
|
|
119
119
|
});
|
|
120
120
|
// Each bin maps to its NEAREST palette entry, not merely the box it fell in: a box's
|
|
121
|
-
// average can sit closer to a
|
|
121
|
+
// average can sit closer to a neighbor's members than to some of its own.
|
|
122
122
|
const entries = palette.length / 3;
|
|
123
123
|
for (const bin of used) {
|
|
124
124
|
const n = count[bin] as number;
|
|
@@ -151,7 +151,7 @@ export function quantizeFrame(rgba: Uint8Array | Uint8ClampedArray, maxColors =
|
|
|
151
151
|
*
|
|
152
152
|
* 🔴 The code width grows when the NEXT code to be assigned reaches `1 << width`, and only
|
|
153
153
|
* then — the decoder learns each entry one code later than the encoder makes it, and growing
|
|
154
|
-
* a code early or late
|
|
154
|
+
* a code early or late desynchronizes every code after it into noise.
|
|
155
155
|
*/
|
|
156
156
|
export function lzwEncode(indices: Uint8Array, minCodeSize = 8): Uint8Array {
|
|
157
157
|
const clear = 1 << minCodeSize;
|
|
@@ -221,7 +221,7 @@ export class GifWriter {
|
|
|
221
221
|
head.set([0x47, 0x49, 0x46, 0x38, 0x39, 0x61]); // GIF89a
|
|
222
222
|
put16(head, 6, width);
|
|
223
223
|
put16(head, 8, height);
|
|
224
|
-
// No global
|
|
224
|
+
// No global color table: every frame carries its own.
|
|
225
225
|
head.set([0x00, 0x00, 0x00], 10);
|
|
226
226
|
// NETSCAPE2.0 application extension — the loop count.
|
|
227
227
|
head.set([0x21, 0xff, 0x0b, ...ascii("NETSCAPE2.0"), 0x03, 0x01], 13);
|
|
@@ -256,7 +256,7 @@ export class GifWriter {
|
|
|
256
256
|
descriptor[0] = 0x2c;
|
|
257
257
|
put16(descriptor, 5, this.width);
|
|
258
258
|
put16(descriptor, 7, this.height);
|
|
259
|
-
descriptor[9] = 0x80 | (tableBits - 1); // a local
|
|
259
|
+
descriptor[9] = 0x80 | (tableBits - 1); // a local color table of 2^tableBits entries
|
|
260
260
|
|
|
261
261
|
// The minimum code size follows the table (never below GIF's floor of 2), so every index
|
|
262
262
|
// is a root code — what every decoder, Safari's included, expects.
|
|
@@ -47,7 +47,7 @@ export async function recordGifClip(video: HTMLVideoElement, options: RecordGifO
|
|
|
47
47
|
const writer = new GifWriter(size.width, size.height);
|
|
48
48
|
try {
|
|
49
49
|
for (const [i, at] of times.entries()) {
|
|
50
|
-
if (options.signal?.aborted) throw new DOMException("The GIF was
|
|
50
|
+
if (options.signal?.aborted) throw new DOMException("The GIF was canceled.", "AbortError");
|
|
51
51
|
await seekForCapture(video, at);
|
|
52
52
|
if (options.filter && "filter" in ctx) ctx.filter = options.filter;
|
|
53
53
|
ctx.drawImage(video, crop.sx, crop.sy, crop.sw, crop.sh, 0, 0, size.width, size.height);
|
|
@@ -144,7 +144,7 @@ describe('attachHlsSource — recovering instead of stopping', () => {
|
|
|
144
144
|
detach();
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
test('an
|
|
147
|
+
test('an unrecognized fatal error goes straight to the remux — a reload does not fix a mux error', async () => {
|
|
148
148
|
installFakeHls();
|
|
149
149
|
const el = videoEl(false);
|
|
150
150
|
const detach = attachHlsSource(el, { hlsUrl: LADDER, streamUrl: REMUX });
|
|
@@ -169,7 +169,7 @@ describe('attachHlsSource — recovering instead of stopping', () => {
|
|
|
169
169
|
emit?.({ fatal: true, type: 'networkError' }); // attempt 1 — 1 s backoff, still pending
|
|
170
170
|
detach();
|
|
171
171
|
await new Promise((r) => setTimeout(r, 1200));
|
|
172
|
-
// Still one. The pending retry was
|
|
172
|
+
// Still one. The pending retry was canceled rather than firing into a destroyed engine.
|
|
173
173
|
expect(calls.filter((c) => c === 'startLoad').length).toBe(1);
|
|
174
174
|
});
|
|
175
175
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test';
|
|
2
2
|
import { attachHlsSource, canPlayHlsNatively } from './hlsSource.js';
|
|
3
3
|
|
|
4
|
-
// 🔴 The RECOVERY specs are a separate file, and the reason is a Bun
|
|
4
|
+
// 🔴 The RECOVERY specs are a separate file, and the reason is a Bun behavior rather than a
|
|
5
5
|
// taste: `mock.module('hls.js', …)` is applied at FILE scope no matter where it is called, so
|
|
6
6
|
// a fake engine registered inside one test is the engine every other test in the file gets.
|
|
7
7
|
// Measured here — "a ladder is preferred over the remux only where it can actually play"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* ── 🔴 An hls.js with no ERROR handler stops for good, and that was this file ────────────
|
|
35
35
|
* Owner report, 2026-09-17: *"sometimes a video is playing and starts buffering and ends up
|
|
36
36
|
* pausing instead of trying to wait it out."* That is not a description of a slow network —
|
|
37
|
-
* it is the documented
|
|
37
|
+
* it is the documented behavior of an unattended hls.js. The library retries a failing
|
|
38
38
|
* fragment on its own (six times, backing off to ~64 s in total) and then emits a FATAL error
|
|
39
39
|
* and **stops the loop**. Recovery is the application's job and always has been; this module
|
|
40
40
|
* was constructing the engine with `new Hls({ enableWorker: true })` and listening to
|
|
@@ -252,7 +252,7 @@ export function attachHlsSource(
|
|
|
252
252
|
engine = null;
|
|
253
253
|
el.src = urls.streamUrl;
|
|
254
254
|
if (at > 0) {
|
|
255
|
-
// `loadedmetadata` is the first moment a seek on a fresh source is
|
|
255
|
+
// `loadedmetadata` is the first moment a seek on a fresh source is honored; setting
|
|
256
256
|
// `currentTime` before it is silently dropped.
|
|
257
257
|
el.addEventListener(
|
|
258
258
|
'loadedmetadata',
|
|
@@ -130,9 +130,9 @@
|
|
|
130
130
|
* The hover plate.
|
|
131
131
|
*
|
|
132
132
|
* 🔴 A TOKEN, where this used to be a hardcoded black radial scrim. The scrim was right while
|
|
133
|
-
* the grip rode on arbitrary media — a photograph has no theme, so app
|
|
133
|
+
* the grip rode on arbitrary media — a photograph has no theme, so app colors tinted it. In
|
|
134
134
|
* the rail the grip rides on app chrome like every other control, so it takes the app's
|
|
135
|
-
*
|
|
135
|
+
* colors and the two `guardrails-ignore no-hardcoded-colors` suppressions this rule used to
|
|
136
136
|
* need are gone with it.
|
|
137
137
|
*/
|
|
138
138
|
.cbmr-corner::before {
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
overflow: visible;
|
|
156
156
|
fill: none;
|
|
157
157
|
/* Legible at rest — see the file header. `--muted-foreground`, never `--border`, which is
|
|
158
|
-
the
|
|
158
|
+
the color of a hairline nobody is meant to look at. */
|
|
159
159
|
stroke: var(--muted-foreground, currentColor);
|
|
160
160
|
stroke-width: 1.6;
|
|
161
161
|
stroke-linecap: round;
|