@charcuterie/ui 3.19.1 → 3.20.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 (53) hide show
  1. package/dist/Board/BoardCard.d.ts +54 -5
  2. package/dist/Board/BoardCard.d.ts.map +1 -1
  3. package/dist/Board/BoardCard.js +2 -2
  4. package/dist/Board/BoardCard.js.map +1 -1
  5. package/dist/Combobox/Combobox.d.ts.map +1 -1
  6. package/dist/Combobox/Combobox.js +50 -1
  7. package/dist/Combobox/Combobox.js.map +1 -1
  8. package/dist/MarkdownEditor/markdownSpans.d.ts +17 -4
  9. package/dist/MarkdownEditor/markdownSpans.d.ts.map +1 -1
  10. package/dist/MarkdownEditor/markdownSpans.js.map +1 -1
  11. package/dist/MarkdownLine/MarkdownLine.d.ts +104 -0
  12. package/dist/MarkdownLine/MarkdownLine.d.ts.map +1 -0
  13. package/dist/MarkdownLine/MarkdownLine.js +187 -0
  14. package/dist/MarkdownLine/MarkdownLine.js.map +1 -0
  15. package/dist/MarkdownLine/inlineMarkdown.d.ts +82 -0
  16. package/dist/MarkdownLine/inlineMarkdown.d.ts.map +1 -0
  17. package/dist/MarkdownLine/inlineMarkdown.js +509 -0
  18. package/dist/MarkdownLine/inlineMarkdown.js.map +1 -0
  19. package/dist/index.d.ts +5 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/markdownEditorCodeMirror/index.d.ts +1 -1
  24. package/dist/markdownEditorCodeMirror/index.d.ts.map +1 -1
  25. package/dist/markdownEditorCodeMirror/index.js +1 -1
  26. package/dist/markdownEditorCodeMirror/index.js.map +1 -1
  27. package/dist/markdownEditorCodeMirror/livePreviewRanges.js +1 -1
  28. package/dist/markdownEditorCodeMirror/livePreviewRanges.js.map +1 -1
  29. package/dist/safeUrls.d.ts.map +1 -0
  30. package/dist/safeUrls.js.map +1 -0
  31. package/package.json +1 -1
  32. package/src/Board/Board.stories.tsx +67 -0
  33. package/src/Board/Board.test.tsx +35 -0
  34. package/src/Board/BoardCard.tsx +65 -10
  35. package/src/Combobox/Combobox.test.tsx +63 -0
  36. package/src/Combobox/Combobox.tsx +64 -1
  37. package/src/MarkdownEditor/markdownSpans.ts +18 -5
  38. package/src/MarkdownLine/MarkdownLine.mdx +135 -0
  39. package/src/MarkdownLine/MarkdownLine.stories.tsx +290 -0
  40. package/src/MarkdownLine/MarkdownLine.test.tsx +241 -0
  41. package/src/MarkdownLine/MarkdownLine.tsx +331 -0
  42. package/src/MarkdownLine/inlineMarkdown.test.ts +253 -0
  43. package/src/MarkdownLine/inlineMarkdown.ts +768 -0
  44. package/src/index.ts +9 -2
  45. package/src/markdownEditorCodeMirror/index.ts +4 -4
  46. package/src/markdownEditorCodeMirror/livePreviewRanges.ts +1 -1
  47. package/src/sourceRules.test.ts +17 -1
  48. package/dist/markdownEditorCodeMirror/safeUrls.d.ts.map +0 -1
  49. package/dist/markdownEditorCodeMirror/safeUrls.js.map +0 -1
  50. /package/dist/{markdownEditorCodeMirror/safeUrls.d.ts → safeUrls.d.ts} +0 -0
  51. /package/dist/{markdownEditorCodeMirror/safeUrls.js → safeUrls.js} +0 -0
  52. /package/src/{markdownEditorCodeMirror/safeUrls.test.ts → safeUrls.test.ts} +0 -0
  53. /package/src/{markdownEditorCodeMirror/safeUrls.ts → safeUrls.ts} +0 -0
@@ -0,0 +1,187 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Fragment } from "react";
3
+ import { FOCUS_RING_CLASS, INTENT_CONTENT_CLASS, } from "../intentStyles.js";
4
+ import { useRouterLink } from "../RouterLink/RouterLinkProvider.js";
5
+ import { getIsRoutedHref } from "../RouterLink/routerLink.js";
6
+ import { toClassName } from "../toClassName.js";
7
+ import { toInlineMarkdownRuns } from "./inlineMarkdown.js";
8
+ /**
9
+ * The link paint, matched to `.cm-md-link` in the CodeMirror
10
+ * surface's theme rather than to `TextLink`'s.
11
+ *
12
+ * `TextLink` would be the obvious reach and it is the wrong one: it
13
+ * declares `rounded-xs`, a cursor and a hover rule that belong to a
14
+ * link in a paragraph, and — the deciding one — it has no way to
15
+ * inherit the title's own weight, so a link inside a bold title
16
+ * would un-bold itself. Two rules is the whole of what is shared
17
+ * with `.cm-md-link`, and sharing them by value is what keeps the
18
+ * editor and the card showing one answer.
19
+ */
20
+ const LINK_CLASS = toClassName(INTENT_CONTENT_CLASS.accent, "underline decoration-1 underline-offset-2 hover:decoration-2", FOCUS_RING_CLASS);
21
+ /**
22
+ * `0.9em` and not a step on the type scale.
23
+ *
24
+ * A monospace face at the same `font-size` as the text around it
25
+ * reads bigger — fixed advance width, taller x-height — so a file
26
+ * name in a title would shout. `em` rather than a fixed size so a
27
+ * code span in a 24px heading and one in a 13px card row are both
28
+ * proportional to their line. This is `.cm-md-code`'s rule, copied
29
+ * by value for the same reason as the link's.
30
+ */
31
+ const CODE_CLASS = "font-mono text-[0.9em] text-intent-info-content";
32
+ /**
33
+ * Position IS the identity here, which is why every `key` in this
34
+ * file is an index.
35
+ *
36
+ * The usual objection to an index key does not reach this component.
37
+ * The list is a **pure function of `value`** — nothing inserts,
38
+ * removes or re-orders a run, and no run holds component state for a
39
+ * key to preserve — so two renders of the same string produce the
40
+ * same runs in the same order, and two renders of different strings
41
+ * are a different line entirely. Content cannot stand in for it: a
42
+ * title like `**Ship** it **Ship**` has two runs with identical text
43
+ * and identical marks, and keying by either would collide.
44
+ */
45
+ const toMarkedContent = (run, key) => {
46
+ /**
47
+ * AN UNMARKED RUN IS A TEXT NODE, NOT A WRAPPED ONE — and this is
48
+ * an accessibility fix rather than a saving.
49
+ *
50
+ * Every run used to come back inside a keyed `<span>`. It looked
51
+ * identical, and it silently broke every accessible name on the
52
+ * page: the name computation **trims** each element child's
53
+ * contribution before joining them, so
54
+ * `<span>Deduplicate </span><code>~/archive</code><span> by</span>`
55
+ * announces as `Deduplicate~/archiveby`. A text node keeps its
56
+ * spaces, so the same line as text-node / `<code>` / text-node
57
+ * announces correctly.
58
+ *
59
+ * Caught by `Board`'s move handle, which is named after the card's
60
+ * title. On screen the two are indistinguishable — the spaces are
61
+ * still painted either way — which is why `MarkdownLine.test.tsx`
62
+ * asserts the NAME rather than the text.
63
+ */
64
+ if (!run.isCode &&
65
+ !run.isEmphasis &&
66
+ !run.isStrikethrough &&
67
+ !run.isStrong) {
68
+ return run.text;
69
+ }
70
+ // Innermost first: the element that carries the text, then the
71
+ // marks wrapped around it. `<code>` is innermost because it is the
72
+ // only one that changes the *face* rather than a variation of it.
73
+ let content = run.isCode ? (_jsx("code", { className: CODE_CLASS, children: run.text })) : (run.text);
74
+ if (run.isEmphasis) {
75
+ content = _jsx("em", { children: content });
76
+ }
77
+ if (run.isStrong) {
78
+ content = _jsx("strong", { children: content });
79
+ }
80
+ if (run.isStrikethrough) {
81
+ // `<s>`, not `<del>`. `<del>` means "removed from the document"
82
+ // and carries an editorial history a title does not have; `<s>`
83
+ // is "no longer accurate", which is what a struck-through task
84
+ // name says.
85
+ content = (_jsx("s", { className: "text-content-secondary", children: content }));
86
+ }
87
+ // A `Fragment` rather than a `<span>`: it carries the key React
88
+ // needs for an array child and adds no element to the DOM, so the
89
+ // mark element sits directly inside the anchor and the name
90
+ // computation sees no extra boundary to trim.
91
+ return _jsx(Fragment, { children: content }, key);
92
+ };
93
+ /**
94
+ * One line of markdown, drawn with its inline marks and nothing
95
+ * else.
96
+ *
97
+ * A **title** is what this is for. Docket's cards carry names like
98
+ * ``Ingest 53 movies from `Downloads/MOVIES` into `G:\Movies` ``,
99
+ * and a grid of them set in one flat weight is a wall the eye cannot
100
+ * scan — the parts that differ between two cards are exactly the
101
+ * parts markdown would have marked. So the marks earn their place
102
+ * by making a list of names *scannable*, which is the same argument
103
+ * as the priority bar and the project colour, one layer down.
104
+ *
105
+ * ### It is not a small `MarkdownView`
106
+ *
107
+ * `MarkdownView` renders a document, through CodeMirror, from the
108
+ * optional `@charcuterie/ui/markdown-editor-codemirror` entry point.
109
+ * Neither half of that suits a name: an editor state and a syntax
110
+ * tree per card is an absurd price for forty characters, and the
111
+ * main entry may not reach the CodeMirror stack at all. This parses
112
+ * the inline grammar directly and returns spans.
113
+ *
114
+ * The two therefore have to agree, and `inlineMarkdown.ts` says how
115
+ * that is kept true — most importantly that both call the **same**
116
+ * URL guard, `safeUrls.ts`, which moved up out of the CodeMirror
117
+ * subpath when this landed.
118
+ *
119
+ * ### The `href` prop is the load-bearing one
120
+ *
121
+ * A card title is usually itself a link. A title may also *contain*
122
+ * one. Nested anchors are invalid HTML and the browser silently
123
+ * closes the outer element, so `href` makes the component emit
124
+ * **siblings** — the plain runs anchored to `href`, the markdown
125
+ * links anchored to their own destination — which reads as one
126
+ * continuous line and behaves as two different destinations.
127
+ *
128
+ * ```tsx
129
+ * <MarkdownLine href={`/tasks/${task.id}`} value={task.title} />
130
+ * ```
131
+ *
132
+ * Anywhere a *string* is required — an `aria-label`, a `title`
133
+ * attribute, `document.title` — call `toPlainMarkdownText` rather
134
+ * than re-stripping the markup with a regex of your own. It is the
135
+ * same parse, so it cannot drift from what is on screen.
136
+ */
137
+ export const MarkdownLine = ({ className, href, isInsideLink = false, value, }) => {
138
+ const RouterLink = useRouterLink();
139
+ const runs = toInlineMarkdownRuns(value);
140
+ /**
141
+ * Consecutive runs that share a destination become **one** anchor.
142
+ *
143
+ * Not cosmetic: an anchor per run would make `**Ship** it` two tab
144
+ * stops and two entries in a screen reader's link list for one
145
+ * destination, and would break the hover underline into pieces at
146
+ * every mark boundary.
147
+ */
148
+ const groups = [];
149
+ for (const run of runs) {
150
+ const last = groups.at(-1);
151
+ if (last && last.href === run.href) {
152
+ last.runs.push(run);
153
+ continue;
154
+ }
155
+ groups.push({
156
+ ...(run.href === undefined ? {} : { href: run.href }),
157
+ runs: [run],
158
+ });
159
+ }
160
+ return (_jsx("span", { className: className, children: groups.map((group, groupIndex) => {
161
+ const content = group.runs.map(toMarkedContent);
162
+ if (isInsideLink) {
163
+ // No anchor, and no link paint either: a word painted as
164
+ // a link that cannot be followed is worse than plain text.
165
+ return (_jsx(Fragment
166
+ // biome-ignore lint/suspicious/noArrayIndexKey: position is the identity — see `toMarkedContent`
167
+ , { children: content }, groupIndex));
168
+ }
169
+ if (group.href !== undefined) {
170
+ // A destination the injected router cannot serve opens in
171
+ // a new tab rather than replacing the app: a title that
172
+ // names a pull request is a reference, and following it
173
+ // should not lose the board the reader was on.
174
+ const isRouted = getIsRoutedHref(group.href);
175
+ const LinkElement = isRouted ? RouterLink : "a";
176
+ return (_jsx(LinkElement, { className: LINK_CLASS, href: group.href, rel: isRouted ? undefined : "noopener noreferrer", target: isRouted ? undefined : "_blank", children: content }, groupIndex));
177
+ }
178
+ if (href === undefined) {
179
+ // biome-ignore lint/suspicious/noArrayIndexKey: position is the identity — see `toMarkedContent`
180
+ return _jsx("span", { children: content }, groupIndex);
181
+ }
182
+ const isRouted = getIsRoutedHref(href);
183
+ const LinkElement = isRouted ? RouterLink : "a";
184
+ return (_jsx(LinkElement, { className: toClassName("hover:underline", FOCUS_RING_CLASS), href: href, children: content }, groupIndex));
185
+ }) }));
186
+ };
187
+ //# sourceMappingURL=MarkdownLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownLine.js","sourceRoot":"","sources":["../../src/MarkdownLine/MarkdownLine.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Markdown's **inline** half, parsed into flat runs of marked text.
3
+ *
4
+ * ### Why this is not the CodeMirror parser
5
+ *
6
+ * `@charcuterie/ui/markdown-editor-codemirror` already renders
7
+ * markdown, through `@lezer/markdown`. It is the right answer for a
8
+ * document and the wrong one for a **name**: an editor instance per
9
+ * card is a CodeMirror state, a view, a syntax tree and a decoration
10
+ * set for a string that is usually under sixty characters, and a
11
+ * backlog grid draws dozens of them at once. The whole CodeMirror
12
+ * stack is also an *optional peer* of this package on purpose — the
13
+ * main entry may not reach it, so a title renderer that lives in the
14
+ * main entry cannot borrow it even if the cost were acceptable.
15
+ *
16
+ * So this is a second parser, which is a thing to be nervous about:
17
+ * two parsers are two answers to "what does this markdown mean", and
18
+ * that divergence is exactly the bug the consumer's
19
+ * renderer-agreement test exists to catch. Three things keep it
20
+ * honest:
21
+ *
22
+ * 1. **It is inline-only, and says so.** A `#`, a `>`, a `|` table
23
+ * row and a `- ` list marker are literal characters here. There
24
+ * is no block level to disagree about, because there is no block
25
+ * level.
26
+ * 2. **The URL guard is shared, not copied.** Both surfaces call
27
+ * `toSafeLinkUrl` from `../safeUrls.ts` — one module, one
28
+ * allowlist. It moved up out of the CodeMirror subpath when this
29
+ * landed, for that reason.
30
+ * 3. **The flanking rules are CommonMark's**, not a convenient
31
+ * approximation. That is what makes `ingest_the_files.sh` a file
32
+ * name rather than a title with an italic word in the middle of
33
+ * it, and file names in titles are the case this was built for.
34
+ *
35
+ * ### The shape it produces
36
+ *
37
+ * A **flat** list of runs, not a tree. Marks compose by set union, so
38
+ * `**bold [link](/x) tail**` is three runs that all carry `isStrong`
39
+ * and of which one carries an `href` — which is precisely the shape
40
+ * `MarkdownLine` needs to render a link *beside* the surrounding
41
+ * anchor rather than inside it. A tree would have to be flattened
42
+ * back into this before it could be drawn.
43
+ */
44
+ /**
45
+ * One run of text, with every mark that covers it.
46
+ *
47
+ * `href` is present only on a run that came from `[text](url)` or
48
+ * from a bare URL — never inherited from the caller's own link. Who
49
+ * the *plain* text points at is `MarkdownLine`'s question, not the
50
+ * parser's.
51
+ */
52
+ export type InlineMarkdownRun = {
53
+ href?: string;
54
+ isCode: boolean;
55
+ isEmphasis: boolean;
56
+ isStrikethrough: boolean;
57
+ isStrong: boolean;
58
+ text: string;
59
+ };
60
+ /**
61
+ * The inline runs of `value`, in order.
62
+ *
63
+ * Exported because a consumer occasionally needs the runs without
64
+ * React — Docket's search highlighter walks them to find which run a
65
+ * match landed in — and because it is the seam every test in this
66
+ * directory drives.
67
+ */
68
+ export declare const toInlineMarkdownRuns: (value: string) => InlineMarkdownRun[];
69
+ /**
70
+ * The same string with its markers **gone** — what the title says,
71
+ * with nothing about how it is painted.
72
+ *
73
+ * This is not a convenience. Every `aria-label`, `title` attribute,
74
+ * `document.title` and confirmation sentence that names a task needs
75
+ * the words without the punctuation, and deriving it from the same
76
+ * parse is the only way it cannot drift from what is on screen. A
77
+ * second regex that "strips markdown" is how the card comes to read
78
+ * `Ingest 53 movies` while the tooltip reads
79
+ * `Ingest 53 movies from ⁠`Downloads/MOVIES⁠``.
80
+ */
81
+ export declare const toPlainMarkdownText: (value: string) => string;
82
+ //# sourceMappingURL=inlineMarkdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inlineMarkdown.d.ts","sourceRoot":"","sources":["../../src/MarkdownLine/inlineMarkdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAIH;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,OAAO,CAAA;IACnB,eAAe,EAAE,OAAO,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAoqBD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,MAAM,KACZ,iBAAiB,EAC8B,CAAA;AAElD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,KACZ,MAGU,CAAA"}