@texuli/blocks 0.0.0-stage → 0.1.0-next.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 +77 -2
- package/dist/code/CodeBlockView.svelte +135 -0
- package/dist/code/CodeBlockView.svelte.d.ts +5 -0
- package/dist/code/check.d.ts +15 -0
- package/dist/code/check.js +14 -0
- package/dist/code/code.css +201 -0
- package/dist/code/code.css.d.ts +1 -0
- package/dist/code/engine-entry.d.ts +10 -0
- package/dist/code/engine-entry.js +10 -0
- package/dist/code/engine.d.ts +18 -0
- package/dist/code/engine.js +18 -0
- package/dist/code/family-engine.d.ts +23 -0
- package/dist/code/family-engine.js +4 -0
- package/dist/code/family.d.ts +7 -0
- package/dist/code/family.js +5 -0
- package/dist/code/grammars.d.ts +12 -0
- package/dist/code/grammars.js +83 -0
- package/dist/code/highlight.d.ts +15 -0
- package/dist/code/highlight.js +53 -0
- package/dist/code/index.d.ts +13 -0
- package/dist/code/index.js +12 -0
- package/dist/code/labels.d.ts +27 -0
- package/dist/code/labels.js +24 -0
- package/dist/code/languages/bash.d.ts +3 -0
- package/dist/code/languages/bash.js +48 -0
- package/dist/code/languages/css.d.ts +10 -0
- package/dist/code/languages/css.js +67 -0
- package/dist/code/languages/html.d.ts +6 -0
- package/dist/code/languages/html.js +35 -0
- package/dist/code/languages/javascript.d.ts +3 -0
- package/dist/code/languages/javascript.js +113 -0
- package/dist/code/languages/json.d.ts +3 -0
- package/dist/code/languages/json.js +24 -0
- package/dist/code/languages/python.d.ts +3 -0
- package/dist/code/languages/python.js +35 -0
- package/dist/code/languages/shared.d.ts +22 -0
- package/dist/code/languages/shared.js +37 -0
- package/dist/code/languages/sql.d.ts +3 -0
- package/dist/code/languages/sql.js +32 -0
- package/dist/code/languages/yaml.d.ts +7 -0
- package/dist/code/languages/yaml.js +36 -0
- package/dist/code/renderers.d.ts +5 -0
- package/dist/code/renderers.js +5 -0
- package/dist/code/token-styles.d.ts +25 -0
- package/dist/code/token-styles.js +51 -0
- package/dist/code/tokenize-code.d.ts +17 -0
- package/dist/code/tokenize-code.js +34 -0
- package/dist/code/tokenizer.d.ts +76 -0
- package/dist/code/tokenizer.js +171 -0
- package/dist/core/catalog/entries.d.ts +10 -0
- package/dist/core/catalog/entries.js +589 -0
- package/dist/core/catalog/index.d.ts +4 -0
- package/dist/core/catalog/index.js +2 -0
- package/dist/core/catalog/types.d.ts +36 -0
- package/dist/core/catalog/types.js +1 -0
- package/dist/core/catalog/validate.d.ts +15 -0
- package/dist/core/catalog/validate.js +46 -0
- package/dist/core/formula/evaluate.d.ts +14 -0
- package/dist/core/formula/evaluate.js +181 -0
- package/dist/core/formula/index.d.ts +8 -0
- package/dist/core/formula/index.js +6 -0
- package/dist/core/formula/parse.d.ts +19 -0
- package/dist/core/formula/parse.js +452 -0
- package/dist/core/formula/types.d.ts +76 -0
- package/dist/core/formula/types.js +7 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.js +13 -0
- package/dist/core/limits.d.ts +27 -0
- package/dist/core/limits.js +26 -0
- package/dist/core/safety.d.ts +30 -0
- package/dist/core/safety.js +110 -0
- package/dist/core/schema/blocks.d.ts +138 -0
- package/dist/core/schema/blocks.js +181 -0
- package/dist/core/schema/code-family.d.ts +4 -0
- package/dist/core/schema/code-family.js +75 -0
- package/dist/core/schema/line-spec.d.ts +7 -0
- package/dist/core/schema/line-spec.js +19 -0
- package/dist/core/schema/media-family.d.ts +4 -0
- package/dist/core/schema/media-family.js +260 -0
- package/dist/core/schema/parse-family.d.ts +14 -0
- package/dist/core/schema/parse-family.js +37 -0
- package/dist/core/schema/primitives.d.ts +73 -0
- package/dist/core/schema/primitives.js +140 -0
- package/dist/core/schema/text-family.d.ts +4 -0
- package/dist/core/schema/text-family.js +121 -0
- package/dist/core/schema/vocabulary.d.ts +20 -0
- package/dist/core/schema/vocabulary.js +33 -0
- package/dist/core/text.d.ts +31 -0
- package/dist/core/text.js +139 -0
- package/dist/core/untrusted.d.ts +20 -0
- package/dist/core/untrusted.js +377 -0
- package/dist/css-modules.d.ts +1 -0
- package/dist/css.d.ts +1 -0
- package/dist/data/ChartBlockView.svelte +77 -0
- package/dist/data/ChartBlockView.svelte.d.ts +10 -0
- package/dist/data/DataBlockView.svelte +109 -0
- package/dist/data/DataBlockView.svelte.d.ts +5 -0
- package/dist/data/check.d.ts +10 -0
- package/dist/data/check.js +9 -0
- package/dist/data/engine.d.ts +18 -0
- package/dist/data/engine.js +10 -0
- package/dist/data/family.d.ts +6 -0
- package/dist/data/family.js +4 -0
- package/dist/data/index.d.ts +9 -0
- package/dist/data/index.js +8 -0
- package/dist/data/labels.d.ts +8 -0
- package/dist/data/labels.js +8 -0
- package/dist/data/renderers.d.ts +2 -0
- package/dist/data/renderers.js +2 -0
- package/dist/data/schema.d.ts +84 -0
- package/dist/data/schema.js +385 -0
- package/dist/diagram/BoardDiagram.svelte +48 -0
- package/dist/diagram/BoardDiagram.svelte.d.ts +8 -0
- package/dist/diagram/DiagramFamily.svelte +46 -0
- package/dist/diagram/DiagramFamily.svelte.d.ts +10 -0
- package/dist/diagram/FlowDiagram.svelte +108 -0
- package/dist/diagram/FlowDiagram.svelte.d.ts +8 -0
- package/dist/diagram/TerminalDiagram.svelte +38 -0
- package/dist/diagram/TerminalDiagram.svelte.d.ts +8 -0
- package/dist/diagram/TreeDiagram.svelte +149 -0
- package/dist/diagram/TreeDiagram.svelte.d.ts +8 -0
- package/dist/diagram/diagram.css +287 -0
- package/dist/diagram/diagram.css.d.ts +1 -0
- package/dist/diagram/engine.d.ts +16 -0
- package/dist/diagram/engine.js +14 -0
- package/dist/diagram/family.d.ts +7 -0
- package/dist/diagram/family.js +5 -0
- package/dist/diagram/index.d.ts +10 -0
- package/dist/diagram/index.js +9 -0
- package/dist/diagram/layout.d.ts +26 -0
- package/dist/diagram/layout.js +165 -0
- package/dist/diagram/schema.d.ts +74 -0
- package/dist/diagram/schema.js +358 -0
- package/dist/diagram/tones.d.ts +6 -0
- package/dist/diagram/tones.js +16 -0
- package/dist/embed/EmbedApp.svelte +138 -0
- package/dist/embed/EmbedApp.svelte.d.ts +17 -0
- package/dist/embed/EmbedBlockView.svelte +32 -0
- package/dist/embed/EmbedBlockView.svelte.d.ts +5 -0
- package/dist/embed/LinkPreview.svelte +48 -0
- package/dist/embed/LinkPreview.svelte.d.ts +10 -0
- package/dist/embed/engine.d.ts +30 -0
- package/dist/embed/engine.js +17 -0
- package/dist/embed/family.d.ts +7 -0
- package/dist/embed/family.js +5 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.js +3 -0
- package/dist/embed/renderers.d.ts +3 -0
- package/dist/embed/renderers.js +3 -0
- package/dist/embed/sandbox.d.ts +86 -0
- package/dist/embed/sandbox.js +114 -0
- package/dist/embed/schema.d.ts +30 -0
- package/dist/embed/schema.js +217 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/interactive/CalculatorBlock.svelte +61 -0
- package/dist/interactive/CalculatorBlock.svelte.d.ts +10 -0
- package/dist/interactive/ChecklistBlock.svelte +44 -0
- package/dist/interactive/ChecklistBlock.svelte.d.ts +10 -0
- package/dist/interactive/InteractiveBlockView.svelte +31 -0
- package/dist/interactive/InteractiveBlockView.svelte.d.ts +5 -0
- package/dist/interactive/PollBlock.svelte +111 -0
- package/dist/interactive/PollBlock.svelte.d.ts +10 -0
- package/dist/interactive/QuizBlock.svelte +75 -0
- package/dist/interactive/QuizBlock.svelte.d.ts +10 -0
- package/dist/interactive/check.d.ts +10 -0
- package/dist/interactive/check.js +9 -0
- package/dist/interactive/engine.d.ts +19 -0
- package/dist/interactive/engine.js +12 -0
- package/dist/interactive/family.d.ts +6 -0
- package/dist/interactive/family.js +4 -0
- package/dist/interactive/index.d.ts +13 -0
- package/dist/interactive/index.js +13 -0
- package/dist/interactive/interactive.css +97 -0
- package/dist/interactive/interactive.css.d.ts +1 -0
- package/dist/interactive/labels.d.ts +16 -0
- package/dist/interactive/labels.js +16 -0
- package/dist/interactive/renderers.d.ts +9 -0
- package/dist/interactive/renderers.js +9 -0
- package/dist/interactive/schema.d.ts +76 -0
- package/dist/interactive/schema.js +324 -0
- package/dist/map/MapBlockView.svelte +465 -0
- package/dist/map/MapBlockView.svelte.d.ts +5 -0
- package/dist/map/check.d.ts +11 -0
- package/dist/map/check.js +6 -0
- package/dist/map/engine.d.ts +19 -0
- package/dist/map/engine.js +8 -0
- package/dist/map/family.d.ts +7 -0
- package/dist/map/family.js +5 -0
- package/dist/map/index.d.ts +11 -0
- package/dist/map/index.js +10 -0
- package/dist/map/labels.d.ts +27 -0
- package/dist/map/labels.js +21 -0
- package/dist/map/renderers.d.ts +2 -0
- package/dist/map/renderers.js +2 -0
- package/dist/map/schema.d.ts +41 -0
- package/dist/map/schema.js +176 -0
- package/dist/map/view-model.d.ts +55 -0
- package/dist/map/view-model.js +168 -0
- package/dist/media/MediaBlockView.svelte +258 -0
- package/dist/media/MediaBlockView.svelte.d.ts +5 -0
- package/dist/media/check.d.ts +14 -0
- package/dist/media/check.js +13 -0
- package/dist/media/engine.d.ts +18 -0
- package/dist/media/engine.js +10 -0
- package/dist/media/family.d.ts +7 -0
- package/dist/media/family.js +5 -0
- package/dist/media/index.d.ts +11 -0
- package/dist/media/index.js +10 -0
- package/dist/media/labels.d.ts +7 -0
- package/dist/media/labels.js +12 -0
- package/dist/media/renderers.d.ts +5 -0
- package/dist/media/renderers.js +5 -0
- package/dist/media/resolve.d.ts +6 -0
- package/dist/media/resolve.js +15 -0
- package/dist/structure/NestedBlocks.svelte +65 -0
- package/dist/structure/NestedBlocks.svelte.d.ts +11 -0
- package/dist/structure/SafeBody.svelte +13 -0
- package/dist/structure/SafeBody.svelte.d.ts +7 -0
- package/dist/structure/StructureFamily.svelte +157 -0
- package/dist/structure/StructureFamily.svelte.d.ts +5 -0
- package/dist/structure/check.d.ts +14 -0
- package/dist/structure/check.js +27 -0
- package/dist/structure/engine.d.ts +18 -0
- package/dist/structure/engine.js +18 -0
- package/dist/structure/family.d.ts +7 -0
- package/dist/structure/family.js +5 -0
- package/dist/structure/index.d.ts +11 -0
- package/dist/structure/index.js +10 -0
- package/dist/structure/labels.d.ts +11 -0
- package/dist/structure/labels.js +11 -0
- package/dist/structure/renderers.d.ts +5 -0
- package/dist/structure/renderers.js +5 -0
- package/dist/structure/schema.d.ts +71 -0
- package/dist/structure/schema.js +327 -0
- package/dist/structure/structure.css +182 -0
- package/dist/structure/structure.css.d.ts +1 -0
- package/dist/text/RichText.svelte +169 -0
- package/dist/text/RichText.svelte.d.ts +13 -0
- package/dist/text/TextBlockView.svelte +177 -0
- package/dist/text/TextBlockView.svelte.d.ts +5 -0
- package/dist/text/check.d.ts +14 -0
- package/dist/text/check.js +13 -0
- package/dist/text/engine.d.ts +17 -0
- package/dist/text/engine.js +10 -0
- package/dist/text/family.d.ts +7 -0
- package/dist/text/family.js +5 -0
- package/dist/text/index.d.ts +12 -0
- package/dist/text/index.js +11 -0
- package/dist/text/labels.d.ts +22 -0
- package/dist/text/labels.js +29 -0
- package/dist/text/markdown.d.ts +80 -0
- package/dist/text/markdown.js +361 -0
- package/dist/text/renderers.d.ts +6 -0
- package/dist/text/renderers.js +6 -0
- package/package.json +167 -4
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
import { BLOCK_CONTENT_LIMITS } from "../schema/primitives.js";
|
|
2
|
+
/**
|
|
3
|
+
* Catalog metadata for the core block vocabulary. Later family tasks extend
|
|
4
|
+
* this list; agents and the website read useWhen / dontUseWhen / limits / a11y.
|
|
5
|
+
*/
|
|
6
|
+
export const BLOCK_CATALOG = Object.freeze([
|
|
7
|
+
{
|
|
8
|
+
type: 'heading',
|
|
9
|
+
label: 'Heading',
|
|
10
|
+
family: 'text',
|
|
11
|
+
useWhen: ['Introduce a section or slide title with a clear hierarchy.'],
|
|
12
|
+
dontUseWhen: ['Long body copy — use a text block instead.'],
|
|
13
|
+
limits: [`text ≤ ${BLOCK_CONTENT_LIMITS.heading} characters`, 'level 1–4'],
|
|
14
|
+
a11y: 'Rendered as the matching heading level; keep one h1 per page when possible.',
|
|
15
|
+
exampleMinimal: { type: 'heading', level: 2, text: 'Section title' },
|
|
16
|
+
exampleRich: {
|
|
17
|
+
type: 'heading',
|
|
18
|
+
level: 1,
|
|
19
|
+
text: 'Northwind quarterly review',
|
|
20
|
+
eyebrow: 'Q3 2026',
|
|
21
|
+
subtitle: 'Fictional example data only',
|
|
22
|
+
id: 'title',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
label: 'Paragraph',
|
|
28
|
+
family: 'text',
|
|
29
|
+
useWhen: ['Body copy with light markdown emphasis.'],
|
|
30
|
+
dontUseWhen: ['A single short label — use heading or list item text.'],
|
|
31
|
+
limits: [`markdown ≤ ${BLOCK_CONTENT_LIMITS.markdown} characters`],
|
|
32
|
+
a11y: 'Markdown is parsed to semantic elements; no raw HTML.',
|
|
33
|
+
exampleMinimal: { type: 'text', markdown: 'A short paragraph.' },
|
|
34
|
+
exampleRich: {
|
|
35
|
+
type: 'text',
|
|
36
|
+
markdown: 'Northwind Labs is a **fictional** company.\n\nEvery number below is example data.',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'list',
|
|
41
|
+
label: 'List',
|
|
42
|
+
family: 'text',
|
|
43
|
+
useWhen: ['Three or more parallel points or steps.'],
|
|
44
|
+
dontUseWhen: ['A single sentence — use text.'],
|
|
45
|
+
limits: [`≤ ${BLOCK_CONTENT_LIMITS.listItems} items`],
|
|
46
|
+
a11y: 'Rendered as ul or ol; items stay plain text or light markdown.',
|
|
47
|
+
exampleMinimal: { type: 'list', items: [{ text: 'First item' }] },
|
|
48
|
+
exampleRich: {
|
|
49
|
+
type: 'list',
|
|
50
|
+
ordered: true,
|
|
51
|
+
items: [{ text: 'Plan' }, { text: 'Ship' }, { text: 'Measure' }],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'quote',
|
|
56
|
+
label: 'Quote',
|
|
57
|
+
family: 'text',
|
|
58
|
+
useWhen: ['A short pull quote or testimonial.'],
|
|
59
|
+
dontUseWhen: ['Long body copy — use text.'],
|
|
60
|
+
limits: [`quote ≤ ${BLOCK_CONTENT_LIMITS.shortMarkdown} characters`],
|
|
61
|
+
a11y: 'Uses the blockquote element; cite is optional plain text.',
|
|
62
|
+
exampleMinimal: { type: 'quote', quote: 'Ship small pieces.' },
|
|
63
|
+
exampleRich: {
|
|
64
|
+
type: 'quote',
|
|
65
|
+
quote: 'Small pieces. Infinite possibilities.',
|
|
66
|
+
cite: 'Texuli docs (fictional)',
|
|
67
|
+
tone: 'accent',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'callout',
|
|
72
|
+
label: 'Callout',
|
|
73
|
+
family: 'text',
|
|
74
|
+
useWhen: ['Highlight a warning, tip or summary beside the main flow.'],
|
|
75
|
+
dontUseWhen: ['Primary body content — use text.'],
|
|
76
|
+
limits: [`body ≤ ${BLOCK_CONTENT_LIMITS.shortMarkdown} characters`],
|
|
77
|
+
a11y: 'Tone maps to theme tokens with AA contrast; title is optional.',
|
|
78
|
+
exampleMinimal: { type: 'callout', body: 'Remember the limits.' },
|
|
79
|
+
exampleRich: {
|
|
80
|
+
type: 'callout',
|
|
81
|
+
title: 'Summary',
|
|
82
|
+
body: 'Median response fell while volume grew **18%**.',
|
|
83
|
+
tone: 'info',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: 'divider',
|
|
88
|
+
label: 'Divider',
|
|
89
|
+
family: 'structure',
|
|
90
|
+
useWhen: ['Separate two sections visually.'],
|
|
91
|
+
dontUseWhen: ['Nesting content — use columns or headings.'],
|
|
92
|
+
limits: ['No text fields'],
|
|
93
|
+
a11y: 'Presented as a thematic break (hr); ignore for screen-reader flow when decorative.',
|
|
94
|
+
exampleMinimal: { type: 'divider' },
|
|
95
|
+
exampleRich: { type: 'divider', tone: 'neutral' },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
type: 'code',
|
|
99
|
+
label: 'Code',
|
|
100
|
+
family: 'code',
|
|
101
|
+
useWhen: ['Show a short code sample or config snippet.'],
|
|
102
|
+
dontUseWhen: ['Prose — use text.'],
|
|
103
|
+
limits: [
|
|
104
|
+
`code ≤ ${BLOCK_CONTENT_LIMITS.code} characters`,
|
|
105
|
+
`≤ ${BLOCK_CONTENT_LIMITS.codeLines} lines`,
|
|
106
|
+
`≤ ${BLOCK_CONTENT_LIMITS.codeHighlightSteps} highlight steps ("1-2,4")`,
|
|
107
|
+
],
|
|
108
|
+
a11y: 'Preformatted text; language is metadata for highlighters, not executed.',
|
|
109
|
+
exampleMinimal: { type: 'code', code: 'const n = 1;' },
|
|
110
|
+
exampleRich: {
|
|
111
|
+
type: 'code',
|
|
112
|
+
lang: 'ts',
|
|
113
|
+
filename: 'example.ts',
|
|
114
|
+
caption: 'One export.',
|
|
115
|
+
lineNumbers: true,
|
|
116
|
+
highlights: ['1', '2'],
|
|
117
|
+
code: 'export const a = 1;\nexport const b = 2;\n',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'cta',
|
|
122
|
+
label: 'Call to action',
|
|
123
|
+
family: 'structure',
|
|
124
|
+
useWhen: ['One to three safe outbound or in-page actions.'],
|
|
125
|
+
dontUseWhen: ['Navigation chrome — use the app shell.'],
|
|
126
|
+
limits: [
|
|
127
|
+
`≤ ${BLOCK_CONTENT_LIMITS.ctaActions} actions`,
|
|
128
|
+
'href uses the untrusted URL policy (https, mailto, #fragment)',
|
|
129
|
+
],
|
|
130
|
+
a11y: 'Actions are real links with visible labels; blocked hrefs never render as anchors.',
|
|
131
|
+
exampleMinimal: {
|
|
132
|
+
type: 'cta',
|
|
133
|
+
actions: [{ label: 'Read the guide', href: 'https://example.com/guide' }],
|
|
134
|
+
},
|
|
135
|
+
exampleRich: {
|
|
136
|
+
type: 'cta',
|
|
137
|
+
actions: [
|
|
138
|
+
{ label: 'Docs', href: 'https://example.com/docs' },
|
|
139
|
+
{ label: 'Contact', href: 'mailto:hello@example.com' },
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'columns',
|
|
145
|
+
label: 'Columns',
|
|
146
|
+
family: 'structure',
|
|
147
|
+
useWhen: ['Place two to four short blocks side by side.'],
|
|
148
|
+
dontUseWhen: ['Deep nesting — keep containers shallow.'],
|
|
149
|
+
limits: [
|
|
150
|
+
`2–${BLOCK_CONTENT_LIMITS.columns} columns`,
|
|
151
|
+
`≤ ${BLOCK_CONTENT_LIMITS.blocksPerColumn} blocks per column`,
|
|
152
|
+
`nesting ≤ ${BLOCK_CONTENT_LIMITS.containerDepth}`,
|
|
153
|
+
],
|
|
154
|
+
a11y: 'Columns reflow on narrow viewports; order follows source order.',
|
|
155
|
+
exampleMinimal: {
|
|
156
|
+
type: 'columns',
|
|
157
|
+
columns: [[{ type: 'text', markdown: 'Left' }], [{ type: 'text', markdown: 'Right' }]],
|
|
158
|
+
},
|
|
159
|
+
exampleRich: {
|
|
160
|
+
type: 'columns',
|
|
161
|
+
columns: [
|
|
162
|
+
[
|
|
163
|
+
{ type: 'heading', level: 3, text: 'Plan' },
|
|
164
|
+
{ type: 'text', markdown: 'Write the brief.' },
|
|
165
|
+
],
|
|
166
|
+
[
|
|
167
|
+
{ type: 'heading', level: 3, text: 'Ship' },
|
|
168
|
+
{ type: 'text', markdown: 'Validate and release.' },
|
|
169
|
+
],
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'grid',
|
|
175
|
+
label: 'Grid',
|
|
176
|
+
family: 'structure',
|
|
177
|
+
useWhen: ['Show a small set of titled cells in a responsive grid.'],
|
|
178
|
+
dontUseWhen: ['Linked feature cards — use cards; nested blocks — use columns.'],
|
|
179
|
+
limits: [
|
|
180
|
+
`≤ ${BLOCK_CONTENT_LIMITS.cards} cells`,
|
|
181
|
+
'columns 2–4 optional',
|
|
182
|
+
`body ≤ ${BLOCK_CONTENT_LIMITS.shortMarkdown} characters`,
|
|
183
|
+
],
|
|
184
|
+
a11y: 'Each cell is an article; the section label comes from title or a default.',
|
|
185
|
+
exampleMinimal: {
|
|
186
|
+
type: 'grid',
|
|
187
|
+
cells: [
|
|
188
|
+
{ title: 'Design', body: 'Tokens and themes.' },
|
|
189
|
+
{ title: 'Build', body: 'Components and blocks.' },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
exampleRich: {
|
|
193
|
+
type: 'grid',
|
|
194
|
+
title: 'Harbor squads',
|
|
195
|
+
columns: 3,
|
|
196
|
+
cells: [
|
|
197
|
+
{ title: 'Design', body: 'Owns the token contract.', tone: 'info' },
|
|
198
|
+
{ title: 'Build', body: 'Ships the structure family.', tone: 'success' },
|
|
199
|
+
{ title: 'Review', body: 'Checks a11y and contrast.', tone: 'warning' },
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: 'tabs',
|
|
205
|
+
label: 'Tabs',
|
|
206
|
+
family: 'structure',
|
|
207
|
+
useWhen: ['Show two to six panels of content, one at a time.'],
|
|
208
|
+
dontUseWhen: ['A long FAQ — use accordion; side-by-side content — use columns.'],
|
|
209
|
+
limits: [
|
|
210
|
+
`2–${BLOCK_CONTENT_LIMITS.tabPanels} panels`,
|
|
211
|
+
`≤ ${BLOCK_CONTENT_LIMITS.blocksPerColumn} blocks per panel`,
|
|
212
|
+
`nesting ≤ ${BLOCK_CONTENT_LIMITS.containerDepth}`,
|
|
213
|
+
'stable id required',
|
|
214
|
+
],
|
|
215
|
+
a11y: 'Renders as a real tab list with tabpanels; keyboard arrows move focus.',
|
|
216
|
+
exampleMinimal: {
|
|
217
|
+
type: 'tabs',
|
|
218
|
+
id: 'overview',
|
|
219
|
+
label: 'Overview',
|
|
220
|
+
panels: [
|
|
221
|
+
{ id: 'plan', label: 'Plan', blocks: [{ type: 'text', markdown: 'Write the brief.' }] },
|
|
222
|
+
{
|
|
223
|
+
id: 'ship',
|
|
224
|
+
label: 'Ship',
|
|
225
|
+
blocks: [{ type: 'text', markdown: 'Validate and release.' }],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
exampleRich: {
|
|
230
|
+
type: 'tabs',
|
|
231
|
+
id: 'harbor-tabs',
|
|
232
|
+
label: 'Harbor product areas',
|
|
233
|
+
defaultPanel: 'design',
|
|
234
|
+
panels: [
|
|
235
|
+
{
|
|
236
|
+
id: 'design',
|
|
237
|
+
label: 'Design',
|
|
238
|
+
blocks: [
|
|
239
|
+
{ type: 'heading', level: 3, text: 'Design' },
|
|
240
|
+
{ type: 'text', markdown: 'Tokens, themes and contrast.' },
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
id: 'build',
|
|
245
|
+
label: 'Build',
|
|
246
|
+
blocks: [{ type: 'text', markdown: 'Components and content blocks.' }],
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
type: 'accordion',
|
|
253
|
+
label: 'Accordion',
|
|
254
|
+
family: 'structure',
|
|
255
|
+
useWhen: ['Collapse short FAQ-style sections under headings.'],
|
|
256
|
+
dontUseWhen: ['One panel at a time with nested blocks — use tabs.'],
|
|
257
|
+
limits: [
|
|
258
|
+
`1–${BLOCK_CONTENT_LIMITS.tabPanels} items`,
|
|
259
|
+
`body ≤ ${BLOCK_CONTENT_LIMITS.shortMarkdown} characters`,
|
|
260
|
+
],
|
|
261
|
+
a11y: 'Each item is a heading button that expands a region; single or multiple mode.',
|
|
262
|
+
exampleMinimal: {
|
|
263
|
+
type: 'accordion',
|
|
264
|
+
items: [
|
|
265
|
+
{ id: 'what', title: 'What is Harbor?', body: 'A fictional product lab.' },
|
|
266
|
+
{ id: 'who', title: 'Who is it for?', body: 'Design and build squads.' },
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
exampleRich: {
|
|
270
|
+
type: 'accordion',
|
|
271
|
+
id: 'faq',
|
|
272
|
+
label: 'Harbor FAQ',
|
|
273
|
+
mode: 'single',
|
|
274
|
+
items: [
|
|
275
|
+
{
|
|
276
|
+
id: 'limits',
|
|
277
|
+
title: 'What are the limits?',
|
|
278
|
+
body: 'Each family keeps short markdown and shallow nesting.',
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
id: 'a11y',
|
|
282
|
+
title: 'How is accessibility handled?',
|
|
283
|
+
body: 'Keyboard operation, AA contrast and forced-colors borders.',
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
type: 'cards',
|
|
290
|
+
label: 'Cards',
|
|
291
|
+
family: 'structure',
|
|
292
|
+
useWhen: ['Present a small set of titled cards, optionally linked.'],
|
|
293
|
+
dontUseWhen: ['Plain cells without links — use grid; data tables — use table.'],
|
|
294
|
+
limits: [
|
|
295
|
+
`≤ ${BLOCK_CONTENT_LIMITS.cards} items`,
|
|
296
|
+
'columns 2–4 optional',
|
|
297
|
+
'href uses the untrusted URL policy',
|
|
298
|
+
],
|
|
299
|
+
a11y: 'Linked cards are single anchors with a visible title; rejected hrefs stay non-interactive.',
|
|
300
|
+
exampleMinimal: {
|
|
301
|
+
type: 'cards',
|
|
302
|
+
items: [
|
|
303
|
+
{ title: 'Docs', body: 'Read the guide.', href: 'https://example.com/docs' },
|
|
304
|
+
{ title: 'Support', body: 'Ask the team.', href: 'mailto:hello@example.com' },
|
|
305
|
+
],
|
|
306
|
+
},
|
|
307
|
+
exampleRich: {
|
|
308
|
+
type: 'cards',
|
|
309
|
+
title: 'Harbor resources',
|
|
310
|
+
columns: 2,
|
|
311
|
+
items: [
|
|
312
|
+
{
|
|
313
|
+
title: 'Design system',
|
|
314
|
+
eyebrow: 'Tokens',
|
|
315
|
+
body: 'Palettes, type and density.',
|
|
316
|
+
href: 'https://example.com/design',
|
|
317
|
+
tone: 'info',
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
title: 'Component kit',
|
|
321
|
+
eyebrow: 'UI',
|
|
322
|
+
body: 'Buttons, cards and tabs.',
|
|
323
|
+
href: 'https://example.com/ui',
|
|
324
|
+
tone: 'success',
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
type: 'image',
|
|
331
|
+
label: 'Image',
|
|
332
|
+
family: 'media',
|
|
333
|
+
useWhen: ['Show one photo or illustration inline.'],
|
|
334
|
+
dontUseWhen: ['A set of related photos — use gallery; a captioned plate — use figure.'],
|
|
335
|
+
limits: [
|
|
336
|
+
'src is avatar:, relative raster path, or png/jpeg/webp/gif data URI (no remote URLs)',
|
|
337
|
+
`width/height ≤ ${BLOCK_CONTENT_LIMITS.mediaDimension}`,
|
|
338
|
+
],
|
|
339
|
+
a11y: 'alt is required unless decorative: true; caption and credit are plain text.',
|
|
340
|
+
exampleMinimal: {
|
|
341
|
+
type: 'image',
|
|
342
|
+
src: 'assets/cover.webp',
|
|
343
|
+
alt: 'Cover',
|
|
344
|
+
width: 16,
|
|
345
|
+
height: 9,
|
|
346
|
+
},
|
|
347
|
+
exampleRich: {
|
|
348
|
+
type: 'image',
|
|
349
|
+
src: 'assets/harbor.webp',
|
|
350
|
+
alt: 'Harbor at dusk',
|
|
351
|
+
width: 1200,
|
|
352
|
+
height: 800,
|
|
353
|
+
caption: 'Northwind Labs dock (fictional).',
|
|
354
|
+
credit: 'Example Studio',
|
|
355
|
+
fit: 'cover',
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
type: 'figure',
|
|
360
|
+
label: 'Figure',
|
|
361
|
+
family: 'media',
|
|
362
|
+
useWhen: ['A single image that must carry a caption.'],
|
|
363
|
+
dontUseWhen: ['Decorative chrome without a caption — use image with decorative: true.'],
|
|
364
|
+
limits: ['caption required', 'same src rules as image'],
|
|
365
|
+
a11y: 'Rendered as figure/figcaption; alt still required unless decorative.',
|
|
366
|
+
exampleMinimal: {
|
|
367
|
+
type: 'figure',
|
|
368
|
+
src: 'assets/diagram.webp',
|
|
369
|
+
alt: 'Flow diagram',
|
|
370
|
+
width: 800,
|
|
371
|
+
height: 500,
|
|
372
|
+
caption: 'Request path through the API gateway.',
|
|
373
|
+
},
|
|
374
|
+
exampleRich: {
|
|
375
|
+
type: 'figure',
|
|
376
|
+
src: 'assets/diagram.webp',
|
|
377
|
+
alt: 'Architecture sketch',
|
|
378
|
+
width: 960,
|
|
379
|
+
height: 540,
|
|
380
|
+
caption: 'Harbor Notes service map (example).',
|
|
381
|
+
credit: 'Northwind Labs',
|
|
382
|
+
fit: 'contain',
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
type: 'video',
|
|
387
|
+
label: 'Video',
|
|
388
|
+
family: 'media',
|
|
389
|
+
useWhen: ['Short product or tutorial clips that ship with the document.'],
|
|
390
|
+
dontUseWhen: ['Remote streams — only embedded or relative mp4/webm sources.'],
|
|
391
|
+
limits: [
|
|
392
|
+
'src is relative mp4/webm or data URI',
|
|
393
|
+
'autoplay requires muted: true',
|
|
394
|
+
`width/height ≤ ${BLOCK_CONTENT_LIMITS.mediaDimension}`,
|
|
395
|
+
],
|
|
396
|
+
a11y: 'label is the accessible name; controls default on; autoplay respects reduced motion.',
|
|
397
|
+
exampleMinimal: {
|
|
398
|
+
type: 'video',
|
|
399
|
+
src: './clips/demo.mp4',
|
|
400
|
+
label: 'Product tour',
|
|
401
|
+
width: 16,
|
|
402
|
+
height: 9,
|
|
403
|
+
},
|
|
404
|
+
exampleRich: {
|
|
405
|
+
type: 'video',
|
|
406
|
+
src: './clips/demo.mp4',
|
|
407
|
+
label: 'Harbor Notes walkthrough',
|
|
408
|
+
poster: 'assets/poster.webp',
|
|
409
|
+
width: 1280,
|
|
410
|
+
height: 720,
|
|
411
|
+
caption: 'Two-minute overview (fictional).',
|
|
412
|
+
controls: true,
|
|
413
|
+
loop: false,
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
type: 'gallery',
|
|
418
|
+
label: 'Gallery',
|
|
419
|
+
family: 'media',
|
|
420
|
+
useWhen: ['Two or more related images in a grid.'],
|
|
421
|
+
dontUseWhen: ['A single image — use image or figure.'],
|
|
422
|
+
limits: [
|
|
423
|
+
`≤ ${BLOCK_CONTENT_LIMITS.galleryItems} items`,
|
|
424
|
+
'each item follows image src rules',
|
|
425
|
+
'columns 2–4 optional',
|
|
426
|
+
],
|
|
427
|
+
a11y: 'Each item keeps its own alt; title labels the group.',
|
|
428
|
+
exampleMinimal: {
|
|
429
|
+
type: 'gallery',
|
|
430
|
+
items: [
|
|
431
|
+
{ src: 'assets/a.webp', alt: 'A', width: 4, height: 3 },
|
|
432
|
+
{ src: 'assets/b.webp', alt: 'B', width: 4, height: 3 },
|
|
433
|
+
],
|
|
434
|
+
},
|
|
435
|
+
exampleRich: {
|
|
436
|
+
type: 'gallery',
|
|
437
|
+
title: 'Harbor Notes screens',
|
|
438
|
+
columns: 3,
|
|
439
|
+
items: [
|
|
440
|
+
{
|
|
441
|
+
src: 'assets/a.webp',
|
|
442
|
+
alt: 'Inbox',
|
|
443
|
+
width: 800,
|
|
444
|
+
height: 600,
|
|
445
|
+
caption: 'Inbox',
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
src: 'assets/b.webp',
|
|
449
|
+
alt: 'Editor',
|
|
450
|
+
width: 800,
|
|
451
|
+
height: 600,
|
|
452
|
+
caption: 'Editor',
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
src: 'assets/c.webp',
|
|
456
|
+
alt: 'Share sheet',
|
|
457
|
+
width: 800,
|
|
458
|
+
height: 600,
|
|
459
|
+
caption: 'Share',
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
type: 'table',
|
|
466
|
+
label: 'Table',
|
|
467
|
+
family: 'data',
|
|
468
|
+
useWhen: ['Compare a small set of labeled values in rows and columns.'],
|
|
469
|
+
dontUseWhen: ['Huge datasets — use a data grid view instead.'],
|
|
470
|
+
limits: [
|
|
471
|
+
`≤ ${BLOCK_CONTENT_LIMITS.tableColumns} columns`,
|
|
472
|
+
`≤ ${BLOCK_CONTENT_LIMITS.tableRows} rows`,
|
|
473
|
+
'cells are plain text, numbers or null',
|
|
474
|
+
],
|
|
475
|
+
a11y: 'Native table markup with caption; keep headers short.',
|
|
476
|
+
exampleMinimal: {
|
|
477
|
+
type: 'table',
|
|
478
|
+
columns: [{ id: 'name', label: 'Name' }],
|
|
479
|
+
rows: [{ name: 'Ada' }],
|
|
480
|
+
},
|
|
481
|
+
exampleRich: {
|
|
482
|
+
type: 'table',
|
|
483
|
+
caption: 'Fictional quarterly scores',
|
|
484
|
+
columns: [
|
|
485
|
+
{ id: 'team', label: 'Team' },
|
|
486
|
+
{ id: 'score', label: 'Score' },
|
|
487
|
+
],
|
|
488
|
+
rows: [
|
|
489
|
+
{ team: 'Design', score: 92 },
|
|
490
|
+
{ team: 'Build', score: 88 },
|
|
491
|
+
],
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
type: 'stat',
|
|
496
|
+
label: 'Stat row',
|
|
497
|
+
family: 'data',
|
|
498
|
+
useWhen: ['Show a few key figures with short labels.'],
|
|
499
|
+
dontUseWhen: ['A full KPI dashboard — prefer kpi with denser cards.'],
|
|
500
|
+
limits: [`≤ ${BLOCK_CONTENT_LIMITS.statItems} items`],
|
|
501
|
+
a11y: 'Each stat is a labeled value; deltas are plain text.',
|
|
502
|
+
exampleMinimal: {
|
|
503
|
+
type: 'stat',
|
|
504
|
+
items: [{ label: 'Active', value: '128' }],
|
|
505
|
+
},
|
|
506
|
+
exampleRich: {
|
|
507
|
+
type: 'stat',
|
|
508
|
+
items: [
|
|
509
|
+
{ label: 'Active seats', value: '128', delta: '+12%', tone: 'success' },
|
|
510
|
+
{ label: 'Median latency', value: '42 ms', tone: 'info' },
|
|
511
|
+
],
|
|
512
|
+
},
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
type: 'kpi',
|
|
516
|
+
label: 'KPI row',
|
|
517
|
+
family: 'data',
|
|
518
|
+
useWhen: ['Highlight outcome metrics in a compact row.'],
|
|
519
|
+
dontUseWhen: ['Narrative explanation — pair with text blocks.'],
|
|
520
|
+
limits: [`≤ ${BLOCK_CONTENT_LIMITS.statItems} items`],
|
|
521
|
+
a11y: 'Same structure as stat; rendered as KPI cards.',
|
|
522
|
+
exampleMinimal: {
|
|
523
|
+
type: 'kpi',
|
|
524
|
+
items: [{ label: 'NPS', value: '54' }],
|
|
525
|
+
},
|
|
526
|
+
exampleRich: {
|
|
527
|
+
type: 'kpi',
|
|
528
|
+
items: [
|
|
529
|
+
{ label: 'NPS', value: '54', delta: '+3', hint: 'Trailing 90 days', tone: 'success' },
|
|
530
|
+
{ label: 'Churn', value: '2.1%', delta: '-0.4%', tone: 'success' },
|
|
531
|
+
],
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
type: 'chart',
|
|
536
|
+
label: 'Chart',
|
|
537
|
+
family: 'data',
|
|
538
|
+
useWhen: ['Embed a small chart with a title and description.'],
|
|
539
|
+
dontUseWhen: ['Exploratory analytics — use a full chart host.'],
|
|
540
|
+
limits: [
|
|
541
|
+
'kind is a closed set (line, area, bar, stacked-bar, heatmap, scatter, bubble)',
|
|
542
|
+
'title and description required',
|
|
543
|
+
'series/points/cells capped for documents',
|
|
544
|
+
],
|
|
545
|
+
a11y: 'description is required; charts expose a data table fallback.',
|
|
546
|
+
exampleMinimal: {
|
|
547
|
+
type: 'chart',
|
|
548
|
+
kind: 'bar',
|
|
549
|
+
title: 'Sign-ups',
|
|
550
|
+
description: 'Weekly fictional sign-ups.',
|
|
551
|
+
series: [
|
|
552
|
+
{
|
|
553
|
+
id: 'new',
|
|
554
|
+
label: 'New',
|
|
555
|
+
points: [
|
|
556
|
+
{ x: 'W1', y: 12 },
|
|
557
|
+
{ x: 'W2', y: 18 },
|
|
558
|
+
],
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
},
|
|
562
|
+
exampleRich: {
|
|
563
|
+
type: 'chart',
|
|
564
|
+
kind: 'line',
|
|
565
|
+
title: 'Latency',
|
|
566
|
+
description: 'Median latency in milliseconds for a fictional service.',
|
|
567
|
+
series: [
|
|
568
|
+
{
|
|
569
|
+
id: 'p50',
|
|
570
|
+
label: 'p50',
|
|
571
|
+
points: [
|
|
572
|
+
{ x: 'Mon', y: 40 },
|
|
573
|
+
{ x: 'Tue', y: 38 },
|
|
574
|
+
{ x: 'Wed', y: 41 },
|
|
575
|
+
],
|
|
576
|
+
},
|
|
577
|
+
],
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
]);
|
|
581
|
+
const byType = new Map(BLOCK_CATALOG.map((entry) => [entry.type, entry]));
|
|
582
|
+
/** Look up catalog metadata for a block type. */
|
|
583
|
+
export function getCatalogEntry(type) {
|
|
584
|
+
return byType.get(type);
|
|
585
|
+
}
|
|
586
|
+
/** All catalog types in registration order. */
|
|
587
|
+
export function listCatalogTypes() {
|
|
588
|
+
return BLOCK_CATALOG.map((entry) => entry.type);
|
|
589
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/// <reference path="../../css-modules.d.ts" />
|
|
2
|
+
export { BLOCK_CATALOG, getCatalogEntry, listCatalogTypes } from './entries.js';
|
|
3
|
+
export type { BlockAuthoringDiagnostic, BlockAuthoringValidation, BlockCatalogEntry, BlockDiagnosticPath, } from './types.js';
|
|
4
|
+
export { parseBlocksForAuthoring, validateBlocksForAuthoring } from './validate.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Block, BlockType } from '../schema/blocks.js';
|
|
2
|
+
import type { BlockFamily } from '../schema/vocabulary.js';
|
|
3
|
+
/**
|
|
4
|
+
* Authoring metadata for one block type (USE WHEN / DON'T USE WHEN / limits /
|
|
5
|
+
* a11y / examples). Agents, MCP and deck lint read this data instead of prose.
|
|
6
|
+
*/
|
|
7
|
+
export interface BlockCatalogEntry {
|
|
8
|
+
type: BlockType;
|
|
9
|
+
/** Short editor label. */
|
|
10
|
+
label: string;
|
|
11
|
+
family: BlockFamily;
|
|
12
|
+
/** Situations where this block is the right choice. */
|
|
13
|
+
useWhen: readonly string[];
|
|
14
|
+
/** Situations where another block (or none) is better. */
|
|
15
|
+
dontUseWhen: readonly string[];
|
|
16
|
+
/** Human-readable caps from the schema (counts, lengths, nesting). */
|
|
17
|
+
limits: readonly string[];
|
|
18
|
+
/** How the block stays usable with keyboard, screen readers and contrast. */
|
|
19
|
+
a11y: string;
|
|
20
|
+
/** Smallest valid instance (required fields only when possible). */
|
|
21
|
+
exampleMinimal: Block;
|
|
22
|
+
/** Richer valid instance showing common optional fields. */
|
|
23
|
+
exampleRich: Block;
|
|
24
|
+
}
|
|
25
|
+
export type BlockDiagnosticPath = string | number;
|
|
26
|
+
export interface BlockAuthoringDiagnostic {
|
|
27
|
+
code: string;
|
|
28
|
+
path: BlockDiagnosticPath[];
|
|
29
|
+
jsonPath: string;
|
|
30
|
+
message: string;
|
|
31
|
+
hint: string;
|
|
32
|
+
}
|
|
33
|
+
export interface BlockAuthoringValidation {
|
|
34
|
+
valid: boolean;
|
|
35
|
+
diagnostics: BlockAuthoringDiagnostic[];
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Block } from '../schema/blocks.js';
|
|
2
|
+
import type { BlockAuthoringValidation } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validate untrusted block author input and return path-addressed repair
|
|
5
|
+
* diagnostics. Never throws.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateBlocksForAuthoring(input: unknown): BlockAuthoringValidation;
|
|
8
|
+
/** Re-export parsed blocks when authoring validation succeeds. */
|
|
9
|
+
export declare function parseBlocksForAuthoring(input: unknown): {
|
|
10
|
+
success: true;
|
|
11
|
+
blocks: Block[];
|
|
12
|
+
} | {
|
|
13
|
+
success: false;
|
|
14
|
+
validation: BlockAuthoringValidation;
|
|
15
|
+
};
|