cursedbelt 5.93.0 → 5.95.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/react/components/AppShell.d.ts +12 -1
- package/dist/react/components/AppShell.d.ts.map +1 -1
- package/dist/react/components/AppShell.js +24 -5
- package/dist/react/components/AppShell.js.map +1 -1
- package/dist/react/components/ComboboxField.js +2 -2
- package/dist/react/components/ComboboxField.js.map +1 -1
- package/dist/react/components/CommentThread.d.ts +9 -3
- package/dist/react/components/CommentThread.d.ts.map +1 -1
- package/dist/react/components/CommentThread.js +25 -11
- package/dist/react/components/CommentThread.js.map +1 -1
- package/dist/react/components/DatePicker.d.ts +9 -5
- package/dist/react/components/DatePicker.d.ts.map +1 -1
- package/dist/react/components/DatePicker.js +192 -27
- package/dist/react/components/DatePicker.js.map +1 -1
- package/dist/react/components/InlineEditableText.d.ts +12 -2
- package/dist/react/components/InlineEditableText.d.ts.map +1 -1
- package/dist/react/components/InlineEditableText.js +11 -8
- package/dist/react/components/InlineEditableText.js.map +1 -1
- package/dist/react/components/VoiceNote.d.ts +20 -0
- package/dist/react/components/VoiceNote.d.ts.map +1 -0
- package/dist/react/components/VoiceNote.js +54 -0
- package/dist/react/components/VoiceNote.js.map +1 -0
- package/dist/react/components/VoiceRecorder.d.ts +35 -0
- package/dist/react/components/VoiceRecorder.d.ts.map +1 -0
- package/dist/react/components/VoiceRecorder.js +155 -0
- package/dist/react/components/VoiceRecorder.js.map +1 -0
- package/dist/react/components/suggestionList.js +2 -2
- package/dist/react/components/suggestionList.js.map +1 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/lib/dateText.d.ts +21 -0
- package/dist/react/lib/dateText.d.ts.map +1 -0
- package/dist/react/lib/dateText.js +94 -0
- package/dist/react/lib/dateText.js.map +1 -0
- package/dist/react/lib/floatingStyles.d.ts +12 -0
- package/dist/react/lib/floatingStyles.d.ts.map +1 -1
- package/dist/react/lib/floatingStyles.js +12 -0
- package/dist/react/lib/floatingStyles.js.map +1 -1
- package/dist/react/map-frame/MapFrame.d.ts +219 -0
- package/dist/react/map-frame/MapFrame.d.ts.map +1 -0
- package/dist/react/map-frame/MapFrame.js +726 -0
- package/dist/react/map-frame/MapFrame.js.map +1 -0
- package/dist/react/map-frame/geo.d.ts +210 -0
- package/dist/react/map-frame/geo.d.ts.map +1 -0
- package/dist/react/map-frame/geo.js +345 -0
- package/dist/react/map-frame/geo.js.map +1 -0
- package/dist/react/map-frame/index.d.ts +5 -0
- package/dist/react/map-frame/index.d.ts.map +1 -0
- package/dist/react/map-frame/index.js +3 -0
- package/dist/react/map-frame/index.js.map +1 -0
- package/dist/styles-areas/analytics.css +11 -10
- package/dist/styles-areas/canvas-hud.css +5 -5
- package/dist/styles-areas/data-table.css +13 -12
- package/dist/styles-areas/fields.css +12 -10
- package/dist/styles-areas/stats.css +12 -11
- package/dist/styles-areas/wizard.css +6 -6
- package/dist/styles-areas/workbench.css +17 -17
- package/dist/styles-utilities.css +15 -0
- package/package.json +13 -1
- package/scripts/guardrails-baseline.json +1 -1
- package/scripts/styleAreas.ts +1 -1
- package/src/react/components/AppShell.spec.tsx +53 -0
- package/src/react/components/AppShell.tsx +79 -23
- package/src/react/components/ComboboxField.tsx +2 -2
- package/src/react/components/CommentThread.spec.tsx +25 -0
- package/src/react/components/CommentThread.tsx +60 -10
- package/src/react/components/ControlHeightScale.spec.tsx +2 -2
- package/src/react/components/DatePicker.spec.tsx +186 -5
- package/src/react/components/DatePicker.tsx +416 -63
- package/src/react/components/InlineEditableText.spec.tsx +29 -0
- package/src/react/components/InlineEditableText.tsx +26 -10
- package/src/react/components/VoiceNote.tsx +92 -0
- package/src/react/components/VoiceRecorder.spec.tsx +116 -0
- package/src/react/components/VoiceRecorder.tsx +224 -0
- package/src/react/components/suggestionList.tsx +2 -2
- package/src/react/index.ts +9 -0
- package/src/react/lib/dateText.ts +94 -0
- package/src/react/lib/floatingStyles.spec.ts +36 -1
- package/src/react/lib/floatingStyles.ts +13 -0
- package/src/react/map-frame/MapFrame.spec.ts +168 -0
- package/src/react/map-frame/MapFrame.tsx +954 -0
- package/src/react/map-frame/geo.spec.ts +393 -0
- package/src/react/map-frame/geo.ts +421 -0
- package/src/react/map-frame/index.ts +34 -0
- package/src/react/media/HoverScrubVideoThumb.spec.tsx +4 -0
- package/src/styles-areas/analytics.css +11 -10
- package/src/styles-areas/canvas-hud.css +5 -5
- package/src/styles-areas/data-table.css +13 -12
- package/src/styles-areas/fields.css +12 -10
- package/src/styles-areas/stats.css +12 -11
- package/src/styles-areas/wizard.css +6 -6
- package/src/styles-areas/workbench.css +17 -17
- package/src/styles-utilities.css +15 -0
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 150 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
@@ -34,14 +34,15 @@
|
|
|
34
34
|
@source inline("[&>*]:hidden [&>*]:max-w-none [&>svg]:size-3.5 active:cursor-grabbing basis basis-full");
|
|
35
35
|
@source inline("bg-[var(--cb-frozen-bg)] bg-accent/15 bg-card/95 bg-gradient-to-t bg-muted/30 bg-muted/50");
|
|
36
36
|
@source inline("border-accent-solid border-accent/60 border-b-0! border-field-error border-solid border-t-2 col");
|
|
37
|
-
@source inline("collapse cursor-grab disabled:opacity-
|
|
38
|
-
@source inline("gap-x-6 h-0 h-105
|
|
39
|
-
@source inline("
|
|
40
|
-
@source inline("
|
|
37
|
+
@source inline("collapse cursor-grab disabled:opacity-30 disabled:opacity-40 fade-in");
|
|
38
|
+
@source inline("focus-visible:ring-field-ring/40 from-card gap-x-6 grid-cols-3 grid-cols-4 h-0 h-105 h-3.5");
|
|
39
|
+
@source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-background hover:bg-muted/40");
|
|
40
|
+
@source inline("hover:border-field-ring hover:text-warning italic justify-self-end last:border-0 left-11");
|
|
41
|
+
@source inline("left-2.5 list-none max-h-60 max-h-88 max-sm:flex-1 max-sm:flex-wrap max-sm:min-w-0");
|
|
41
42
|
@source inline("max-sm:min-w-24 max-sm:min-w-32 max-sm:ml-13.5 max-sm:w-auto max-w-32 max-w-36 max-w-45 max-w-48");
|
|
42
43
|
@source inline("max-w-60 min-h-20 min-h-dvh min-w-0! min-w-20 min-w-4 min-w-52 min-w-max mr-2 mt-1.5 mt-3 mt-4");
|
|
43
|
-
@source inline("not-italic ordinal p-0! pb-1.5 pl-1.5 pr-0.5 pr-10 pr-16 pr-3 pr-9
|
|
44
|
-
@source inline("resize-y right-3 ring-field-error/30 self self-stretch
|
|
45
|
-
@source inline("shrink-[2] size-7 slide-in-from-top-1 table-fixed
|
|
46
|
-
@source inline("text-
|
|
47
|
-
@source inline("w-36 w-40 w-88");
|
|
44
|
+
@source inline("not-italic ordinal p-0! pb-1.5 pl-1.5 pointer-coarse:pr-12 pr-0.5 pr-10 pr-11 pr-16 pr-3 pr-9");
|
|
45
|
+
@source inline("pt-1 py-0! resize-none resize-y right-3 ring-field-error/30 self self-stretch");
|
|
46
|
+
@source inline("shadow-[1px_0_0_0_var(--color-border)] shrink-[2] size-7 slide-in-from-top-1 table-fixed");
|
|
47
|
+
@source inline("text-[length:0] text-accent-solid-foreground text-field-placeholder text-success text-xl");
|
|
48
|
+
@source inline("to-transparent top-3 w-0 w-0! w-11 w-12 w-20 w-3.5 w-32 w-36 w-40 w-88");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* cursedbelt — the `canvas-hud` area's utility candidates. GENERATED BUILD ARTIFACT. Never hand-edit.
|
|
3
3
|
*
|
|
4
|
-
* the pan-and-zoom canvas HUD — zoom keys, minimap, find pill, node menu.
|
|
4
|
+
* the pan-and-zoom canvas HUD — zoom keys, minimap, find pill, node menu — and the map frame, which draws with inline styles and adds no utility.
|
|
5
5
|
*
|
|
6
6
|
* Every Tailwind utility the modules in this area's import closure use, MINUS the
|
|
7
7
|
* ones `styles-areas/core.css` already ships. 🔴 Import ALL of these, in
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 42 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
@source inline("[&::-webkit-scrollbar]:hidden [&::-webkit-search-cancel-button]:hidden [&_select]:w-full");
|
|
29
29
|
@source inline("[scrollbar-width:none] aria-pressed:bg-muted aria-pressed:text-foreground basis-0 basis-full");
|
|
30
30
|
@source inline("bg-background/40 bg-background/70 bottom-3 bottom-4 focus-visible:border-transparent");
|
|
31
|
-
@source inline("focus-visible:ring-0 left-3 max-w-48 min-w-10 min-w-26 min-w-40 ml-2 opacity-100 order-1
|
|
32
|
-
@source inline("order-3 overflow-visible pb-1.5 pl-0 pl-1 place-items-center pt-1 px-0.5 right-3 right-4
|
|
33
|
-
@source inline("w-64 z-[5000]");
|
|
31
|
+
@source inline("focus-visible:ring-0 left-3 max-w-48 mi min-w-10 min-w-26 min-w-40 ml-2 opacity-100 order-1");
|
|
32
|
+
@source inline("order-2 order-3 overflow-visible pb-1.5 pl-0 pl-1 place-items-center pt-1 px-0.5 right-3 right-4");
|
|
33
|
+
@source inline("w-40 w-64 z-[5000]");
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 145 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
@@ -34,14 +34,15 @@
|
|
|
34
34
|
@source inline("[&>*]:hidden [&>*]:max-w-none [&>svg]:size-3.5 active:cursor-grabbing basis-full");
|
|
35
35
|
@source inline("bg-[var(--cb-frozen-bg)] bg-accent/15 bg-card/95 bg-gradient-to-t bg-muted/30 bg-muted/50");
|
|
36
36
|
@source inline("border-accent-solid border-accent/60 border-b-0! border-field-error border-solid border-t-2 col");
|
|
37
|
-
@source inline("collapse cursor-grab disabled:opacity-
|
|
38
|
-
@source inline("gap-x-6 h-0 h-105
|
|
39
|
-
@source inline("
|
|
40
|
-
@source inline("
|
|
41
|
-
@source inline("max-
|
|
42
|
-
@source inline("max-
|
|
43
|
-
@source inline("
|
|
44
|
-
@source inline("
|
|
45
|
-
@source inline("
|
|
46
|
-
@source inline("
|
|
47
|
-
@source inline("
|
|
37
|
+
@source inline("collapse cursor-grab disabled:opacity-30 disabled:opacity-40 fade-in");
|
|
38
|
+
@source inline("focus-visible:ring-field-ring/40 from-card gap-x-6 grid-cols-3 grid-cols-4 h-0 h-105 h-3.5");
|
|
39
|
+
@source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-background hover:bg-muted/40");
|
|
40
|
+
@source inline("hover:border-field-ring hover:text-warning justify-self-end last:border-0 left-11 left-2.5");
|
|
41
|
+
@source inline("list-none max-h-60 max-h-88 max-sm:flex-1 max-sm:flex-wrap max-sm:min-w-0 max-sm:min-w-24");
|
|
42
|
+
@source inline("max-sm:min-w-32 max-sm:ml-13.5 max-sm:w-auto max-w-32 max-w-36 max-w-45 max-w-48 max-w-60");
|
|
43
|
+
@source inline("min-h-20 min-h-dvh min-w-0! min-w-4 min-w-52 min-w-max mr-2 mt-1.5 mt-3 mt-4 not-italic ordinal");
|
|
44
|
+
@source inline("p-0! pb-1.5 pl-1.5 pointer-coarse:pr-12 pr-0.5 pr-10 pr-11 pr-16 pr-3 pr-9 pt-1 py-0!");
|
|
45
|
+
@source inline("resize-none resize-y right-3 ring-field-error/30 self self-stretch");
|
|
46
|
+
@source inline("shadow-[1px_0_0_0_var(--color-border)] size-7 slide-in-from-top-1 table-fixed text-[length:0]");
|
|
47
|
+
@source inline("text-accent-solid-foreground text-field-placeholder text-success text-xl to-transparent top-3");
|
|
48
|
+
@source inline("w-0! w-11 w-12 w-20 w-3.5 w-32 w-36 w-40 w-88");
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 94 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
@@ -28,17 +28,19 @@
|
|
|
28
28
|
@source inline("[scrollbar-width:none] appearance-none aria-checked:ring-2 aria-checked:ring-foreground");
|
|
29
29
|
@source inline("aria-checked:ring-offset-1 bg-accent/15 bg-surface-sunken/80 bg-warning/10 border-border/40");
|
|
30
30
|
@source inline("border-field-error caret-transparent cursor-text data-[state=checked]:ring-foreground");
|
|
31
|
-
@source inline("data-[state=checked]:ring-offset-1 disabled:hover:scale-100 disabled:opacity-
|
|
32
|
-
@source inline("focus-visible:border-border-strong focus-visible:ring-0
|
|
33
|
-
@source inline("focus-
|
|
34
|
-
@source inline("
|
|
35
|
-
@source inline("
|
|
31
|
+
@source inline("data-[state=checked]:ring-offset-1 disabled:hover:scale-100 disabled:opacity-30");
|
|
32
|
+
@source inline("disabled:opacity-40 focus-visible:border-border-strong focus-visible:ring-0");
|
|
33
|
+
@source inline("focus-visible:ring-field-ring/40 focus-within:ring-offset-1 focus-within:ring-ring grid-cols-3");
|
|
34
|
+
@source inline("grid-cols-4 group-focus-within:opacity-100 h-105 h-12 h-3.5");
|
|
35
|
+
@source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-muted/50 hover:border-field-ring");
|
|
36
|
+
@source inline("hover:scale-110 hover:text-warning italic left-2.5 li list-none max-h-60 md:flex-col md:gap-0.5");
|
|
36
37
|
@source inline("md:justify-start md:overflow-visible md:text-left md:w-full min-h-20 min-w-64 min-w-full");
|
|
37
38
|
@source inline("min-w-max mix-blend-difference mr-2 pl-1.5 pl-2.5 pointer-coarse:before:-left-1");
|
|
38
39
|
@source inline("pointer-coarse:before:-right-1 pointer-coarse:before:absolute");
|
|
39
40
|
@source inline("pointer-coarse:before:bottom-[calc(var(--hit-slop-y)*-1)]");
|
|
40
|
-
@source inline("pointer-coarse:before:top-[calc(var(--hit-slop-y)*-1)] pointer-coarse:items-center
|
|
41
|
-
@source inline("pr-3 pr-9 pt-1 resize-none resize-y right-1.5 right-3
|
|
42
|
-
@source inline("self-stretch size-7 size-9 size-full sm:w-11 sm:w-56
|
|
43
|
-
@source inline("top-1.5 w-20 w-32 w-36 w-40 w-88 w-fit w-max
|
|
41
|
+
@source inline("pointer-coarse:before:top-[calc(var(--hit-slop-y)*-1)] pointer-coarse:items-center");
|
|
42
|
+
@source inline("pointer-coarse:pr-12 pr-11 pr-16 pr-2 pr-3 pr-9 pt-1 resize-none resize-y right-1.5 right-3");
|
|
43
|
+
@source inline("ring-accent/30 ring-field-error/30 self-stretch size-7 size-9 size-full sm:w-11 sm:w-56");
|
|
44
|
+
@source inline("text-field-placeholder text-success text-xl top-1.5 w-20 w-3.5 w-32 w-36 w-40 w-88 w-fit w-max");
|
|
45
|
+
@source inline("whitespace-pre");
|
|
44
46
|
@source inline('pointer-coarse:before:content-[""]');
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 94 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
@@ -27,16 +27,17 @@
|
|
|
27
27
|
@source inline("[&>div]:sm:[grid-template-columns:…] [&_svg]:size-3.5 basis-40 bg-accent/15 bg-accent/40");
|
|
28
28
|
@source inline("bg-background/70 bg-success/10 bg-warning/10 bg-warning/20 border-field-error border-l-2");
|
|
29
29
|
@source inline("border-l-border-strong border-l-destructive border-l-warning bottom-3 col col-span-2 col-start-2");
|
|
30
|
-
@source inline("collapse cursor-help divide-x first:pl-1 focus-visible:ring-field-ring/40
|
|
31
|
-
@source inline("gap-y-0.5 grid-cols-[minmax(0,1fr)_auto]
|
|
32
|
-
@source inline("group-focus-visible/
|
|
33
|
-
@source inline("group-
|
|
34
|
-
@source inline("group/meter group/stat group/tile h-105
|
|
35
|
-
@source inline("hover:bg-muted/50 hover:border-field-ring
|
|
36
|
-
@source inline("left-[var(--timeline-rail-x)] list-none
|
|
37
|
-
@source inline("
|
|
38
|
-
@source inline("
|
|
30
|
+
@source inline("collapse cursor-help disabled:opacity-30 divide-x first:pl-1 focus-visible:ring-field-ring/40");
|
|
31
|
+
@source inline("gap-x-1.5 gap-x-2 gap-y-0.5 grid-cols-3 grid-cols-4 grid-cols-[minmax(0,1fr)_auto]");
|
|
32
|
+
@source inline("group-focus-visible/meter:opacity-100 group-focus-visible/stat:opacity-100");
|
|
33
|
+
@source inline("group-focus-visible/tile:opacity-100 group-hover/meter:opacity-100 group-hover/stat:opacity-100");
|
|
34
|
+
@source inline("group-hover/tile:opacity-100 group/meter group/stat group/tile h-105 h-3.5");
|
|
35
|
+
@source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-muted/50 hover:border-field-ring");
|
|
36
|
+
@source inline("hover:text-warning last:pr-1 left-3 left-[var(--timeline-rail-x)] list-none max-h-60 min-h-20");
|
|
37
|
+
@source inline("min-h-9 min-w-34 min-w-full mr-0.5 mr-1.5 mr-2 normal-case pl-1.5 pointer-coarse:pr-12 pr-11");
|
|
38
|
+
@source inline("pr-16 pr-3 pt-1 resize-none resize-y ring-field-error/30 rounded-b-md rounded-t-md row-start-1");
|
|
39
|
+
@source inline("self-stretch shadow-md size-7 sm:col-auto sm:col-span-1 sm:flex-nowrap");
|
|
39
40
|
@source inline("sm:grid-cols-[minmax(7rem,18rem)_minmax(4rem,1fr)_auto]");
|
|
40
41
|
@source inline("sm:grid-cols-[minmax(7rem,34rem)_minmax(4rem,1fr)_auto] sm:row-auto sm:truncate text-3xl");
|
|
41
42
|
@source inline("text-[length:var(--text-glyph)] text-field-placeholder text-foreground/80 text-success text-xl");
|
|
42
|
-
@source inline("top-7 tracking-normal w-36 w-48 w-88 whitespace-pre z-[1]");
|
|
43
|
+
@source inline("top-7 tracking-normal w-3.5 w-36 w-48 w-88 whitespace-pre z-[1]");
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 33 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
25
25
|
* import closures rather than a hand-written list, is scripts/styleAreas.ts.
|
|
26
26
|
*/
|
|
27
|
-
@source inline("border-field-error collapse disabled:bg-transparent disabled:opacity-100");
|
|
28
|
-
@source inline("focus-visible:ring-field-ring/40
|
|
29
|
-
@source inline("hover:border-field-ring hover:text-warning
|
|
30
|
-
@source inline("
|
|
31
|
-
@source inline("w-88");
|
|
27
|
+
@source inline("border-field-error collapse disabled:bg-transparent disabled:opacity-100 disabled:opacity-30");
|
|
28
|
+
@source inline("focus-visible:ring-field-ring/40 grid-cols-3 grid-cols-4 h-105 h-3.5");
|
|
29
|
+
@source inline("has-[[aria-invalid=true]]:border-field-error hover:border-field-ring hover:text-warning max-h-60");
|
|
30
|
+
@source inline("min-h-20 mr-1.5 mr-2 pl-1.5 pointer-coarse:pr-12 pr-11 pr-16 pr-3 resize-none resize-y");
|
|
31
|
+
@source inline("ring-field-error/30 self-stretch size-7 sm:inline text-field-placeholder text-xl w-3.5 w-36 w-88");
|
|
@@ -18,27 +18,27 @@
|
|
|
18
18
|
* after an app's responsive variant (task 2124). An app that imports every area gets exactly
|
|
19
19
|
* what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
|
|
20
20
|
* src/stylesAreas.spec.ts, which is also what fails when this file is stale.
|
|
21
|
-
*
|
|
21
|
+
* 102 candidate(s).
|
|
22
22
|
*
|
|
23
23
|
* Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
|
|
24
24
|
* `bun run build` runs. The map of what is in which area, and why the areas are
|
|
25
25
|
* import closures rather than a hand-written list, is scripts/styleAreas.ts.
|
|
26
26
|
*/
|
|
27
|
-
@source inline("-my-0.5 [&::-webkit-scrollbar]:hidden [&_svg]:size-3.5 [scrollbar-width:none]
|
|
28
|
-
@source inline("
|
|
29
|
-
@source inline("bg-success/8 border-2 border-8 border-accent-solid
|
|
30
|
-
@source inline("border-border/50 border-dashed border-solid bottom-6");
|
|
27
|
+
@source inline("-my-0.5 [&::-webkit-scrollbar]:hidden [&_svg]:size-3.5 [scrollbar-width:none]");
|
|
28
|
+
@source inline("accent-[var(--accent-solid)] bg-accent/15 bg-accent/40 bg-accent/8 bg-background/85");
|
|
29
|
+
@source inline("bg-card-overlay/85 bg-muted/30 bg-muted/60 bg-success/8 border-2 border-8 border-accent-solid");
|
|
30
|
+
@source inline("border-accent/70 border-border-strong/60 border-border/50 border-dashed border-solid bottom-6");
|
|
31
31
|
@source inline("bottom-[max(env(safe-area-inset-bottom,0px),0.75rem)] disabled:opacity-0 duration-150 first:pt-1");
|
|
32
|
-
@source inline("flex-row group-hover:disabled:opacity-50 h-105 h-40 hover:bg-card-overlay");
|
|
32
|
+
@source inline("flex-row group-hover:disabled:opacity-50 h-105 h-3.5 h-40 hover:bg-card-overlay");
|
|
33
33
|
@source inline("hover:bg-muted-foreground/10 hover:bg-muted/80 hover:border-field-ring hover:shadow-popover");
|
|
34
|
-
@source inline("inset-x-3 italic items-stretch left-2.5 max-h-full min-h min-h-20 min-h-8 min-h-9
|
|
35
|
-
@source inline("min-h-full min-w-20 min-w-40 opacity-100 pb-0.5
|
|
36
|
-
@source inline("
|
|
37
|
-
@source inline("peer-focus:rounded-lg pl-1 pl-3
|
|
38
|
-
@source inline("pointer-coarse:w-12 pr-16 pr-9 pt-1.5
|
|
39
|
-
@source inline("ring-
|
|
40
|
-
@source inline("rounded-[var(--radius-device)] scale-[1.01] self-stretch
|
|
41
|
-
@source inline("sm:shrink-0 sm:w-56 text-muted-foreground/60
|
|
42
|
-
@source inline("text-tone-
|
|
43
|
-
@source inline("text-tone-
|
|
44
|
-
@source inline("translate-y-2 w-0 w-88");
|
|
34
|
+
@source inline("inset-x-3 italic items-stretch left-2.5 max-h-full max-w-80 min-h min-h-20 min-h-8 min-h-9");
|
|
35
|
+
@source inline("min-h-dvh min-h-full min-w-16 min-w-20 min-w-40 opacity-100 pb-0.5");
|
|
36
|
+
@source inline("pb-[max(env(safe-area-inset-bottom,0px),0.5rem)] peer-focus peer-focus:outline-none");
|
|
37
|
+
@source inline("peer-focus:ring-2 peer-focus:ring-field-ring/40 peer-focus:rounded-lg pl-1 pl-3");
|
|
38
|
+
@source inline("pointer-coarse:disabled:opacity-50 pointer-coarse:h-12 pointer-coarse:w-12 pr-16 pr-9 pt-1.5");
|
|
39
|
+
@source inline("resize-none right-4 ring-1 ring-4 ring-accent/20 ring-accent/30 ring-accent/40 ring-border");
|
|
40
|
+
@source inline("ring-inset ring-ring rounded-2xl rounded-[var(--radius-device)] scale-[1.01] self-stretch");
|
|
41
|
+
@source inline("shrink-[2] size-7 sm:flex-1 sm:min-w-40 sm:shrink-0 sm:w-56 text-muted-foreground/60");
|
|
42
|
+
@source inline("text-tone-amber-ink text-tone-cyan-ink text-tone-emerald-ink text-tone-orange-ink");
|
|
43
|
+
@source inline("text-tone-purple-ink text-tone-rose-ink text-tone-sky-ink text-tone-slate-ink text-xl");
|
|
44
|
+
@source inline("transition-[opacity,transform] translate-y-0 translate-y-2 w-0 w-88");
|
|
@@ -773,6 +773,9 @@
|
|
|
773
773
|
.max-h-56 {
|
|
774
774
|
max-height: calc(var(--spacing) * 56);
|
|
775
775
|
}
|
|
776
|
+
.max-h-60 {
|
|
777
|
+
max-height: calc(var(--spacing) * 60);
|
|
778
|
+
}
|
|
776
779
|
.max-h-64 {
|
|
777
780
|
max-height: calc(var(--spacing) * 64);
|
|
778
781
|
}
|
|
@@ -1371,6 +1374,9 @@
|
|
|
1371
1374
|
.grid-cols-2 {
|
|
1372
1375
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1373
1376
|
}
|
|
1377
|
+
.grid-cols-3 {
|
|
1378
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
1379
|
+
}
|
|
1374
1380
|
.grid-cols-4 {
|
|
1375
1381
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
1376
1382
|
}
|
|
@@ -2733,6 +2739,9 @@
|
|
|
2733
2739
|
.pr-10 {
|
|
2734
2740
|
padding-right: calc(var(--spacing) * 10);
|
|
2735
2741
|
}
|
|
2742
|
+
.pr-11 {
|
|
2743
|
+
padding-right: calc(var(--spacing) * 11);
|
|
2744
|
+
}
|
|
2736
2745
|
.pr-16 {
|
|
2737
2746
|
padding-right: calc(var(--spacing) * 16);
|
|
2738
2747
|
}
|
|
@@ -4183,6 +4192,9 @@
|
|
|
4183
4192
|
.disabled\:opacity-0:disabled {
|
|
4184
4193
|
opacity: 0%;
|
|
4185
4194
|
}
|
|
4195
|
+
.disabled\:opacity-30:disabled {
|
|
4196
|
+
opacity: 30%;
|
|
4197
|
+
}
|
|
4186
4198
|
.disabled\:opacity-40:disabled {
|
|
4187
4199
|
opacity: 40%;
|
|
4188
4200
|
}
|
|
@@ -5243,6 +5255,9 @@
|
|
|
5243
5255
|
.pointer-coarse\:p-0 {
|
|
5244
5256
|
padding: 0px;
|
|
5245
5257
|
}
|
|
5258
|
+
.pointer-coarse\:pr-12 {
|
|
5259
|
+
padding-right: calc(var(--spacing) * 12);
|
|
5260
|
+
}
|
|
5246
5261
|
.pointer-coarse\:opacity-100 {
|
|
5247
5262
|
opacity: 100%;
|
|
5248
5263
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursedbelt",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.95.0",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
|
|
@@ -337,6 +337,18 @@
|
|
|
337
337
|
"source": "./src/react/markdown/MarkdownDoc.tsx",
|
|
338
338
|
"import": "./dist/react/markdown/MarkdownDoc.js"
|
|
339
339
|
},
|
|
340
|
+
"./react/map-frame": {
|
|
341
|
+
"types": "./dist/react/map-frame/index.d.ts",
|
|
342
|
+
"bun": "./src/react/map-frame/index.ts",
|
|
343
|
+
"source": "./src/react/map-frame/index.ts",
|
|
344
|
+
"import": "./dist/react/map-frame/index.js"
|
|
345
|
+
},
|
|
346
|
+
"./react/map-frame/geo": {
|
|
347
|
+
"types": "./dist/react/map-frame/geo.d.ts",
|
|
348
|
+
"bun": "./src/react/map-frame/geo.ts",
|
|
349
|
+
"source": "./src/react/map-frame/geo.ts",
|
|
350
|
+
"import": "./dist/react/map-frame/geo.js"
|
|
351
|
+
},
|
|
340
352
|
"./react/master-detail": {
|
|
341
353
|
"types": "./dist/react/master-detail/index.d.ts",
|
|
342
354
|
"bun": "./src/react/master-detail/index.ts",
|
package/scripts/styleAreas.ts
CHANGED
|
@@ -234,7 +234,7 @@ export const AREAS: readonly Area[] = [
|
|
|
234
234
|
roots: ['components/auth', 'AuthGate.tsx'],
|
|
235
235
|
},
|
|
236
236
|
{ name: 'calendar', why: 'the date-picker family: a calendar grid is a whole layout nothing else shares', roots: ['components/calendar'] },
|
|
237
|
-
{ name: 'canvas-hud', why: 'the pan-and-zoom canvas HUD — zoom keys, minimap, find pill, node menu', roots: ['canvas-hud'] },
|
|
237
|
+
{ name: 'canvas-hud', why: 'the pan-and-zoom canvas HUD — zoom keys, minimap, find pill, node menu — and the map frame, which draws with inline styles and adds no utility', roots: ['canvas-hud', 'map-frame'] },
|
|
238
238
|
{ name: 'charts', why: 'the recharts wrappers — an app with no dashboard renders none of them', roots: ['charts'] },
|
|
239
239
|
{
|
|
240
240
|
name: 'chart-table',
|
|
@@ -58,6 +58,59 @@ describe('AppShell', () => {
|
|
|
58
58
|
expect(q(container, '[data-cb-nav-backdrop]')).toBeNull();
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
test('🔴 navCollapsed folds the lg sidebar to the icon rail, and the fold button in the rail head asks for the next state (forge task 3773)', () => {
|
|
62
|
+
const changes: boolean[] = [];
|
|
63
|
+
const { container, rerender } = render(
|
|
64
|
+
<AppShell nav={station} navHeader={<span data-brand=''>Photos</span>} account={<span>CU</span>} onNavCollapsedChange={(next) => changes.push(next)}>
|
|
65
|
+
x
|
|
66
|
+
</AppShell>,
|
|
67
|
+
);
|
|
68
|
+
const [icon, full] = qa(container, '[data-cb-nav-rail]') as [HTMLElement, HTMLElement];
|
|
69
|
+
// Open: the icon rail hides at lg, the full sidebar shows there — as before.
|
|
70
|
+
expect(icon.className).toContain('lg:hidden');
|
|
71
|
+
expect(full.className).toContain('lg:flex');
|
|
72
|
+
// The fold button is in BOTH heads (the rail must be able to unfold itself), and says what it does.
|
|
73
|
+
const folds = qa(container, '[data-cb-rail-fold]');
|
|
74
|
+
expect(folds).toHaveLength(2);
|
|
75
|
+
expect(folds.map((b) => b.getAttribute('aria-label'))).toEqual(['Show the sidebar', 'Hide the sidebar']);
|
|
76
|
+
// With no ⌘K row it sits on the brand line; with one, beside the ⌘K trigger — never a third control
|
|
77
|
+
// beside a worded account launcher, which left the brand no width (photos, WebKit, 2026-10-25).
|
|
78
|
+
const { container: noCommand } = render(
|
|
79
|
+
<AppShell nav={station} commandPalette={false} navHeader={<span>Photos</span>} account={<span>CU</span>} onNavCollapsedChange={() => {}}>
|
|
80
|
+
x
|
|
81
|
+
</AppShell>,
|
|
82
|
+
);
|
|
83
|
+
const fullNoCommand = qa(noCommand, '[data-cb-nav-rail]')[1] as HTMLElement;
|
|
84
|
+
expect(q(fullNoCommand, '[data-cb-rail-command-row]')).toBeNull();
|
|
85
|
+
expect(q(fullNoCommand, '[data-cb-account]')?.parentElement?.querySelector('[data-cb-rail-fold]')).not.toBeNull();
|
|
86
|
+
const { container: withCommand } = render(
|
|
87
|
+
<AppShell nav={station} navHeader={<span>Photos</span>} account={<span>Curt Phillips ▾</span>} onOpenCommand={() => {}} onNavCollapsedChange={() => {}}>
|
|
88
|
+
x
|
|
89
|
+
</AppShell>,
|
|
90
|
+
);
|
|
91
|
+
const fullWithCommand = qa(withCommand, '[data-cb-nav-rail]')[1] as HTMLElement;
|
|
92
|
+
expect(q(fullWithCommand, '[data-cb-account]')?.parentElement?.querySelector('[data-cb-rail-fold]')).toBeNull();
|
|
93
|
+
expect(q(fullWithCommand, '[data-cb-rail-command-row] [data-cb-rail-fold]')).not.toBeNull();
|
|
94
|
+
expect(q(fullWithCommand, '[data-cb-rail-command-row] [data-cb-command-trigger]')).not.toBeNull();
|
|
95
|
+
fireEvent.click(folds[1] as HTMLElement);
|
|
96
|
+
expect(changes).toEqual([true]);
|
|
97
|
+
// Folded: the icon rail stays at lg and the full sidebar is gone from every width.
|
|
98
|
+
rerender(
|
|
99
|
+
<AppShell nav={station} navHeader={<span data-brand=''>Photos</span>} account={<span>CU</span>} navCollapsed onNavCollapsedChange={(next) => changes.push(next)}>
|
|
100
|
+
x
|
|
101
|
+
</AppShell>,
|
|
102
|
+
);
|
|
103
|
+
const [iconFolded, fullFolded] = qa(container, '[data-cb-nav-rail]') as [HTMLElement, HTMLElement];
|
|
104
|
+
expect(iconFolded.className).not.toContain('lg:hidden');
|
|
105
|
+
expect(fullFolded.className).not.toContain('lg:flex');
|
|
106
|
+
expect(fullFolded.className).toContain('hidden');
|
|
107
|
+
fireEvent.click(q(iconFolded, '[data-cb-rail-fold]') as HTMLElement);
|
|
108
|
+
expect(changes).toEqual([true, false]);
|
|
109
|
+
// Without the callback nothing is offered: a shell that cannot remember the choice does not ask for it.
|
|
110
|
+
rerender(<AppShell nav={station}>x</AppShell>);
|
|
111
|
+
expect(qa(container, '[data-cb-rail-fold]')).toHaveLength(0);
|
|
112
|
+
});
|
|
113
|
+
|
|
61
114
|
test('🔴 NAV-15 · with a sidebar the header is phone-only, and the brand, account and ⌘K head the sidebar (owner, 2026-10-20)', () => {
|
|
62
115
|
const { container } = render(
|
|
63
116
|
<AppShell
|
|
@@ -18,8 +18,10 @@ import { SideNav } from '../nav/SideNav.js';
|
|
|
18
18
|
import { TopBarPlaces } from '../nav/TopBar.js';
|
|
19
19
|
import { CommandSourceProvider, useCommandSources } from '../palette/commandSources.js';
|
|
20
20
|
import { useCommandPalette } from '../palette/useCommandPalette.js';
|
|
21
|
+
import { IconSidebar } from '../icons.js';
|
|
21
22
|
import { AmbientBackdrop, type AmbientBackdropProps } from './AmbientBackdrop.js';
|
|
22
23
|
import { BannerLane, type ShellBanner } from './BannerLane.js';
|
|
24
|
+
import { IconButton } from './IconButton.js';
|
|
23
25
|
import { lazyPart } from './DataTable/lazyPart.js';
|
|
24
26
|
import { ScrollArea, type ScrollAreaSpace } from './ScrollArea.js';
|
|
25
27
|
|
|
@@ -79,6 +81,18 @@ export interface AppShellProps {
|
|
|
79
81
|
* the section's NEXT state. */
|
|
80
82
|
onNavSectionToggle?: (section: string, collapsed: boolean) => void;
|
|
81
83
|
|
|
84
|
+
/**
|
|
85
|
+
* The 240px sidebar folded to the 64px icon rail at every width — the reader's choice, to see
|
|
86
|
+
* the page wider (a photo archive's grid, a canvas): Linear's `⌘\` and Notion's `«` fold theirs
|
|
87
|
+
* the same way. Controlled: the app remembers it (a setting, `localStorage`) and passes it back.
|
|
88
|
+
* With `onNavCollapsedChange` the rail head carries the fold button (`IconSidebar`, a tooltip
|
|
89
|
+
* either way); without it the sidebar is fixed open, as before. The rail keeps its places, the
|
|
90
|
+
* account and the ⌘K trigger folded (NAV-2, NAV-15); a phone is never folded — it has no sidebar.
|
|
91
|
+
*/
|
|
92
|
+
navCollapsed?: boolean;
|
|
93
|
+
/** The fold button was pressed; `collapsed` is the sidebar's NEXT state. */
|
|
94
|
+
onNavCollapsedChange?: (collapsed: boolean) => void;
|
|
95
|
+
|
|
82
96
|
/** Dynamic per-place badge (unread counts), keyed by domain id. A badge may carry its own tone (`{ value, tone }`) — see {@link NavBadge}. */
|
|
83
97
|
navBadges?: Record<string, NavBadge>;
|
|
84
98
|
/** How those counts READ — `alert` (default, red) for "this needs you", `neutral` or
|
|
@@ -233,7 +247,7 @@ const UNSECTIONED_MAX_PLACES = 7;
|
|
|
233
247
|
* <header h-[--header-h]> ← left: brand · center: places or ⌘K field · right: account
|
|
234
248
|
* <BannerLane /> ← NAV-10, only when there is a banner
|
|
235
249
|
* <div flex min-h-0 grow> ← sidebar + content row
|
|
236
|
-
* <aside md:flex lg:hidden w-16 /> ← 6+ places: the icon rail
|
|
250
|
+
* <aside md:flex lg:hidden w-16 /> ← 6+ places: the icon rail (and at lg, folded by `navCollapsed`)
|
|
237
251
|
* <aside lg:flex w-60 /> ← 6+ places: the sectioned SideNav
|
|
238
252
|
* <main><ScrollArea>{children}</ScrollArea></main> ← THE ONLY page scroll container
|
|
239
253
|
* </div>
|
|
@@ -266,6 +280,8 @@ function Shell({
|
|
|
266
280
|
onNavPrefsChange,
|
|
267
281
|
navCollapsedSections,
|
|
268
282
|
onNavSectionToggle,
|
|
283
|
+
navCollapsed = false,
|
|
284
|
+
onNavCollapsedChange,
|
|
269
285
|
navBadges,
|
|
270
286
|
navBadgeTone,
|
|
271
287
|
navHeader,
|
|
@@ -354,8 +370,31 @@ function Shell({
|
|
|
354
370
|
* rail (md–lg) gets the account and the square ⌘K trigger; `onCapture` stays on the full sidebar
|
|
355
371
|
* and the phone's PlaceBar, as a worded primary button cannot fit a 64px rail.
|
|
356
372
|
*/
|
|
357
|
-
|
|
358
|
-
|
|
373
|
+
// The fold button (`navCollapsed`): only where the app takes the choice back — a shell that cannot
|
|
374
|
+
// remember it does not offer it. On the icon rail it stacks under the account. On the full sidebar it
|
|
375
|
+
// sits at the leading edge of the ⌘K row, NOT on the brand line: the account launcher there is a
|
|
376
|
+
// worded control (cursedauth's "Curt Phillips ▾", 175px in a 240px rail), and a third control on
|
|
377
|
+
// that line left the brand no width at all (photos, WebKit, 2026-10-25). A shell with no ⌘K row
|
|
378
|
+
// keeps it on the brand line, where there is room.
|
|
379
|
+
const foldButton = (collapsed: boolean) =>
|
|
380
|
+
onNavCollapsedChange ? (
|
|
381
|
+
<IconButton
|
|
382
|
+
data-cb-rail-fold=''
|
|
383
|
+
aria-pressed={collapsed}
|
|
384
|
+
label={collapsed ? 'Show the sidebar' : 'Hide the sidebar'}
|
|
385
|
+
tooltip={collapsed ? 'Show the sidebar with its names' : 'Fold the sidebar to icons, for a wider page'}
|
|
386
|
+
size='sm'
|
|
387
|
+
variant='ghost'
|
|
388
|
+
className='mt-0.5'
|
|
389
|
+
onClick={() => onNavCollapsedChange(!collapsed)}
|
|
390
|
+
>
|
|
391
|
+
<IconSidebar />
|
|
392
|
+
</IconButton>
|
|
393
|
+
) : null;
|
|
394
|
+
const hasCommandRow = (collapsed: boolean) => Boolean(openCommand || (!collapsed && (onCapture || commandBarExtra)));
|
|
395
|
+
const railCommand = (collapsed: boolean) => {
|
|
396
|
+
if (!hasCommandRow(collapsed)) return null;
|
|
397
|
+
const bar = (
|
|
359
398
|
<CommandBar
|
|
360
399
|
className={collapsed ? 'flex-col' : 'w-full min-w-0 flex-wrap'}
|
|
361
400
|
compact={collapsed}
|
|
@@ -366,22 +405,36 @@ function Shell({
|
|
|
366
405
|
commandHint={commandHint}
|
|
367
406
|
extra={collapsed ? undefined : commandBarExtra}
|
|
368
407
|
/>
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
408
|
+
);
|
|
409
|
+
const fold = collapsed ? null : foldButton(false);
|
|
410
|
+
return fold ? (
|
|
411
|
+
<div data-cb-rail-command-row='' className='flex w-full min-w-0 items-start gap-1'>
|
|
412
|
+
{fold}
|
|
413
|
+
<div className='min-w-0 flex-1'>{bar}</div>
|
|
414
|
+
</div>
|
|
415
|
+
) : (
|
|
416
|
+
bar
|
|
417
|
+
);
|
|
418
|
+
};
|
|
419
|
+
const railHead = (collapsed: boolean) => {
|
|
420
|
+
const foldOnBrandLine = collapsed || !hasCommandRow(collapsed);
|
|
421
|
+
return (
|
|
422
|
+
<div data-cb-rail-head='' className={cn('flex flex-col gap-3', collapsed && 'items-center')}>
|
|
423
|
+
{(navHeader && !collapsed) || account || (foldOnBrandLine && onNavCollapsedChange) ? (
|
|
424
|
+
<div className={cn('flex min-w-0 items-center gap-2', collapsed && 'flex-col')}>
|
|
425
|
+
{navHeader && !collapsed ? <div className='flex min-w-0 flex-1 items-center overflow-hidden'>{navHeader}</div> : null}
|
|
426
|
+
{account ? (
|
|
427
|
+
<div data-cb-account='' className='shrink-0'>
|
|
428
|
+
{account}
|
|
429
|
+
</div>
|
|
430
|
+
) : null}
|
|
431
|
+
{foldOnBrandLine ? foldButton(collapsed) : null}
|
|
432
|
+
</div>
|
|
433
|
+
) : null}
|
|
434
|
+
{railCommand(collapsed)}
|
|
435
|
+
</div>
|
|
436
|
+
);
|
|
437
|
+
};
|
|
385
438
|
|
|
386
439
|
const sideNavProps = {
|
|
387
440
|
model: nav as NavigationModel,
|
|
@@ -483,15 +536,17 @@ function Shell({
|
|
|
483
536
|
<div className='relative flex min-h-0 grow overflow-hidden'>
|
|
484
537
|
{/* 6+ places: the labeled, sectioned sidebar at lg (240px), the icon rail at md–lg
|
|
485
538
|
(64px — a 240px rail on an ~820px screen squeezes the workspace, owner tablet
|
|
486
|
-
teardown 2026-07-15 §4)
|
|
487
|
-
prop, not a media query, and the
|
|
539
|
+
teardown 2026-07-15 §4) — and at lg too while the reader has folded it (`navCollapsed`).
|
|
540
|
+
Two CSS-switched renders: SideNav's `collapsed` is a prop, not a media query, and the
|
|
541
|
+
rail is cheap to render twice. */}
|
|
488
542
|
{pattern === 'side' && (
|
|
489
543
|
<>
|
|
490
544
|
<aside
|
|
491
545
|
data-cb-nav-rail=''
|
|
492
546
|
data-cb-nav-collapsed=''
|
|
493
547
|
className={cn(
|
|
494
|
-
'hidden w-[var(--rail-w-collapsed)] border-r border-border md:flex md:shrink-0 md:flex-col
|
|
548
|
+
'hidden w-[var(--rail-w-collapsed)] border-r border-border md:flex md:shrink-0 md:flex-col',
|
|
549
|
+
!navCollapsed && 'lg:hidden',
|
|
495
550
|
chrome,
|
|
496
551
|
)}
|
|
497
552
|
>
|
|
@@ -500,7 +555,8 @@ function Shell({
|
|
|
500
555
|
<aside
|
|
501
556
|
data-cb-nav-rail=''
|
|
502
557
|
className={cn(
|
|
503
|
-
'hidden w-[var(--rail-w)] border-r border-border
|
|
558
|
+
'hidden w-[var(--rail-w)] border-r border-border',
|
|
559
|
+
!navCollapsed && 'lg:flex lg:shrink-0 lg:flex-col',
|
|
504
560
|
chrome,
|
|
505
561
|
)}
|
|
506
562
|
>
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
choiceFieldWidth,
|
|
12
12
|
declareFieldWidth,
|
|
13
13
|
} from '../lib/field.js';
|
|
14
|
-
import { FLOATING_COLLISION_PADDING,
|
|
14
|
+
import { BASE_UI_POSITIONER, FLOATING_COLLISION_PADDING,
|
|
15
15
|
FLOATING_CONTENT_BASE, FLOATING_ITEM_BASE } from '../lib/floatingStyles.js';
|
|
16
16
|
import { TAP_TARGET, TAP_TARGET_HEIGHT } from '../lib/tapTarget.js';
|
|
17
17
|
|
|
@@ -336,7 +336,7 @@ export function ComboboxField(props: ComboboxFieldProps) {
|
|
|
336
336
|
<Combobox.Positioner
|
|
337
337
|
sideOffset={4}
|
|
338
338
|
collisionPadding={FLOATING_COLLISION_PADDING}
|
|
339
|
-
className=
|
|
339
|
+
className={BASE_UI_POSITIONER}
|
|
340
340
|
>
|
|
341
341
|
<Combobox.Popup
|
|
342
342
|
className={cn(
|