@charcuterie/ui 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/Badge/Badge.d.ts +33 -3
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +20 -2
- package/dist/Badge/Badge.js.map +1 -1
- package/dist/Board/Board.d.ts +119 -0
- package/dist/Board/Board.d.ts.map +1 -0
- package/dist/Board/Board.js +165 -0
- package/dist/Board/Board.js.map +1 -0
- package/dist/Board/BoardCard.d.ts +120 -0
- package/dist/Board/BoardCard.d.ts.map +1 -0
- package/dist/Board/BoardCard.js +77 -0
- package/dist/Board/BoardCard.js.map +1 -0
- package/dist/Board/BoardLaneList.d.ts +103 -0
- package/dist/Board/BoardLaneList.d.ts.map +1 -0
- package/dist/Board/BoardLaneList.js +69 -0
- package/dist/Board/BoardLaneList.js.map +1 -0
- package/dist/Board/boardMove.d.ts +116 -0
- package/dist/Board/boardMove.d.ts.map +1 -0
- package/dist/Board/boardMove.js +116 -0
- package/dist/Board/boardMove.js.map +1 -0
- package/dist/Board/useBoardDrag.d.ts +44 -0
- package/dist/Board/useBoardDrag.d.ts.map +1 -0
- package/dist/Board/useBoardDrag.js +237 -0
- package/dist/Board/useBoardDrag.js.map +1 -0
- package/dist/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox/Checkbox.js +15 -4
- package/dist/Checkbox/Checkbox.js.map +1 -1
- package/dist/DataTable/DataTable.d.ts +159 -0
- package/dist/DataTable/DataTable.d.ts.map +1 -0
- package/dist/DataTable/DataTable.js +197 -0
- package/dist/DataTable/DataTable.js.map +1 -0
- package/dist/DatePicker/DateGrid.d.ts +79 -0
- package/dist/DatePicker/DateGrid.d.ts.map +1 -0
- package/dist/DatePicker/DateGrid.js +220 -0
- package/dist/DatePicker/DateGrid.js.map +1 -0
- package/dist/DatePicker/DatePicker.d.ts +138 -0
- package/dist/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/DatePicker/DatePicker.js +384 -0
- package/dist/DatePicker/DatePicker.js.map +1 -0
- package/dist/DatePicker/datePresets.d.ts +29 -0
- package/dist/DatePicker/datePresets.d.ts.map +1 -0
- package/dist/DatePicker/datePresets.js +28 -0
- package/dist/DatePicker/datePresets.js.map +1 -0
- package/dist/DatePicker/parseDateInput.d.ts +106 -0
- package/dist/DatePicker/parseDateInput.d.ts.map +1 -0
- package/dist/DatePicker/parseDateInput.js +419 -0
- package/dist/DatePicker/parseDateInput.js.map +1 -0
- package/dist/DatePicker/plainDate.d.ts +167 -0
- package/dist/DatePicker/plainDate.d.ts.map +1 -0
- package/dist/DatePicker/plainDate.js +272 -0
- package/dist/DatePicker/plainDate.js.map +1 -0
- package/dist/MarkdownEditor/MarkdownEditor.d.ts +147 -0
- package/dist/MarkdownEditor/MarkdownEditor.d.ts.map +1 -0
- package/dist/MarkdownEditor/MarkdownEditor.js +492 -0
- package/dist/MarkdownEditor/MarkdownEditor.js.map +1 -0
- package/dist/MarkdownEditor/markdownCommands.d.ts +202 -0
- package/dist/MarkdownEditor/markdownCommands.d.ts.map +1 -0
- package/dist/MarkdownEditor/markdownCommands.js +379 -0
- package/dist/MarkdownEditor/markdownCommands.js.map +1 -0
- package/dist/MarkdownEditor/markdownSpans.d.ts +92 -0
- package/dist/MarkdownEditor/markdownSpans.d.ts.map +1 -0
- package/dist/MarkdownEditor/markdownSpans.js +303 -0
- package/dist/MarkdownEditor/markdownSpans.js.map +1 -0
- package/dist/categoricalStyles.d.ts +53 -0
- package/dist/categoricalStyles.d.ts.map +1 -0
- package/dist/categoricalStyles.js +195 -0
- package/dist/categoricalStyles.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/Badge/Badge.mdx +46 -0
- package/src/Badge/Badge.stories.tsx +98 -4
- package/src/Badge/Badge.test.tsx +157 -2
- package/src/Badge/Badge.tsx +49 -3
- package/src/Board/Board.mdx +199 -0
- package/src/Board/Board.stories.tsx +707 -0
- package/src/Board/Board.test.tsx +310 -0
- package/src/Board/Board.tsx +333 -0
- package/src/Board/BoardCard.tsx +290 -0
- package/src/Board/BoardLaneList.tsx +275 -0
- package/src/Board/boardMove.test.ts +213 -0
- package/src/Board/boardMove.ts +225 -0
- package/src/Board/useBoardDrag.ts +413 -0
- package/src/Checkbox/Checkbox.tsx +34 -3
- package/src/DataTable/DataTable.mdx +123 -0
- package/src/DataTable/DataTable.stories.tsx +411 -0
- package/src/DataTable/DataTable.test.tsx +386 -0
- package/src/DataTable/DataTable.tsx +497 -0
- package/src/DatePicker/DateGrid.tsx +467 -0
- package/src/DatePicker/DatePicker.mdx +170 -0
- package/src/DatePicker/DatePicker.stories.tsx +268 -0
- package/src/DatePicker/DatePicker.test.tsx +455 -0
- package/src/DatePicker/DatePicker.tsx +852 -0
- package/src/DatePicker/datePresets.ts +34 -0
- package/src/DatePicker/parseDateInput.test.ts +187 -0
- package/src/DatePicker/parseDateInput.ts +629 -0
- package/src/DatePicker/plainDate.test.ts +375 -0
- package/src/DatePicker/plainDate.ts +465 -0
- package/src/MarkdownEditor/MarkdownEditor.mdx +189 -0
- package/src/MarkdownEditor/MarkdownEditor.stories.tsx +267 -0
- package/src/MarkdownEditor/MarkdownEditor.test.tsx +627 -0
- package/src/MarkdownEditor/MarkdownEditor.tsx +862 -0
- package/src/MarkdownEditor/markdownCommands.test.ts +384 -0
- package/src/MarkdownEditor/markdownCommands.ts +566 -0
- package/src/MarkdownEditor/markdownSpans.test.ts +217 -0
- package/src/MarkdownEditor/markdownSpans.ts +458 -0
- package/src/argTypes.storyHelpers.ts +39 -0
- package/src/categoricalStyles.ts +244 -0
- package/src/index.ts +89 -0
- 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 `` 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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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
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
|
+
export const CATEGORICAL_APPEARANCE_CLASS = {
|
|
29
|
+
1: {
|
|
30
|
+
ghost: "border-transparent bg-transparent text-categorical-1-content",
|
|
31
|
+
outline: "border-categorical-1-border bg-transparent text-categorical-1-content",
|
|
32
|
+
soft: "border-categorical-1-border bg-categorical-1-surface text-categorical-1-content",
|
|
33
|
+
solid: "border-transparent bg-categorical-1-solid text-categorical-1-on-solid",
|
|
34
|
+
},
|
|
35
|
+
2: {
|
|
36
|
+
ghost: "border-transparent bg-transparent text-categorical-2-content",
|
|
37
|
+
outline: "border-categorical-2-border bg-transparent text-categorical-2-content",
|
|
38
|
+
soft: "border-categorical-2-border bg-categorical-2-surface text-categorical-2-content",
|
|
39
|
+
solid: "border-transparent bg-categorical-2-solid text-categorical-2-on-solid",
|
|
40
|
+
},
|
|
41
|
+
3: {
|
|
42
|
+
ghost: "border-transparent bg-transparent text-categorical-3-content",
|
|
43
|
+
outline: "border-categorical-3-border bg-transparent text-categorical-3-content",
|
|
44
|
+
soft: "border-categorical-3-border bg-categorical-3-surface text-categorical-3-content",
|
|
45
|
+
solid: "border-transparent bg-categorical-3-solid text-categorical-3-on-solid",
|
|
46
|
+
},
|
|
47
|
+
4: {
|
|
48
|
+
ghost: "border-transparent bg-transparent text-categorical-4-content",
|
|
49
|
+
outline: "border-categorical-4-border bg-transparent text-categorical-4-content",
|
|
50
|
+
soft: "border-categorical-4-border bg-categorical-4-surface text-categorical-4-content",
|
|
51
|
+
solid: "border-transparent bg-categorical-4-solid text-categorical-4-on-solid",
|
|
52
|
+
},
|
|
53
|
+
5: {
|
|
54
|
+
ghost: "border-transparent bg-transparent text-categorical-5-content",
|
|
55
|
+
outline: "border-categorical-5-border bg-transparent text-categorical-5-content",
|
|
56
|
+
soft: "border-categorical-5-border bg-categorical-5-surface text-categorical-5-content",
|
|
57
|
+
solid: "border-transparent bg-categorical-5-solid text-categorical-5-on-solid",
|
|
58
|
+
},
|
|
59
|
+
6: {
|
|
60
|
+
ghost: "border-transparent bg-transparent text-categorical-6-content",
|
|
61
|
+
outline: "border-categorical-6-border bg-transparent text-categorical-6-content",
|
|
62
|
+
soft: "border-categorical-6-border bg-categorical-6-surface text-categorical-6-content",
|
|
63
|
+
solid: "border-transparent bg-categorical-6-solid text-categorical-6-on-solid",
|
|
64
|
+
},
|
|
65
|
+
7: {
|
|
66
|
+
ghost: "border-transparent bg-transparent text-categorical-7-content",
|
|
67
|
+
outline: "border-categorical-7-border bg-transparent text-categorical-7-content",
|
|
68
|
+
soft: "border-categorical-7-border bg-categorical-7-surface text-categorical-7-content",
|
|
69
|
+
solid: "border-transparent bg-categorical-7-solid text-categorical-7-on-solid",
|
|
70
|
+
},
|
|
71
|
+
8: {
|
|
72
|
+
ghost: "border-transparent bg-transparent text-categorical-8-content",
|
|
73
|
+
outline: "border-categorical-8-border bg-transparent text-categorical-8-content",
|
|
74
|
+
soft: "border-categorical-8-border bg-categorical-8-surface text-categorical-8-content",
|
|
75
|
+
solid: "border-transparent bg-categorical-8-solid text-categorical-8-on-solid",
|
|
76
|
+
},
|
|
77
|
+
9: {
|
|
78
|
+
ghost: "border-transparent bg-transparent text-categorical-9-content",
|
|
79
|
+
outline: "border-categorical-9-border bg-transparent text-categorical-9-content",
|
|
80
|
+
soft: "border-categorical-9-border bg-categorical-9-surface text-categorical-9-content",
|
|
81
|
+
solid: "border-transparent bg-categorical-9-solid text-categorical-9-on-solid",
|
|
82
|
+
},
|
|
83
|
+
10: {
|
|
84
|
+
ghost: "border-transparent bg-transparent text-categorical-10-content",
|
|
85
|
+
outline: "border-categorical-10-border bg-transparent text-categorical-10-content",
|
|
86
|
+
soft: "border-categorical-10-border bg-categorical-10-surface text-categorical-10-content",
|
|
87
|
+
solid: "border-transparent bg-categorical-10-solid text-categorical-10-on-solid",
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Hover, split out for exactly the reason `INTENT_HOVER_CLASS` is:
|
|
92
|
+
* most things wearing a colour are not interactive. A label pill in
|
|
93
|
+
* a task list that lightens under the cursor is telling the user it
|
|
94
|
+
* can be clicked, and a `Badge` cannot be. So an interactive
|
|
95
|
+
* component opts in, and a static one cannot accidentally opt in.
|
|
96
|
+
*
|
|
97
|
+
* `solid` hovers toward `solidHover`, which for this family is
|
|
98
|
+
* **brighter** rather than deeper — the fill carries a near-black
|
|
99
|
+
* label, so it moves away from it in the opposite direction to an
|
|
100
|
+
* intent's white-labelled fill.
|
|
101
|
+
*/
|
|
102
|
+
export const CATEGORICAL_HOVER_CLASS = {
|
|
103
|
+
1: {
|
|
104
|
+
ghost: "hover:bg-categorical-1-surface",
|
|
105
|
+
outline: "hover:bg-categorical-1-surface",
|
|
106
|
+
soft: "hover:bg-categorical-1-surface-hover",
|
|
107
|
+
solid: "hover:bg-categorical-1-solid-hover",
|
|
108
|
+
},
|
|
109
|
+
2: {
|
|
110
|
+
ghost: "hover:bg-categorical-2-surface",
|
|
111
|
+
outline: "hover:bg-categorical-2-surface",
|
|
112
|
+
soft: "hover:bg-categorical-2-surface-hover",
|
|
113
|
+
solid: "hover:bg-categorical-2-solid-hover",
|
|
114
|
+
},
|
|
115
|
+
3: {
|
|
116
|
+
ghost: "hover:bg-categorical-3-surface",
|
|
117
|
+
outline: "hover:bg-categorical-3-surface",
|
|
118
|
+
soft: "hover:bg-categorical-3-surface-hover",
|
|
119
|
+
solid: "hover:bg-categorical-3-solid-hover",
|
|
120
|
+
},
|
|
121
|
+
4: {
|
|
122
|
+
ghost: "hover:bg-categorical-4-surface",
|
|
123
|
+
outline: "hover:bg-categorical-4-surface",
|
|
124
|
+
soft: "hover:bg-categorical-4-surface-hover",
|
|
125
|
+
solid: "hover:bg-categorical-4-solid-hover",
|
|
126
|
+
},
|
|
127
|
+
5: {
|
|
128
|
+
ghost: "hover:bg-categorical-5-surface",
|
|
129
|
+
outline: "hover:bg-categorical-5-surface",
|
|
130
|
+
soft: "hover:bg-categorical-5-surface-hover",
|
|
131
|
+
solid: "hover:bg-categorical-5-solid-hover",
|
|
132
|
+
},
|
|
133
|
+
6: {
|
|
134
|
+
ghost: "hover:bg-categorical-6-surface",
|
|
135
|
+
outline: "hover:bg-categorical-6-surface",
|
|
136
|
+
soft: "hover:bg-categorical-6-surface-hover",
|
|
137
|
+
solid: "hover:bg-categorical-6-solid-hover",
|
|
138
|
+
},
|
|
139
|
+
7: {
|
|
140
|
+
ghost: "hover:bg-categorical-7-surface",
|
|
141
|
+
outline: "hover:bg-categorical-7-surface",
|
|
142
|
+
soft: "hover:bg-categorical-7-surface-hover",
|
|
143
|
+
solid: "hover:bg-categorical-7-solid-hover",
|
|
144
|
+
},
|
|
145
|
+
8: {
|
|
146
|
+
ghost: "hover:bg-categorical-8-surface",
|
|
147
|
+
outline: "hover:bg-categorical-8-surface",
|
|
148
|
+
soft: "hover:bg-categorical-8-surface-hover",
|
|
149
|
+
solid: "hover:bg-categorical-8-solid-hover",
|
|
150
|
+
},
|
|
151
|
+
9: {
|
|
152
|
+
ghost: "hover:bg-categorical-9-surface",
|
|
153
|
+
outline: "hover:bg-categorical-9-surface",
|
|
154
|
+
soft: "hover:bg-categorical-9-surface-hover",
|
|
155
|
+
solid: "hover:bg-categorical-9-solid-hover",
|
|
156
|
+
},
|
|
157
|
+
10: {
|
|
158
|
+
ghost: "hover:bg-categorical-10-surface",
|
|
159
|
+
outline: "hover:bg-categorical-10-surface",
|
|
160
|
+
soft: "hover:bg-categorical-10-surface-hover",
|
|
161
|
+
solid: "hover:bg-categorical-10-solid-hover",
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* The fill on its own, for the parts of a component that are a dot
|
|
166
|
+
* or a bar rather than a box — the swatch beside a label in a
|
|
167
|
+
* picker, a series marker on a chart. Same values, no border and no
|
|
168
|
+
* hover, because neither of those is a surface anyone can point at.
|
|
169
|
+
*/
|
|
170
|
+
export const CATEGORICAL_SOLID_FILL_CLASS = {
|
|
171
|
+
1: "bg-categorical-1-solid",
|
|
172
|
+
2: "bg-categorical-2-solid",
|
|
173
|
+
3: "bg-categorical-3-solid",
|
|
174
|
+
4: "bg-categorical-4-solid",
|
|
175
|
+
5: "bg-categorical-5-solid",
|
|
176
|
+
6: "bg-categorical-6-solid",
|
|
177
|
+
7: "bg-categorical-7-solid",
|
|
178
|
+
8: "bg-categorical-8-solid",
|
|
179
|
+
9: "bg-categorical-9-solid",
|
|
180
|
+
10: "bg-categorical-10-solid",
|
|
181
|
+
};
|
|
182
|
+
/** The same ten as text, for a glyph or a dot's ring. */
|
|
183
|
+
export const CATEGORICAL_CONTENT_CLASS = {
|
|
184
|
+
1: "text-categorical-1-content",
|
|
185
|
+
2: "text-categorical-2-content",
|
|
186
|
+
3: "text-categorical-3-content",
|
|
187
|
+
4: "text-categorical-4-content",
|
|
188
|
+
5: "text-categorical-5-content",
|
|
189
|
+
6: "text-categorical-6-content",
|
|
190
|
+
7: "text-categorical-7-content",
|
|
191
|
+
8: "text-categorical-8-content",
|
|
192
|
+
9: "text-categorical-9-content",
|
|
193
|
+
10: "text-categorical-10-content",
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=categoricalStyles.js.map
|