cursedbelt 1.0.0 → 2.3.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/client/index.js +1 -1
- package/dist/core/category/index.d.ts.map +1 -1
- package/dist/core/category/index.js +2 -1
- package/dist/core/category/index.js.map +1 -1
- package/dist/core/category/types.js +1 -1
- package/dist/core/category/types.js.map +1 -1
- package/dist/core/file-tree/fileTreeModel.d.ts +49 -0
- package/dist/core/file-tree/fileTreeModel.d.ts.map +1 -1
- package/dist/core/file-tree/fileTreeModel.js +84 -0
- package/dist/core/file-tree/fileTreeModel.js.map +1 -1
- package/dist/core/layout/index.js +1 -1
- package/dist/core/layout/index.js.map +1 -1
- package/dist/core/media/index.js +1 -1
- package/dist/core/media/index.js.map +1 -1
- package/dist/core/media/types.js +1 -1
- package/dist/core/media/types.js.map +1 -1
- package/dist/core/media/uploadLimits.js +1 -1
- package/dist/core/media/uploadLimits.js.map +1 -1
- package/dist/core/sharing/model.d.ts +1 -1
- package/dist/ctgr/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/activity-bar/ActivityBar.d.ts +17 -0
- package/dist/react/activity-bar/ActivityBar.d.ts.map +1 -1
- package/dist/react/activity-bar/ActivityBar.js.map +1 -1
- package/dist/react/analytics/index.d.ts +1 -1
- package/dist/react/analytics/index.js +1 -1
- package/dist/react/chat/MessageComposer.d.ts.map +1 -1
- package/dist/react/chat/MessageComposer.js +5 -4
- package/dist/react/chat/MessageComposer.js.map +1 -1
- package/dist/react/components/Button.d.ts.map +1 -1
- package/dist/react/components/Button.js +3 -2
- package/dist/react/components/Button.js.map +1 -1
- package/dist/react/components/Checkbox.d.ts +19 -3
- package/dist/react/components/Checkbox.d.ts.map +1 -1
- package/dist/react/components/Checkbox.js +29 -12
- package/dist/react/components/Checkbox.js.map +1 -1
- package/dist/react/components/CodeArea.d.ts.map +1 -1
- package/dist/react/components/CodeArea.js +2 -1
- package/dist/react/components/CodeArea.js.map +1 -1
- package/dist/react/components/Collapsible.d.ts.map +1 -1
- package/dist/react/components/Collapsible.js +2 -1
- package/dist/react/components/Collapsible.js.map +1 -1
- package/dist/react/components/ComboboxField.d.ts.map +1 -1
- package/dist/react/components/ComboboxField.js +3 -2
- package/dist/react/components/ComboboxField.js.map +1 -1
- package/dist/react/components/CopyButton.d.ts.map +1 -1
- package/dist/react/components/CopyButton.js +2 -1
- package/dist/react/components/CopyButton.js.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.d.ts.map +1 -1
- package/dist/react/components/DataTable/ColumnChecklist.js +2 -1
- package/dist/react/components/DataTable/ColumnChecklist.js.map +1 -1
- package/dist/react/components/DataTable/Pagination.d.ts.map +1 -1
- package/dist/react/components/DataTable/Pagination.js +2 -1
- package/dist/react/components/DataTable/Pagination.js.map +1 -1
- package/dist/react/components/DataTable/SortHeader.d.ts.map +1 -1
- package/dist/react/components/DataTable/SortHeader.js +2 -1
- package/dist/react/components/DataTable/SortHeader.js.map +1 -1
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts +61 -0
- package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -0
- package/dist/react/components/DataTable/{FilterBuilder.js → TableFilterBuilder.js} +26 -3
- package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -0
- package/dist/react/components/DataTable/Toolbar.d.ts +1 -1
- package/dist/react/components/DataTable/Toolbar.js +3 -3
- package/dist/react/components/DataTable/Toolbar.js.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.d.ts.map +1 -1
- package/dist/react/components/DataTable/cells/LinkCell.js +2 -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 +4 -1
- package/dist/react/components/DataTable/index.js.map +1 -1
- package/dist/react/components/DragHandle.d.ts.map +1 -1
- package/dist/react/components/DragHandle.js +2 -1
- package/dist/react/components/DragHandle.js.map +1 -1
- package/dist/react/components/EmojiField.d.ts.map +1 -1
- package/dist/react/components/EmojiField.js +2 -1
- package/dist/react/components/EmojiField.js.map +1 -1
- package/dist/react/components/EventTimeline.d.ts +3 -2
- package/dist/react/components/EventTimeline.d.ts.map +1 -1
- package/dist/react/components/EventTimeline.js +3 -2
- package/dist/react/components/EventTimeline.js.map +1 -1
- package/dist/react/components/IconButton.d.ts +1 -1
- package/dist/react/components/IconButton.js +1 -1
- package/dist/react/components/InfoHint.d.ts.map +1 -1
- package/dist/react/components/InfoHint.js +5 -4
- package/dist/react/components/InfoHint.js.map +1 -1
- package/dist/react/components/InheritBadge.js +1 -1
- package/dist/react/components/InheritBadge.js.map +1 -1
- package/dist/react/components/InlineEditableText.d.ts.map +1 -1
- package/dist/react/components/InlineEditableText.js +2 -1
- package/dist/react/components/InlineEditableText.js.map +1 -1
- package/dist/react/components/MeterList.d.ts.map +1 -1
- package/dist/react/components/MeterList.js +2 -1
- package/dist/react/components/MeterList.js.map +1 -1
- package/dist/react/components/PathText.d.ts +2 -2
- package/dist/react/components/PathText.d.ts.map +1 -1
- package/dist/react/components/PathText.js +2 -1
- package/dist/react/components/PathText.js.map +1 -1
- package/dist/react/components/RatingField.d.ts.map +1 -1
- package/dist/react/components/RatingField.js +2 -1
- package/dist/react/components/RatingField.js.map +1 -1
- package/dist/react/components/SecretInput.js +3 -2
- package/dist/react/components/SecretInput.js.map +1 -1
- package/dist/react/components/SegmentedControl.d.ts.map +1 -1
- package/dist/react/components/SegmentedControl.js +2 -1
- package/dist/react/components/SegmentedControl.js.map +1 -1
- package/dist/react/components/StarRating.d.ts.map +1 -1
- package/dist/react/components/StarRating.js +9 -5
- package/dist/react/components/StarRating.js.map +1 -1
- package/dist/react/components/StatStrip.d.ts.map +1 -1
- package/dist/react/components/StatStrip.js +2 -1
- package/dist/react/components/StatStrip.js.map +1 -1
- package/dist/react/components/StatTile.d.ts.map +1 -1
- package/dist/react/components/StatTile.js +3 -2
- package/dist/react/components/StatTile.js.map +1 -1
- package/dist/react/components/Tabs.d.ts.map +1 -1
- package/dist/react/components/Tabs.js +2 -1
- package/dist/react/components/Tabs.js.map +1 -1
- package/dist/react/components/TruncatedText.d.ts +2 -1
- package/dist/react/components/TruncatedText.d.ts.map +1 -1
- package/dist/react/components/TruncatedText.js +2 -1
- package/dist/react/components/TruncatedText.js.map +1 -1
- package/dist/react/components/calendar/MonthGrid.d.ts.map +1 -1
- package/dist/react/components/calendar/MonthGrid.js +2 -1
- package/dist/react/components/calendar/MonthGrid.js.map +1 -1
- package/dist/react/components/calendar/WeekView.d.ts.map +1 -1
- package/dist/react/components/calendar/WeekView.js +2 -1
- package/dist/react/components/calendar/WeekView.js.map +1 -1
- package/dist/react/components/revealOnHover.d.ts.map +1 -1
- package/dist/react/components/revealOnHover.js +2 -1
- package/dist/react/components/revealOnHover.js.map +1 -1
- package/dist/react/file-tree/FileTree.d.ts +50 -1
- package/dist/react/file-tree/FileTree.d.ts.map +1 -1
- package/dist/react/file-tree/FileTree.js +234 -6
- package/dist/react/file-tree/FileTree.js.map +1 -1
- package/dist/react/file-tree/fileTree.css +52 -0
- package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
- package/dist/react/filter-rail/FilterRail.js +5 -4
- package/dist/react/filter-rail/FilterRail.js.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.d.ts.map +1 -1
- package/dist/react/folder-tree/FolderTreeRail.js +2 -1
- package/dist/react/folder-tree/FolderTreeRail.js.map +1 -1
- package/dist/react/index.d.ts +5 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/layoutEngine/index.js +1 -1
- package/dist/react/layoutEngine/index.js.map +1 -1
- package/dist/react/lib/field.d.ts.map +1 -1
- package/dist/react/lib/field.js +3 -2
- package/dist/react/lib/field.js.map +1 -1
- package/dist/react/lib/floatingStyles.d.ts.map +1 -1
- package/dist/react/lib/floatingStyles.js +2 -1
- package/dist/react/lib/floatingStyles.js.map +1 -1
- package/dist/react/lib/tapTarget.d.ts +96 -0
- package/dist/react/lib/tapTarget.d.ts.map +1 -0
- package/dist/react/lib/tapTarget.js +96 -0
- package/dist/react/lib/tapTarget.js.map +1 -0
- package/dist/react/media/VideoTrimmer.d.ts +1 -1
- package/dist/react/media/VideoTrimmer.js +1 -1
- package/dist/react/media/denseGallery.css +3 -3
- package/dist/react/media/ffmpegWasm.js +2 -2
- package/dist/react/media/ffmpegWasm.js.map +1 -1
- package/dist/react/media/videoPlayer.css +42 -0
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts +2 -2
- package/dist/react/namespace/NamespaceTargetCapsule.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.d.ts.map +1 -1
- package/dist/react/nav/BreadcrumbTrail.js +4 -3
- package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
- package/dist/react/nav/HubTileGrid.d.ts.map +1 -1
- package/dist/react/nav/HubTileGrid.js +2 -1
- package/dist/react/nav/HubTileGrid.js.map +1 -1
- package/dist/react/nav/SideNav.d.ts.map +1 -1
- package/dist/react/nav/SideNav.js +4 -3
- package/dist/react/nav/SideNav.js.map +1 -1
- package/dist/react/nav/SideNavCustomize.d.ts.map +1 -1
- package/dist/react/nav/SideNavCustomize.js +2 -1
- package/dist/react/nav/SideNavCustomize.js.map +1 -1
- package/dist/react/palette/CommandPalette.d.ts.map +1 -1
- package/dist/react/palette/CommandPalette.js +3 -2
- package/dist/react/palette/CommandPalette.js.map +1 -1
- package/dist/server/drivers/pooledControlStores.pg.test.js +1 -0
- package/dist/server/drivers/pooledControlStores.pg.test.js.map +1 -1
- package/dist/server/drivers/pooledIdentityStore.pg.test.js +1 -0
- package/dist/server/drivers/pooledIdentityStore.pg.test.js.map +1 -1
- package/dist/server/drivers/retentionPolicy.pg.test.js +1 -0
- package/dist/server/drivers/retentionPolicy.pg.test.js.map +1 -1
- package/dist/server/guard/argon2Binding.d.ts +1 -1
- package/dist/server/guard/argon2Binding.js +1 -1
- package/dist/server/incidents/store.d.ts +3 -3
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/master-lock/masterLock.d.ts +1 -1
- package/dist/server/media-bun/index.js +1 -1
- package/dist/server/media-bun/index.js.map +1 -1
- package/dist/server/paths/appDataHome.d.ts +20 -0
- package/dist/server/paths/appDataHome.d.ts.map +1 -0
- package/dist/server/paths/appDataHome.js +69 -0
- package/dist/server/paths/appDataHome.js.map +1 -0
- package/dist/server/retention/archive.d.ts +3 -4
- package/dist/server/retention/archive.d.ts.map +1 -1
- package/dist/server/retention/archive.js +20 -15
- package/dist/server/retention/archive.js.map +1 -1
- package/dist/server/retention/index.d.ts +1 -1
- package/dist/server/retention/index.js +1 -1
- package/dist/server/retention/policy.d.ts +2 -2
- package/dist/server/retention/policy.d.ts.map +1 -1
- package/dist/server/retention/policy.js +1 -1
- package/dist/server/retention/store.d.ts.map +1 -1
- package/dist/server/retention/store.js +27 -20
- package/dist/server/retention/store.js.map +1 -1
- package/dist/server/runtime/localHost.d.ts +10 -5
- package/dist/server/runtime/localHost.d.ts.map +1 -1
- package/dist/server/runtime/localHost.js +12 -8
- package/dist/server/runtime/localHost.js.map +1 -1
- package/dist/server/runtime/meterRollup.pg.test.js +1 -0
- package/dist/server/runtime/meterRollup.pg.test.js.map +1 -1
- package/dist/server/runtime/recipe.d.ts +4 -4
- package/dist/server/runtime/retentionJob.pg.test.js +1 -0
- package/dist/server/runtime/retentionJob.pg.test.js.map +1 -1
- package/dist/server/search/pgSearchProvider.pg.test.js +1 -0
- package/dist/server/search/pgSearchProvider.pg.test.js.map +1 -1
- package/dist/shared/errors.d.ts +1 -1
- package/dist/shared/errors.js +1 -1
- package/dist/styles-static.css +391 -0
- package/dist/styles.css +27 -0
- package/package.json +19 -167
- package/scripts/generateStaticStyles.ts +122 -0
- package/scripts/publicSurface.ts +455 -0
- package/scripts/testTmpRoot.ts +34 -5
- package/src/client/index.ts +1 -1
- package/src/core/category/index.ts +2 -1
- package/src/core/category/types.ts +1 -1
- package/src/core/file-tree/fileTreeModel.spec.ts +134 -0
- package/src/core/file-tree/fileTreeModel.ts +104 -0
- package/src/core/layout/index.ts +1 -1
- package/src/core/media/index.ts +1 -1
- package/src/core/media/types.ts +1 -1
- package/src/core/media/uploadLimits.ts +1 -1
- package/src/core/sharing/model.ts +1 -1
- package/src/ctgr/index.ts +1 -1
- package/src/declaredDepsAreImported.spec.ts +87 -0
- package/src/demoFixture.spec.ts +133 -0
- package/src/index.ts +1 -1
- package/src/lockfileIsTracked.spec.ts +50 -0
- package/src/namedSubpathsResolve.spec.ts +119 -0
- package/src/publicSurface.spec.ts +72 -0
- package/src/react/activity-bar/ActivityBar.tsx +17 -0
- package/src/react/analytics/index.ts +1 -1
- package/src/react/chat/MessageComposer.tsx +5 -4
- package/src/react/components/Button.tsx +3 -2
- package/src/react/components/Checkbox.spec.tsx +51 -0
- package/src/react/components/Checkbox.tsx +68 -26
- package/src/react/components/CodeArea.tsx +2 -1
- package/src/react/components/CodeChip.spec.tsx +2 -2
- package/src/react/components/Collapsible.tsx +2 -1
- package/src/react/components/ComboboxField.tsx +3 -2
- package/src/react/components/CopyButton.tsx +2 -1
- package/src/react/components/CopyableText.spec.tsx +1 -1
- package/src/react/components/DataTable/ColumnChecklist.tsx +2 -1
- package/src/react/components/DataTable/Pagination.tsx +2 -1
- package/src/react/components/DataTable/SortHeader.tsx +2 -1
- package/src/react/components/DataTable/{FilterBuilder.tsx → TableFilterBuilder.tsx} +33 -5
- package/src/react/components/DataTable/Toolbar.tsx +3 -3
- package/src/react/components/DataTable/cells/LinkCell.tsx +2 -1
- package/src/react/components/DataTable/index.ts +8 -1
- package/src/react/components/DragHandle.tsx +2 -1
- package/src/react/components/EmojiField.tsx +2 -1
- package/src/react/components/EventTimeline.tsx +3 -2
- package/src/react/components/FileLocation.spec.tsx +1 -1
- package/src/react/components/IconButton.tsx +1 -1
- package/src/react/components/InfoHint.tsx +5 -4
- package/src/react/components/InheritBadge.tsx +1 -1
- package/src/react/components/InlineEditableText.tsx +2 -1
- package/src/react/components/MeterList.tsx +2 -1
- package/src/react/components/PathText.tsx +4 -3
- package/src/react/components/RatingField.tsx +2 -1
- package/src/react/components/SecretInput.tsx +3 -3
- package/src/react/components/SegmentedControl.tsx +2 -2
- package/src/react/components/StarRating.spec.tsx +2 -2
- package/src/react/components/StarRating.tsx +9 -5
- package/src/react/components/StatStrip.tsx +2 -1
- package/src/react/components/StatTile.tsx +3 -3
- package/src/react/components/Tabs.spec.tsx +3 -2
- package/src/react/components/Tabs.tsx +2 -1
- package/src/react/components/TruncatedText.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.spec.tsx +2 -1
- package/src/react/components/calendar/MonthGrid.tsx +2 -1
- package/src/react/components/calendar/WeekView.tsx +2 -1
- package/src/react/components/revealOnHover.ts +3 -2
- package/src/react/file-tree/FileTree.spec.tsx +248 -0
- package/src/react/file-tree/FileTree.tsx +304 -4
- package/src/react/file-tree/fileTree.css +52 -0
- package/src/react/file-tree/fileTreeGeometry.fixture.json +151 -0
- package/src/react/file-tree/fileTreeGeometry.spec.ts +33 -52
- package/src/react/filter-rail/FilterRail.spec.tsx +2 -1
- package/src/react/filter-rail/FilterRail.tsx +5 -4
- package/src/react/folder-tree/FolderTreeRail.tsx +2 -1
- package/src/react/index.ts +13 -3
- package/src/react/layoutEngine/index.ts +1 -1
- package/src/react/layoutEngine/types.ts +1 -1
- package/src/react/lib/field.ts +4 -2
- package/src/react/lib/floatingStyles.spec.ts +2 -1
- package/src/react/lib/floatingStyles.ts +3 -1
- package/src/react/lib/tapTarget.ts +100 -0
- package/src/react/media/MaskPainter.tsx +2 -2
- package/src/react/media/VideoTrimmer.tsx +1 -1
- package/src/react/media/denseGallery.css +3 -3
- package/src/react/media/ffmpegWasm.ts +2 -2
- package/src/react/media/videoPlayer.css +42 -0
- package/src/react/namespace/NamespaceTargetCapsule.tsx +2 -2
- package/src/react/nav/BreadcrumbTrail.tsx +4 -3
- package/src/react/nav/HubTileGrid.tsx +2 -1
- package/src/react/nav/SideNav.tsx +4 -3
- package/src/react/nav/SideNavCustomize.tsx +2 -1
- package/src/react/palette/CommandPalette.tsx +3 -2
- package/src/server/ctgr.ts +1 -1
- package/src/server/drivers/pooledControlStores.pg.test.ts +1 -0
- package/src/server/drivers/pooledIdentityStore.pg.test.ts +1 -0
- package/src/server/drivers/retentionPolicy.pg.test.ts +1 -0
- package/src/server/guard/argon2Binding.ts +1 -1
- package/src/server/incidents/store.ts +3 -3
- package/src/server/index.ts +1 -1
- package/src/server/master-lock/masterLock.spec.ts +18 -2
- package/src/server/master-lock/masterLock.ts +1 -1
- package/src/server/media-bun/image.spec.ts +1 -0
- package/src/server/media-bun/index.ts +1 -1
- package/src/server/media-bun/video.spec.ts +1 -0
- package/src/server/paths/appDataHome.spec.ts +87 -0
- package/src/server/paths/appDataHome.ts +84 -0
- package/src/server/retention/archive.spec.ts +26 -4
- package/src/server/retention/archive.ts +20 -15
- package/src/server/retention/index.ts +1 -1
- package/src/server/retention/policy.ts +2 -2
- package/src/server/retention/store.spec.ts +38 -10
- package/src/server/retention/store.ts +26 -19
- package/src/server/runtime/localHost.spec.ts +22 -3
- package/src/server/runtime/localHost.ts +12 -9
- package/src/server/runtime/meterRollup.pg.test.ts +1 -0
- package/src/server/runtime/recipe.ts +4 -4
- package/src/server/runtime/retentionJob.pg.test.ts +1 -0
- package/src/server/search/pgSearchProvider.pg.test.ts +1 -0
- package/src/server/storage/binaryServerProcessing.integration.spec.ts +6 -2
- package/src/server/storage/chunked.integration.spec.ts +5 -2
- package/src/server/storage/fileUploadClient-chunked.integration.spec.ts +5 -2
- package/src/server/storage/files/adapter.photo.display.spec.ts +1 -0
- package/src/server/storage/imageThumbnail.spec.ts +1 -0
- package/src/server/storage/transcode.integration.spec.ts +5 -2
- package/src/server/storage/videoProcessor.posterOnly.spec.ts +1 -0
- package/src/shared/errors.ts +1 -1
- package/src/skippedTestsAreAnswered.spec.ts +215 -0
- package/src/styles-static.css +391 -0
- package/src/styles.css +27 -0
- package/src/stylesStaticMatches.spec.ts +134 -0
- package/src/tapTargetStylesheet.spec.ts +150 -0
- package/src/testTmpRoot.spec.ts +102 -0
- package/dist/core/duplicates/index.d.ts +0 -116
- package/dist/core/duplicates/index.d.ts.map +0 -1
- package/dist/core/duplicates/index.js +0 -178
- package/dist/core/duplicates/index.js.map +0 -1
- package/dist/core/namespace/helpers.d.ts +0 -14
- package/dist/core/namespace/helpers.d.ts.map +0 -1
- package/dist/core/namespace/helpers.js +0 -29
- package/dist/core/namespace/helpers.js.map +0 -1
- package/dist/core/namespace/index.d.ts +0 -4
- package/dist/core/namespace/index.d.ts.map +0 -1
- package/dist/core/namespace/index.js +0 -6
- package/dist/core/namespace/index.js.map +0 -1
- package/dist/core/namespace/memoryStore.d.ts +0 -19
- package/dist/core/namespace/memoryStore.d.ts.map +0 -1
- package/dist/core/namespace/memoryStore.js +0 -70
- package/dist/core/namespace/memoryStore.js.map +0 -1
- package/dist/core/namespace/types.d.ts +0 -44
- package/dist/core/namespace/types.d.ts.map +0 -1
- package/dist/core/namespace/types.js +0 -8
- package/dist/core/namespace/types.js.map +0 -1
- package/dist/game/core/DisposeRegistry.d.ts +0 -42
- package/dist/game/core/DisposeRegistry.d.ts.map +0 -1
- package/dist/game/core/DisposeRegistry.js +0 -67
- package/dist/game/core/DisposeRegistry.js.map +0 -1
- package/dist/game/core/drawBudget.d.ts +0 -26
- package/dist/game/core/drawBudget.d.ts.map +0 -1
- package/dist/game/core/drawBudget.js +0 -55
- package/dist/game/core/drawBudget.js.map +0 -1
- package/dist/game/core/fixedTimestep.d.ts +0 -38
- package/dist/game/core/fixedTimestep.d.ts.map +0 -1
- package/dist/game/core/fixedTimestep.js +0 -47
- package/dist/game/core/fixedTimestep.js.map +0 -1
- package/dist/game/core/index.d.ts +0 -9
- package/dist/game/core/index.d.ts.map +0 -1
- package/dist/game/core/index.js +0 -8
- package/dist/game/core/index.js.map +0 -1
- package/dist/game/core/inputCollector.d.ts +0 -82
- package/dist/game/core/inputCollector.d.ts.map +0 -1
- package/dist/game/core/inputCollector.js +0 -176
- package/dist/game/core/inputCollector.js.map +0 -1
- package/dist/game/core/resizeCanvas.d.ts +0 -19
- package/dist/game/core/resizeCanvas.d.ts.map +0 -1
- package/dist/game/core/resizeCanvas.js +0 -29
- package/dist/game/core/resizeCanvas.js.map +0 -1
- package/dist/game/react/index.d.ts +0 -3
- package/dist/game/react/index.d.ts.map +0 -1
- package/dist/game/react/index.js +0 -5
- package/dist/game/react/index.js.map +0 -1
- package/dist/game/react/useGameEngine.d.ts +0 -64
- package/dist/game/react/useGameEngine.d.ts.map +0 -1
- package/dist/game/react/useGameEngine.js +0 -78
- package/dist/game/react/useGameEngine.js.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.d.ts +0 -64
- package/dist/react/canvas/CanvasNavHUD.d.ts.map +0 -1
- package/dist/react/canvas/CanvasNavHUD.js +0 -58
- package/dist/react/canvas/CanvasNavHUD.js.map +0 -1
- package/dist/react/canvas/fitLabel.d.ts +0 -53
- package/dist/react/canvas/fitLabel.d.ts.map +0 -1
- package/dist/react/canvas/fitLabel.js +0 -104
- package/dist/react/canvas/fitLabel.js.map +0 -1
- package/dist/react/canvas/index.d.ts +0 -4
- package/dist/react/canvas/index.d.ts.map +0 -1
- package/dist/react/canvas/index.js +0 -4
- package/dist/react/canvas/index.js.map +0 -1
- package/dist/react/canvas/lod.d.ts +0 -40
- package/dist/react/canvas/lod.d.ts.map +0 -1
- package/dist/react/canvas/lod.js +0 -37
- package/dist/react/canvas/lod.js.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.d.ts +0 -38
- package/dist/react/components/DataTable/FilterBuilder.d.ts.map +0 -1
- package/dist/react/components/DataTable/FilterBuilder.js.map +0 -1
- package/dist/react/seo/HeadProvider.d.ts +0 -14
- package/dist/react/seo/HeadProvider.d.ts.map +0 -1
- package/dist/react/seo/HeadProvider.js +0 -44
- package/dist/react/seo/HeadProvider.js.map +0 -1
- package/dist/react/seo/applyHeadToDocument.d.ts +0 -3
- package/dist/react/seo/applyHeadToDocument.d.ts.map +0 -1
- package/dist/react/seo/applyHeadToDocument.js +0 -66
- package/dist/react/seo/applyHeadToDocument.js.map +0 -1
- package/dist/react/seo/index.d.ts +0 -3
- package/dist/react/seo/index.d.ts.map +0 -1
- package/dist/react/seo/index.js +0 -7
- package/dist/react/seo/index.js.map +0 -1
- package/dist/react/timeline/ClipView.d.ts +0 -29
- package/dist/react/timeline/ClipView.d.ts.map +0 -1
- package/dist/react/timeline/ClipView.js +0 -53
- package/dist/react/timeline/ClipView.js.map +0 -1
- package/dist/react/timeline/Playhead.d.ts +0 -16
- package/dist/react/timeline/Playhead.d.ts.map +0 -1
- package/dist/react/timeline/Playhead.js +0 -26
- package/dist/react/timeline/Playhead.js.map +0 -1
- package/dist/react/timeline/TimeRuler.d.ts +0 -21
- package/dist/react/timeline/TimeRuler.d.ts.map +0 -1
- package/dist/react/timeline/TimeRuler.js +0 -31
- package/dist/react/timeline/TimeRuler.js.map +0 -1
- package/dist/react/timeline/TimelineSurface.d.ts +0 -29
- package/dist/react/timeline/TimelineSurface.d.ts.map +0 -1
- package/dist/react/timeline/TimelineSurface.js +0 -56
- package/dist/react/timeline/TimelineSurface.js.map +0 -1
- package/dist/react/timeline/TrackLane.d.ts +0 -31
- package/dist/react/timeline/TrackLane.d.ts.map +0 -1
- package/dist/react/timeline/TrackLane.js +0 -32
- package/dist/react/timeline/TrackLane.js.map +0 -1
- package/dist/react/timeline/index.d.ts +0 -6
- package/dist/react/timeline/index.d.ts.map +0 -1
- package/dist/react/timeline/index.js +0 -12
- package/dist/react/timeline/index.js.map +0 -1
- package/dist/server/private-media/index.d.ts +0 -7
- package/dist/server/private-media/index.d.ts.map +0 -1
- package/dist/server/private-media/index.js +0 -13
- package/dist/server/private-media/index.js.map +0 -1
- package/dist/server/seo/index.d.ts +0 -3
- package/dist/server/seo/index.d.ts.map +0 -1
- package/dist/server/seo/index.js +0 -6
- package/dist/server/seo/index.js.map +0 -1
- package/dist/server/seo/mountSeoRoutes.d.ts +0 -9
- package/dist/server/seo/mountSeoRoutes.d.ts.map +0 -1
- package/dist/server/seo/mountSeoRoutes.js +0 -19
- package/dist/server/seo/mountSeoRoutes.js.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.d.ts +0 -9
- package/dist/server/seo/serveHeadInjectedIndex.d.ts.map +0 -1
- package/dist/server/seo/serveHeadInjectedIndex.js +0 -20
- package/dist/server/seo/serveHeadInjectedIndex.js.map +0 -1
- package/dist/upload.d.ts +0 -148
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -159
- package/dist/upload.js.map +0 -1
- package/dist/verify/runtime/index.d.ts +0 -16
- package/dist/verify/runtime/index.d.ts.map +0 -1
- package/dist/verify/runtime/index.js +0 -16
- package/dist/verify/runtime/index.js.map +0 -1
- package/scripts/demoCheck.ts +0 -42
- package/src/core/duplicates/index.spec.ts +0 -116
- package/src/core/duplicates/index.ts +0 -203
- package/src/core/namespace/helpers.ts +0 -31
- package/src/core/namespace/index.ts +0 -12
- package/src/core/namespace/memoryStore.ts +0 -77
- package/src/core/namespace/namespace.spec.ts +0 -117
- package/src/core/namespace/types.ts +0 -53
- package/src/game/core/DisposeRegistry.spec.ts +0 -53
- package/src/game/core/DisposeRegistry.ts +0 -70
- package/src/game/core/drawBudget.spec.ts +0 -51
- package/src/game/core/drawBudget.ts +0 -75
- package/src/game/core/fixedTimestep.spec.ts +0 -91
- package/src/game/core/fixedTimestep.ts +0 -79
- package/src/game/core/index.ts +0 -16
- package/src/game/core/inputCollector.spec.ts +0 -29
- package/src/game/core/inputCollector.ts +0 -245
- package/src/game/core/resizeCanvas.ts +0 -31
- package/src/game/react/index.ts +0 -10
- package/src/game/react/useGameEngine.ts +0 -125
- package/src/react/canvas/CanvasNavHUD.spec.tsx +0 -62
- package/src/react/canvas/CanvasNavHUD.tsx +0 -210
- package/src/react/canvas/fitLabel.spec.ts +0 -82
- package/src/react/canvas/fitLabel.ts +0 -150
- package/src/react/canvas/index.ts +0 -15
- package/src/react/canvas/lod.ts +0 -53
- package/src/react/seo/HeadProvider.tsx +0 -67
- package/src/react/seo/applyHeadToDocument.ts +0 -73
- package/src/react/seo/index.ts +0 -12
- package/src/react/seo/seo.spec.tsx +0 -101
- package/src/react/timeline/ClipView.tsx +0 -146
- package/src/react/timeline/Playhead.tsx +0 -63
- package/src/react/timeline/TimeRuler.tsx +0 -85
- package/src/react/timeline/TimelineSurface.tsx +0 -157
- package/src/react/timeline/TrackLane.tsx +0 -87
- package/src/react/timeline/index.ts +0 -12
- package/src/react/timeline/timeline.spec.tsx +0 -175
- package/src/server/private-media/index.ts +0 -45
- package/src/server/seo/index.ts +0 -8
- package/src/server/seo/mountSeoRoutes.ts +0 -37
- package/src/server/seo/seo.spec.ts +0 -128
- package/src/server/seo/serveHeadInjectedIndex.ts +0 -36
- package/src/upload.spec.ts +0 -300
- package/src/upload.ts +0 -288
- package/src/verify/runtime/index.ts +0 -64
|
@@ -4,30 +4,38 @@
|
|
|
4
4
|
* ── Why a test reads a stylesheet ───────────────────────────────────────────────────────
|
|
5
5
|
* Owner, 2026-09-10: *"We have two sidenav components now. I need updates and we need them
|
|
6
6
|
* in two places because of the copying."* The two are this one and
|
|
7
|
-
* `cursed-embeddable-spreadsheet`'s, and they cannot be merged into one —
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* this reads.
|
|
7
|
+
* `cursed-embeddable-spreadsheet`'s, and they cannot be merged into one — the two ship as
|
|
8
|
+
* separate published packages, and cb's tree is a deliberate generalisation that has fewer
|
|
9
|
+
* features than ces's, not the same ones. The full reasoning is in the spec file this reads.
|
|
11
10
|
*
|
|
12
11
|
* So the design is shared and the code is not, and this is the seam that keeps the design
|
|
13
|
-
* shared: **a number changed here without being changed
|
|
14
|
-
* rather than being noticed by eye some months later. Its twin is
|
|
12
|
+
* shared: **a number changed here without being changed in the design file fails on the next
|
|
13
|
+
* run**, rather than being noticed by eye some months later. Its twin is
|
|
15
14
|
* `test/ui/tree-geometry.test.ts` over in the spreadsheet.
|
|
16
15
|
*
|
|
17
|
-
* 🔴
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* 🔴 EVERY assertion here runs unconditionally, on any machine. Until 2026-09-13 the shared
|
|
17
|
+
* numbers were read out of a checkout in the owner's home directory and SKIPPED when it was
|
|
18
|
+
* missing — in a package that is published to npm. That is a test that passes for one person
|
|
19
|
+
* and quietly does nothing for everybody else, which is worse than no test: half this file
|
|
20
|
+
* would have been inert for every installer. The design now lives in
|
|
21
|
+
* `fileTreeGeometry.fixture.json`, committed beside this spec, and nothing is conditional.
|
|
21
22
|
*/
|
|
22
23
|
import { describe, expect, it } from 'bun:test';
|
|
23
24
|
import { readFileSync } from 'node:fs';
|
|
24
|
-
import { homedir } from 'node:os';
|
|
25
25
|
import { join } from 'node:path';
|
|
26
26
|
import { flattenFileTree } from '../../core/file-tree/fileTreeModel';
|
|
27
27
|
|
|
28
28
|
const CSS = readFileSync(join(import.meta.dir, 'fileTree.css'), 'utf8');
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* The shared design, committed in this repo. Read once — a published package's suite may not
|
|
32
|
+
* depend on a directory outside its own checkout.
|
|
33
|
+
*/
|
|
34
|
+
const DESIGN = JSON.parse(readFileSync(join(import.meta.dir, 'fileTreeGeometry.fixture.json'), 'utf8')) as {
|
|
35
|
+
geometry: Record<string, number>;
|
|
36
|
+
scrollbar: { width: number; thumbInset: number };
|
|
37
|
+
behaviour: Record<string, { value: boolean }>;
|
|
38
|
+
};
|
|
31
39
|
|
|
32
40
|
/**
|
|
33
41
|
* A token's value in px, resolved one level through `var()` and `calc(a / 2)`.
|
|
@@ -141,15 +149,6 @@ describe('the file tree geometry', () => {
|
|
|
141
149
|
expect(CSS.indexOf('-webkit-font-smoothing')).toBeGreaterThan(CSS.indexOf(':where(.dark) .cbft {'));
|
|
142
150
|
});
|
|
143
151
|
|
|
144
|
-
/*
|
|
145
|
-
* ── The cross-repo half ───────────────────────────────────────────────────────────────
|
|
146
|
-
*
|
|
147
|
-
* Skipped rather than failed when fleet is not beside this checkout, because a clone
|
|
148
|
-
* without it is a legitimate state and a red suite there would teach people to ignore this
|
|
149
|
-
* file. On this machine it is the whole point: it is what makes "update it in two places"
|
|
150
|
-
* something the machine reports instead of something a person has to remember.
|
|
151
|
-
*/
|
|
152
|
-
|
|
153
152
|
/*
|
|
154
153
|
* ── The shared BEHAVIOUR, not just the numbers ────────────────────────────────────────
|
|
155
154
|
*
|
|
@@ -157,26 +156,24 @@ describe('the file tree geometry', () => {
|
|
|
157
156
|
* never against itself. A test that read `true` out of the JSON and then asserted `true`
|
|
158
157
|
* would pass on a tree that does neither thing — it would gate nothing while looking
|
|
159
158
|
* exactly like a gate. So the flag is the CONDITION and the behaviour is the assertion:
|
|
160
|
-
* flip the flag in
|
|
159
|
+
* flip the flag in the design file and this suite reds until the code here follows it.
|
|
161
160
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
};
|
|
161
|
+
it('declares every behaviour flag this suite asserts against', () => {
|
|
162
|
+
// The fixture is the CONDITION for the two tests below, so a missing key would turn
|
|
163
|
+
// each of them into a silent pass — the exact failure mode that vendoring it fixed.
|
|
164
|
+
expect(Object.keys(DESIGN.behaviour).sort()).toEqual(
|
|
165
|
+
['$comment', 'everyFolderDrawsATwisty', 'mediaRowDrawsItsThumbnail'].sort(),
|
|
166
|
+
);
|
|
167
|
+
});
|
|
169
168
|
|
|
170
169
|
it('draws a twisty on EVERY folder, empty ones included, as the shared design declares', () => {
|
|
171
|
-
const declared = behaviour
|
|
172
|
-
if (!declared) return;
|
|
170
|
+
const declared = DESIGN.behaviour.everyFolderDrawsATwisty!;
|
|
173
171
|
const rows = flattenFileTree([{ id: 'empty', name: 'Empty', kind: 'folder', children: [] }], []);
|
|
174
172
|
expect(rows[0]!.expandable).toBe(declared.value);
|
|
175
173
|
});
|
|
176
174
|
|
|
177
175
|
it('gives a media row a thumbnail slot, as the shared design declares', () => {
|
|
178
|
-
const declared = behaviour
|
|
179
|
-
if (!declared) return;
|
|
176
|
+
const declared = DESIGN.behaviour.mediaRowDrawsItsThumbnail!;
|
|
180
177
|
// The three constraints the shared file names, each asserted where it lives:
|
|
181
178
|
// · one glyph box, never a second track — the box is `--cbft-glyph` wide either way;
|
|
182
179
|
// · the row height does not move — `.cbft-thumb` declares no height of its own beyond it;
|
|
@@ -212,17 +209,8 @@ describe('the file tree geometry', () => {
|
|
|
212
209
|
* Both APIs are required rather than interchangeable: `scrollbar-width` is the standard
|
|
213
210
|
* property and the `::-webkit-` rules are what Safari and older Chrome read.
|
|
214
211
|
*/
|
|
215
|
-
const scrollbar = (): { width: number; thumbInset: number } | null => {
|
|
216
|
-
try {
|
|
217
|
-
return JSON.parse(readFileSync(SPEC_PATH, 'utf8')).scrollbar;
|
|
218
|
-
} catch {
|
|
219
|
-
return null; // no fleet checkout here — see above
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
|
|
223
212
|
it('draws a very thin gutter, at the width the shared design names', () => {
|
|
224
|
-
const width = scrollbar
|
|
225
|
-
if (width === undefined) return;
|
|
213
|
+
const width = DESIGN.scrollbar.width;
|
|
226
214
|
// The standard property first — a stylesheet with only the `-webkit-` half is thin in
|
|
227
215
|
// Firefox and fat in Safari, or the other way round, depending which half went missing.
|
|
228
216
|
expect(CSS).toContain('scrollbar-width: thin;');
|
|
@@ -231,9 +219,7 @@ describe('the file tree geometry', () => {
|
|
|
231
219
|
});
|
|
232
220
|
|
|
233
221
|
it('keeps the marker FLUSH with the edge — no border, no margin on the thumb', () => {
|
|
234
|
-
|
|
235
|
-
if (inset === undefined) return;
|
|
236
|
-
expect(inset).toBe(0);
|
|
222
|
+
expect(DESIGN.scrollbar.thumbInset).toBe(0);
|
|
237
223
|
const thumb = CSS.slice(
|
|
238
224
|
CSS.indexOf('.cbft-scroll::-webkit-scrollbar-thumb {'),
|
|
239
225
|
CSS.indexOf('.cbft-scroll::-webkit-scrollbar-thumb:hover'),
|
|
@@ -261,12 +247,7 @@ describe('the file tree geometry', () => {
|
|
|
261
247
|
});
|
|
262
248
|
|
|
263
249
|
it('agrees with the shared design the spreadsheet also implements', () => {
|
|
264
|
-
|
|
265
|
-
try {
|
|
266
|
-
spec = JSON.parse(readFileSync(SPEC_PATH, 'utf8'));
|
|
267
|
-
} catch {
|
|
268
|
-
return; // no fleet checkout here — see above
|
|
269
|
-
}
|
|
250
|
+
const spec = DESIGN;
|
|
270
251
|
expect({
|
|
271
252
|
row: token('cbft-row'),
|
|
272
253
|
pad: token('cbft-pad'),
|
|
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, test } from 'bun:test';
|
|
|
2
2
|
import { cleanup, fireEvent, render, waitFor } from '@testing-library/react';
|
|
3
3
|
import { FilterRail, type FilterRailSection } from './FilterRail';
|
|
4
4
|
import { hoverHint } from '../../testing/tooltip';
|
|
5
|
+
import { TAP_TARGET_ALWAYS } from '../lib/tapTarget';
|
|
5
6
|
|
|
6
7
|
afterEach(cleanup);
|
|
7
8
|
|
|
@@ -331,7 +332,7 @@ describe('FilterRail — rows that are more than a choice', () => {
|
|
|
331
332
|
expect(shelf?.className).toContain('group-hover/rail-row:opacity-100');
|
|
332
333
|
expect(shelf?.className).toContain('group-focus-within/rail-row:opacity-100');
|
|
333
334
|
// A phone has no hover at all; without this the control is unreachable by any gesture.
|
|
334
|
-
expect(shelf?.className).toContain(
|
|
335
|
+
expect(shelf?.className).toContain(TAP_TARGET_ALWAYS);
|
|
335
336
|
// DESIGN.md §5 — a row control is a real tap target, whatever glyph the host put in it.
|
|
336
337
|
expect(shelf?.className).toContain('pointer-coarse:[&_button]:min-h-11');
|
|
337
338
|
});
|
|
@@ -3,6 +3,7 @@ import type { DragEvent, ReactNode } from 'react';
|
|
|
3
3
|
import { ScrollArea } from '../components/ScrollArea';
|
|
4
4
|
import { cn } from '../lib/cn';
|
|
5
5
|
import { Tooltip } from '../components/Tooltip';
|
|
6
|
+
import { TAP_TARGET, TAP_TARGET_ALWAYS, TAP_TARGET_HEIGHT } from '../lib/tapTarget';
|
|
6
7
|
|
|
7
8
|
export interface FilterRailItem {
|
|
8
9
|
/** Stable key, and the value handed to `onSelect`. */
|
|
@@ -260,7 +261,7 @@ export function FilterRail({
|
|
|
260
261
|
onClick={() => onCollapsedChange(!collapsed)}
|
|
261
262
|
aria-label={collapsed ? `Expand ${label}` : `Collapse ${label}`}
|
|
262
263
|
aria-expanded={!collapsed}
|
|
263
|
-
className=
|
|
264
|
+
className={`grid size-8 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-card-raised hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${TAP_TARGET} [&_svg]:size-4`}
|
|
264
265
|
>
|
|
265
266
|
{collapsed ? <ChevronsRight /> : <ChevronsLeft />}
|
|
266
267
|
</button>
|
|
@@ -387,7 +388,7 @@ function FilterRailRow({
|
|
|
387
388
|
<span
|
|
388
389
|
data-cb-rail-tools={active ? 'solid' : 'quiet'}
|
|
389
390
|
className={cn(
|
|
390
|
-
|
|
391
|
+
`flex shrink-0 items-center gap-px transition-opacity ${TAP_TARGET_ALWAYS}`,
|
|
391
392
|
// 🔴 A rail row is DENSE, and the shelf is now always visible, so its width
|
|
392
393
|
// comes straight out of the label's. Measured at 14rem with three tools at
|
|
393
394
|
// the `sm` control height (32px each): `screencaps` rendered as ":" and a
|
|
@@ -486,8 +487,8 @@ function FilterRailButton({
|
|
|
486
487
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
487
488
|
// 44px touch floor on coarse pointers only, so the dense desktop rail stays dense.
|
|
488
489
|
collapsed
|
|
489
|
-
?
|
|
490
|
-
:
|
|
490
|
+
? `size-10 justify-center ${TAP_TARGET}`
|
|
491
|
+
: `px-2.5 py-1.5 ${TAP_TARGET_HEIGHT}`,
|
|
491
492
|
item.disabled && 'cursor-not-allowed opacity-50',
|
|
492
493
|
// 🔴 THREE states, TWO channels — see the component doc. Hover gets a real
|
|
493
494
|
// background rather than a suggestion of one; active steps up again AND takes the
|
|
@@ -33,6 +33,7 @@ import type { FolderNode } from "../../core/folder-tree/tree";
|
|
|
33
33
|
import { isRowDrag, readRowDrag, type RowDragPayload } from "../components/DataTable/rowDrag";
|
|
34
34
|
import { Tooltip } from '../components/Tooltip';
|
|
35
35
|
import { NewFolderControl } from './NewFolderControl';
|
|
36
|
+
import { TAP_TARGET_HEIGHT } from "../lib/tapTarget";
|
|
36
37
|
|
|
37
38
|
export interface FolderTreeRailProps {
|
|
38
39
|
nodes: readonly FolderNode[];
|
|
@@ -167,7 +168,7 @@ export function FolderTreeRail({
|
|
|
167
168
|
aria-expanded={open}
|
|
168
169
|
// `pointer-coarse:` only — see FilterRail's twisty for why a finger-sized
|
|
169
170
|
// box everywhere would re-indent the whole tree for a mouse.
|
|
170
|
-
className=
|
|
171
|
+
className={`w-4 shrink-0 self-stretch text-[var(--muted-foreground)] ${TAP_TARGET_HEIGHT} pointer-coarse:w-11`}
|
|
171
172
|
onClick={() => toggle(node)}
|
|
172
173
|
>
|
|
173
174
|
{open ? "▾" : "▸"}
|
package/src/react/index.ts
CHANGED
|
@@ -217,9 +217,6 @@ export {
|
|
|
217
217
|
EMPTY_FILTER_QUERY,
|
|
218
218
|
evaluateFilterQuery,
|
|
219
219
|
FILTER_OP_LABELS,
|
|
220
|
-
FilterBuilder,
|
|
221
|
-
type FilterBuilderColumn,
|
|
222
|
-
type FilterBuilderProps,
|
|
223
220
|
type FilterCondition,
|
|
224
221
|
type FilterGroup,
|
|
225
222
|
type FilterOp,
|
|
@@ -255,6 +252,9 @@ export {
|
|
|
255
252
|
SortHeader,
|
|
256
253
|
type SortHeaderProps,
|
|
257
254
|
setAssetUrlResolver,
|
|
255
|
+
TableFilterBuilder,
|
|
256
|
+
type TableFilterBuilderColumn,
|
|
257
|
+
type TableFilterBuilderProps,
|
|
258
258
|
TablePagination,
|
|
259
259
|
type TablePaginationProps,
|
|
260
260
|
TableToolbar,
|
|
@@ -765,6 +765,16 @@ export { makeFormConfig } from './lib/form';
|
|
|
765
765
|
* writing a literal delay; `no-fast-tooltip` fails a build on a smaller one. */
|
|
766
766
|
export { HOVER_HINT_DELAY_MS, HOVER_HINT_INSTANT_MS } from './lib/hoverIntent';
|
|
767
767
|
export { createPersistedStore } from './lib/store';
|
|
768
|
+
/** `DESIGN.md` §5's 44px tap floor, as the four class strings it actually takes —
|
|
769
|
+
* import these rather than writing `pointer-coarse:` utilities by hand, so the floor
|
|
770
|
+
* moves once when it moves. See `react/lib/tapTarget.ts` for which shape is which. */
|
|
771
|
+
export {
|
|
772
|
+
TAP_TARGET,
|
|
773
|
+
TAP_TARGET_ALWAYS,
|
|
774
|
+
TAP_TARGET_HALO,
|
|
775
|
+
TAP_TARGET_HEIGHT,
|
|
776
|
+
TAP_TARGET_SQUARE,
|
|
777
|
+
} from './lib/tapTarget';
|
|
768
778
|
export * from './nav';
|
|
769
779
|
export * from './palette';
|
|
770
780
|
export * from './prompt';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// cursedbelt layout engine (React) — the read-only renderer + the from-scratch
|
|
2
2
|
// WYSIWYG drag editor (canvas, inspector, palette, dialog) for the
|
|
3
|
-
// `
|
|
3
|
+
// `cwip/layout` model (re-exported at `src/core/layout`). Generic over the app's field type; the app supplies a
|
|
4
4
|
// widget registry (how each node type renders) + optionally a custom binding
|
|
5
5
|
// resolver. Built on the design-system primitives (Surface/Grid, Modal/Drawer,
|
|
6
6
|
// Collapsible) and @atlaskit/pragmatic-drag-and-drop. Exported as part of `cursedbelt/react`.
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
} from '../../core/layout';
|
|
10
10
|
|
|
11
11
|
// The React widget contract for the layout engine. The pure model + binding
|
|
12
|
-
// resolution live in `
|
|
12
|
+
// resolution live in `cwip/layout` (re-exported at `src/core/layout`); this adds the rendering + editing side.
|
|
13
13
|
// Everything is generic over the app's field type `F` (which must extend
|
|
14
14
|
// `LayoutField`), so an app keeps its full column type inside `render`.
|
|
15
15
|
|
package/src/react/lib/field.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TAP_TARGET_HEIGHT } from './tapTarget';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The single field-control class — driven ENTIRELY by the `--field-*` token layer
|
|
3
5
|
* (see theme.css), so restyling every form control app-wide is a one-block change.
|
|
@@ -54,11 +56,11 @@ export const CONTROL_MIN_HEIGHT_CLASS: Record<ControlSize, string> = {
|
|
|
54
56
|
* line up on the same baseline as every other control at the same `size`.
|
|
55
57
|
*/
|
|
56
58
|
export function fieldControlClass(size: ControlSize = 'md'): string {
|
|
57
|
-
// `
|
|
59
|
+
// `TAP_TARGET_HEIGHT` — the `sm`/`md` tokens (32px/36px) clear a mouse
|
|
58
60
|
// pointer's norms but fall short of the 44px WCAG/HIG touch-target floor; widen
|
|
59
61
|
// only on coarse pointers, same pattern as Button (owner orch-host 390px
|
|
60
62
|
// teardown — the orchChat composer's task-type SelectField trigger measured
|
|
61
63
|
// 356×32). Every `fieldControlClass` consumer (Input, SelectField, Date,
|
|
62
64
|
// Combobox, …) inherits the fix for free.
|
|
63
|
-
return `w-full rounded-field border border-field-border bg-field-bg px-3 ${CONTROL_HEIGHT_CLASS[size]}
|
|
65
|
+
return `w-full rounded-field border border-field-border bg-field-bg px-3 ${CONTROL_HEIGHT_CLASS[size]} ${TAP_TARGET_HEIGHT} text-base text-field-fg placeholder:text-field-placeholder sm:text-sm focus-visible:border-field-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-field-ring/30 aria-[invalid=true]:border-field-error aria-[invalid=true]:ring-field-error/30 disabled:cursor-not-allowed disabled:opacity-50`;
|
|
64
66
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
FLOATING_CONTENT_BASE,
|
|
7
7
|
FLOATING_ITEM_BASE,
|
|
8
8
|
} from './floatingStyles';
|
|
9
|
+
import { TAP_TARGET_HEIGHT } from './tapTarget';
|
|
9
10
|
|
|
10
11
|
const REACT_DIR = join(import.meta.dir, '..');
|
|
11
12
|
|
|
@@ -52,6 +53,6 @@ describe('the floating layer — DESIGN.md §5 containment', () => {
|
|
|
52
53
|
|
|
53
54
|
test('a menu row clears 44px on a touch pointer', () => {
|
|
54
55
|
// A mis-tap in a MENU costs the most: the neighbouring row is a different action.
|
|
55
|
-
expect(FLOATING_ITEM_BASE).toContain(
|
|
56
|
+
expect(FLOATING_ITEM_BASE).toContain(TAP_TARGET_HEIGHT);
|
|
56
57
|
});
|
|
57
58
|
});
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* from `tw-animate-css`, which `src/styles.css` imports.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { TAP_TARGET_HEIGHT } from './tapTarget';
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* The gap a floating panel keeps from every viewport edge, in px.
|
|
15
17
|
*
|
|
@@ -44,7 +46,7 @@ export const FLOATING_ITEM_BASE =
|
|
|
44
46
|
// DESIGN.md §5's 44px floor, on coarse pointers only so the dense desktop menu
|
|
45
47
|
// keeps its rhythm. A 32px menu row is a miss on a phone, and a menu is exactly
|
|
46
48
|
// where a mis-tap costs the most: the neighbouring row is a different action.
|
|
47
|
-
|
|
49
|
+
`${TAP_TARGET_HEIGHT} ` +
|
|
48
50
|
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50 ' +
|
|
49
51
|
'focus:bg-accent/10 focus:text-accent';
|
|
50
52
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DESIGN.md` §5's tap floor, written once.
|
|
3
|
+
*
|
|
4
|
+
* > *"Every interactive text link, button, or tab on a mobile screen viewport MUST
|
|
5
|
+
* > maintain a minimum tap footprint of 44px x 44px."*
|
|
6
|
+
*
|
|
7
|
+
* ── 🔴 Why `pointer-coarse:` and not a plain `min-h-11` ─────────────────────
|
|
8
|
+
* The floor is about a FINGER, not about a narrow window. `pointer-coarse:` is a
|
|
9
|
+
* media query on the INPUT DEVICE, so a 390px-wide desktop window matches none of
|
|
10
|
+
* these utilities and a phone matches all of them. That is deliberate twice over:
|
|
11
|
+
* a 44px row of chips on a desktop toolbar is a toolbar that has lost its density
|
|
12
|
+
* (`DESIGN.md` §2 wants those controls on ONE line), and a mouse does not need the
|
|
13
|
+
* padding. The corollary is that **a narrow desktop window proves nothing** —
|
|
14
|
+
* `e2e/touch-targets.spec.ts` runs in a real touch profile, the only configuration
|
|
15
|
+
* in which any of this is switched on at all.
|
|
16
|
+
*
|
|
17
|
+
* ── Why a constant rather than the classes inline ───────────────────────────
|
|
18
|
+
* Because the floor was written out by hand 48 times across 33 files in this
|
|
19
|
+
* package, and a floor written 48 times is a floor that moves 47 times the next
|
|
20
|
+
* time it moves. The hover half below was hand-rolled in 12 separate places, each
|
|
21
|
+
* of which had to independently re-derive that a control revealed on hover does
|
|
22
|
+
* not exist on a phone. `apps/flix` then grew its own fourth-generation copy of
|
|
23
|
+
* all of it, because at the time it could not consume this package.
|
|
24
|
+
*
|
|
25
|
+
* Same kind of file, same reasons, as `floatingStyles.ts` next door — which
|
|
26
|
+
* carries this very floor inside `FLOATING_ITEM_BASE`.
|
|
27
|
+
*
|
|
28
|
+
* ── 🔴 Tailwind has to SEE these strings ────────────────────────────────────
|
|
29
|
+
* The JIT scans source TEXT for candidates; it does not evaluate anything. These
|
|
30
|
+
* constants therefore have to live under this package's own `@source "."` glob
|
|
31
|
+
* (declared in `src/styles.css`, rooted at `src/`) and has to spell each utility
|
|
32
|
+
* out as a literal — a class assembled at runtime from a variable is a class
|
|
33
|
+
* Tailwind never emits, and the symptom is not a type error or a failed build but
|
|
34
|
+
* a stylesheet with no `pointer-coarse` utilities in it at all, i.e. the floor
|
|
35
|
+
* silently gone fleet-wide. `src/tapTargetStylesheet.spec.ts` compiles the real
|
|
36
|
+
* stylesheet and fails on exactly that.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The HEIGHT half of the floor, alone — for a control that is already at least
|
|
41
|
+
* 44px wide by construction: a full-width row, a menu item, a table header, a
|
|
42
|
+
* text input, a chip with real padding.
|
|
43
|
+
*
|
|
44
|
+
* Kept separate from {@link TAP_TARGET} rather than folded into it because a
|
|
45
|
+
* `min-width` is not free everywhere: on a dense desktop-first control that a
|
|
46
|
+
* touch device merely needs to make TALLER, forcing 44px of width too is a layout
|
|
47
|
+
* change on a phone that nothing asked for.
|
|
48
|
+
*/
|
|
49
|
+
export const TAP_TARGET_HEIGHT = 'pointer-coarse:min-h-11';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The floor for a control that sizes itself from its content — a text button, a
|
|
53
|
+
* chip, a nav tab, an icon button drawn small. Grows the box to 44×44 without
|
|
54
|
+
* touching padding, so nothing re-flows on a mouse.
|
|
55
|
+
*
|
|
56
|
+
* Pair it with `inline-flex items-center justify-center` on anything that is not
|
|
57
|
+
* already a flex container: a `min-height` on a plain `<button>` leaves the label
|
|
58
|
+
* riding at the top of the taller box in Firefox and Safari.
|
|
59
|
+
*/
|
|
60
|
+
export const TAP_TARGET = `${TAP_TARGET_HEIGHT} pointer-coarse:min-w-11`;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The floor for a fixed-size ICON button — one that is deliberately a small
|
|
64
|
+
* square on a desktop (`h-7 w-7`, `h-9 w-9`) and must become a 44×44 target on a
|
|
65
|
+
* phone without its glyph growing with it.
|
|
66
|
+
*/
|
|
67
|
+
export const TAP_TARGET_SQUARE = 'pointer-coarse:h-11 pointer-coarse:w-11';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The same 44×44, taken out of the surrounding layout.
|
|
71
|
+
*
|
|
72
|
+
* A poster's ⋯ trigger is anchored to a corner of the artwork. Growing it from
|
|
73
|
+
* 28px to 44px in place would push its visible disc 8px in from that corner on a
|
|
74
|
+
* phone and nowhere else, so the pill moves when you change device. The negative
|
|
75
|
+
* margin spends the extra 16px OUTWARD instead: the disc stays exactly where the
|
|
76
|
+
* design put it and the finger gets the other 8px on every side, over the poster
|
|
77
|
+
* and the gutter, where there is nothing else to hit.
|
|
78
|
+
*
|
|
79
|
+
* Use it for a control that is corner-anchored or overlaid on artwork. Do NOT use
|
|
80
|
+
* it inside a scrolling row or a clipped frame, where the 8px it takes back is
|
|
81
|
+
* somebody else's overflow.
|
|
82
|
+
*/
|
|
83
|
+
export const TAP_TARGET_HALO = `${TAP_TARGET_SQUARE} pointer-coarse:-m-2`;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 🔴 A control that is only revealed on HOVER does not exist on a phone.
|
|
87
|
+
*
|
|
88
|
+
* The ⋯ menu on a poster rests at `opacity-0` and comes back on
|
|
89
|
+
* `group-hover`/`group-focus-within`. On a touch device there is no hover, and
|
|
90
|
+
* `:focus-within` needs a tap that has nowhere to land — so the whole tile menu
|
|
91
|
+
* (save, favorite, mark watched, hide) was measurable, invisible and unreachable
|
|
92
|
+
* on a phone when `apps/flix` measured it on 2026-09-07. The same fix was already
|
|
93
|
+
* hand-written at twelve sites in here — `FilterRail`'s action shelf and
|
|
94
|
+
* `StatTile`'s trend caption among them — which is twelve separate copies of
|
|
95
|
+
* knowing the trap and no way to find the thirteenth site that forgot.
|
|
96
|
+
*
|
|
97
|
+
* Anything that reveals itself on hover must pair that with this; the packaged
|
|
98
|
+
* version of the whole pattern is `REVEAL_ON_HOVER`.
|
|
99
|
+
*/
|
|
100
|
+
export const TAP_TARGET_ALWAYS = 'pointer-coarse:opacity-100';
|
|
@@ -69,8 +69,8 @@ import {
|
|
|
69
69
|
import { buildMaskImageData, rgbaToAlpha } from './maskRaster';
|
|
70
70
|
import type { MaskPainterProps, MaskRegionResult } from './types';
|
|
71
71
|
|
|
72
|
-
// Re-exported
|
|
73
|
-
// prop type
|
|
72
|
+
// Re-exported alongside the component so a consumer of `cursedbelt/react/media` gets
|
|
73
|
+
// the prop type from the same module it imports the component from.
|
|
74
74
|
export type { MaskPainterProps, MaskRegionResult } from './types';
|
|
75
75
|
|
|
76
76
|
const DEFAULT_BRUSH = 40;
|
|
@@ -32,7 +32,7 @@ const QUALITY_OPTIONS = [
|
|
|
32
32
|
* In-browser trim UI: a native `<video>` preview + a dual-handle range slider (with a
|
|
33
33
|
* mediabunny/`<video>` filmstrip), format + quality choices, and a Trim action. No
|
|
34
34
|
* ffmpeg in the browser — `onTrim` hands the chosen range to the app, which routes it
|
|
35
|
-
* to the server (`cursedbelt/server
|
|
35
|
+
* to the server (`cursedbelt/server` `trimVideo`). A Spinner overlays while the
|
|
36
36
|
* server trims.
|
|
37
37
|
*/
|
|
38
38
|
export function VideoTrimmer({
|
|
@@ -655,9 +655,9 @@
|
|
|
655
655
|
}
|
|
656
656
|
}
|
|
657
657
|
|
|
658
|
-
/* ≥44px touch target on coarse pointers only — mirrors
|
|
659
|
-
|
|
660
|
-
|
|
658
|
+
/* ≥44px touch target on coarse pointers only — mirrors `TAP_TARGET_HEIGHT` from
|
|
659
|
+
src/react/lib/tapTarget.ts (STANDARDS.md §4a), hand-rolled here since this is a
|
|
660
|
+
plain `.cbgd-` CSS file, not a Tailwind className. */
|
|
661
661
|
@media (pointer: coarse) {
|
|
662
662
|
.cbgd-order-btn {
|
|
663
663
|
min-height: 44px;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// src/react/media/ffmpegWasm — the browser executor for core/media
|
|
2
2
|
// render plans. A DEDICATED subpath (like video-player): `@ffmpeg/ffmpeg` +
|
|
3
3
|
// `@ffmpeg/util` are heavy OPTIONAL peers, loaded via dynamic import only when
|
|
4
4
|
// an engine actually loads — apps that never export video bundle nothing.
|
|
@@ -83,7 +83,7 @@ export function createFfmpegWasmEngine(config: FfmpegWasmConfig = {}): FfmpegWas
|
|
|
83
83
|
]);
|
|
84
84
|
} catch (cause) {
|
|
85
85
|
throw new Error(
|
|
86
|
-
'cursedbelt/react/media
|
|
86
|
+
'cursedbelt/react/media needs the optional peers "@ffmpeg/ffmpeg" and "@ffmpeg/util" to export video in the browser — install them in your app.',
|
|
87
87
|
{ cause },
|
|
88
88
|
);
|
|
89
89
|
}
|
|
@@ -25,3 +25,45 @@
|
|
|
25
25
|
width: var(--media-button-icon-size, 80%);
|
|
26
26
|
height: var(--media-button-icon-size, 80%);
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* ── 🔴 DESIGN.md §5's 44px tap floor, inside a DEPENDENCY's control bar ──────────────
|
|
31
|
+
*
|
|
32
|
+
* Vidstack draws its own buttons, and on a phone they are under the floor:
|
|
33
|
+
*
|
|
34
|
+
* theme.css --media-button-size 38px (every layout)
|
|
35
|
+
* layouts/video.css:111 --video-sm-button-size 36px (the small layout)
|
|
36
|
+
* theme.css --media-fullscreen-button-size 42px
|
|
37
|
+
* theme.css --media-sm-fullscreen-button-size 42px
|
|
38
|
+
*
|
|
39
|
+
* Measured 2026-09-14 on a Pixel 7 profile: `.vds-menu-button` ("Settings") and
|
|
40
|
+
* `.vds-fullscreen-button` both rendered 36×36 and reddened
|
|
41
|
+
* `e2e/touch-targets.spec.ts`. Nothing in this package had ever looked, because the
|
|
42
|
+
* floor was only ever enforced against controls THIS package draws — and the player
|
|
43
|
+
* is one of the few surfaces where a third party draws the buttons a thumb aims at.
|
|
44
|
+
*
|
|
45
|
+
* 🔴 Set the VARIABLES, never `.vds-button { width }`. Those four names are Vidstack's
|
|
46
|
+
* published override hooks, declared behind `:where()` so a plain custom property wins
|
|
47
|
+
* with no specificity war; overriding the box itself would be a second declaration of
|
|
48
|
+
* the bar's geometry and would drift on the next upgrade — the rule this file opens
|
|
49
|
+
* with. All four are needed, not just the small one: a tablet in landscape gets the
|
|
50
|
+
* wide layout (38px) and fullscreen has its own pair (42px). Every one of them is
|
|
51
|
+
* under 44.
|
|
52
|
+
*
|
|
53
|
+
* The glyph is deliberately left proportional (`--media-button-icon-size` stays at its
|
|
54
|
+
* 70% default) rather than pinned: it keeps `.cbvp-step`'s 80%-of-button relationship
|
|
55
|
+
* above intact — that rule reads the same variable — and a video control bar is the
|
|
56
|
+
* one place where a finger-sized target SHOULD carry a finger-sized glyph.
|
|
57
|
+
*
|
|
58
|
+
* `(pointer: coarse)`, not a width breakpoint: the floor is about a finger, and a
|
|
59
|
+
* narrow desktop window must not get a taller control bar. Same reasoning, and the
|
|
60
|
+
* same media query, as `src/react/lib/tapTarget.ts`.
|
|
61
|
+
*/
|
|
62
|
+
@media (pointer: coarse) {
|
|
63
|
+
[data-media-player] {
|
|
64
|
+
--video-sm-button-size: 44px;
|
|
65
|
+
--media-button-size: 44px;
|
|
66
|
+
--media-fullscreen-button-size: 44px;
|
|
67
|
+
--media-sm-fullscreen-button-size: 44px;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -8,8 +8,8 @@ export interface NamespaceTargetOption {
|
|
|
8
8
|
/** `null` = the General pool (no namespace). */
|
|
9
9
|
id: string | null;
|
|
10
10
|
label: string;
|
|
11
|
-
/** Colorway seed (0-359),
|
|
12
|
-
*
|
|
11
|
+
/** Colorway seed (0-359), hue-on-a-colour-wheel. Omitted (e.g. General)
|
|
12
|
+
* renders a neutral dot. */
|
|
13
13
|
hue?: number;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
planOverflow,
|
|
58
58
|
} from './breadcrumbModel';
|
|
59
59
|
import { NavLink, type NavNavigationProps } from './navShared';
|
|
60
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
60
61
|
|
|
61
62
|
/** Fallback width for the `…` trigger before one has ever been rendered. */
|
|
62
63
|
const ESTIMATED_TRIGGER_WIDTH = 36;
|
|
@@ -552,7 +553,7 @@ const Crumb = memo(function Crumb({
|
|
|
552
553
|
'flex min-w-0 items-center gap-1.5 rounded px-0.5 text-muted-foreground transition-colors ' +
|
|
553
554
|
'hover:text-foreground hover:underline hover:decoration-border hover:underline-offset-4 ' +
|
|
554
555
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' +
|
|
555
|
-
|
|
556
|
+
TAP_TARGET;
|
|
556
557
|
|
|
557
558
|
const body = isLeaf ? (
|
|
558
559
|
<span
|
|
@@ -651,7 +652,7 @@ function PivotTrigger({ node }: { node: BreadcrumbTrailNode }) {
|
|
|
651
652
|
);
|
|
652
653
|
const buttonClass =
|
|
653
654
|
'h-6 w-6 shrink-0 rounded p-0 text-muted-foreground hover:text-foreground ' +
|
|
654
|
-
|
|
655
|
+
TAP_TARGET;
|
|
655
656
|
|
|
656
657
|
if (isAsyncAction(action)) {
|
|
657
658
|
const trigger = (
|
|
@@ -732,7 +733,7 @@ function OverflowMenu({
|
|
|
732
733
|
onPointerEnter={onPointerEnter}
|
|
733
734
|
onFocus={onFocus}
|
|
734
735
|
onClick={onClick}
|
|
735
|
-
className=
|
|
736
|
+
className={`h-6 w-8 shrink-0 rounded p-0 text-muted-foreground hover:text-foreground ${TAP_TARGET}`}
|
|
736
737
|
>
|
|
737
738
|
<MoreHorizontal className='size-4' />
|
|
738
739
|
</Button>
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from './navShared';
|
|
28
28
|
|
|
29
29
|
import { Tooltip } from '../components/Tooltip';
|
|
30
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
30
31
|
export interface HubTileGridProps extends NavNavigationProps {
|
|
31
32
|
/** The domain whose items become tiles. */
|
|
32
33
|
domain: NavDomain;
|
|
@@ -223,7 +224,7 @@ function Tile({
|
|
|
223
224
|
// tabIndex AFTER the spread so it overrides dnd-kit's tabIndex=0 — the grip
|
|
224
225
|
// is a pointer affordance only, never a Tab stop.
|
|
225
226
|
tabIndex={-1}
|
|
226
|
-
className={`inline-flex size-7 cursor-grab items-center justify-center rounded-md bg-background/80 text-muted-foreground backdrop-blur hover:text-foreground ${
|
|
227
|
+
className={`inline-flex size-7 cursor-grab items-center justify-center rounded-md bg-background/80 text-muted-foreground backdrop-blur hover:text-foreground ${TAP_TARGET}`}
|
|
227
228
|
>
|
|
228
229
|
<GripVertical className='size-4' />
|
|
229
230
|
</button>
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
rankBySavedOrder,
|
|
24
24
|
renderIcon,
|
|
25
25
|
} from './navShared';
|
|
26
|
+
import { TAP_TARGET, TAP_TARGET_HEIGHT } from '../lib/tapTarget';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* 🔴 Lazy on purpose, and the number is why: drag-to-reorder pulls three
|
|
@@ -335,14 +336,14 @@ function DomainRow({
|
|
|
335
336
|
// A place that cannot work on THIS host stays VISIBLE and reads as
|
|
336
337
|
// unavailable — never hidden. See `NavHostLimit`.
|
|
337
338
|
limited && 'opacity-55',
|
|
338
|
-
// `
|
|
339
|
+
// `TAP_TARGET`/`TAP_TARGET_HEIGHT` — a 36px-tall row (icon + `py-2`) or a
|
|
339
340
|
// 40px collapsed icon square both clear desktop mouse-target norms but fall
|
|
340
341
|
// short of the 44px WCAG/HIG touch-target floor; widen only on coarse
|
|
341
342
|
// pointers so the dense desktop rail keeps its compact rows (owner orch-host
|
|
342
343
|
// 390px mobile-drawer teardown — sidenav rows measured 223×36).
|
|
343
344
|
collapsed
|
|
344
|
-
?
|
|
345
|
-
:
|
|
345
|
+
? `size-10 justify-center ${TAP_TARGET}`
|
|
346
|
+
: `w-full gap-3 px-3 py-2 ${TAP_TARGET_HEIGHT}`,
|
|
346
347
|
active ? 'bg-muted text-foreground' : 'text-foreground hover:bg-muted',
|
|
347
348
|
)}
|
|
348
349
|
>
|