@soroush.tech/markdown 0.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/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/CodeBlock-CVlrvVPP.mjs +159 -0
- package/dist/CodeBlock-Cymx1ZAY.cjs +176 -0
- package/dist/CodeBlock.cjs +5 -0
- package/dist/CodeBlock.d.cts +2 -0
- package/dist/CodeBlock.d.mts +2 -0
- package/dist/CodeBlock.mjs +2 -0
- package/dist/Control.cjs +61 -0
- package/dist/Control.d.cts +18 -0
- package/dist/Control.d.mts +18 -0
- package/dist/Control.mjs +60 -0
- package/dist/Editor.cjs +129 -0
- package/dist/Editor.d.cts +40 -0
- package/dist/Editor.d.mts +40 -0
- package/dist/Editor.mjs +128 -0
- package/dist/MarkdownContext.cjs +13 -0
- package/dist/MarkdownContext.d.cts +2 -0
- package/dist/MarkdownContext.d.mts +2 -0
- package/dist/MarkdownContext.mjs +11 -0
- package/dist/Mermaid-BclI9A7e.mjs +231 -0
- package/dist/Mermaid-DqP2Q0bt.cjs +236 -0
- package/dist/Mermaid.cjs +3 -0
- package/dist/Mermaid.d.cts +2 -0
- package/dist/Mermaid.d.mts +2 -0
- package/dist/Mermaid.mjs +2 -0
- package/dist/Preview-BVT70uXa.cjs +276 -0
- package/dist/Preview-C1CwRDj5.mjs +246 -0
- package/dist/Preview.cjs +3 -0
- package/dist/Preview.d.cts +53 -0
- package/dist/Preview.d.mts +53 -0
- package/dist/Preview.mjs +2 -0
- package/dist/Toolbar-Ba3l-oBU.cjs +600 -0
- package/dist/Toolbar-C0SNI-JK.mjs +589 -0
- package/dist/Toolbar.cjs +4 -0
- package/dist/Toolbar.d.cts +13 -0
- package/dist/Toolbar.d.mts +13 -0
- package/dist/Toolbar.mjs +2 -0
- package/dist/applyAction-BDkgYhOd.cjs +120 -0
- package/dist/applyAction-BGWMbUYT.mjs +115 -0
- package/dist/index-BO0LyUUG.d.cts +27 -0
- package/dist/index-BO0LyUUG.d.mts +27 -0
- package/dist/index-BtMTBOcM.d.cts +48 -0
- package/dist/index-BtMTBOcM.d.mts +48 -0
- package/dist/index-rGZIhUgj.d.cts +76 -0
- package/dist/index-rGZIhUgj.d.mts +76 -0
- package/dist/index.cjs +19 -0
- package/dist/index.d.cts +50 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.mjs +8 -0
- package/package.json +110 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
const require_MarkdownContext = require("./MarkdownContext.cjs");
|
|
2
|
+
let react = require("react");
|
|
3
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
|
+
let _soroush_tech_design_system_Button = require("@soroush.tech/design-system/Button");
|
|
5
|
+
let _soroush_tech_design_system_ButtonGroup = require("@soroush.tech/design-system/ButtonGroup");
|
|
6
|
+
let _soroush_tech_design_system_Flex = require("@soroush.tech/design-system/Flex");
|
|
7
|
+
let _soroush_tech_design_system_Icon = require("@soroush.tech/design-system/Icon");
|
|
8
|
+
let _soroush_tech_design_system_NativeSelect = require("@soroush.tech/design-system/NativeSelect");
|
|
9
|
+
let _soroush_tech_design_system_Typography = require("@soroush.tech/design-system/Typography");
|
|
10
|
+
let _soroush_tech_design_system = require("@soroush.tech/design-system");
|
|
11
|
+
let _soroush_tech_design_system_theme = require("@soroush.tech/design-system/theme");
|
|
12
|
+
let _soroush_tech_design_system_Popover = require("@soroush.tech/design-system/Popover");
|
|
13
|
+
//#region src/utils/buildTableSnippet.ts
|
|
14
|
+
/**
|
|
15
|
+
* Builds a GFM table snippet with `rows` total rows (a header row plus `rows - 1` body rows)
|
|
16
|
+
* and `cols` columns, wrapped in blank lines so it sits on its own block.
|
|
17
|
+
*/
|
|
18
|
+
function buildTableSnippet(rows, cols) {
|
|
19
|
+
const row = (cell) => `| ${Array.from({ length: cols }, (_, index) => cell(index)).join(" | ")} |`;
|
|
20
|
+
return `\n${[
|
|
21
|
+
row((index) => `Column ${index + 1}`),
|
|
22
|
+
row(() => "---"),
|
|
23
|
+
...Array.from({ length: rows - 1 }, () => row(() => "Cell"))
|
|
24
|
+
].join("\n")}\n`;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/utils/groupToolbarActions.ts
|
|
28
|
+
/**
|
|
29
|
+
* Splits actions into render segments: consecutive actions sharing a `group` id collapse into
|
|
30
|
+
* one segment (rendered as a joined `ButtonGroup`); ungrouped actions each get their own.
|
|
31
|
+
*/
|
|
32
|
+
function groupToolbarActions(actions) {
|
|
33
|
+
const segments = [];
|
|
34
|
+
actions.forEach((action) => {
|
|
35
|
+
const current = segments.at(-1);
|
|
36
|
+
if (current && action.group !== void 0 && current[0].group === action.group) current.push(action);
|
|
37
|
+
else segments.push([action]);
|
|
38
|
+
});
|
|
39
|
+
return segments;
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/const.ts
|
|
43
|
+
const LIST_MARKER = /^(?:- \[[ xX]\] |- |\d+\. )/;
|
|
44
|
+
/**
|
|
45
|
+
* Every formatting action the toolbar exposes — one per markdown feature the `Markdown`
|
|
46
|
+
* renderer supports (GFM + the component map in `Markdown.Preview`). Data-driven so the
|
|
47
|
+
* toolbar and the transform logic stay in sync.
|
|
48
|
+
*/
|
|
49
|
+
const TOOLBAR_ACTIONS = [
|
|
50
|
+
{
|
|
51
|
+
id: "bold",
|
|
52
|
+
label: "B",
|
|
53
|
+
ariaLabel: "Bold",
|
|
54
|
+
emphasis: "bold",
|
|
55
|
+
group: "inline",
|
|
56
|
+
kind: "wrap",
|
|
57
|
+
prefix: "**",
|
|
58
|
+
suffix: "**",
|
|
59
|
+
placeholder: "bold text"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "italic",
|
|
63
|
+
label: "I",
|
|
64
|
+
ariaLabel: "Italic",
|
|
65
|
+
emphasis: "italic",
|
|
66
|
+
group: "inline",
|
|
67
|
+
kind: "wrap",
|
|
68
|
+
prefix: "_",
|
|
69
|
+
suffix: "_",
|
|
70
|
+
placeholder: "italic text"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "strikethrough",
|
|
74
|
+
label: "S",
|
|
75
|
+
ariaLabel: "Strikethrough",
|
|
76
|
+
emphasis: "strike",
|
|
77
|
+
group: "inline",
|
|
78
|
+
kind: "wrap",
|
|
79
|
+
prefix: "~~",
|
|
80
|
+
suffix: "~~",
|
|
81
|
+
placeholder: "struck text"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "quote",
|
|
85
|
+
label: "Quote",
|
|
86
|
+
ariaLabel: "Blockquote",
|
|
87
|
+
icon: "format_quote",
|
|
88
|
+
kind: "linePrefix",
|
|
89
|
+
linePrefix: "> ",
|
|
90
|
+
family: /^> /
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: "ul",
|
|
94
|
+
label: "List",
|
|
95
|
+
ariaLabel: "Bulleted list",
|
|
96
|
+
icon: "format_list_bulleted",
|
|
97
|
+
group: "list",
|
|
98
|
+
kind: "linePrefix",
|
|
99
|
+
linePrefix: "- ",
|
|
100
|
+
family: LIST_MARKER
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "ol",
|
|
104
|
+
label: "Ordered",
|
|
105
|
+
ariaLabel: "Numbered list",
|
|
106
|
+
icon: "format_list_numbered",
|
|
107
|
+
group: "list",
|
|
108
|
+
kind: "linePrefix",
|
|
109
|
+
linePrefix: "1. ",
|
|
110
|
+
family: LIST_MARKER
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "task",
|
|
114
|
+
label: "Task",
|
|
115
|
+
ariaLabel: "Task list",
|
|
116
|
+
icon: "checklist",
|
|
117
|
+
group: "list",
|
|
118
|
+
kind: "linePrefix",
|
|
119
|
+
linePrefix: "- [ ] ",
|
|
120
|
+
family: LIST_MARKER
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: "link",
|
|
124
|
+
label: "Link",
|
|
125
|
+
ariaLabel: "Link",
|
|
126
|
+
icon: "link",
|
|
127
|
+
kind: "wrap",
|
|
128
|
+
prefix: "[",
|
|
129
|
+
suffix: "](url)",
|
|
130
|
+
placeholder: "link text"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: "image",
|
|
134
|
+
label: "Image",
|
|
135
|
+
ariaLabel: "Image",
|
|
136
|
+
icon: "image",
|
|
137
|
+
kind: "wrap",
|
|
138
|
+
prefix: "",
|
|
140
|
+
placeholder: "alt text"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: "hr",
|
|
144
|
+
label: "HR",
|
|
145
|
+
ariaLabel: "Horizontal rule",
|
|
146
|
+
kind: "insert",
|
|
147
|
+
snippet: "\n\n---\n\n"
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
/** Fence languages offered by the code-block select; `value` is appended after the opening ```. */
|
|
151
|
+
const CODE_LANGUAGES = [
|
|
152
|
+
{
|
|
153
|
+
label: "Plain",
|
|
154
|
+
value: "text"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
label: "HTML",
|
|
158
|
+
value: "html"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
label: "CSS",
|
|
162
|
+
value: "css"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
label: "JavaScript",
|
|
166
|
+
value: "js"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
label: "TypeScript",
|
|
170
|
+
value: "ts"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
label: "JSON",
|
|
174
|
+
value: "json"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
label: "Bash",
|
|
178
|
+
value: "bash"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
label: "Python",
|
|
182
|
+
value: "python"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
label: "Markdown",
|
|
186
|
+
value: "md"
|
|
187
|
+
}
|
|
188
|
+
];
|
|
189
|
+
/** Inline `code` — rendered next to the code-block select so both code controls sit together. */
|
|
190
|
+
const INLINE_CODE_ACTION = {
|
|
191
|
+
id: "inline-code",
|
|
192
|
+
label: "Code",
|
|
193
|
+
ariaLabel: "Inline code",
|
|
194
|
+
icon: "code",
|
|
195
|
+
kind: "wrap",
|
|
196
|
+
prefix: "`",
|
|
197
|
+
suffix: "`",
|
|
198
|
+
placeholder: "code"
|
|
199
|
+
};
|
|
200
|
+
/** Builds the fenced-code-block wrap action for a chosen `language`. */
|
|
201
|
+
const codeBlockAction = (language) => ({
|
|
202
|
+
id: "code-block",
|
|
203
|
+
label: "Code block",
|
|
204
|
+
ariaLabel: "Code block",
|
|
205
|
+
kind: "wrap",
|
|
206
|
+
prefix: `\`\`\`${language}\n`,
|
|
207
|
+
suffix: "\n```",
|
|
208
|
+
placeholder: "code",
|
|
209
|
+
block: true
|
|
210
|
+
});
|
|
211
|
+
const HEADING_MARKER = /^#{1,6} /;
|
|
212
|
+
const headingAction = (level) => ({
|
|
213
|
+
id: `h${level}`,
|
|
214
|
+
label: `H${level}`,
|
|
215
|
+
ariaLabel: `Heading ${level}`,
|
|
216
|
+
kind: "linePrefix",
|
|
217
|
+
linePrefix: `${"#".repeat(level)} `,
|
|
218
|
+
family: HEADING_MARKER,
|
|
219
|
+
toggle: false
|
|
220
|
+
});
|
|
221
|
+
/** Every heading level the `Markdown` renderer supports (h1–h6) — offered via the toolbar select. */
|
|
222
|
+
const HEADING_ACTIONS = [
|
|
223
|
+
1,
|
|
224
|
+
2,
|
|
225
|
+
3,
|
|
226
|
+
4,
|
|
227
|
+
5,
|
|
228
|
+
6
|
|
229
|
+
].map(headingAction);
|
|
230
|
+
/**
|
|
231
|
+
* Every mermaid diagram type the renderer can draw, each with a minimal valid starter, validated
|
|
232
|
+
* against mermaid's own parser.
|
|
233
|
+
*/
|
|
234
|
+
const MERMAID_DIAGRAMS = [
|
|
235
|
+
{
|
|
236
|
+
label: "Flowchart",
|
|
237
|
+
value: "flowchart",
|
|
238
|
+
snippet: "graph TD\n A[Start] --> B[End]"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
label: "Sequence",
|
|
242
|
+
value: "sequence",
|
|
243
|
+
snippet: "sequenceDiagram\n Alice->>Bob: Hello\n Bob-->>Alice: Hi"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
label: "Class",
|
|
247
|
+
value: "class",
|
|
248
|
+
snippet: "classDiagram\n class Animal {\n +String name\n +move()\n }\n Animal <|-- Dog"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
label: "State",
|
|
252
|
+
value: "state",
|
|
253
|
+
snippet: "stateDiagram-v2\n [*] --> Active\n Active --> [*]"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
label: "Entity Relationship",
|
|
257
|
+
value: "er",
|
|
258
|
+
snippet: "erDiagram\n CUSTOMER ||--o{ ORDER : places"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
label: "User Journey",
|
|
262
|
+
value: "journey",
|
|
263
|
+
snippet: "journey\n title My Day\n section Work\n Code: 5: Me"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
label: "Gantt",
|
|
267
|
+
value: "gantt",
|
|
268
|
+
snippet: "gantt\n title Schedule\n dateFormat YYYY-MM-DD\n section Phase\n Task A :a1, 2024-01-01, 3d"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
label: "Git",
|
|
272
|
+
value: "git",
|
|
273
|
+
snippet: "gitGraph\n commit\n branch develop\n commit\n checkout main\n merge develop"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
label: "Pie",
|
|
277
|
+
value: "pie",
|
|
278
|
+
snippet: "pie title Pets\n \"Dogs\" : 40\n \"Cats\" : 60"
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
label: "Mindmap",
|
|
282
|
+
value: "mindmap",
|
|
283
|
+
snippet: "mindmap\n root((mindmap))\n Origins\n Tools"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
label: "Timeline",
|
|
287
|
+
value: "timeline",
|
|
288
|
+
snippet: "timeline\n title History\n 2021 : Started\n 2022 : Grew"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
label: "Quadrant",
|
|
292
|
+
value: "quadrant",
|
|
293
|
+
snippet: "quadrantChart\n title Reach vs Effort\n x-axis Low --> High\n y-axis Low --> High\n Campaign: [0.3, 0.6]"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
label: "Requirement",
|
|
297
|
+
value: "requirement",
|
|
298
|
+
snippet: "requirementDiagram\n requirement test_req {\n id: 1\n text: the test text.\n risk: high\n verifymethod: test\n }"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
label: "C4",
|
|
302
|
+
value: "c4",
|
|
303
|
+
snippet: "C4Context\n title System Context\n Person(user, \"User\")\n System(sys, \"System\")\n Rel(user, sys, \"Uses\")"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
label: "Sankey",
|
|
307
|
+
value: "sankey",
|
|
308
|
+
snippet: "sankey-beta\n\nA,B,10\nA,C,5"
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
label: "XY",
|
|
312
|
+
value: "xy",
|
|
313
|
+
snippet: "xychart-beta\n title \"Sales\"\n x-axis [jan, feb, mar]\n y-axis \"Revenue\" 0 --> 100\n bar [30, 50, 80]"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
label: "Block",
|
|
317
|
+
value: "block",
|
|
318
|
+
snippet: "block-beta\n columns 2\n A B"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
label: "Packet",
|
|
322
|
+
value: "packet",
|
|
323
|
+
snippet: "packet-beta\n 0-15: \"Source Port\"\n 16-31: \"Destination Port\""
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
label: "Kanban",
|
|
327
|
+
value: "kanban",
|
|
328
|
+
snippet: "kanban\n Todo\n [Create sample]\n Doing\n [In progress]"
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
label: "Architecture",
|
|
332
|
+
value: "architecture",
|
|
333
|
+
snippet: "architecture-beta\n group api(cloud)[API]\n service db(database)[Database] in api\n service server(server)[Server] in api\n server:R --> L:db"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
label: "Radar",
|
|
337
|
+
value: "radar",
|
|
338
|
+
snippet: "radar-beta\n axis a, b, c, d, e\n curve c1{1, 2, 3, 4, 5}"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
label: "Treemap",
|
|
342
|
+
value: "treemap",
|
|
343
|
+
snippet: "treemap\n \"Root\"\n \"A\": 10\n \"B\": 20"
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
/** Builds the insert action that drops a chosen mermaid diagram's starter as a fenced block. */
|
|
347
|
+
const mermaidDiagramAction = (snippet) => ({
|
|
348
|
+
id: "mermaid",
|
|
349
|
+
label: "Diagram",
|
|
350
|
+
ariaLabel: "Insert mermaid diagram",
|
|
351
|
+
kind: "insert",
|
|
352
|
+
snippet: `\n\`\`\`mermaid\n${snippet}\n\`\`\`\n`
|
|
353
|
+
});
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region src/Toolbar/TablePicker.tsx
|
|
356
|
+
/** Smallest grid shown, and the hard cap it grows to as the hover nears the edge. */
|
|
357
|
+
const MIN_EXTENT = 8;
|
|
358
|
+
const MAX_EXTENT = 20;
|
|
359
|
+
const DEFAULT_EXTENT = {
|
|
360
|
+
rows: MIN_EXTENT,
|
|
361
|
+
cols: MIN_EXTENT
|
|
362
|
+
};
|
|
363
|
+
const growExtent = (current, hovered) => Math.min(MAX_EXTENT, Math.max(current, hovered + 1));
|
|
364
|
+
const Cell = (0, _soroush_tech_design_system.styled)("button", {
|
|
365
|
+
name: "MarkdownToolbar",
|
|
366
|
+
slot: "tablePickerCell",
|
|
367
|
+
label: "MarkdownEditorTableCell",
|
|
368
|
+
shouldForwardProp: (prop) => prop !== "isActive"
|
|
369
|
+
})(({ theme, isActive }) => ({
|
|
370
|
+
width: 16,
|
|
371
|
+
height: 16,
|
|
372
|
+
padding: 0,
|
|
373
|
+
margin: 0,
|
|
374
|
+
appearance: "none",
|
|
375
|
+
cursor: "pointer",
|
|
376
|
+
borderRadius: theme.radii.sm,
|
|
377
|
+
border: `${theme.borderWidths.thin} solid ${theme.border.light}`,
|
|
378
|
+
backgroundColor: isActive ? theme.palette[(0, _soroush_tech_design_system_theme.themeDefault)(theme, "color", "primary")].main : theme.background[(0, _soroush_tech_design_system_theme.themeDefault)(theme, "inputBg", "terminal")]
|
|
379
|
+
}));
|
|
380
|
+
/** A "Table" trigger that opens a hover grid for choosing table dimensions. */
|
|
381
|
+
function TablePicker({ onSelect }) {
|
|
382
|
+
const [anchorEl, setAnchorEl] = (0, react.useState)(null);
|
|
383
|
+
const [hover, setHover] = (0, react.useState)({
|
|
384
|
+
rows: 0,
|
|
385
|
+
cols: 0
|
|
386
|
+
});
|
|
387
|
+
const [extent, setExtent] = (0, react.useState)(DEFAULT_EXTENT);
|
|
388
|
+
const open = anchorEl !== null;
|
|
389
|
+
const close = () => {
|
|
390
|
+
setAnchorEl(null);
|
|
391
|
+
setHover({
|
|
392
|
+
rows: 0,
|
|
393
|
+
cols: 0
|
|
394
|
+
});
|
|
395
|
+
setExtent(DEFAULT_EXTENT);
|
|
396
|
+
};
|
|
397
|
+
const hoverCell = (rows, cols) => {
|
|
398
|
+
setHover({
|
|
399
|
+
rows,
|
|
400
|
+
cols
|
|
401
|
+
});
|
|
402
|
+
setExtent((prev) => ({
|
|
403
|
+
rows: growExtent(prev.rows, rows),
|
|
404
|
+
cols: growExtent(prev.cols, cols)
|
|
405
|
+
}));
|
|
406
|
+
};
|
|
407
|
+
const pick = (rows, cols) => {
|
|
408
|
+
onSelect(rows, cols);
|
|
409
|
+
close();
|
|
410
|
+
};
|
|
411
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Button.Button, {
|
|
412
|
+
type: "button",
|
|
413
|
+
variant: "outlined",
|
|
414
|
+
size: "sm",
|
|
415
|
+
"aria-label": "Table",
|
|
416
|
+
"aria-haspopup": "grid",
|
|
417
|
+
"aria-expanded": open,
|
|
418
|
+
onClick: (event) => setAnchorEl(event.currentTarget),
|
|
419
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Icon.Icon, {
|
|
420
|
+
name: "table",
|
|
421
|
+
size: "1.1rem"
|
|
422
|
+
})
|
|
423
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Popover.Popover, {
|
|
424
|
+
open,
|
|
425
|
+
anchorEl,
|
|
426
|
+
onClose: close,
|
|
427
|
+
anchorOrigin: {
|
|
428
|
+
vertical: "bottom",
|
|
429
|
+
horizontal: "left"
|
|
430
|
+
},
|
|
431
|
+
transformOrigin: {
|
|
432
|
+
vertical: "top",
|
|
433
|
+
horizontal: "left"
|
|
434
|
+
},
|
|
435
|
+
disableAriaHidden: true,
|
|
436
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_soroush_tech_design_system_Flex.Flex, {
|
|
437
|
+
flexDirection: "column",
|
|
438
|
+
gap: 2,
|
|
439
|
+
p: 2,
|
|
440
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Flex.Flex, {
|
|
441
|
+
flexDirection: "column",
|
|
442
|
+
gap: 1,
|
|
443
|
+
role: "grid",
|
|
444
|
+
"aria-label": "Table size",
|
|
445
|
+
children: Array.from({ length: extent.rows }, (_, r) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Flex.Flex, {
|
|
446
|
+
flexDirection: "row",
|
|
447
|
+
gap: 1,
|
|
448
|
+
role: "row",
|
|
449
|
+
children: Array.from({ length: extent.cols }, (_, c) => {
|
|
450
|
+
const rows = r + 1;
|
|
451
|
+
const cols = c + 1;
|
|
452
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cell, {
|
|
453
|
+
type: "button",
|
|
454
|
+
role: "gridcell",
|
|
455
|
+
isActive: rows <= hover.rows && cols <= hover.cols,
|
|
456
|
+
"aria-label": `${rows} by ${cols}`,
|
|
457
|
+
onMouseEnter: () => hoverCell(rows, cols),
|
|
458
|
+
onFocus: () => hoverCell(rows, cols),
|
|
459
|
+
onClick: () => pick(rows, cols)
|
|
460
|
+
}, c);
|
|
461
|
+
})
|
|
462
|
+
}, r))
|
|
463
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Typography.Typography, {
|
|
464
|
+
variant: "caption",
|
|
465
|
+
color: "secondary",
|
|
466
|
+
align: "center",
|
|
467
|
+
m: 0,
|
|
468
|
+
children: hover.rows > 0 ? `${hover.rows} × ${hover.cols}` : "Select size"
|
|
469
|
+
})]
|
|
470
|
+
})
|
|
471
|
+
})] });
|
|
472
|
+
}
|
|
473
|
+
//#endregion
|
|
474
|
+
//#region src/Toolbar/Toolbar.tsx
|
|
475
|
+
const HEADING_OPTIONS = HEADING_ACTIONS.map((action) => ({
|
|
476
|
+
label: action.label,
|
|
477
|
+
value: action.id
|
|
478
|
+
}));
|
|
479
|
+
const DIAGRAM_OPTIONS = MERMAID_DIAGRAMS.map((diagram) => ({
|
|
480
|
+
label: diagram.label,
|
|
481
|
+
value: diagram.value
|
|
482
|
+
}));
|
|
483
|
+
const DIAGRAM_SNIPPET_BY_VALUE = Object.fromEntries(MERMAID_DIAGRAMS.map((diagram) => [diagram.value, diagram.snippet]));
|
|
484
|
+
const HEADING_BY_ID = Object.fromEntries(HEADING_ACTIONS.map((action) => [action.id, action]));
|
|
485
|
+
const ToolbarRoot = (0, _soroush_tech_design_system.styled)(_soroush_tech_design_system_Flex.Flex, {
|
|
486
|
+
name: "MarkdownToolbar",
|
|
487
|
+
label: "MarkdownToolbar"
|
|
488
|
+
})();
|
|
489
|
+
const StrikeLabel = (0, _soroush_tech_design_system.styled)(_soroush_tech_design_system_Typography.Typography, {
|
|
490
|
+
name: "MarkdownToolbar",
|
|
491
|
+
slot: "strike",
|
|
492
|
+
label: "MarkdownStrike"
|
|
493
|
+
})({ textDecoration: "line-through" });
|
|
494
|
+
/** Renders a button's content: an icon, an emphasis-styled letter, or the plain label. */
|
|
495
|
+
function ActionLabel({ action }) {
|
|
496
|
+
if (action.icon) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Icon.Icon, {
|
|
497
|
+
name: action.icon,
|
|
498
|
+
size: "1.1rem"
|
|
499
|
+
});
|
|
500
|
+
if (action.emphasis === "bold") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Typography.Typography, {
|
|
501
|
+
as: "span",
|
|
502
|
+
variant: "inherit",
|
|
503
|
+
fontWeight: "extraBold",
|
|
504
|
+
children: action.label
|
|
505
|
+
});
|
|
506
|
+
if (action.emphasis === "italic") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Typography.Typography, {
|
|
507
|
+
as: "span",
|
|
508
|
+
variant: "inherit",
|
|
509
|
+
fontStyle: "italic",
|
|
510
|
+
children: action.label
|
|
511
|
+
});
|
|
512
|
+
if (action.emphasis === "strike") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StrikeLabel, {
|
|
513
|
+
as: "span",
|
|
514
|
+
variant: "inherit",
|
|
515
|
+
children: action.label
|
|
516
|
+
});
|
|
517
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: action.label });
|
|
518
|
+
}
|
|
519
|
+
/** Formatting buttons, heading + code-language selects, and the table-size picker. */
|
|
520
|
+
function Toolbar() {
|
|
521
|
+
const { dispatch } = require_MarkdownContext.useMarkdownContext();
|
|
522
|
+
const renderButton = (action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_Button.Button, {
|
|
523
|
+
type: "button",
|
|
524
|
+
variant: "outlined",
|
|
525
|
+
size: "sm",
|
|
526
|
+
"aria-label": action.ariaLabel,
|
|
527
|
+
onClick: () => dispatch(action),
|
|
528
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionLabel, { action })
|
|
529
|
+
}, action.id);
|
|
530
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ToolbarRoot, {
|
|
531
|
+
flexDirection: "row",
|
|
532
|
+
flexWrap: "wrap",
|
|
533
|
+
gap: 1,
|
|
534
|
+
role: "toolbar",
|
|
535
|
+
"aria-label": "Markdown formatting",
|
|
536
|
+
children: [
|
|
537
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_NativeSelect.NativeSelect, {
|
|
538
|
+
size: "sm",
|
|
539
|
+
variant: "outlined",
|
|
540
|
+
placeholder: "Heading",
|
|
541
|
+
value: "",
|
|
542
|
+
options: HEADING_OPTIONS,
|
|
543
|
+
onChange: (value) => dispatch(HEADING_BY_ID[String(value)]),
|
|
544
|
+
selectProps: { "aria-label": "Heading level" }
|
|
545
|
+
}),
|
|
546
|
+
groupToolbarActions(TOOLBAR_ACTIONS).map((segment) => segment.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_ButtonGroup.ButtonGroup, {
|
|
547
|
+
borderRadius: "sq",
|
|
548
|
+
size: "sm",
|
|
549
|
+
variant: "outlined",
|
|
550
|
+
children: segment.map(renderButton)
|
|
551
|
+
}, segment[0].id) : renderButton(segment[0])),
|
|
552
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TablePicker, { onSelect: (rows, cols) => dispatch({
|
|
553
|
+
id: "table",
|
|
554
|
+
label: "Table",
|
|
555
|
+
ariaLabel: "Table",
|
|
556
|
+
kind: "insert",
|
|
557
|
+
snippet: buildTableSnippet(rows, cols)
|
|
558
|
+
}) }),
|
|
559
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_soroush_tech_design_system_Flex.Flex, {
|
|
560
|
+
flexDirection: "row",
|
|
561
|
+
gap: 0,
|
|
562
|
+
alignItems: "stretch",
|
|
563
|
+
children: [
|
|
564
|
+
renderButton(INLINE_CODE_ACTION),
|
|
565
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_NativeSelect.NativeSelect, {
|
|
566
|
+
size: "sm",
|
|
567
|
+
variant: "outlined",
|
|
568
|
+
placeholder: "Code",
|
|
569
|
+
value: "",
|
|
570
|
+
options: CODE_LANGUAGES,
|
|
571
|
+
onChange: (value) => dispatch(codeBlockAction(String(value))),
|
|
572
|
+
selectProps: { "aria-label": "Code block language" }
|
|
573
|
+
}),
|
|
574
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_soroush_tech_design_system_NativeSelect.NativeSelect, {
|
|
575
|
+
size: "sm",
|
|
576
|
+
variant: "outlined",
|
|
577
|
+
placeholder: "Diagram",
|
|
578
|
+
value: "",
|
|
579
|
+
options: DIAGRAM_OPTIONS,
|
|
580
|
+
onChange: (value) => dispatch(mermaidDiagramAction(DIAGRAM_SNIPPET_BY_VALUE[String(value)])),
|
|
581
|
+
selectProps: { "aria-label": "Mermaid diagram type" }
|
|
582
|
+
})
|
|
583
|
+
]
|
|
584
|
+
})
|
|
585
|
+
]
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
//#endregion
|
|
589
|
+
Object.defineProperty(exports, "TablePicker", {
|
|
590
|
+
enumerable: true,
|
|
591
|
+
get: function() {
|
|
592
|
+
return TablePicker;
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
Object.defineProperty(exports, "Toolbar", {
|
|
596
|
+
enumerable: true,
|
|
597
|
+
get: function() {
|
|
598
|
+
return Toolbar;
|
|
599
|
+
}
|
|
600
|
+
});
|