@charcuterie/ui 3.23.0 → 3.25.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.
Files changed (68) hide show
  1. package/README.md +18 -0
  2. package/dist/Board/Board.d.ts +6 -3
  3. package/dist/Board/Board.d.ts.map +1 -1
  4. package/dist/Board/Board.js +19 -1
  5. package/dist/Board/Board.js.map +1 -1
  6. package/dist/Board/BoardCard.d.ts +42 -7
  7. package/dist/Board/BoardCard.d.ts.map +1 -1
  8. package/dist/Board/BoardCard.js +54 -8
  9. package/dist/Board/BoardCard.js.map +1 -1
  10. package/dist/DeploymentUpdate/useDeploymentUpdate.d.ts +31 -0
  11. package/dist/DeploymentUpdate/useDeploymentUpdate.d.ts.map +1 -0
  12. package/dist/DeploymentUpdate/useDeploymentUpdate.js +94 -0
  13. package/dist/DeploymentUpdate/useDeploymentUpdate.js.map +1 -0
  14. package/dist/Nav/Nav.d.ts +167 -0
  15. package/dist/Nav/Nav.d.ts.map +1 -0
  16. package/dist/Nav/Nav.js +165 -0
  17. package/dist/Nav/Nav.js.map +1 -0
  18. package/dist/Nav/NavLink.d.ts +43 -0
  19. package/dist/Nav/NavLink.d.ts.map +1 -0
  20. package/dist/Nav/NavLink.js +111 -0
  21. package/dist/Nav/NavLink.js.map +1 -0
  22. package/dist/Nav/navItems.d.ts +67 -0
  23. package/dist/Nav/navItems.d.ts.map +1 -0
  24. package/dist/Nav/navItems.js +104 -0
  25. package/dist/Nav/navItems.js.map +1 -0
  26. package/dist/Nav/useNavLayout.d.ts +86 -0
  27. package/dist/Nav/useNavLayout.d.ts.map +1 -0
  28. package/dist/Nav/useNavLayout.js +114 -0
  29. package/dist/Nav/useNavLayout.js.map +1 -0
  30. package/dist/NavBar/NavBar.d.ts +37 -111
  31. package/dist/NavBar/NavBar.d.ts.map +1 -1
  32. package/dist/NavBar/NavBar.js +30 -110
  33. package/dist/NavBar/NavBar.js.map +1 -1
  34. package/dist/index.d.ts +8 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +4 -1
  37. package/dist/index.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/Board/Board.mdx +25 -2
  40. package/src/Board/Board.stories.tsx +52 -1
  41. package/src/Board/Board.test.tsx +82 -0
  42. package/src/Board/Board.tsx +24 -4
  43. package/src/Board/BoardCard.tsx +103 -21
  44. package/src/Board/boardMoveHandleContainer.test.ts +54 -0
  45. package/src/DeploymentUpdate/useDeploymentUpdate.ts +143 -0
  46. package/src/Nav/Nav.mdx +169 -0
  47. package/src/Nav/Nav.stories.tsx +402 -0
  48. package/src/Nav/Nav.test.tsx +338 -0
  49. package/src/Nav/Nav.tsx +406 -0
  50. package/src/Nav/NavLink.tsx +220 -0
  51. package/src/Nav/navItems.test.ts +163 -0
  52. package/src/Nav/navItems.ts +175 -0
  53. package/src/Nav/useNavLayout.ts +197 -0
  54. package/src/NavBar/NavBar.mdx +26 -0
  55. package/src/NavBar/NavBar.tsx +54 -240
  56. package/src/index.ts +29 -1
  57. package/src/sourceRules.test.ts +13 -1
  58. package/dist/NavBar/NavBarLink.d.ts +0 -43
  59. package/dist/NavBar/NavBarLink.d.ts.map +0 -1
  60. package/dist/NavBar/NavBarLink.js +0 -67
  61. package/dist/NavBar/NavBarLink.js.map +0 -1
  62. package/dist/NavBar/navBarCurrent.d.ts +0 -37
  63. package/dist/NavBar/navBarCurrent.d.ts.map +0 -1
  64. package/dist/NavBar/navBarCurrent.js +0 -48
  65. package/dist/NavBar/navBarCurrent.js.map +0 -1
  66. package/src/NavBar/NavBarLink.tsx +0 -139
  67. package/src/NavBar/navBarCurrent.test.ts +0 -81
  68. package/src/NavBar/navBarCurrent.ts +0 -64
package/README.md CHANGED
@@ -117,6 +117,24 @@ CSS `@import` that misses fails **silently**: no error, no utilities, an unstyle
117
117
 
118
118
  The testing gates are at `@charcuterie/ui/testing`.
119
119
 
120
+ ## Detect a new deployment
121
+
122
+ `useDeploymentUpdate` detects that a static SPA has been replaced. It works with
123
+ `createStaticHandler` from `@charcuterie/server`, which provides a no-cache build marker
124
+ and an SSE marker stream by default.
125
+
126
+ ```tsx
127
+ const { isUpdateAvailable, reload } = useDeploymentUpdate()
128
+
129
+ return isUpdateAvailable ? (
130
+ <Button onClick={reload}>Update this app</Button>
131
+ ) : null
132
+ ```
133
+
134
+ The hook never reloads without the user's action. A page can have unsaved state. If the app
135
+ already owns an SSE connection, set `isEventSourceEnabled: false` and call
136
+ `checkForUpdate()` after that source reconnects.
137
+
120
138
  ### While the packages are unpublished: three lines, and you need all three
121
139
 
122
140
  A consumer links by `portal:` until this publishes
@@ -30,12 +30,15 @@ export type BoardProps = {
30
30
  label: string;
31
31
  lanes: readonly BoardLane[];
32
32
  /**
33
- * What the move handle shows instead of the word "Move". The
34
- * library ships no icons and no symbol glyphs in a default —
33
+ * What the move handle shows **while the lanes are side by side**.
34
+ * Below `cq-lg` the handle says "Move" whatever this is, because
35
+ * there is nowhere to drag to — see `BoardCard`.
36
+ *
37
+ * The library ships no icons and no symbol glyphs in a default —
35
38
  * they render as nothing where the font lacks them, which
36
39
  * includes this sandbox's chromium, the kiosk image and the
37
40
  * ePaper build — so the default is a word and an app that owns a
38
- * glyph set passes one. On a dense board it is worth ~55px a row.
41
+ * glyph set passes one. On a dense board it is worth ~35px a row.
39
42
  */
40
43
  moveIcon?: ReactNode;
41
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Board.d.ts","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AASpD,MAAM,MAAM,SAAS,GAAG;IACtB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,eAAO,MAAM,KAAK,GAAI,6EAQnB,UAAU,KAAG,SAgMf,CAAA"}
1
+ {"version":3,"file":"Board.d.ts","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AASpD,MAAM,MAAM,SAAS,GAAG;IACtB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IAC3B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;CACnC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,eAAO,MAAM,KAAK,GAAI,6EAQnB,UAAU,KAAG,SAiNf,CAAA"}
@@ -121,7 +121,25 @@ export const Board = ({ className, headingLevel = 3, label, lanes, moveIcon, nar
121
121
  });
122
122
  },
123
123
  });
124
- return (_jsxs("section", { "aria-label": label, className: toClassName("@container", className), children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(SegmentedControl, { className: "max-w-full flex-wrap cq-lg:hidden", items: lanes.map((lane) => ({
124
+ return (_jsxs("section", { "aria-label": label,
125
+ /*
126
+ * `@container/board`, and the NAME is what a card's move
127
+ * handle needs.
128
+ *
129
+ * An unnamed container query matches the nearest ancestor
130
+ * container, and between this box and a card there is a
131
+ * second one — the lane's, one level down, which decides what
132
+ * shape a card is. So a `cq-lg:` written inside `BoardCard`
133
+ * asks about the LANE, and the answer is inverted against the
134
+ * question the handle has to ask: in a three-up board a lane
135
+ * is ~280px, and in the Narrow View the single lane is the
136
+ * whole board. Naming this one lets the handle query past the
137
+ * lane to the box that actually decides how many lanes are on
138
+ * screen. Naming changes nothing else — a named container
139
+ * still answers an unnamed query, which is why the segmented
140
+ * control and the lanes below keep their plain `cq-lg:`.
141
+ */
142
+ className: toClassName("@container/board", className), children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(SegmentedControl, { className: "max-w-full flex-wrap cq-lg:hidden", items: lanes.map((lane) => ({
125
143
  // Stacked rather than `Todo (6)`, because the count is
126
144
  // the reason to look: a lane picker that reads
127
145
  // "In Progress (5)" on one line is a long label with a
@@ -1 +1 @@
1
- {"version":3,"file":"Board.js","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Board.js","sourceRoot":"","sources":["../../src/Board/Board.tsx"],"names":[],"mappings":"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"}
@@ -127,13 +127,16 @@ export type BoardCardProps = {
127
127
  item: BoardItem;
128
128
  laneLabel: string;
129
129
  /**
130
- * Shown on the move handle instead of the word "Move". The
131
- * library ships no icons, so the default is words — a `⋮` renders
132
- * as nothing where the font lacks it, which includes the kiosk
133
- * image and the ePaper build. An app that already owns a glyph
134
- * set passes one and buys back the ~55px per row that a word
135
- * costs, which in a 500px lane is the difference between twenty
136
- * characters of title and thirty.
130
+ * Shown on the move handle **while the lanes are side by side**,
131
+ * instead of the word "Move". Below the board's `cq-lg` the word
132
+ * comes back whatever this is — see the handle section below.
133
+ *
134
+ * The library ships no icons, so the default is words — a `⋮`
135
+ * renders as nothing where the font lacks it, which includes the
136
+ * kiosk image and the ePaper build. An app that already owns a
137
+ * glyph set passes one and buys back the ~35px per row that a
138
+ * word costs, which in a 500px lane is several characters of
139
+ * title.
137
140
  */
138
141
  moveIcon?: ReactNode;
139
142
  /** The lanes this card can be sent to — never its own. */
@@ -187,6 +190,38 @@ export type BoardCardProps = {
187
190
  * on screen at all. Dragging from it moves the card directly. Both
188
191
  * commit through the same callback, so there is no second code path
189
192
  * to keep honest and neither is a fallback for the other.
193
+ *
194
+ * ### What it WEARS depends on whether a drag can succeed
195
+ *
196
+ * The two drivers are not equally available at every width, so the
197
+ * handle does not claim they are:
198
+ *
199
+ * | The board is | The handle shows | Because |
200
+ * | --- | --- | --- |
201
+ * | `cq-lg` and wider — lanes side by side | the app's `moveIcon` | the other lanes are on screen, so a drag has somewhere to land, and a grip glyph teaches that gesture |
202
+ * | narrower — one lane and a segmented control | the word **Move** | there is nothing on screen to drop onto, so the only gesture the glyph teaches is the one that cannot work |
203
+ *
204
+ * That table is a bug report. QueuePilot shipped a `≡` handle in a
205
+ * one-lane board and the owner could not move anybody: *"I can't
206
+ * seem to drag 'n drop the names from Everyone Else anywhere else.
207
+ * There's no right-click or anything. How do I move these?"* The
208
+ * first fix took the glyph away everywhere, which was the wrong
209
+ * half — *"I think the drag handles were fine, but now you have it
210
+ * in a 3-column mode, so dragging would work, but it has this
211
+ * 'move' button instead."*
212
+ *
213
+ * Both are in the DOM and CSS picks; neither is rendered from a
214
+ * measurement. A `ResizeObserver` would get the first paint wrong,
215
+ * and a kiosk Pi shows that. Both are `aria-hidden`, and the
216
+ * handle's whole accessible name comes from the `VisuallyHidden`
217
+ * beside them — so the name is the same sentence at every width,
218
+ * which is what keeps one `getByRole` query working in both
219
+ * layouts.
220
+ *
221
+ * The query is against the **board's** container, named `board`,
222
+ * not the lane's. A lane in a three-up board is narrow and the
223
+ * Narrow View's single lane is wide, so the nearer container
224
+ * answers this question exactly backwards.
190
225
  */
191
226
  export declare const BoardCard: ({ item, laneLabel, moveIcon, moveTargets, onMoveToLane, onStartDrag, }: BoardCardProps) => ReactNode;
192
227
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"BoardCard.d.ts","sourceRoot":"","sources":["../../src/Board/BoardCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAc/D,KAAK,eAAe,GAAG;IACrB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,eAAe,GAChB;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,UAAU,CAAA;CAAE,GACjD;IAAE,UAAU,EAAE,cAAc,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,KAAK,kBAAkB,GACnB;IACE,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,KAAK,CAAA;CACrB,GACD;IACE,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB;;;;;;;;OAQG;IACH,YAAY,EAAE,SAAS,CAAA;CACxB,CAAA;AAEL,MAAM,MAAM,SAAS,GAAG,eAAe,GACrC,eAAe,GACf,kBAAkB,CAAA;AAEpB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,0DAA0D;IAC1D,WAAW,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtD,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,aAAa,EAAE,WAAW,GAAG,OAAO,CAAA;QACpC,SAAS,EAAE,MAAM,CAAA;KAClB,KAAK,IAAI,CAAA;CACX,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,SAAS,GAAI,wEAOvB,cAAc,KAAG,SAsLnB,CAAA"}
1
+ {"version":3,"file":"BoardCard.d.ts","sourceRoot":"","sources":["../../src/Board/BoardCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAc/D,KAAK,eAAe,GAAG;IACrB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,eAAe,GAChB;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,UAAU,CAAA;CAAE,GACjD;IAAE,UAAU,EAAE,cAAc,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,KAAK,kBAAkB,GACnB;IACE,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,KAAK,CAAA;CACrB,GACD;IACE,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB;;;;;;;;OAQG;IACH,YAAY,EAAE,SAAS,CAAA;CACxB,CAAA;AAEL,MAAM,MAAM,SAAS,GAAG,eAAe,GACrC,eAAe,GACf,kBAAkB,CAAA;AAEpB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,0DAA0D;IAC1D,WAAW,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACtD,8DAA8D;IAC9D,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,aAAa,EAAE,WAAW,GAAG,OAAO,CAAA;QACpC,SAAS,EAAE,MAAM,CAAA;KAClB,KAAK,IAAI,CAAA;CACX,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,eAAO,MAAM,SAAS,GAAI,wEAOvB,cAAc,KAAG,SAqOnB,CAAA"}
@@ -44,6 +44,38 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
44
44
  * on screen at all. Dragging from it moves the card directly. Both
45
45
  * commit through the same callback, so there is no second code path
46
46
  * to keep honest and neither is a fallback for the other.
47
+ *
48
+ * ### What it WEARS depends on whether a drag can succeed
49
+ *
50
+ * The two drivers are not equally available at every width, so the
51
+ * handle does not claim they are:
52
+ *
53
+ * | The board is | The handle shows | Because |
54
+ * | --- | --- | --- |
55
+ * | `cq-lg` and wider — lanes side by side | the app's `moveIcon` | the other lanes are on screen, so a drag has somewhere to land, and a grip glyph teaches that gesture |
56
+ * | narrower — one lane and a segmented control | the word **Move** | there is nothing on screen to drop onto, so the only gesture the glyph teaches is the one that cannot work |
57
+ *
58
+ * That table is a bug report. QueuePilot shipped a `≡` handle in a
59
+ * one-lane board and the owner could not move anybody: *"I can't
60
+ * seem to drag 'n drop the names from Everyone Else anywhere else.
61
+ * There's no right-click or anything. How do I move these?"* The
62
+ * first fix took the glyph away everywhere, which was the wrong
63
+ * half — *"I think the drag handles were fine, but now you have it
64
+ * in a 3-column mode, so dragging would work, but it has this
65
+ * 'move' button instead."*
66
+ *
67
+ * Both are in the DOM and CSS picks; neither is rendered from a
68
+ * measurement. A `ResizeObserver` would get the first paint wrong,
69
+ * and a kiosk Pi shows that. Both are `aria-hidden`, and the
70
+ * handle's whole accessible name comes from the `VisuallyHidden`
71
+ * beside them — so the name is the same sentence at every width,
72
+ * which is what keeps one `getByRole` query working in both
73
+ * layouts.
74
+ *
75
+ * The query is against the **board's** container, named `board`,
76
+ * not the lane's. A lane in a three-up board is narrow and the
77
+ * Narrow View's single lane is wide, so the nearer container
78
+ * answers this question exactly backwards.
47
79
  */
48
80
  export const BoardCard = ({ item, laneLabel, moveIcon, moveTargets, onMoveToLane, onStartDrag, }) => {
49
81
  const [isMenuVisible, setIsMenuVisible] = useState(false);
@@ -76,18 +108,32 @@ export const BoardCard = ({ item, laneLabel, moveIcon, moveTargets, onMoveToLane
76
108
  },
77
109
  })), onDismiss: () => {
78
110
  setIsMenuVisible(false);
79
- }, placement: "bottom-end", trigger: _jsxs(Button, { appearance: "ghost", intent: "neutral",
111
+ }, placement: "bottom-end", trigger: _jsxs(Button, { appearance: "ghost", intent: "neutral", className: toClassName(
80
112
  // `touch-none` so a touch drag is a drag
81
113
  // rather than a page scroll. Only the handle
82
- // needs it; the rest of the gesture is covered
83
- // by `preventDefault` on the captured
84
- // `pointermove`.
85
- className: "touch-none opacity-70 group-hover:opacity-100", onClick: () => {
114
+ // needs it; the rest of the gesture is
115
+ // covered by `preventDefault` on the
116
+ // captured `pointermove`.
117
+ "touch-none opacity-70 group-hover:opacity-100",
118
+ // `sizing` is a prop and cannot be two
119
+ // things at once, so the button stays
120
+ // `control`-sized — which is what the word
121
+ // needs — and takes `icon` sizing back at
122
+ // the width where the glyph is what is
123
+ // showing. These are the two utilities
124
+ // `ICON_CONTROL_SIZE_CLASS.sm` is, minus the
125
+ // height `CONTROL_SIZE_CLASS.sm` already
126
+ // set. Deterministic rather than a
127
+ // specificity coin-flip: Tailwind orders a
128
+ // variant after the utility it varies, which
129
+ // is the same thing the lane's own
130
+ // `cq-lg:p-0` relies on.
131
+ moveIcon != null &&
132
+ "@min-[48rem]/board:w-(--control-height-sm) @min-[48rem]/board:px-0"), onClick: () => {
86
133
  setIsMenuVisible((isVisible) => !isVisible);
87
134
  }, onPointerDown: (pointerEvent) => {
88
135
  onStartDrag?.(pointerEvent);
89
- }, size: "sm", sizing: moveIcon ? "icon" : "control", children: [moveIcon ?? "Move", _jsx(VisuallyHidden, { children: moveIcon
90
- ? `Move ${item.title}, currently in ${laneLabel}`
91
- : ` ${item.title}, currently in ${laneLabel}` })] }) })) : null] })) : null] }), item.footer ? (_jsx("div", { className: "min-w-0 text-content-secondary text-xs", children: item.footer })) : null] })] }));
136
+ }, size: "sm", sizing: "control", children: [moveIcon == null ? null : (_jsx("span", { "aria-hidden": "true", className: "hidden @min-[48rem]/board:contents", children: moveIcon })), _jsx("span", { "aria-hidden": "true", className: toClassName(moveIcon != null &&
137
+ "@min-[48rem]/board:hidden"), children: "Move" }), _jsx(VisuallyHidden, { children: `Move ${item.title}, currently in ${laneLabel}` })] }) })) : null] })) : null] }), item.footer ? (_jsx("div", { className: "min-w-0 text-content-secondary text-xs", children: item.footer })) : null] })] }));
92
138
  };
93
139
  //# sourceMappingURL=BoardCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BoardCard.js","sourceRoot":"","sources":["../../src/Board/BoardCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BoardCard.js","sourceRoot":"","sources":["../../src/Board/BoardCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /** Matches `@charcuterie/server`'s default build-marker URL. */
2
+ export declare const DEFAULT_DEPLOYMENT_PATH = "/__charcuterie/deployment";
3
+ /** Matches `@charcuterie/server`'s default SSE URL. */
4
+ export declare const DEFAULT_DEPLOYMENT_EVENTS_PATH = "/__charcuterie/deployment/events";
5
+ export type UseDeploymentUpdateOptions = {
6
+ deploymentPath?: string;
7
+ deploymentEventsPath?: string;
8
+ /** `0` disables polling. SSE is normally enough. */
9
+ pollIntervalMs?: number;
10
+ /** Disable when an app calls `checkForUpdate` after its own SSE reconnects. */
11
+ isEventSourceEnabled?: boolean;
12
+ };
13
+ export type DeploymentUpdate = {
14
+ isUpdateAvailable: boolean;
15
+ /** Revalidate the marker now. Safe to call after an app SSE reconnects. */
16
+ checkForUpdate: () => Promise<boolean>;
17
+ /** Reload after the user has saved or finished their current work. */
18
+ reload: () => void;
19
+ };
20
+ /**
21
+ * Detects a replacement static SPA without taking control away from
22
+ * the app. It never reloads by itself: a tab can contain unsaved
23
+ * form state, so the app shows its own accessible update action and
24
+ * calls `reload` only when the user is ready.
25
+ *
26
+ * `createStaticHandler` supplies both endpoints by default. Existing
27
+ * app SSE can keep its one connection: set `isEventSourceEnabled` to
28
+ * `false`, then call `checkForUpdate` in its post-reconnect callback.
29
+ */
30
+ export declare const useDeploymentUpdate: ({ deploymentEventsPath, deploymentPath, isEventSourceEnabled, pollIntervalMs, }?: UseDeploymentUpdateOptions) => DeploymentUpdate;
31
+ //# sourceMappingURL=useDeploymentUpdate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDeploymentUpdate.d.ts","sourceRoot":"","sources":["../../src/DeploymentUpdate/useDeploymentUpdate.ts"],"names":[],"mappings":"AAOA,gEAAgE;AAChE,eAAO,MAAM,uBAAuB,8BACP,CAAA;AAE7B,uDAAuD;AACvD,eAAO,MAAM,8BAA8B,qCACP,CAAA;AAEpC,MAAM,MAAM,0BAA0B,GAAG;IACvC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,2EAA2E;IAC3E,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACtC,sEAAsE;IACtE,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAcD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,kFAKjC,0BAA+B,KAAG,gBAmFpC,CAAA"}
@@ -0,0 +1,94 @@
1
+ import { useCallback, useEffect, useRef, useState, } from "react";
2
+ /** Matches `@charcuterie/server`'s default build-marker URL. */
3
+ export const DEFAULT_DEPLOYMENT_PATH = "/__charcuterie/deployment";
4
+ /** Matches `@charcuterie/server`'s default SSE URL. */
5
+ export const DEFAULT_DEPLOYMENT_EVENTS_PATH = "/__charcuterie/deployment/events";
6
+ const getBuildId = (value) => {
7
+ if (typeof value === "object" &&
8
+ value !== null &&
9
+ "buildId" in value &&
10
+ typeof value.buildId === "string") {
11
+ return value.buildId;
12
+ }
13
+ return undefined;
14
+ };
15
+ /**
16
+ * Detects a replacement static SPA without taking control away from
17
+ * the app. It never reloads by itself: a tab can contain unsaved
18
+ * form state, so the app shows its own accessible update action and
19
+ * calls `reload` only when the user is ready.
20
+ *
21
+ * `createStaticHandler` supplies both endpoints by default. Existing
22
+ * app SSE can keep its one connection: set `isEventSourceEnabled` to
23
+ * `false`, then call `checkForUpdate` in its post-reconnect callback.
24
+ */
25
+ export const useDeploymentUpdate = ({ deploymentEventsPath = DEFAULT_DEPLOYMENT_EVENTS_PATH, deploymentPath = DEFAULT_DEPLOYMENT_PATH, isEventSourceEnabled = true, pollIntervalMs = 0, } = {}) => {
26
+ const buildIdRef = useRef(undefined);
27
+ const [isUpdateAvailable, setIsUpdateAvailable] = useState(false);
28
+ const acceptBuildId = useCallback((buildId) => {
29
+ if (buildIdRef.current === undefined) {
30
+ buildIdRef.current = buildId;
31
+ return false;
32
+ }
33
+ if (buildIdRef.current === buildId) {
34
+ return false;
35
+ }
36
+ setIsUpdateAvailable(true);
37
+ return true;
38
+ }, []);
39
+ const checkForUpdate = useCallback(async () => {
40
+ const response = await globalThis.fetch(deploymentPath, {
41
+ cache: "no-store",
42
+ headers: { Accept: "application/json" },
43
+ });
44
+ if (!response.ok) {
45
+ return false;
46
+ }
47
+ const buildId = getBuildId(await response.json());
48
+ return buildId === undefined
49
+ ? false
50
+ : acceptBuildId(buildId);
51
+ }, [acceptBuildId, deploymentPath]);
52
+ useEffect(() => {
53
+ void checkForUpdate().catch(() => undefined);
54
+ }, [checkForUpdate]);
55
+ useEffect(() => {
56
+ if (!isEventSourceEnabled ||
57
+ typeof EventSource === "undefined") {
58
+ return;
59
+ }
60
+ const source = new EventSource(deploymentEventsPath);
61
+ const onDeployment = (event) => {
62
+ try {
63
+ const buildId = getBuildId(JSON.parse(event.data));
64
+ if (buildId !== undefined) {
65
+ acceptBuildId(buildId);
66
+ }
67
+ }
68
+ catch {
69
+ // A malformed marker is not a reason to interrupt the tab.
70
+ }
71
+ };
72
+ source.addEventListener("deployment", onDeployment);
73
+ return () => source.close();
74
+ }, [
75
+ acceptBuildId,
76
+ deploymentEventsPath,
77
+ isEventSourceEnabled,
78
+ ]);
79
+ useEffect(() => {
80
+ if (pollIntervalMs <= 0) {
81
+ return;
82
+ }
83
+ const interval = globalThis.setInterval(() => {
84
+ void checkForUpdate().catch(() => undefined);
85
+ }, pollIntervalMs);
86
+ return () => globalThis.clearInterval(interval);
87
+ }, [checkForUpdate, pollIntervalMs]);
88
+ return {
89
+ checkForUpdate,
90
+ isUpdateAvailable,
91
+ reload: () => globalThis.location.reload(),
92
+ };
93
+ };
94
+ //# sourceMappingURL=useDeploymentUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDeploymentUpdate.js","sourceRoot":"","sources":["../../src/DeploymentUpdate/useDeploymentUpdate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import type { ControlSize } from "@charcuterie/tokens";
2
+ import type { Placement } from "@floating-ui/react";
3
+ import type { ReactElement, ReactNode } from "react";
4
+ import type { NavItem } from "./navItems.ts";
5
+ /**
6
+ * Where the destinations are drawn. Not *whether* — see
7
+ * `useNavLayout`, which answers that from the width.
8
+ */
9
+ export type NavLayout = "bar" | "bottom" | "menu" | "rail" | "railIcons";
10
+ type NavCommonProps = {
11
+ /**
12
+ * The destinations, in the order the product reads.
13
+ *
14
+ * Annotate the array as `NavRailItem[]` when the app uses a rail:
15
+ * it is the same shape with `icon` made **required**, because
16
+ * `railIcons` takes the label away and an item with no glyph is a
17
+ * blank square that still navigates. `NavItem` keeps `icon`
18
+ * optional so that a `bar`, where the label never goes anywhere,
19
+ * does not have to invent one.
20
+ */
21
+ items: readonly NavItem[];
22
+ /**
23
+ * The address the app is at — usually `location.pathname`. The
24
+ * item that matches wears `aria-current="page"`.
25
+ *
26
+ * Omitted means nothing is current, which is honest on a screen
27
+ * the nav does not contain (a modal route, an error page) and is
28
+ * better than marking the closest thing.
29
+ */
30
+ activeHref?: string;
31
+ className?: string;
32
+ /**
33
+ * The `<nav>`'s accessible name. Default `"Main"`.
34
+ *
35
+ * Required in spirit and defaulted in practice: two unnamed
36
+ * navigations on one page are two landmarks a screen reader
37
+ * announces identically, which is axe's `landmark-unique`. An app
38
+ * with a second nav — a queue's sub-navigation, a footer — names
39
+ * that one and leaves this one alone.
40
+ */
41
+ label?: string;
42
+ };
43
+ type NavPlacedProps = NavCommonProps & {
44
+ /**
45
+ * **Initial** only, and the bar owns it from then on — the same
46
+ * uncontrolled contract every other component here has. It exists
47
+ * so a story (and a screenshot) can show the menu open; an app
48
+ * almost never passes it. `bar` only.
49
+ */
50
+ isMenuVisible?: boolean;
51
+ layout?: "bar" | "bottom" | "rail" | "railIcons";
52
+ /**
53
+ * Where the trigger sits in the bar's track once the row has
54
+ * folded. `"end"` when the header puts its own actions at the far
55
+ * edge, so the fold control joins them instead of hugging the
56
+ * wordmark with the whole track empty after it.
57
+ *
58
+ * It reaches **only** the folded row, which holds exactly one
59
+ * item — so it cannot disturb where the links sit when the bar is
60
+ * whole, and there is deliberately no prop that can.
61
+ */
62
+ menuAlign?: "end" | "start";
63
+ /**
64
+ * The folded trigger's glyph. **No default** — the library ships
65
+ * no icons, and a hamburger renders as nothing where the font
66
+ * lacks it. With no icon the trigger is a text button reading
67
+ * `menuLabel`, which works everywhere.
68
+ */
69
+ menuIcon?: ReactNode;
70
+ /**
71
+ * Names the trigger and, through it, the panel it opens. A
72
+ * `role="dialog"` takes no accessible name from its content.
73
+ */
74
+ menuLabel?: string;
75
+ menuPlacement?: Placement;
76
+ size?: ControlSize;
77
+ };
78
+ type NavMenuProps = NavCommonProps & {
79
+ isVisible: boolean;
80
+ layout: "menu";
81
+ onDismiss: () => void;
82
+ placement?: Placement;
83
+ /** The control the panel hangs off. **Cloned, not wrapped.** */
84
+ trigger: ReactElement;
85
+ };
86
+ /**
87
+ * The union splits on `menu` and **only** on `menu`, because that is
88
+ * the one layout an app cannot reach with a variable: its trigger
89
+ * goes in the `Header`, so the app is already writing the branch.
90
+ *
91
+ * Everything else takes `layout={navLayout.layout}` straight from
92
+ * `useNavLayout` — which is a *variable*, not a literal, so a union
93
+ * that also split `items` by layout would force a `switch` at the
94
+ * one call site this component exists to make short.
95
+ */
96
+ export type NavProps = NavMenuProps | NavPlacedProps;
97
+ /**
98
+ * The app's destinations — a header row, a side rail, a collapsed
99
+ * rail, a strip along the foot of the Narrow View, or a panel behind
100
+ * one control. The same list, drawn where it fits.
101
+ *
102
+ * ## What was actually missing
103
+ *
104
+ * `Shell` / `Header` / `Rail` / `Main` shipped the page frame on
105
+ * 2026-08-10 and left the **contents of the nav rail empty**. Twelve
106
+ * UI repos, and exactly two of them had a `<nav>` at all: Docket
107
+ * hand-rolled a row of `NavLink`s with the collapse rule in the
108
+ * app's own stylesheet, Folio hand-rolled another, and the other ten
109
+ * had no destinations anywhere. The two that existed already
110
+ * disagreed — Docket *wraps* below its breakpoint and stands three
111
+ * lines tall on a phone, which is not a decision anybody made, it is
112
+ * what `flex-wrap` does when nobody writes the other rule.
113
+ *
114
+ * ## Every item is a real link
115
+ *
116
+ * `<a href>`, through the injected `RouterLinkProvider` — see
117
+ * `NavLink`, which is where that argument is written down.
118
+ *
119
+ * ## `aria-current="page"`, and exactly one of them
120
+ *
121
+ * `resolveActiveKey` takes the **deepest** matching path, so an app
122
+ * holding both `/settings` and `/settings/labels` marks the page the
123
+ * reader is actually on rather than both.
124
+ *
125
+ * ## `bar` folds WHOLE, and it is measured
126
+ *
127
+ * There is no `collapseAt` and no media query on this axis. The bar
128
+ * reads the width its links actually have and folds when their sum
129
+ * stops fitting, so a longer label, a tenth destination, a
130
+ * `data-density="kiosk"` or a reader at 175% browser zoom each move
131
+ * the fold on their own. mux-magic collapses at a hardcoded `480px`
132
+ * and plex-channels at `760px`, and neither number has a reason.
133
+ *
134
+ * It folds *whole* rather than progressively, unlike `Toolbar`:
135
+ * `Toolbar`'s items are ranked, and a nav's order is the shape of
136
+ * the product (Docket's reads as the pipeline: Triage → Backlog →
137
+ * Phases → Board → Archives). Half of that behind a button is a rule
138
+ * no reader can learn.
139
+ *
140
+ * ⚠️ **A `bar` must not be sized by its own contents.** It measures
141
+ * its own box to decide what to draw in it, so a container that
142
+ * shrink-wraps makes the answer its own input: put it in a
143
+ * `minmax(0, 1fr)` grid track or a `flex-1 min-w-0` row. The root
144
+ * carries `min-w-0 flex-1` for the flex case; a grid track is the
145
+ * caller's to declare.
146
+ *
147
+ * ## `menu` is the rail's narrow state, and the app owns it
148
+ *
149
+ * `bar` builds its own trigger because it knows when it folded.
150
+ * `menu` takes one, because the rail's narrow state puts that
151
+ * control in the `Header` — a different corner of `Shell`'s grid
152
+ * from a side rail, and no media query moves an element across a
153
+ * grid. `useNavLayout` is what tells the app which of the two it is
154
+ * rendering.
155
+ *
156
+ * ## Mounted exactly once
157
+ *
158
+ * A destination is in the bar or in the panel, never both. The
159
+ * fleet's habit is to render the whole nav twice and hide one copy
160
+ * with `hidden md:flex` — mux-magic's `PageHeader` across two
161
+ * ~55-line blocks, mail-sifter's `TriageQueue` again — which puts
162
+ * every link in the DOM at every width, so an agent driving the page
163
+ * finds two of each and cannot tell which one a human can see.
164
+ */
165
+ export declare const Nav: (props: NavProps) => ReactNode;
166
+ export {};
167
+ //# sourceMappingURL=Nav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Nav.d.ts","sourceRoot":"","sources":["../../src/Nav/Nav.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AASpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAM5C;;;GAGG;AACH,MAAM,MAAM,SAAS,GACjB,KAAK,GACL,QAAQ,GACR,MAAM,GACN,MAAM,GACN,WAAW,CAAA;AAEf,KAAK,cAAc,GAAG;IACpB;;;;;;;;;OASG;IACH,KAAK,EAAE,SAAS,OAAO,EAAE,CAAA;IACzB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,cAAc,GAAG,cAAc,GAAG;IACrC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;IAChD;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,CAAA;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB,CAAA;AAED,KAAK,YAAY,GAAG,cAAc,GAAG;IACnC,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,gEAAgE;IAChE,OAAO,EAAE,YAAY,CAAA;CACtB,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAA;AAqBpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,KAAG,SAsMrC,CAAA"}