@charcuterie/ui 3.0.0 → 3.2.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 (130) hide show
  1. package/README.md +10 -0
  2. package/dist/Badge/Badge.d.ts +33 -3
  3. package/dist/Badge/Badge.d.ts.map +1 -1
  4. package/dist/Badge/Badge.js +20 -2
  5. package/dist/Badge/Badge.js.map +1 -1
  6. package/dist/Board/Board.d.ts +119 -0
  7. package/dist/Board/Board.d.ts.map +1 -0
  8. package/dist/Board/Board.js +165 -0
  9. package/dist/Board/Board.js.map +1 -0
  10. package/dist/Board/BoardCard.d.ts +120 -0
  11. package/dist/Board/BoardCard.d.ts.map +1 -0
  12. package/dist/Board/BoardCard.js +77 -0
  13. package/dist/Board/BoardCard.js.map +1 -0
  14. package/dist/Board/BoardLaneList.d.ts +103 -0
  15. package/dist/Board/BoardLaneList.d.ts.map +1 -0
  16. package/dist/Board/BoardLaneList.js +69 -0
  17. package/dist/Board/BoardLaneList.js.map +1 -0
  18. package/dist/Board/boardMove.d.ts +116 -0
  19. package/dist/Board/boardMove.d.ts.map +1 -0
  20. package/dist/Board/boardMove.js +116 -0
  21. package/dist/Board/boardMove.js.map +1 -0
  22. package/dist/Board/useBoardDrag.d.ts +44 -0
  23. package/dist/Board/useBoardDrag.d.ts.map +1 -0
  24. package/dist/Board/useBoardDrag.js +237 -0
  25. package/dist/Board/useBoardDrag.js.map +1 -0
  26. package/dist/Checkbox/Checkbox.d.ts.map +1 -1
  27. package/dist/Checkbox/Checkbox.js +15 -4
  28. package/dist/Checkbox/Checkbox.js.map +1 -1
  29. package/dist/DataTable/DataTable.d.ts +159 -0
  30. package/dist/DataTable/DataTable.d.ts.map +1 -0
  31. package/dist/DataTable/DataTable.js +197 -0
  32. package/dist/DataTable/DataTable.js.map +1 -0
  33. package/dist/DatePicker/DateGrid.d.ts +79 -0
  34. package/dist/DatePicker/DateGrid.d.ts.map +1 -0
  35. package/dist/DatePicker/DateGrid.js +220 -0
  36. package/dist/DatePicker/DateGrid.js.map +1 -0
  37. package/dist/DatePicker/DatePicker.d.ts +138 -0
  38. package/dist/DatePicker/DatePicker.d.ts.map +1 -0
  39. package/dist/DatePicker/DatePicker.js +384 -0
  40. package/dist/DatePicker/DatePicker.js.map +1 -0
  41. package/dist/DatePicker/datePresets.d.ts +29 -0
  42. package/dist/DatePicker/datePresets.d.ts.map +1 -0
  43. package/dist/DatePicker/datePresets.js +28 -0
  44. package/dist/DatePicker/datePresets.js.map +1 -0
  45. package/dist/DatePicker/parseDateInput.d.ts +106 -0
  46. package/dist/DatePicker/parseDateInput.d.ts.map +1 -0
  47. package/dist/DatePicker/parseDateInput.js +419 -0
  48. package/dist/DatePicker/parseDateInput.js.map +1 -0
  49. package/dist/DatePicker/plainDate.d.ts +167 -0
  50. package/dist/DatePicker/plainDate.d.ts.map +1 -0
  51. package/dist/DatePicker/plainDate.js +272 -0
  52. package/dist/DatePicker/plainDate.js.map +1 -0
  53. package/dist/Dialog/Dialog.d.ts +12 -2
  54. package/dist/Dialog/Dialog.d.ts.map +1 -1
  55. package/dist/Dialog/Dialog.js +2 -2
  56. package/dist/Dialog/Dialog.js.map +1 -1
  57. package/dist/MarkdownEditor/MarkdownEditor.d.ts +147 -0
  58. package/dist/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
  59. package/dist/MarkdownEditor/MarkdownEditor.js +492 -0
  60. package/dist/MarkdownEditor/MarkdownEditor.js.map +1 -0
  61. package/dist/MarkdownEditor/markdownCommands.d.ts +202 -0
  62. package/dist/MarkdownEditor/markdownCommands.d.ts.map +1 -0
  63. package/dist/MarkdownEditor/markdownCommands.js +379 -0
  64. package/dist/MarkdownEditor/markdownCommands.js.map +1 -0
  65. package/dist/MarkdownEditor/markdownSpans.d.ts +92 -0
  66. package/dist/MarkdownEditor/markdownSpans.d.ts.map +1 -0
  67. package/dist/MarkdownEditor/markdownSpans.js +303 -0
  68. package/dist/MarkdownEditor/markdownSpans.js.map +1 -0
  69. package/dist/Modal/Modal.d.ts +6 -2
  70. package/dist/Modal/Modal.d.ts.map +1 -1
  71. package/dist/Modal/Modal.js +1 -1
  72. package/dist/Modal/Modal.js.map +1 -1
  73. package/dist/Overlay/OverlayPanel.d.ts +13 -2
  74. package/dist/Overlay/OverlayPanel.d.ts.map +1 -1
  75. package/dist/Overlay/OverlayPanel.js +5 -1
  76. package/dist/Overlay/OverlayPanel.js.map +1 -1
  77. package/dist/categoricalStyles.d.ts +53 -0
  78. package/dist/categoricalStyles.d.ts.map +1 -0
  79. package/dist/categoricalStyles.js +195 -0
  80. package/dist/categoricalStyles.js.map +1 -0
  81. package/dist/index.d.ts +22 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +11 -0
  84. package/dist/index.js.map +1 -1
  85. package/package.json +2 -2
  86. package/src/Badge/Badge.mdx +46 -0
  87. package/src/Badge/Badge.stories.tsx +98 -4
  88. package/src/Badge/Badge.test.tsx +157 -2
  89. package/src/Badge/Badge.tsx +49 -3
  90. package/src/Board/Board.mdx +199 -0
  91. package/src/Board/Board.stories.tsx +707 -0
  92. package/src/Board/Board.test.tsx +310 -0
  93. package/src/Board/Board.tsx +333 -0
  94. package/src/Board/BoardCard.tsx +290 -0
  95. package/src/Board/BoardLaneList.tsx +275 -0
  96. package/src/Board/boardMove.test.ts +213 -0
  97. package/src/Board/boardMove.ts +225 -0
  98. package/src/Board/useBoardDrag.ts +413 -0
  99. package/src/Checkbox/Checkbox.tsx +34 -3
  100. package/src/DataTable/DataTable.mdx +123 -0
  101. package/src/DataTable/DataTable.stories.tsx +411 -0
  102. package/src/DataTable/DataTable.test.tsx +386 -0
  103. package/src/DataTable/DataTable.tsx +497 -0
  104. package/src/DatePicker/DateGrid.tsx +467 -0
  105. package/src/DatePicker/DatePicker.mdx +170 -0
  106. package/src/DatePicker/DatePicker.stories.tsx +268 -0
  107. package/src/DatePicker/DatePicker.test.tsx +455 -0
  108. package/src/DatePicker/DatePicker.tsx +852 -0
  109. package/src/DatePicker/datePresets.ts +34 -0
  110. package/src/DatePicker/parseDateInput.test.ts +187 -0
  111. package/src/DatePicker/parseDateInput.ts +629 -0
  112. package/src/DatePicker/plainDate.test.ts +375 -0
  113. package/src/DatePicker/plainDate.ts +465 -0
  114. package/src/Dialog/Dialog.stories.tsx +48 -0
  115. package/src/Dialog/Dialog.test.tsx +30 -0
  116. package/src/Dialog/Dialog.tsx +13 -1
  117. package/src/MarkdownEditor/MarkdownEditor.mdx +189 -0
  118. package/src/MarkdownEditor/MarkdownEditor.stories.tsx +267 -0
  119. package/src/MarkdownEditor/MarkdownEditor.test.tsx +627 -0
  120. package/src/MarkdownEditor/MarkdownEditor.tsx +862 -0
  121. package/src/MarkdownEditor/markdownCommands.test.ts +384 -0
  122. package/src/MarkdownEditor/markdownCommands.ts +566 -0
  123. package/src/MarkdownEditor/markdownSpans.test.ts +217 -0
  124. package/src/MarkdownEditor/markdownSpans.ts +458 -0
  125. package/src/Modal/Modal.tsx +7 -1
  126. package/src/Overlay/OverlayPanel.tsx +17 -1
  127. package/src/argTypes.storyHelpers.ts +39 -0
  128. package/src/categoricalStyles.ts +244 -0
  129. package/src/index.ts +89 -0
  130. package/src/sourceRules.test.ts +52 -1
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Markdown → coloured spans, with **every character kept**.
3
+ *
4
+ * This is the half of the live-hybrid editor that decides what a
5
+ * line looks like, and its one hard requirement is not a parsing
6
+ * requirement at all — it is a geometry one.
7
+ *
8
+ * ### The concatenation invariant
9
+ *
10
+ * The editing surface is a real `<textarea>` with a painted layer
11
+ * behind it, sharing one grid cell. The textarea owns the caret,
12
+ * the selection, the undo stack and the IME; the layer owns the
13
+ * colour. That only works while the two layers **wrap identically**,
14
+ * and they only wrap identically while they contain the *same
15
+ * characters in the same order*.
16
+ *
17
+ * So `toMarkdownLines(text)` is not a parser in the usual sense. It
18
+ * never drops a marker, never normalises whitespace, never resolves
19
+ * a reference, and never emits a node the source did not contain.
20
+ * Joining every span's text back together, with `\n` between lines,
21
+ * reproduces the input byte for byte — `markdownSpans.test.ts`
22
+ * asserts exactly that over a fixture corpus, and it is the test
23
+ * that stops a well-meaning "let's trim the trailing space"
24
+ * from silently shearing the caret away from the glyphs.
25
+ *
26
+ * ### It emits kinds, not HTML
27
+ *
28
+ * The return value is a list of `{ kind, text }` pairs. There is no
29
+ * HTML string anywhere in this module, no `innerHTML`, and no
30
+ * sanitiser — because there is nothing to sanitise. Docket's whole
31
+ * reason to exist is that HTML-in-the-field destroyed a previous
32
+ * tool's data, and the cheapest possible guarantee against that is
33
+ * a pipeline in which HTML is never *constructed*. React renders
34
+ * these spans as text nodes; a `<script>` in the source is a
35
+ * `<script>` on screen.
36
+ *
37
+ * ### Why it is line-based, and what that costs
38
+ *
39
+ * A CommonMark parser resolves lazy continuation, setext headings,
40
+ * link reference definitions and nested block containers across the
41
+ * whole document. This resolves one line at a time, carrying
42
+ * exactly one bit of cross-line state: whether we are inside a
43
+ * fenced code block.
44
+ *
45
+ * That is a deliberate trade. Painting is per-line and re-runs on
46
+ * every keystroke, so the cost has to be linear in the line, not in
47
+ * the document; and a mis-coloured marker is a cosmetic defect
48
+ * while a mis-*placed* one is a broken editor. The known gaps are
49
+ * written down in `MarkdownEditor.mdx` rather than hidden: setext
50
+ * headings, indented (four-space) code blocks, reference links, and
51
+ * emphasis that spans a line break all colour as plain text. They
52
+ * still **store** correctly, because the stored value is the
53
+ * textarea's, not this module's.
54
+ */
55
+ export type MarkdownSpanKind = "code" | "emphasis" | "heading" | "link" | "marker" | "plain" | "strikethrough" | "strong" | "url";
56
+ export type MarkdownSpan = {
57
+ kind: MarkdownSpanKind;
58
+ text: string;
59
+ };
60
+ export type MarkdownLineKind = "blockquote" | "code" | "heading" | "list" | "paragraph" | "table" | "thematicBreak";
61
+ export type MarkdownLine = {
62
+ kind: MarkdownLineKind;
63
+ spans: MarkdownSpan[];
64
+ };
65
+ /**
66
+ * The inline scanner.
67
+ *
68
+ * `baseKind` is what unmarked text becomes — `"plain"` in a
69
+ * paragraph, `"heading"` inside a heading — so a heading's words
70
+ * carry the heading colour while the `##` in front of them stays a
71
+ * marker.
72
+ */
73
+ export declare const toInlineSpans: (text: string, baseKind?: MarkdownSpanKind) => MarkdownSpan[];
74
+ /**
75
+ * The whole document, one entry per line.
76
+ *
77
+ * `text.split("\n")` on an empty string yields `[""]` — one empty
78
+ * line — which is right: an empty editor still has a line for the
79
+ * caret to sit on, and the painted layer still needs a row so the
80
+ * two layers agree about where line 0 is.
81
+ */
82
+ export declare const toMarkdownLines: (text: string) => MarkdownLine[];
83
+ /**
84
+ * Which line the caret is on, from a character offset.
85
+ *
86
+ * The active line is the one construct in this editor that is
87
+ * *state* rather than syntax: its markers paint at full strength
88
+ * and every other line's fade back, which is the whole "raw syntax
89
+ * on the cursor's line" behaviour.
90
+ */
91
+ export declare const toLineIndex: (text: string, offset: number) => number;
92
+ //# sourceMappingURL=markdownSpans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownSpans.d.ts","sourceRoot":"","sources":["../../src/MarkdownEditor/markdownSpans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,UAAU,GACV,SAAS,GACT,MAAM,GACN,QAAQ,GACR,OAAO,GACP,eAAe,GACf,QAAQ,GACR,KAAK,CAAA;AAET,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,MAAM,GACN,SAAS,GACT,MAAM,GACN,WAAW,GACX,OAAO,GACP,eAAe,CAAA;AAEnB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,gBAAgB,CAAA;IACtB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB,CAAA;AA2ED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,WAAU,gBAA0B,KACnC,YAAY,EAkId,CAAA;AAkGD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,KACX,YAAY,EAyBd,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,MAYF,CAAA"}
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Markdown → coloured spans, with **every character kept**.
3
+ *
4
+ * This is the half of the live-hybrid editor that decides what a
5
+ * line looks like, and its one hard requirement is not a parsing
6
+ * requirement at all — it is a geometry one.
7
+ *
8
+ * ### The concatenation invariant
9
+ *
10
+ * The editing surface is a real `<textarea>` with a painted layer
11
+ * behind it, sharing one grid cell. The textarea owns the caret,
12
+ * the selection, the undo stack and the IME; the layer owns the
13
+ * colour. That only works while the two layers **wrap identically**,
14
+ * and they only wrap identically while they contain the *same
15
+ * characters in the same order*.
16
+ *
17
+ * So `toMarkdownLines(text)` is not a parser in the usual sense. It
18
+ * never drops a marker, never normalises whitespace, never resolves
19
+ * a reference, and never emits a node the source did not contain.
20
+ * Joining every span's text back together, with `\n` between lines,
21
+ * reproduces the input byte for byte — `markdownSpans.test.ts`
22
+ * asserts exactly that over a fixture corpus, and it is the test
23
+ * that stops a well-meaning "let's trim the trailing space"
24
+ * from silently shearing the caret away from the glyphs.
25
+ *
26
+ * ### It emits kinds, not HTML
27
+ *
28
+ * The return value is a list of `{ kind, text }` pairs. There is no
29
+ * HTML string anywhere in this module, no `innerHTML`, and no
30
+ * sanitiser — because there is nothing to sanitise. Docket's whole
31
+ * reason to exist is that HTML-in-the-field destroyed a previous
32
+ * tool's data, and the cheapest possible guarantee against that is
33
+ * a pipeline in which HTML is never *constructed*. React renders
34
+ * these spans as text nodes; a `<script>` in the source is a
35
+ * `<script>` on screen.
36
+ *
37
+ * ### Why it is line-based, and what that costs
38
+ *
39
+ * A CommonMark parser resolves lazy continuation, setext headings,
40
+ * link reference definitions and nested block containers across the
41
+ * whole document. This resolves one line at a time, carrying
42
+ * exactly one bit of cross-line state: whether we are inside a
43
+ * fenced code block.
44
+ *
45
+ * That is a deliberate trade. Painting is per-line and re-runs on
46
+ * every keystroke, so the cost has to be linear in the line, not in
47
+ * the document; and a mis-coloured marker is a cosmetic defect
48
+ * while a mis-*placed* one is a broken editor. The known gaps are
49
+ * written down in `MarkdownEditor.mdx` rather than hidden: setext
50
+ * headings, indented (four-space) code blocks, reference links, and
51
+ * emphasis that spans a line break all colour as plain text. They
52
+ * still **store** correctly, because the stored value is the
53
+ * textarea's, not this module's.
54
+ */
55
+ /**
56
+ * A fence opens or closes on any line whose first non-space run is
57
+ * three or more backticks or tildes. Up to three leading spaces,
58
+ * per CommonMark; a fourth would be an indented code block, which
59
+ * this module deliberately does not track.
60
+ */
61
+ const FENCE_PATTERN = /^ {0,3}(?:```|~~~)/;
62
+ const INDENT_PATTERN = /^[ \t]*/;
63
+ const BLOCKQUOTE_PATTERN = /^(?:>[ \t]?)+/;
64
+ const THEMATIC_BREAK_PATTERN = /^(?:\*[ \t]*){3,}$|^(?:-[ \t]*){3,}$|^(?:_[ \t]*){3,}$/;
65
+ const HEADING_PATTERN = /^#{1,6}[ \t]+/;
66
+ const LIST_MARKER_PATTERN = /^(?:[-*+]|\d{1,9}[.)])[ \t]+/;
67
+ const TASK_MARKER_PATTERN = /^\[[ xX]\][ \t]*/;
68
+ /**
69
+ * Sticky, because every one of these is tried at a known index
70
+ * rather than searched for. A non-sticky `exec` would happily match
71
+ * an emphasis pair fifty characters further down the line and the
72
+ * scanner would swallow everything in between.
73
+ *
74
+ * Order is the whole grammar here, and two orderings are
75
+ * load-bearing:
76
+ *
77
+ * - **Escape first.** `\*not emphasis\*` has to lose to the
78
+ * backslash, or the editor colours text the renderer will not.
79
+ * - **Code before everything.** A code span suppresses every other
80
+ * construct inside it, which is what makes `` `**` `` render as
81
+ * two asterisks rather than an unterminated bold run.
82
+ * - **Image before link**, because `![alt](url)` starts with a
83
+ * valid link at index 1.
84
+ * - **Strong before emphasis**, because `**` starts with `*`.
85
+ */
86
+ const INLINE_PATTERNS = {
87
+ code: /(`+)([^\n]*?)\1/y,
88
+ emphasis: /([*_])(?=[^\s*_])([^\n*_]*?[^\s*_])\1/y,
89
+ escape: /\\([\\`*_{}[\]()#+\-.!>~|])/y,
90
+ image: /(!\[)([^\]\n]*)(\]\()([^)\s\n]*)(\))/y,
91
+ link: /(\[)([^\]\n]*)(\]\()([^)\s\n]*)(\))/y,
92
+ strikethrough: /(~~)(?=\S)([^\n]*?\S)\1/y,
93
+ strong: /(\*\*|__)(?=\S)([^\n]*?\S)\1/y,
94
+ };
95
+ const pushSpan = (spans, kind, text) => {
96
+ if (text === "") {
97
+ return;
98
+ }
99
+ const previous = spans.at(-1);
100
+ // Merged as they are pushed rather than in a second pass. The
101
+ // scanner emits one span per plain *character*, so without this a
102
+ // 200-character paragraph is 200 React elements and every
103
+ // keystroke reconciles all of them.
104
+ if (previous?.kind === kind) {
105
+ previous.text += text;
106
+ return;
107
+ }
108
+ spans.push({ kind, text });
109
+ };
110
+ /**
111
+ * The inline scanner.
112
+ *
113
+ * `baseKind` is what unmarked text becomes — `"plain"` in a
114
+ * paragraph, `"heading"` inside a heading — so a heading's words
115
+ * carry the heading colour while the `##` in front of them stays a
116
+ * marker.
117
+ */
118
+ export const toInlineSpans = (text, baseKind = "plain") => {
119
+ const spans = [];
120
+ let index = 0;
121
+ while (index < text.length) {
122
+ INLINE_PATTERNS.escape.lastIndex = index;
123
+ const escaped = INLINE_PATTERNS.escape.exec(text);
124
+ if (escaped) {
125
+ pushSpan(spans, "marker", "\\");
126
+ pushSpan(spans, baseKind, escaped[1] ?? "");
127
+ index += escaped[0].length;
128
+ continue;
129
+ }
130
+ INLINE_PATTERNS.code.lastIndex = index;
131
+ const code = INLINE_PATTERNS.code.exec(text);
132
+ if (code) {
133
+ pushSpan(spans, "marker", code[1] ?? "");
134
+ pushSpan(spans, "code", code[2] ?? "");
135
+ pushSpan(spans, "marker", code[1] ?? "");
136
+ index += code[0].length;
137
+ continue;
138
+ }
139
+ INLINE_PATTERNS.image.lastIndex = index;
140
+ const image = INLINE_PATTERNS.image.exec(text);
141
+ if (image) {
142
+ pushSpan(spans, "marker", image[1] ?? "");
143
+ pushSpan(spans, "link", image[2] ?? "");
144
+ pushSpan(spans, "marker", image[3] ?? "");
145
+ pushSpan(spans, "url", image[4] ?? "");
146
+ pushSpan(spans, "marker", image[5] ?? "");
147
+ index += image[0].length;
148
+ continue;
149
+ }
150
+ INLINE_PATTERNS.link.lastIndex = index;
151
+ const link = INLINE_PATTERNS.link.exec(text);
152
+ if (link) {
153
+ pushSpan(spans, "marker", link[1] ?? "");
154
+ pushSpan(spans, "link", link[2] ?? "");
155
+ pushSpan(spans, "marker", link[3] ?? "");
156
+ pushSpan(spans, "url", link[4] ?? "");
157
+ pushSpan(spans, "marker", link[5] ?? "");
158
+ index += link[0].length;
159
+ continue;
160
+ }
161
+ INLINE_PATTERNS.strong.lastIndex = index;
162
+ const strong = INLINE_PATTERNS.strong.exec(text);
163
+ if (strong) {
164
+ pushSpan(spans, "marker", strong[1] ?? "");
165
+ pushSpan(spans, "strong", strong[2] ?? "");
166
+ pushSpan(spans, "marker", strong[1] ?? "");
167
+ index += strong[0].length;
168
+ continue;
169
+ }
170
+ INLINE_PATTERNS.strikethrough.lastIndex = index;
171
+ const struck = INLINE_PATTERNS.strikethrough.exec(text);
172
+ if (struck) {
173
+ pushSpan(spans, "marker", struck[1] ?? "");
174
+ pushSpan(spans, "strikethrough", struck[2] ?? "");
175
+ pushSpan(spans, "marker", struck[1] ?? "");
176
+ index += struck[0].length;
177
+ continue;
178
+ }
179
+ INLINE_PATTERNS.emphasis.lastIndex = index;
180
+ const emphasised = INLINE_PATTERNS.emphasis.exec(text);
181
+ if (emphasised) {
182
+ pushSpan(spans, "marker", emphasised[1] ?? "");
183
+ pushSpan(spans, "emphasis", emphasised[2] ?? "");
184
+ pushSpan(spans, "marker", emphasised[1] ?? "");
185
+ index += emphasised[0].length;
186
+ continue;
187
+ }
188
+ pushSpan(spans, baseKind, text[index] ?? "");
189
+ index += 1;
190
+ }
191
+ return spans;
192
+ };
193
+ const toTableSpans = (text) => {
194
+ const spans = [];
195
+ for (const part of text.split(/(\|)/)) {
196
+ if (part === "|") {
197
+ pushSpan(spans, "marker", part);
198
+ continue;
199
+ }
200
+ for (const span of toInlineSpans(part)) {
201
+ pushSpan(spans, span.kind, span.text);
202
+ }
203
+ }
204
+ return spans;
205
+ };
206
+ const toBlockLine = (line) => {
207
+ const spans = [];
208
+ const indent = INDENT_PATTERN.exec(line)?.[0] ?? "";
209
+ pushSpan(spans, "plain", indent);
210
+ let rest = line.slice(indent.length);
211
+ const quote = BLOCKQUOTE_PATTERN.exec(rest)?.[0];
212
+ if (quote !== undefined) {
213
+ pushSpan(spans, "marker", quote);
214
+ rest = rest.slice(quote.length);
215
+ }
216
+ if (THEMATIC_BREAK_PATTERN.test(rest)) {
217
+ pushSpan(spans, "marker", rest);
218
+ return { kind: "thematicBreak", spans };
219
+ }
220
+ const heading = HEADING_PATTERN.exec(rest)?.[0];
221
+ if (heading !== undefined) {
222
+ pushSpan(spans, "marker", heading);
223
+ for (const span of toInlineSpans(rest.slice(heading.length), "heading")) {
224
+ pushSpan(spans, span.kind, span.text);
225
+ }
226
+ return { kind: "heading", spans };
227
+ }
228
+ const listMarker = LIST_MARKER_PATTERN.exec(rest)?.[0];
229
+ if (listMarker !== undefined) {
230
+ pushSpan(spans, "marker", listMarker);
231
+ rest = rest.slice(listMarker.length);
232
+ const taskMarker = TASK_MARKER_PATTERN.exec(rest)?.[0];
233
+ if (taskMarker !== undefined) {
234
+ pushSpan(spans, "marker", taskMarker);
235
+ rest = rest.slice(taskMarker.length);
236
+ }
237
+ for (const span of toInlineSpans(rest)) {
238
+ pushSpan(spans, span.kind, span.text);
239
+ }
240
+ return { kind: "list", spans };
241
+ }
242
+ if (rest.startsWith("|")) {
243
+ for (const span of toTableSpans(rest)) {
244
+ pushSpan(spans, span.kind, span.text);
245
+ }
246
+ return { kind: "table", spans };
247
+ }
248
+ for (const span of toInlineSpans(rest)) {
249
+ pushSpan(spans, span.kind, span.text);
250
+ }
251
+ return {
252
+ kind: quote === undefined ? "paragraph" : "blockquote",
253
+ spans,
254
+ };
255
+ };
256
+ /**
257
+ * The whole document, one entry per line.
258
+ *
259
+ * `text.split("\n")` on an empty string yields `[""]` — one empty
260
+ * line — which is right: an empty editor still has a line for the
261
+ * caret to sit on, and the painted layer still needs a row so the
262
+ * two layers agree about where line 0 is.
263
+ */
264
+ export const toMarkdownLines = (text) => {
265
+ let isInsideFence = false;
266
+ return text.split("\n").map((line) => {
267
+ if (FENCE_PATTERN.test(line)) {
268
+ isInsideFence = !isInsideFence;
269
+ return {
270
+ kind: "code",
271
+ spans: [{ kind: "marker", text: line }],
272
+ };
273
+ }
274
+ if (isInsideFence) {
275
+ return {
276
+ kind: "code",
277
+ spans: line === ""
278
+ ? []
279
+ : [{ kind: "code", text: line }],
280
+ };
281
+ }
282
+ return toBlockLine(line);
283
+ });
284
+ };
285
+ /**
286
+ * Which line the caret is on, from a character offset.
287
+ *
288
+ * The active line is the one construct in this editor that is
289
+ * *state* rather than syntax: its markers paint at full strength
290
+ * and every other line's fade back, which is the whole "raw syntax
291
+ * on the cursor's line" behaviour.
292
+ */
293
+ export const toLineIndex = (text, offset) => {
294
+ const clamped = Math.max(0, Math.min(offset, text.length));
295
+ let lineIndex = 0;
296
+ for (let index = 0; index < clamped; index += 1) {
297
+ if (text[index] === "\n") {
298
+ lineIndex += 1;
299
+ }
300
+ }
301
+ return lineIndex;
302
+ };
303
+ //# sourceMappingURL=markdownSpans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownSpans.js","sourceRoot":"","sources":["../../src/MarkdownEditor/markdownSpans.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,13 @@
1
- import type { ReactNode } from "react";
1
+ import type { ReactNode, RefObject } from "react";
2
2
  export type ModalProps = {
3
3
  "aria-label"?: string;
4
4
  "aria-labelledby"?: string;
5
5
  children: ReactNode;
6
6
  className?: string;
7
+ /** Which element takes the caret when the modal opens. Without
8
+ * it the focus manager takes the first tabbable element — the
9
+ * Close button on anything with chrome. */
10
+ initialFocus?: RefObject<HTMLElement | null>;
7
11
  /** Escape and a backdrop press both close. */
8
12
  isDismissable?: boolean;
9
13
  isVisible: boolean;
@@ -14,5 +18,5 @@ export type ModalProps = {
14
18
  onClose: () => void;
15
19
  role?: "alertdialog" | "dialog";
16
20
  };
17
- export declare const Modal: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, isDismissable, isVisible, onClose, role, }: ModalProps) => ReactNode;
21
+ export declare const Modal: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, initialFocus, isDismissable, isVisible, onClose, role, }: ModalProps) => ReactNode;
18
22
  //# sourceMappingURL=Modal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAA;CAChC,CAAA;AAqCD,eAAO,MAAM,KAAK,GAAI,+HASnB,UAAU,KAAG,SAYf,CAAA"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../src/Modal/Modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKjD,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;+CAE2C;IAC3C,YAAY,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC5C,8CAA8C;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAA;CAChC,CAAA;AAqCD,eAAO,MAAM,KAAK,GAAI,6IAUnB,UAAU,KAAG,SAaf,CAAA"}
@@ -34,5 +34,5 @@ import { toClassName } from "../toClassName.js";
34
34
  * and dismiss top-first.
35
35
  */
36
36
  const MODAL_BOX_CLASS = "flex max-h-[85dvh] flex-col overflow-hidden rounded-lg border border-border-default bg-surface-overlay text-content-primary shadow-high";
37
- export const Modal = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, isDismissable = true, isVisible, onClose, role = "dialog", }) => (_jsx(OverlayPanel, { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className: toClassName(MODAL_BOX_CLASS, className), isDismissable: isDismissable, isVisible: isVisible, onClose: onClose, role: role, children: children }));
37
+ export const Modal = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, initialFocus, isDismissable = true, isVisible, onClose, role = "dialog", }) => (_jsx(OverlayPanel, { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className: toClassName(MODAL_BOX_CLASS, className), initialFocus: initialFocus, isDismissable: isDismissable, isVisible: isVisible, onClose: onClose, role: role, children: children }));
38
38
  //# sourceMappingURL=Modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/Modal/Modal.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA6B,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAkB/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,eAAe,GACnB,yIAAyI,CAAA;AAE3I,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EACpB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,QAAQ,EACR,SAAS,EACT,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,OAAO,EACP,IAAI,GAAG,QAAQ,GACJ,EAAa,EAAE,CAAC,CAC3B,KAAC,YAAY,kBACC,SAAS,qBACJ,cAAc,EAC/B,SAAS,EAAE,WAAW,CAAC,eAAe,EAAE,SAAS,CAAC,EAClD,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,YAET,QAAQ,GACI,CAChB,CAAA"}
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/Modal/Modal.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA6B,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAsB/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,eAAe,GACnB,yIAAyI,CAAA;AAE3I,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EACpB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,aAAa,GAAG,IAAI,EACpB,SAAS,EACT,OAAO,EACP,IAAI,GAAG,QAAQ,GACJ,EAAa,EAAE,CAAC,CAC3B,KAAC,YAAY,kBACC,SAAS,qBACJ,cAAc,EAC/B,SAAS,EAAE,WAAW,CAAC,eAAe,EAAE,SAAS,CAAC,EAClD,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,YAET,QAAQ,GACI,CAChB,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import type { ReactNode, RefObject } from "react";
2
2
  /**
3
3
  * The portalled, backdrop-backed, focus-trapping panel that `Modal`
4
4
  * renders. No chrome — that is `Dialog`'s job — only the four things
@@ -40,11 +40,22 @@ export type OverlayPanelProps = {
40
40
  "aria-labelledby"?: string;
41
41
  children: ReactNode;
42
42
  className?: string;
43
+ /**
44
+ * Which element takes the caret when the panel opens.
45
+ *
46
+ * Without it the focus manager takes the first tabbable element,
47
+ * which for anything with chrome is the **Close button** — so a
48
+ * panel wrapping a form opens with the caret on "Close" and the
49
+ * first thing typed goes nowhere. A consumer cannot fix that from
50
+ * outside: focusing in its own effect races the manager, and the
51
+ * manager wins, which reads as the app ignoring you.
52
+ */
53
+ initialFocus?: RefObject<HTMLElement | null>;
43
54
  /** Escape and an outside press both close. */
44
55
  isDismissable?: boolean;
45
56
  isVisible: boolean;
46
57
  onClose: () => void;
47
58
  role?: "alertdialog" | "dialog";
48
59
  };
49
- export declare const OverlayPanel: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, isDismissable, isVisible, onClose, role, }: OverlayPanelProps) => ReactNode;
60
+ export declare const OverlayPanel: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, initialFocus, isDismissable, isVisible, onClose, role, }: OverlayPanelProps) => ReactNode;
50
61
  //# sourceMappingURL=OverlayPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayPanel.d.ts","sourceRoot":"","sources":["../../src/Overlay/OverlayPanel.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,+HAS1B,iBAAiB,KAAG,SAsHtB,CAAA"}
1
+ {"version":3,"file":"OverlayPanel.d.ts","sourceRoot":"","sources":["../../src/Overlay/OverlayPanel.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC5C,8CAA8C;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,IAAI,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,6IAU1B,iBAAiB,KAAG,SA0HtB,CAAA"}
@@ -5,7 +5,7 @@ import { useCallback, useEffect } from "react";
5
5
  import { lockScrollBehind } from "./lockScrollBehind.js";
6
6
  import { useOverlayStack } from "./OverlayStack.js";
7
7
  import { SharedBackdrop } from "./SharedBackdrop.js";
8
- export const OverlayPanel = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, isDismissable = true, isVisible, onClose, role = "dialog", }) => {
8
+ export const OverlayPanel = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children, className, initialFocus, isDismissable = true, isVisible, onClose, role = "dialog", }) => {
9
9
  const stack = useOverlayStack();
10
10
  const id = useUniqueId();
11
11
  // A stable close, so registering it does not churn the stack as the
@@ -59,6 +59,10 @@ export const OverlayPanel = ({ "aria-label": ariaLabel, "aria-labelledby": ariaL
59
59
  return null;
60
60
  }
61
61
  return (_jsxs(_Fragment, { children: [stack.isProvided ? null : (_jsx(SharedBackdrop, { isVisible: true })), _jsx(FloatingPortal, { children: _jsx("div", { className: "fixed inset-0 z-[var(--layer-modal)] flex items-center justify-center", children: _jsx(FloatingFocusManager, { context: context,
62
+ // `undefined` keeps the manager's own default (the first
63
+ // tabbable), so nothing changes for a panel that does not
64
+ // ask.
65
+ initialFocus: initialFocus ?? undefined,
62
66
  // Only the top traps focus; a lower panel is `inert`
63
67
  // anyway, and two live traps fight over one caret.
64
68
  disabled: !isTop, modal: true, children: _jsx("div", { ...getFloatingProps(), "aria-label": ariaLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayPanel.js","sourceRoot":"","sources":["../../src/Overlay/OverlayPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OverlayPanel.js","sourceRoot":"","sources":["../../src/Overlay/OverlayPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * One categorical index → class map, the twin of
3
+ * `intentStyles.ts`.
4
+ *
5
+ * Its own file rather than ten more entries in that one, because
6
+ * the two families are keyed by different things and mean different
7
+ * things. `intentStyles.ts` opens by explaining that it exists to
8
+ * delete rip-deck's duplicated `TONE_CLASS` — a *status* map, where
9
+ * every key is a claim about state. Nothing here is a claim about
10
+ * anything: an index is a user's pick for a label, and the only
11
+ * thing a component may do with it is paint it. Keeping them apart
12
+ * is also what keeps `IntentName` an exhaustive union that
13
+ * `getAsyncIntent` can switch over.
14
+ *
15
+ * **Every class name is written out in full, and that is not
16
+ * negotiable.** Tailwind v4 scans source text for *complete* class
17
+ * strings, so `` `bg-categorical-${index}-solid` `` generates
18
+ * nothing at all — the badge renders unstyled with no error, no
19
+ * warning, and no failing test unless something checks. Something
20
+ * does: `tailwindCandidates.test.ts` compiles every literal in this
21
+ * package through the real Tailwind and fails on any candidate it
22
+ * cannot generate. Forty lines of near-duplication is the price,
23
+ * and the alternative is the `--color-danger-9` that shipped in
24
+ * Docket: a token name that had never existed, resolving to
25
+ * nothing, painting transparent, and passing every assertion about
26
+ * whether the element was rendered.
27
+ */
28
+ import type { CategoricalIndex } from "@charcuterie/tokens";
29
+ import type { IntentAppearance } from "./intentStyles.ts";
30
+ export declare const CATEGORICAL_APPEARANCE_CLASS: Record<CategoricalIndex, Record<IntentAppearance, string>>;
31
+ /**
32
+ * Hover, split out for exactly the reason `INTENT_HOVER_CLASS` is:
33
+ * most things wearing a colour are not interactive. A label pill in
34
+ * a task list that lightens under the cursor is telling the user it
35
+ * can be clicked, and a `Badge` cannot be. So an interactive
36
+ * component opts in, and a static one cannot accidentally opt in.
37
+ *
38
+ * `solid` hovers toward `solidHover`, which for this family is
39
+ * **brighter** rather than deeper — the fill carries a near-black
40
+ * label, so it moves away from it in the opposite direction to an
41
+ * intent's white-labelled fill.
42
+ */
43
+ export declare const CATEGORICAL_HOVER_CLASS: Record<CategoricalIndex, Record<IntentAppearance, string>>;
44
+ /**
45
+ * The fill on its own, for the parts of a component that are a dot
46
+ * or a bar rather than a box — the swatch beside a label in a
47
+ * picker, a series marker on a chart. Same values, no border and no
48
+ * hover, because neither of those is a surface anyone can point at.
49
+ */
50
+ export declare const CATEGORICAL_SOLID_FILL_CLASS: Record<CategoricalIndex, string>;
51
+ /** The same ten as text, for a glyph or a dot's ring. */
52
+ export declare const CATEGORICAL_CONTENT_CLASS: Record<CategoricalIndex, string>;
53
+ //# sourceMappingURL=categoricalStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categoricalStyles.d.ts","sourceRoot":"","sources":["../src/categoricalStyles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAC/C,gBAAgB,EAChB,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CA4FjC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,gBAAgB,EAChB,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CA8DjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAC/C,gBAAgB,EAChB,MAAM,CAYP,CAAA;AAED,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAC5C,gBAAgB,EAChB,MAAM,CAYP,CAAA"}