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
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* | layer | lives in | why |
|
|
7
7
|
* |---|---|---|
|
|
8
8
|
* | the marks (bar, area, heatmap, …) | `cursedbelt/react/charts` | a chart is a chart whether or not it is on a dashboard |
|
|
9
|
-
* | the range vocabulary + bucketing | `cursedbelt/
|
|
9
|
+
* | the range vocabulary + bucketing | `cursedbelt/analytics` | framework-free, because the SERVER buckets too and both sides must agree |
|
|
10
10
|
* | the dashboard furniture (this) | here | a panel with a question, a range switcher |
|
|
11
11
|
* | what the numbers MEAN | the consuming app | orch's task categories are not station's traffic sources |
|
|
12
12
|
*
|
|
@@ -5,6 +5,7 @@ import { IconButton } from '../components/IconButton';
|
|
|
5
5
|
import { Input } from '../components/Input';
|
|
6
6
|
import { cn } from '../lib/cn';
|
|
7
7
|
import { FIELD_CLASS } from '../lib/field';
|
|
8
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
8
9
|
|
|
9
10
|
export interface MessageComposerProps {
|
|
10
11
|
/** Called when the user submits a message. */
|
|
@@ -106,10 +107,10 @@ export function MessageComposer({
|
|
|
106
107
|
label={`Remove ${f.name}`}
|
|
107
108
|
onClick={() => setPendingFiles((prev) => prev.filter((_, j) => j !== i))}
|
|
108
109
|
// `size-4` keeps the glyph compact inline in the pill on a mouse/trackpad;
|
|
109
|
-
// `
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
className=
|
|
110
|
+
// `TAP_TARGET` still floors the REAL tap target to 44px on touch (an
|
|
111
|
+
// earlier `min-h-0` here silently defeated IconButton's own pointer-coarse
|
|
112
|
+
// baseline — cbux-184).
|
|
113
|
+
className={`ml-0.5 size-4 p-0 text-muted-foreground hover:bg-transparent hover:text-foreground [&_svg]:size-3 ${TAP_TARGET}`}
|
|
113
114
|
>
|
|
114
115
|
<X aria-hidden />
|
|
115
116
|
</IconButton>
|
|
@@ -5,6 +5,7 @@ import { useRef, useState, type ButtonHTMLAttributes, type MouseEvent, type Reac
|
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
6
|
import { cn } from '../lib/cn';
|
|
7
7
|
import { Tooltip, type TooltipMobile, type TooltipPlacement } from './Tooltip';
|
|
8
|
+
import { TAP_TARGET_HEIGHT } from '../lib/tapTarget';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* The single source of truth for every interactive element that triggers an action.
|
|
@@ -24,7 +25,7 @@ export const buttonVariants = cva(
|
|
|
24
25
|
[
|
|
25
26
|
'relative inline-flex items-center justify-center gap-2 rounded-md font-medium',
|
|
26
27
|
'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',
|
|
27
|
-
|
|
28
|
+
TAP_TARGET_HEIGHT, // ≥44px touch target on coarse pointers
|
|
28
29
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-offset-background',
|
|
29
30
|
// Disabled = muted surface + faded + inert (never color-alone): clearly off, not a low-contrast haze.
|
|
30
31
|
'disabled:pointer-events-none disabled:opacity-50 disabled:border-transparent disabled:bg-muted disabled:text-muted-foreground',
|
|
@@ -90,7 +91,7 @@ export const buttonVariants = cva(
|
|
|
90
91
|
sm: 'h-[var(--control-h-sm)] px-3 text-sm pointer-coarse:min-w-11',
|
|
91
92
|
md: 'h-[var(--control-h-md)] px-4 text-sm pointer-coarse:min-w-11',
|
|
92
93
|
lg: 'h-[var(--control-h-lg)] px-6 text-base pointer-coarse:min-w-11',
|
|
93
|
-
// `pointer-coarse:min-w-11` alongside the shared `
|
|
94
|
+
// `pointer-coarse:min-w-11` alongside the shared `TAP_TARGET_HEIGHT`
|
|
94
95
|
// above: these are the SQUARE shapes, so a coarse pointer must widen them too
|
|
95
96
|
// — `min-h-11` alone leaves a 36×44 target (width still short of the 44px
|
|
96
97
|
// floor) whenever the token width is below 44px (owner orch-host 390px
|
|
@@ -30,4 +30,55 @@ describe('Checkbox', () => {
|
|
|
30
30
|
expect(getByText('Accept terms')).toBeDefined();
|
|
31
31
|
expect(getByRole('checkbox')).toBeDefined();
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
// 🔴 The floor is on the TARGET, never on the painted box. happy-dom computes no
|
|
35
|
+
// layout, so this can only pin the classes — `e2e/touch-targets.spec.ts` measures
|
|
36
|
+
// the rendered pixels in a Pixel 7 profile, which is the assertion that counts.
|
|
37
|
+
test('the coarse-pointer floor is on the label target, not on the painted box', () => {
|
|
38
|
+
const { getByRole } = render(<Checkbox checked={false} onCheckedChange={() => {}} />);
|
|
39
|
+
const box = getByRole('checkbox');
|
|
40
|
+
const boxClass = box.getAttribute('class') ?? '';
|
|
41
|
+
// `min-height` beats `height`: any coarse floor here repaints the square at
|
|
42
|
+
// 44×44 rather than growing a target around it.
|
|
43
|
+
expect(boxClass).toContain('size-4');
|
|
44
|
+
expect(boxClass).not.toContain('pointer-coarse:min-h-11');
|
|
45
|
+
expect(boxClass).not.toContain('pointer-coarse:min-w-11');
|
|
46
|
+
|
|
47
|
+
const target = box.closest('[data-cb-tap-target]');
|
|
48
|
+
expect(target).not.toBeNull();
|
|
49
|
+
const targetClass = target?.getAttribute('class') ?? '';
|
|
50
|
+
expect(targetClass).toContain('pointer-coarse:min-h-11');
|
|
51
|
+
expect(targetClass).toContain('pointer-coarse:min-w-11');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('the caption is inside the tap target and wired to the box', () => {
|
|
55
|
+
const { getByText, getByRole } = render(
|
|
56
|
+
<Checkbox checked={false} onCheckedChange={() => {}} label='Show hidden' />,
|
|
57
|
+
);
|
|
58
|
+
const caption = getByText('Show hidden');
|
|
59
|
+
const target = getByRole('checkbox').closest('[data-cb-tap-target]');
|
|
60
|
+
expect(target?.contains(caption)).toBe(true);
|
|
61
|
+
expect((target as HTMLLabelElement).htmlFor).toBe(getByRole('checkbox').id);
|
|
62
|
+
expect((target as HTMLLabelElement).htmlFor).not.toBe('');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('labelClassName restyles the caption without touching the box', () => {
|
|
66
|
+
const { getByText, getByRole } = render(
|
|
67
|
+
<Checkbox
|
|
68
|
+
checked={false}
|
|
69
|
+
onCheckedChange={() => {}}
|
|
70
|
+
label='Show hidden'
|
|
71
|
+
labelClassName='text-xs text-muted-foreground'
|
|
72
|
+
/>,
|
|
73
|
+
);
|
|
74
|
+
const caption = (getByText('Show hidden').getAttribute('class') ?? '').split(/\s+/);
|
|
75
|
+
// tailwind-merge drops the defaults it replaces rather than leaving both, so
|
|
76
|
+
// the call site does not have to out-specify the component.
|
|
77
|
+
expect(caption).toContain('text-xs');
|
|
78
|
+
expect(caption).toContain('text-muted-foreground');
|
|
79
|
+
expect(caption).not.toContain('text-sm');
|
|
80
|
+
expect(caption).not.toContain('text-foreground');
|
|
81
|
+
// …and `className` still means the box, as it always has.
|
|
82
|
+
expect(getByRole('checkbox').getAttribute('class') ?? '').toContain('size-4');
|
|
83
|
+
});
|
|
33
84
|
});
|
|
@@ -2,52 +2,94 @@ import * as RadixCheckbox from '@radix-ui/react-checkbox';
|
|
|
2
2
|
import { Check, Minus } from 'lucide-react';
|
|
3
3
|
import { type ComponentPropsWithoutRef, type ReactNode, useId } from 'react';
|
|
4
4
|
import { cn } from '../lib/cn';
|
|
5
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
5
6
|
|
|
6
7
|
export interface CheckboxProps extends ComponentPropsWithoutRef<typeof RadixCheckbox.Root> {
|
|
7
|
-
/** Optional caption rendered beside the box;
|
|
8
|
+
/** Optional caption rendered beside the box; rendered inside the `<label>` target. */
|
|
8
9
|
label?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Typography for the caption. Defaults to `text-sm text-foreground`; `cn` is
|
|
12
|
+
* tailwind-merge, so `text-xs text-muted-foreground` here REPLACES both rather
|
|
13
|
+
* than fighting them.
|
|
14
|
+
*
|
|
15
|
+
* It exists because `className` lands on the painted box, so a dense toolbar
|
|
16
|
+
* that wanted a 12px muted caption had no way to ask for one — and the app that
|
|
17
|
+
* wanted it (`apps/flix`'s filter bar) kept a private copy of this whole control
|
|
18
|
+
* for that one reason. Restyling a shared component's defaults at every call
|
|
19
|
+
* site is how the copies start.
|
|
20
|
+
*/
|
|
21
|
+
labelClassName?: string;
|
|
9
22
|
}
|
|
10
23
|
|
|
24
|
+
// ── 🔴 The painted box is 16px at EVERY pointer type ────────────────────────────
|
|
25
|
+
// The floor lives on the `<label>` target below, never here. This element carries
|
|
26
|
+
// `bg-surface` and `data-[state=checked]:bg-accent-solid` — it IS the painted
|
|
27
|
+
// square — and `min-height` beats `height`, so a `pointer-coarse:min-h-11` on it
|
|
28
|
+
// does not grow a target AROUND a 16px box, it repaints the box itself at 44×44.
|
|
29
|
+
// That is exactly what this file did from the day it was written, under a comment
|
|
30
|
+
// asserting it did not: `size-4` + `TAP_TARGET` drew a fingernail-sized checkbox
|
|
31
|
+
// on every phone, and left the words beside it under 44px besides.
|
|
32
|
+
//
|
|
33
|
+
// A comment cannot hold this. `e2e/touch-targets.spec.ts` measures both halves in
|
|
34
|
+
// a real Pixel 7 profile — 16px painted, ≥44px reachable — which is the only
|
|
35
|
+
// configuration where `pointer-coarse:` is switched on at all.
|
|
11
36
|
const BOX = cn(
|
|
12
|
-
// The painted box stays 16px — a 44px checkbox is a design change. The TARGET
|
|
13
|
-
// grows around it on a coarse pointer, which is what DESIGN.md §5 asks for.
|
|
14
37
|
'peer size-4 shrink-0 rounded-sm border border-border-strong bg-surface transition-colors',
|
|
15
|
-
'pointer-coarse:min-h-11 pointer-coarse:min-w-11',
|
|
16
38
|
'data-[state=checked]:border-accent-solid data-[state=checked]:bg-accent-solid data-[state=checked]:text-white',
|
|
17
39
|
'data-[state=indeterminate]:border-accent-solid data-[state=indeterminate]:bg-accent-solid data-[state=indeterminate]:text-white',
|
|
18
40
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
|
19
41
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
20
42
|
);
|
|
21
43
|
|
|
44
|
+
// The tap target: the whole label, box and caption and the gap between them.
|
|
45
|
+
//
|
|
46
|
+
// Clicking a `<label>` toggles the control it labels — native browser behaviour,
|
|
47
|
+
// not something this component implements — so the 44px floor belongs on the
|
|
48
|
+
// region a thumb is actually aiming at, which is the words as much as the box.
|
|
49
|
+
// `data-cb-tap-target` is the seam `e2e/touch-targets.spec.ts` measures a
|
|
50
|
+
// sub-44px control through, the way a checkbox has to be measured.
|
|
51
|
+
const TARGET = cn(
|
|
52
|
+
'inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 align-middle',
|
|
53
|
+
TAP_TARGET,
|
|
54
|
+
);
|
|
55
|
+
|
|
22
56
|
/**
|
|
23
57
|
* Checkbox vendored from shadcn (Radix `Checkbox`). White check on a solid-accent
|
|
24
58
|
* fill when checked (a dash when `indeterminate`); a visible `--ring` focus ring on
|
|
25
59
|
* keyboard focus. Use `checked` + `onCheckedChange` (RHF wires this via
|
|
26
|
-
* `<Controller>`). Pass `label` for a captioned control
|
|
60
|
+
* `<Controller>`). Pass `label` for a captioned control, and `labelClassName` to
|
|
61
|
+
* set that caption's typography without touching the box.
|
|
62
|
+
*
|
|
63
|
+
* `className` lands on the painted 16px box; the 44px coarse-pointer target is the
|
|
64
|
+
* enclosing `<label>` and is not overridable, because it is the rule.
|
|
27
65
|
*/
|
|
28
|
-
export function Checkbox({
|
|
66
|
+
export function Checkbox({
|
|
67
|
+
label,
|
|
68
|
+
className,
|
|
69
|
+
labelClassName,
|
|
70
|
+
id: idProp,
|
|
71
|
+
...props
|
|
72
|
+
}: CheckboxProps) {
|
|
29
73
|
const reactId = useId();
|
|
30
74
|
const id = idProp ?? reactId;
|
|
31
|
-
const box = (
|
|
32
|
-
<RadixCheckbox.Root id={id} className={cn(BOX, className)} {...props}>
|
|
33
|
-
<RadixCheckbox.Indicator className='flex items-center justify-center text-current'>
|
|
34
|
-
{props.checked === 'indeterminate' ? (
|
|
35
|
-
<Minus className='size-3.5' />
|
|
36
|
-
) : (
|
|
37
|
-
<Check className='size-3.5' />
|
|
38
|
-
)}
|
|
39
|
-
</RadixCheckbox.Indicator>
|
|
40
|
-
</RadixCheckbox.Root>
|
|
41
|
-
);
|
|
42
|
-
if (label == null) return box;
|
|
43
|
-
// Sibling label associated by id (a label can't statically "contain" the Radix
|
|
44
|
-
// button control); clicking the caption toggles the box.
|
|
45
75
|
return (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
// `htmlFor` is explicit rather than relying on the label's first labelable
|
|
77
|
+
// descendant: Radix renders a hidden bubble `<input type="checkbox">` inside
|
|
78
|
+
// the Root when the control sits in a form, and an implicit association would
|
|
79
|
+
// resolve to THAT instead of the button the user can see.
|
|
80
|
+
<label htmlFor={id} data-cb-tap-target='' className={TARGET}>
|
|
81
|
+
<RadixCheckbox.Root id={id} className={cn(BOX, className)} {...props}>
|
|
82
|
+
<RadixCheckbox.Indicator className='flex items-center justify-center text-current'>
|
|
83
|
+
{props.checked === 'indeterminate' ? (
|
|
84
|
+
<Minus className='size-3.5' />
|
|
85
|
+
) : (
|
|
86
|
+
<Check className='size-3.5' />
|
|
87
|
+
)}
|
|
88
|
+
</RadixCheckbox.Indicator>
|
|
89
|
+
</RadixCheckbox.Root>
|
|
90
|
+
{label == null ? null : (
|
|
91
|
+
<span className={cn('text-sm text-foreground', labelClassName)}>{label}</span>
|
|
92
|
+
)}
|
|
93
|
+
</label>
|
|
52
94
|
);
|
|
53
95
|
}
|
|
@@ -3,6 +3,7 @@ import { cn } from '../lib/cn';
|
|
|
3
3
|
import { handleCodeTabIndent } from '../lib/tabIndent';
|
|
4
4
|
import { CopyButton } from './CopyButton';
|
|
5
5
|
import { ScrollArea } from './ScrollArea';
|
|
6
|
+
import { TAP_TARGET_ALWAYS } from '../lib/tapTarget';
|
|
6
7
|
|
|
7
8
|
export interface CodeAreaProps {
|
|
8
9
|
/** The code text (controlled). */
|
|
@@ -102,7 +103,7 @@ export function CodeArea({
|
|
|
102
103
|
// Reveal on hover/focus on fine pointers; always visible on touch,
|
|
103
104
|
// where there is no hover to reveal it.
|
|
104
105
|
'opacity-0 transition-opacity duration-[var(--duration-fast)]',
|
|
105
|
-
|
|
106
|
+
`group-focus-within:opacity-100 group-hover:opacity-100 ${TAP_TARGET_ALWAYS}`,
|
|
106
107
|
)}
|
|
107
108
|
>
|
|
108
109
|
<CopyButton value={value} confirmToast={false} />
|
|
@@ -7,9 +7,9 @@ afterEach(cleanup);
|
|
|
7
7
|
|
|
8
8
|
describe('CodeChip — DESIGN.md §3, an inline literal is a monospace chip with a tint', () => {
|
|
9
9
|
test('it is monospace, tinted, and inline enough to sit in a sentence', () => {
|
|
10
|
-
const { container } = render(<CodeChip>~/.
|
|
10
|
+
const { container } = render(<CodeChip>~/.local/state/deploy</CodeChip>);
|
|
11
11
|
const chip = container.querySelector('[data-cb-code-chip]');
|
|
12
|
-
expect(chip?.textContent).toBe('~/.
|
|
12
|
+
expect(chip?.textContent).toBe('~/.local/state/deploy');
|
|
13
13
|
expect(chip?.className).toContain('font-mono');
|
|
14
14
|
// The TINT is the clause — a grey monospace run reads as prose in a different face.
|
|
15
15
|
expect(chip?.className).toContain('bg-surface-sunken');
|
|
@@ -2,6 +2,7 @@ import * as RadixCollapsible from '@radix-ui/react-collapsible';
|
|
|
2
2
|
import { ChevronDown } from 'lucide-react';
|
|
3
3
|
import type { ReactNode } from 'react';
|
|
4
4
|
import { cn } from '../lib/cn';
|
|
5
|
+
import { TAP_TARGET_HEIGHT } from '../lib/tapTarget';
|
|
5
6
|
|
|
6
7
|
export interface CollapsibleProps {
|
|
7
8
|
/** The always-visible clickable header content (shown left of the chevron). */
|
|
@@ -52,7 +53,7 @@ export function Collapsible({
|
|
|
52
53
|
// guardrails-ignore no-raw-action-button: this IS the Collapsible section-toggle
|
|
53
54
|
// primitive — its own trigger is necessarily a raw <button> (Radix Trigger asChild).
|
|
54
55
|
type='button'
|
|
55
|
-
className=
|
|
56
|
+
className={`group flex w-full items-center justify-between gap-2 py-2 text-left text-sm font-medium text-foreground transition-colors hover:text-accent disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${TAP_TARGET_HEIGHT}`}
|
|
56
57
|
>
|
|
57
58
|
{trigger}
|
|
58
59
|
<ChevronDown className='size-4 shrink-0 text-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-180' />
|
|
@@ -7,6 +7,7 @@ import { cn } from '../lib/cn';
|
|
|
7
7
|
import { CONTROL_HEIGHT_CLASS, CONTROL_MIN_HEIGHT_CLASS, type ControlSize } from '../lib/field';
|
|
8
8
|
import { FLOATING_COLLISION_PADDING,
|
|
9
9
|
FLOATING_CONTENT_BASE, FLOATING_ITEM_BASE } from '../lib/floatingStyles';
|
|
10
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
10
11
|
|
|
11
12
|
/** A single option in the combobox list. */
|
|
12
13
|
export interface ComboboxOption {
|
|
@@ -255,7 +256,7 @@ export function ComboboxField(props: ComboboxFieldProps) {
|
|
|
255
256
|
<span>{lbl}</span>
|
|
256
257
|
<Combobox.ChipRemove
|
|
257
258
|
aria-label={`Remove ${lbl}`}
|
|
258
|
-
className=
|
|
259
|
+
className={`inline-flex size-4 items-center justify-center rounded-sm text-muted-foreground transition hover:bg-border hover:text-foreground ${TAP_TARGET}`}
|
|
259
260
|
>
|
|
260
261
|
<X className='size-3' aria-hidden />
|
|
261
262
|
</Combobox.ChipRemove>
|
|
@@ -282,7 +283,7 @@ export function ComboboxField(props: ComboboxFieldProps) {
|
|
|
282
283
|
) : (
|
|
283
284
|
<Combobox.Trigger
|
|
284
285
|
aria-label='Toggle options'
|
|
285
|
-
className=
|
|
286
|
+
className={`mr-2 flex size-5 shrink-0 items-center justify-center text-muted-foreground transition hover:text-foreground ${TAP_TARGET}`}
|
|
286
287
|
>
|
|
287
288
|
<ChevronDown className='size-4' />
|
|
288
289
|
</Combobox.Trigger>
|
|
@@ -5,6 +5,7 @@ import { useCopyToClipboard } from '../hooks/useCopyToClipboard';
|
|
|
5
5
|
import { cn } from '../lib/cn';
|
|
6
6
|
import { Button } from './Button';
|
|
7
7
|
import type { TooltipPlacement } from './Tooltip';
|
|
8
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
8
9
|
|
|
9
10
|
export interface CopyButtonProps {
|
|
10
11
|
/** Text written to the clipboard (or a resolver called on click). */
|
|
@@ -88,7 +89,7 @@ export function CopyButton({
|
|
|
88
89
|
onClick={onClick}
|
|
89
90
|
disabled={disabled}
|
|
90
91
|
className={cn(
|
|
91
|
-
|
|
92
|
+
`h-auto min-h-0 w-auto shrink-0 cursor-pointer gap-1 rounded p-1 text-muted-foreground hover:bg-transparent hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50 ${TAP_TARGET}`,
|
|
92
93
|
className,
|
|
93
94
|
)}
|
|
94
95
|
>
|
|
@@ -24,7 +24,7 @@ describe('CopyableText', () => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
test('block mode shows the full value in a wrapping mono panel', () => {
|
|
27
|
-
const path = '/
|
|
27
|
+
const path = '/srv/worktrees/cc-orch/tsk_01KXFNYZSFPAEP6XVJGZPEGWX4/packages/app/src';
|
|
28
28
|
const { getByText, container } = render(<CopyableText value={path} block />);
|
|
29
29
|
expect(getByText(path)).toBeDefined();
|
|
30
30
|
expect(getByText(path).className).toContain('break-all');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Check } from 'lucide-react';
|
|
2
2
|
import { cn } from '../../lib/cn';
|
|
3
|
+
import { TAP_TARGET_HEIGHT } from '../../lib/tapTarget';
|
|
3
4
|
|
|
4
5
|
export interface ColumnChecklistItem {
|
|
5
6
|
key: string;
|
|
@@ -97,7 +98,7 @@ export function ColumnChecklist({
|
|
|
97
98
|
className={cn(
|
|
98
99
|
'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors',
|
|
99
100
|
'hover:bg-muted focus-visible:bg-muted focus-visible:outline-none',
|
|
100
|
-
|
|
101
|
+
TAP_TARGET_HEIGHT,
|
|
101
102
|
item.disabled && 'cursor-not-allowed opacity-50',
|
|
102
103
|
)}
|
|
103
104
|
>
|
|
@@ -3,6 +3,7 @@ import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-r
|
|
|
3
3
|
import { IconButton } from '../IconButton';
|
|
4
4
|
import { Cluster } from '../layout';
|
|
5
5
|
import { SelectField } from '../SelectField';
|
|
6
|
+
import { TAP_TARGET_HEIGHT } from '../../lib/tapTarget';
|
|
6
7
|
|
|
7
8
|
export interface TablePaginationProps<TRow> {
|
|
8
9
|
table: Table<TRow>;
|
|
@@ -33,7 +34,7 @@ export function TablePagination<TRow>({ table, pageSizeOptions }: TablePaginatio
|
|
|
33
34
|
<SelectField
|
|
34
35
|
fieldStyle={false}
|
|
35
36
|
aria-label='Rows per page'
|
|
36
|
-
className=
|
|
37
|
+
className={`h-8 rounded-md border border-border bg-background px-2 ${TAP_TARGET_HEIGHT}`}
|
|
37
38
|
value={String(pageSize)}
|
|
38
39
|
onValueChange={(v) => table.setPageSize(Number(v))}
|
|
39
40
|
options={pageSizeOptions.map((n) => ({ value: String(n), label: String(n) }))}
|
|
@@ -2,6 +2,7 @@ import type { Column } from '@tanstack/react-table';
|
|
|
2
2
|
import { ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react';
|
|
3
3
|
import type { ReactNode } from 'react';
|
|
4
4
|
import { Tooltip } from '../Tooltip';
|
|
5
|
+
import { TAP_TARGET_HEIGHT } from '../../lib/tapTarget';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* The full label, one hover away — and it is OURS, not the browser's.
|
|
@@ -84,7 +85,7 @@ export function SortHeader<TRow>({
|
|
|
84
85
|
// computed styles on orch's Fleet tab, 2026-08-12: `th` uppercase,
|
|
85
86
|
// `button` none. Letter-spacing does inherit (0.55px on both), so only
|
|
86
87
|
// the case needs restating.
|
|
87
|
-
className=
|
|
88
|
+
className={`-mx-1 -my-2.5 inline-flex max-w-full items-center gap-1 rounded px-1 py-2.5 uppercase transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${TAP_TARGET_HEIGHT}`}
|
|
88
89
|
>
|
|
89
90
|
{/* min-w-0 so the label is what gives way in a narrow track — the sort
|
|
90
91
|
arrow is the affordance and must survive at any width. */}
|
|
@@ -18,13 +18,13 @@ import {
|
|
|
18
18
|
VALUELESS_OPS,
|
|
19
19
|
} from './filterQuery';
|
|
20
20
|
|
|
21
|
-
export interface
|
|
21
|
+
export interface TableFilterBuilderColumn {
|
|
22
22
|
key: string;
|
|
23
23
|
label: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export interface
|
|
27
|
-
columns:
|
|
26
|
+
export interface TableFilterBuilderProps {
|
|
27
|
+
columns: TableFilterBuilderColumn[];
|
|
28
28
|
value: FilterQuery;
|
|
29
29
|
onChange: (next: FilterQuery) => void;
|
|
30
30
|
className?: string;
|
|
@@ -36,7 +36,30 @@ const OP_OPTIONS = (Object.keys(FILTER_OP_LABELS) as FilterOp[]).map((op) => ({
|
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* The filter builder — `(A and B) or (C and D)`, and the UX is the hard half.
|
|
39
|
+
* The TABLE's filter builder — `(A and B) or (C and D)`, and the UX is the hard half.
|
|
40
|
+
*
|
|
41
|
+
* ── 🔴 Why the name carries `Table`, 2026-09-13 ─────────────────────────────
|
|
42
|
+
* It was `FilterBuilder`, and `cursedesk` has a `FilterBuilder` of its own. The
|
|
43
|
+
* graduation pass that looked at the pair to decide which one should live here
|
|
44
|
+
* found they are not two copies of one component — they are two different
|
|
45
|
+
* components wearing one basename, which is the trap that makes the next person
|
|
46
|
+
* merge them wrongly:
|
|
47
|
+
*
|
|
48
|
+
* - **This one is a VIEW filter.** Two levels by construction (groups OR'd,
|
|
49
|
+
* conditions AND'd inside one), values are strings, columns are `{key,label}`
|
|
50
|
+
* with no type, and it narrows rows already on screen behind a popover on the
|
|
51
|
+
* `DataTable` toolbar. Nothing it builds crosses a wire.
|
|
52
|
+
* - **`cursedesk`'s is a QUERY builder** — an arbitrarily-nested AND/OR/NOT
|
|
53
|
+
* tree with per-type operator sets (`between`, `matches`, `in`, `isEmpty`),
|
|
54
|
+
* range and set editors, `caseSensitive` per rule and a validator, editing
|
|
55
|
+
* the exact `FilterNode` its API consumes so what is built is what the server
|
|
56
|
+
* filters and exports by.
|
|
57
|
+
*
|
|
58
|
+
* Neither is the other generalised. Collapsing them would mean either giving a
|
|
59
|
+
* table toolbar a regex field and a three-deep nesting rule, or taking typed
|
|
60
|
+
* operators away from a filter the server evaluates — so they stay two, and
|
|
61
|
+
* this one says which it is. See {@link FilterQuery} for the shape it edits;
|
|
62
|
+
* the name of the thing it is NOT is `cursedesk`'s `ui/workbench/FilterBuilder`.
|
|
40
63
|
*
|
|
41
64
|
* The owner's closing clause is the acceptance test, not a nicety: *"easy enough
|
|
42
65
|
* that I don't give up on trying it."* So every decision here is made against
|
|
@@ -60,7 +83,12 @@ const OP_OPTIONS = (Object.keys(FILTER_OP_LABELS) as FilterOp[]).map((op) => ({
|
|
|
60
83
|
* The trigger carries the live count so the toolbar says how many constraints
|
|
61
84
|
* are on without opening anything (DESIGN.md §2 — one line, state legible on it).
|
|
62
85
|
*/
|
|
63
|
-
export function
|
|
86
|
+
export function TableFilterBuilder({
|
|
87
|
+
columns,
|
|
88
|
+
value,
|
|
89
|
+
onChange,
|
|
90
|
+
className,
|
|
91
|
+
}: TableFilterBuilderProps) {
|
|
64
92
|
const [open, setOpen] = useState(false);
|
|
65
93
|
const activeCount = countActiveConditions(value);
|
|
66
94
|
const firstColumn = columns[0]?.key ?? '';
|
|
@@ -3,9 +3,9 @@ import { Download, Plus, Upload } from 'lucide-react';
|
|
|
3
3
|
import type { ReactNode } from 'react';
|
|
4
4
|
import { Button } from '../Button';
|
|
5
5
|
import { Cluster, Split } from '../layout';
|
|
6
|
-
import { FilterBuilder } from './FilterBuilder';
|
|
7
6
|
import { SearchBox } from './SearchBox';
|
|
8
7
|
import { SortStack } from './SortStack';
|
|
8
|
+
import { TableFilterBuilder } from './TableFilterBuilder';
|
|
9
9
|
import { TableViewToggle } from './TableViewToggle';
|
|
10
10
|
import { ViewOptionsMenu } from './ViewOptionsMenu';
|
|
11
11
|
|
|
@@ -34,7 +34,7 @@ export interface TableToolbarProps<TRow> {
|
|
|
34
34
|
* left/centre, actions far right, never a second row.
|
|
35
35
|
*
|
|
36
36
|
* What sits on it, left to right: the search box with its use-time scope control
|
|
37
|
-
* ({@link SearchBox}), the filter builder ({@link
|
|
37
|
+
* ({@link SearchBox}), the filter builder ({@link TableFilterBuilder}), the sort stack
|
|
38
38
|
* ({@link SortStack}), anything the caller adds, then — right-aligned — the
|
|
39
39
|
* rows ⇄ cards toggle, the column menu, and import/export/add.
|
|
40
40
|
*
|
|
@@ -88,7 +88,7 @@ export function TableToolbar<TRow>({
|
|
|
88
88
|
/>
|
|
89
89
|
) : null}
|
|
90
90
|
{enableFilterBuilder && controls ? (
|
|
91
|
-
<
|
|
91
|
+
<TableFilterBuilder
|
|
92
92
|
columns={controls.filterColumns}
|
|
93
93
|
value={controls.filterQuery}
|
|
94
94
|
onChange={controls.setFilterQuery}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import { ExternalLink } from '../../ExternalLink';
|
|
3
|
+
import { TAP_TARGET_HEIGHT } from '../../../lib/tapTarget';
|
|
3
4
|
|
|
4
5
|
export interface LinkCellProps {
|
|
5
6
|
href: string;
|
|
@@ -24,7 +25,7 @@ export function LinkCell({ href, label }: LinkCellProps): JSX.Element | null {
|
|
|
24
25
|
url={href}
|
|
25
26
|
{...(label === undefined ? {} : { display: label })}
|
|
26
27
|
stopPropagation
|
|
27
|
-
className=
|
|
28
|
+
className={`max-w-[180px] truncate font-sans not-italic ${TAP_TARGET_HEIGHT}`}
|
|
28
29
|
/>
|
|
29
30
|
);
|
|
30
31
|
}
|
|
@@ -18,7 +18,14 @@ export {
|
|
|
18
18
|
type DataTableProps,
|
|
19
19
|
nextSortStack,
|
|
20
20
|
} from './DataTable';
|
|
21
|
-
|
|
21
|
+
// 🔴 `TableFilterBuilder`, not `FilterBuilder` — see its header. The bare name belonged to
|
|
22
|
+
// two different components in two repos, and a shared basename that is not a shared
|
|
23
|
+
// component is how the next person merges them wrongly.
|
|
24
|
+
export {
|
|
25
|
+
TableFilterBuilder,
|
|
26
|
+
type TableFilterBuilderColumn,
|
|
27
|
+
type TableFilterBuilderProps,
|
|
28
|
+
} from './TableFilterBuilder';
|
|
22
29
|
export {
|
|
23
30
|
activeGroups,
|
|
24
31
|
compareValues,
|
|
@@ -3,6 +3,7 @@ import { DragHandleIcon } from '../hooks/DragHandleIcon';
|
|
|
3
3
|
import { cn } from '../lib/cn';
|
|
4
4
|
import { REVEAL_ON_HOVER } from './revealOnHover';
|
|
5
5
|
import { Tooltip } from './Tooltip';
|
|
6
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
6
7
|
|
|
7
8
|
export interface DragHandleProps {
|
|
8
9
|
/** Spread from a drag hook's `handleProps` — the pointer/keyboard drag wiring. */
|
|
@@ -35,7 +36,7 @@ export function DragHandle({
|
|
|
35
36
|
{...handleProps}
|
|
36
37
|
aria-label={label}
|
|
37
38
|
className={cn(
|
|
38
|
-
|
|
39
|
+
`flex w-6 shrink-0 items-center justify-center self-stretch text-muted-foreground/60 ${TAP_TARGET}`,
|
|
39
40
|
alwaysVisible ? 'transition' : REVEAL_ON_HOVER,
|
|
40
41
|
className,
|
|
41
42
|
)}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { EmojiPicker } from '../emoji/EmojiPicker';
|
|
3
3
|
import { cn } from '../lib/cn';
|
|
4
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
4
5
|
|
|
5
6
|
export interface EmojiFieldProps {
|
|
6
7
|
/** The current emoji (a single grapheme), or '' for none. */
|
|
@@ -46,7 +47,7 @@ export function EmojiField({
|
|
|
46
47
|
aria-describedby={ariaDescribedBy}
|
|
47
48
|
aria-label={value ? `Emoji: ${value}` : 'Pick an emoji'}
|
|
48
49
|
className={cn(
|
|
49
|
-
|
|
50
|
+
`inline-flex size-10 items-center justify-center rounded-field border border-field-border bg-field-bg text-xl transition hover:border-field-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-field-ring/30 disabled:cursor-not-allowed disabled:opacity-50 ${TAP_TARGET}`,
|
|
50
51
|
className,
|
|
51
52
|
)}
|
|
52
53
|
>
|
|
@@ -43,8 +43,9 @@ const TONE_MARKER: Record<EventTimelineTone, { icon: ReactNode; className: strin
|
|
|
43
43
|
* consistently indented body. Subtle dividers separate events; the axis line
|
|
44
44
|
* connects markers so the sequence reads as one story.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
* canvas
|
|
46
|
+
* This is the presentational history list. (It used to need distinguishing from a
|
|
47
|
+
* time-scaled editing canvas in `react/timeline`; that went with the unreferenced
|
|
48
|
+
* subpaths on 2026-09-13, so `EventTimeline` is now the only timeline here.)
|
|
48
49
|
*/
|
|
49
50
|
export function EventTimeline({ items, className }: EventTimelineProps) {
|
|
50
51
|
return (
|
|
@@ -4,7 +4,7 @@ import { FileLocation } from './FileLocation';
|
|
|
4
4
|
|
|
5
5
|
afterEach(cleanup);
|
|
6
6
|
|
|
7
|
-
const PATH = '/
|
|
7
|
+
const PATH = '/srv/demo-app/.aliasManager/aliases.sh';
|
|
8
8
|
|
|
9
9
|
describe('FileLocation', () => {
|
|
10
10
|
test('shows the path and the default "Saved in" label', () => {
|
|
@@ -30,7 +30,7 @@ export interface IconButtonProps extends Omit<ButtonProps, 'size' | 'leftIcon' |
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Icon-only button: a {@link Button} locked to a square `icon*` size (≥44px touch
|
|
33
|
-
* target on coarse pointers via Button's `
|
|
33
|
+
* target on coarse pointers via Button's `TAP_TARGET_HEIGHT` baseline,
|
|
34
34
|
* regardless of `size`) with a mandatory `aria-label`. Defaults to the `ghost`
|
|
35
35
|
* variant — the right weight for toolbars/row actions. Slightly larger glyphs
|
|
36
36
|
* (`size-5`) than a text button's, since the icon carries the whole meaning.
|
|
@@ -17,6 +17,7 @@ import { type ReactNode, useState } from 'react';
|
|
|
17
17
|
import { useHasHover } from '../hooks/useHasHover';
|
|
18
18
|
import { cn } from '../lib/cn';
|
|
19
19
|
import { HOVER_HINT_DELAY_MS } from '../lib/hoverIntent';
|
|
20
|
+
import { TAP_TARGET } from '../lib/tapTarget';
|
|
20
21
|
|
|
21
22
|
export interface InfoHintProps {
|
|
22
23
|
/** The help body. */
|
|
@@ -90,10 +91,10 @@ export function InfoHint({
|
|
|
90
91
|
ref={refs.setReference}
|
|
91
92
|
aria-label={label}
|
|
92
93
|
className={cn(
|
|
93
|
-
// ≥44px touch target on coarse pointers (same floor
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
|
|
94
|
+
// ≥44px touch target on coarse pointers (the same `TAP_TARGET` floor
|
|
95
|
+
// Button/IconButton carry — a bare `size-4` icon glyph with no padding
|
|
96
|
+
// measured 16×16px on mobile, cc/197).
|
|
97
|
+
`inline-flex items-center justify-center text-muted-foreground hover:text-accent ${TAP_TARGET}`,
|
|
97
98
|
className,
|
|
98
99
|
)}
|
|
99
100
|
{...getReferenceProps()}
|
|
@@ -135,7 +135,7 @@ export function InheritBadge({
|
|
|
135
135
|
label={resetLabel}
|
|
136
136
|
disabled={disabled}
|
|
137
137
|
onClick={onReset}
|
|
138
|
-
// Glyph only is shrunk, never the BOX: Button's `
|
|
138
|
+
// Glyph only is shrunk, never the BOX: Button's `TAP_TARGET_HEIGHT`
|
|
139
139
|
// is what keeps this a real touch target, and forcing a size-5 square
|
|
140
140
|
// would quietly delete that on every phone.
|
|
141
141
|
className={cn('[&_svg]:size-3.5', REVEAL_ON_HOVER)}
|