@aglyn/plugins-mui 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +22 -0
  3. package/package.json +47 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +22 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/accordion.d.ts +96 -0
  8. package/src/lib/components/accordion.js +392 -0
  9. package/src/lib/components/accordion.js.map +1 -0
  10. package/src/lib/components/app-bar.d.ts +32 -0
  11. package/src/lib/components/app-bar.js +86 -0
  12. package/src/lib/components/app-bar.js.map +1 -0
  13. package/src/lib/components/blocks.d.ts +46 -0
  14. package/src/lib/components/blocks.js +1007 -0
  15. package/src/lib/components/blocks.js.map +1 -0
  16. package/src/lib/components/box.d.ts +47 -0
  17. package/src/lib/components/box.js +125 -0
  18. package/src/lib/components/box.js.map +1 -0
  19. package/src/lib/components/breadcrumbs.d.ts +44 -0
  20. package/src/lib/components/breadcrumbs.js +172 -0
  21. package/src/lib/components/breadcrumbs.js.map +1 -0
  22. package/src/lib/components/button.d.ts +89 -0
  23. package/src/lib/components/button.js +272 -0
  24. package/src/lib/components/button.js.map +1 -0
  25. package/src/lib/components/card.d.ts +61 -0
  26. package/src/lib/components/card.js +336 -0
  27. package/src/lib/components/card.js.map +1 -0
  28. package/src/lib/components/collection.d.ts +514 -0
  29. package/src/lib/components/collection.js +2999 -0
  30. package/src/lib/components/collection.js.map +1 -0
  31. package/src/lib/components/container.d.ts +42 -0
  32. package/src/lib/components/container.js +169 -0
  33. package/src/lib/components/container.js.map +1 -0
  34. package/src/lib/components/custom-html.d.ts +78 -0
  35. package/src/lib/components/custom-html.js +219 -0
  36. package/src/lib/components/custom-html.js.map +1 -0
  37. package/src/lib/components/data-table.d.ts +57 -0
  38. package/src/lib/components/data-table.js +216 -0
  39. package/src/lib/components/data-table.js.map +1 -0
  40. package/src/lib/components/document-root.d.ts +77 -0
  41. package/src/lib/components/document-root.js +118 -0
  42. package/src/lib/components/document-root.js.map +1 -0
  43. package/src/lib/components/drawer.d.ts +93 -0
  44. package/src/lib/components/drawer.js +566 -0
  45. package/src/lib/components/drawer.js.map +1 -0
  46. package/src/lib/components/function-controls.d.ts +66 -0
  47. package/src/lib/components/function-controls.js +207 -0
  48. package/src/lib/components/function-controls.js.map +1 -0
  49. package/src/lib/components/function-scope.d.ts +110 -0
  50. package/src/lib/components/function-scope.js +478 -0
  51. package/src/lib/components/function-scope.js.map +1 -0
  52. package/src/lib/components/function-widget.d.ts +75 -0
  53. package/src/lib/components/function-widget.js +307 -0
  54. package/src/lib/components/function-widget.js.map +1 -0
  55. package/src/lib/components/grid.d.ts +91 -0
  56. package/src/lib/components/grid.js +322 -0
  57. package/src/lib/components/grid.js.map +1 -0
  58. package/src/lib/components/icon.d.ts +54 -0
  59. package/src/lib/components/icon.js +163 -0
  60. package/src/lib/components/icon.js.map +1 -0
  61. package/src/lib/components/image-list.d.ts +58 -0
  62. package/src/lib/components/image-list.js +336 -0
  63. package/src/lib/components/image-list.js.map +1 -0
  64. package/src/lib/components/image.d.ts +154 -0
  65. package/src/lib/components/image.js +451 -0
  66. package/src/lib/components/image.js.map +1 -0
  67. package/src/lib/components/inline-text.d.ts +74 -0
  68. package/src/lib/components/inline-text.js +407 -0
  69. package/src/lib/components/inline-text.js.map +1 -0
  70. package/src/lib/components/language-switcher.d.ts +35 -0
  71. package/src/lib/components/language-switcher.js +179 -0
  72. package/src/lib/components/language-switcher.js.map +1 -0
  73. package/src/lib/components/layout-slot.d.ts +68 -0
  74. package/src/lib/components/layout-slot.js +192 -0
  75. package/src/lib/components/layout-slot.js.map +1 -0
  76. package/src/lib/components/link-box-accessible-name.d.ts +79 -0
  77. package/src/lib/components/link-box-accessible-name.js +158 -0
  78. package/src/lib/components/link-box-accessible-name.js.map +1 -0
  79. package/src/lib/components/link-box.d.ts +66 -0
  80. package/src/lib/components/link-box.js +212 -0
  81. package/src/lib/components/link-box.js.map +1 -0
  82. package/src/lib/components/list-item-text.d.ts +22 -0
  83. package/src/lib/components/list-item-text.js +86 -0
  84. package/src/lib/components/list-item-text.js.map +1 -0
  85. package/src/lib/components/list-item.d.ts +32 -0
  86. package/src/lib/components/list-item.js +127 -0
  87. package/src/lib/components/list-item.js.map +1 -0
  88. package/src/lib/components/list.d.ts +34 -0
  89. package/src/lib/components/list.js +108 -0
  90. package/src/lib/components/list.js.map +1 -0
  91. package/src/lib/components/markdown.d.ts +129 -0
  92. package/src/lib/components/markdown.js +853 -0
  93. package/src/lib/components/markdown.js.map +1 -0
  94. package/src/lib/components/nav-menu.d.ts +68 -0
  95. package/src/lib/components/nav-menu.js +683 -0
  96. package/src/lib/components/nav-menu.js.map +1 -0
  97. package/src/lib/components/pagination.d.ts +59 -0
  98. package/src/lib/components/pagination.js +243 -0
  99. package/src/lib/components/pagination.js.map +1 -0
  100. package/src/lib/components/paper.d.ts +47 -0
  101. package/src/lib/components/paper.js +202 -0
  102. package/src/lib/components/paper.js.map +1 -0
  103. package/src/lib/components/plugin-frame.d.ts +64 -0
  104. package/src/lib/components/plugin-frame.js +335 -0
  105. package/src/lib/components/plugin-frame.js.map +1 -0
  106. package/src/lib/components/plugin.d.ts +95 -0
  107. package/src/lib/components/plugin.js +304 -0
  108. package/src/lib/components/plugin.js.map +1 -0
  109. package/src/lib/components/product.d.ts +40 -0
  110. package/src/lib/components/product.js +287 -0
  111. package/src/lib/components/product.js.map +1 -0
  112. package/src/lib/components/reusable-instance.d.ts +57 -0
  113. package/src/lib/components/reusable-instance.js +126 -0
  114. package/src/lib/components/reusable-instance.js.map +1 -0
  115. package/src/lib/components/screen-link.d.ts +85 -0
  116. package/src/lib/components/screen-link.js +324 -0
  117. package/src/lib/components/screen-link.js.map +1 -0
  118. package/src/lib/components/search-box.d.ts +41 -0
  119. package/src/lib/components/search-box.js +125 -0
  120. package/src/lib/components/search-box.js.map +1 -0
  121. package/src/lib/components/section.d.ts +56 -0
  122. package/src/lib/components/section.js +132 -0
  123. package/src/lib/components/section.js.map +1 -0
  124. package/src/lib/components/stack.d.ts +55 -0
  125. package/src/lib/components/stack.js +309 -0
  126. package/src/lib/components/stack.js.map +1 -0
  127. package/src/lib/components/tabs.d.ts +288 -0
  128. package/src/lib/components/tabs.js +788 -0
  129. package/src/lib/components/tabs.js.map +1 -0
  130. package/src/lib/components/theme-mode-switcher.d.ts +38 -0
  131. package/src/lib/components/theme-mode-switcher.js +168 -0
  132. package/src/lib/components/theme-mode-switcher.js.map +1 -0
  133. package/src/lib/components/toolbar.d.ts +37 -0
  134. package/src/lib/components/toolbar.js +117 -0
  135. package/src/lib/components/toolbar.js.map +1 -0
  136. package/src/lib/components/typography.d.ts +33 -0
  137. package/src/lib/components/typography.js +433 -0
  138. package/src/lib/components/typography.js.map +1 -0
  139. package/src/lib/components/video-lightbox-controls.d.ts +131 -0
  140. package/src/lib/components/video-lightbox-controls.js +536 -0
  141. package/src/lib/components/video-lightbox-controls.js.map +1 -0
  142. package/src/lib/components/video-lightbox.d.ts +60 -0
  143. package/src/lib/components/video-lightbox.js +247 -0
  144. package/src/lib/components/video-lightbox.js.map +1 -0
  145. package/src/lib/components/video-playback-beacon.d.ts +80 -0
  146. package/src/lib/components/video-playback-beacon.js +128 -0
  147. package/src/lib/components/video-playback-beacon.js.map +1 -0
  148. package/src/lib/components/video-player-frame.d.ts +58 -0
  149. package/src/lib/components/video-player-frame.js +51 -0
  150. package/src/lib/components/video-player-frame.js.map +1 -0
  151. package/src/lib/components/video.d.ts +220 -0
  152. package/src/lib/components/video.js +874 -0
  153. package/src/lib/components/video.js.map +1 -0
  154. package/src/lib/constants/bundle-common.d.ts +17 -0
  155. package/src/lib/constants/bundle-common.js +18 -0
  156. package/src/lib/constants/bundle-common.js.map +1 -0
  157. package/src/lib/constants/field-presets.d.ts +93 -0
  158. package/src/lib/constants/field-presets.js +248 -0
  159. package/src/lib/constants/field-presets.js.map +1 -0
  160. package/src/lib/plugin.d.ts +80 -0
  161. package/src/lib/plugin.js +599 -0
  162. package/src/lib/plugin.js.map +1 -0
  163. package/src/lib/utils/author-html-label.d.ts +73 -0
  164. package/src/lib/utils/author-html-label.js +89 -0
  165. package/src/lib/utils/author-html-label.js.map +1 -0
  166. package/src/lib/utils/drop-cleared-props.d.ts +18 -0
  167. package/src/lib/utils/drop-cleared-props.js +74 -0
  168. package/src/lib/utils/drop-cleared-props.js.map +1 -0
  169. package/src/lib/utils/element-picker.d.ts +99 -0
  170. package/src/lib/utils/element-picker.js +140 -0
  171. package/src/lib/utils/element-picker.js.map +1 -0
  172. package/src/lib/utils/generate-preset-id.d.ts +19 -0
  173. package/src/lib/utils/generate-preset-id.js +25 -0
  174. package/src/lib/utils/generate-preset-id.js.map +1 -0
  175. package/src/lib/utils/link-target-props.d.ts +53 -0
  176. package/src/lib/utils/link-target-props.js +53 -0
  177. package/src/lib/utils/link-target-props.js.map +1 -0
@@ -0,0 +1,853 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2026 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import * as Aglyn from "@aglyn/aglyn";
20
+ import { mdiLanguageMarkdown, mdiTableOfContents } from "@aglyn/shared-data-mdi";
21
+ import { AppLink } from "@aglyn/shared-ui-jsx";
22
+ import { scrollOverflowFadeKeyframes, scrollOverflowFadeTimeline, scrollRegionProps, scrollableTableSx, scrollableTableWrapperSx } from "@aglyn/shared-ui-jsx/utils/scroll-overflow";
23
+ import Box from "@mui/material/Box";
24
+ import MuiLink from "@mui/material/Link";
25
+ import Typography from "@mui/material/Typography";
26
+ import { observer } from "mobx-react-lite";
27
+ import { forwardRef, useContext, useMemo } from "react";
28
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
29
+ import { dropClearedProps } from "../utils/drop-cleared-props.js";
30
+ import { generatePresetId } from "../utils/generate-preset-id.js";
31
+ // Component ids are persisted in screen documents; never rename.
32
+ export const MARKDOWN_ID = 'markdown';
33
+ /** A compose-time token the tenant has not substituted — never a document. */ const UNRESOLVED_TOKEN = /^\{\{[^}]+\}\}$/;
34
+ /**
35
+ * What a screen reader announces on reaching a table's scroll box.
36
+ *
37
+ * The plain word, not the table's own heading: the name has to come from
38
+ * something every document has, and a markdown table carries no caption.
39
+ */ const TABLE_REGION_LABEL = 'Table';
40
+ export const TABLE_OF_CONTENTS_ID = 'tableOfContents';
41
+ /**
42
+ * A long document's body type, which is NOT MUI's `body1` (AGL-1162).
43
+ *
44
+ * A privacy policy is read, not skimmed: the house measure for running prose
45
+ * is 17px on a 1.75 leading, in `text.primary` rather than the softened
46
+ * secondary a caption uses. MUI's default 16/1.5 sets the same words tighter
47
+ * and lighter, and a page built from Typography defaults reads visibly
48
+ * different from one built by hand next to it — which is how the legal pages
49
+ * ended up hand-assembled from hundreds of Typography nodes in the first
50
+ * place.
51
+ */ const BODY_SX = {
52
+ fontSize: 17,
53
+ lineHeight: 1.75,
54
+ color: 'text.primary'
55
+ };
56
+ /**
57
+ * Heading ramp (AGL-1162). Sizes step across `{xs, sm, md}` and the tracking
58
+ * steps WITH them: tracking is a function of size, so a single letterSpacing
59
+ * that looks right at the desktop size is visibly loose on a phone. Negative
60
+ * throughout — display sizes need the letters pulled together, which is the
61
+ * opposite of the positive tracking small uppercase labels take.
62
+ */ const HEADING_SX = {
63
+ 2: {
64
+ fontSize: {
65
+ xs: 26,
66
+ sm: 30,
67
+ md: 34
68
+ },
69
+ letterSpacing: {
70
+ xs: '-0.3px',
71
+ sm: '-0.4px',
72
+ md: '-0.5px'
73
+ },
74
+ lineHeight: 1.25,
75
+ fontWeight: 700
76
+ },
77
+ 3: {
78
+ fontSize: {
79
+ xs: 19,
80
+ sm: 20,
81
+ md: 22
82
+ },
83
+ letterSpacing: {
84
+ xs: '-0.1px',
85
+ sm: '-0.15px',
86
+ md: '-0.2px'
87
+ },
88
+ lineHeight: 1.35,
89
+ fontWeight: 700
90
+ }
91
+ };
92
+ /**
93
+ * Breathing room a heading keeps above it when an anchor lands on it. Sites
94
+ * built here usually have a sticky app bar, and without this the browser
95
+ * scrolls the heading to y=0 — underneath the bar — so a working link looks
96
+ * like a broken one.
97
+ */ const ANCHOR_SCROLL_MARGIN = Aglyn.HEADING_ANCHOR_SCROLL_MARGIN;
98
+ /**
99
+ * Inline runs as elements (AGL-1162), following the entry-body renderer:
100
+ * internal links route through AppLink for client-side navigation, external
101
+ * ones stay plain anchors, and editing surfaces render the link look without
102
+ * an href so clicking never leaves the canvas.
103
+ *
104
+ * Which of those a link is — and whether it is a link at all — is
105
+ * `resolveMarkdownLink`'s to say (AGL-3118), so a target named by reference
106
+ * resolves through the same routing map an element link does, and one whose
107
+ * target is gone renders as its words rather than as `href="entry:…"`.
108
+ */ const renderInlines = (inlines, links)=>inlines.map((inline, index)=>{
109
+ if (inline.type === 'bold') return /*#__PURE__*/ _jsx("strong", {
110
+ children: inline.text
111
+ }, index);
112
+ if (inline.type === 'italic') return /*#__PURE__*/ _jsx("em", {
113
+ children: inline.text
114
+ }, index);
115
+ if (inline.type === 'link') {
116
+ const link = Aglyn.resolveMarkdownLink(inline.href, links);
117
+ if (link.kind === 'text') return /*#__PURE__*/ _jsx("span", {
118
+ children: inline.text
119
+ }, index);
120
+ if (link.kind === 'inert') {
121
+ return /*#__PURE__*/ _jsx(MuiLink, {
122
+ component: "span",
123
+ sx: {
124
+ cursor: 'default'
125
+ },
126
+ children: inline.text
127
+ }, index);
128
+ }
129
+ return link.kind === 'internal' ? /*#__PURE__*/ _jsx(AppLink, {
130
+ href: link.href,
131
+ children: inline.text
132
+ }, index) : /*#__PURE__*/ _jsx(MuiLink, {
133
+ href: link.href,
134
+ children: inline.text
135
+ }, index);
136
+ }
137
+ return /*#__PURE__*/ _jsx("span", {
138
+ children: inline.text
139
+ }, index);
140
+ });
141
+ /**
142
+ * A whole document authored as markdown (AGL-1162).
143
+ *
144
+ * The elements that made a legal or policy page before this were hundreds of
145
+ * Typography nodes, one per paragraph — which meant the page could not be
146
+ * pasted from, or back into, the markdown file in Drive that is its actual
147
+ * source. Here the source IS the element's content, so updating the page is
148
+ * one paste.
149
+ *
150
+ * Rendered through the shared markdown-lite parser, which emits plain data
151
+ * blocks and never an HTML string — so there is no `dangerouslySetInnerHTML`
152
+ * anywhere on this path and nothing to sanitize. Parsing is pure, so the full
153
+ * document server-renders and the text is in the crawled HTML.
154
+ *
155
+ * Child NODES are never rendered, in either branch (AGL-1388). The document
156
+ * is the `content` prop; there is no position in a parsed block list that a
157
+ * dropped element could occupy, so the schema turns dropping off and
158
+ * `nodeAcceptsChildren` now honors that — a drop lands as a sibling instead.
159
+ * `children` is destructured away rather than left in `rest` because the
160
+ * empty-content branch spreads `rest` onto a childless Box: without this, a
161
+ * Markdown element rendered exactly the child nodes it had swallowed a
162
+ * moment earlier as soon as its content was cleared.
163
+ */ const Markdown = /*#__PURE__*/ forwardRef((props, ref)=>{
164
+ const { content, intrinsicSizes, sx, children: _children } = props, rest = _object_without_properties_loose(props, [
165
+ "content",
166
+ "intrinsicSizes",
167
+ "sx",
168
+ "children"
169
+ ]);
170
+ // The routing map travels with the suppression flag: both decide what a
171
+ // link in this document renders as (AGL-3118).
172
+ const { suppressNavigation, screens } = useContext(Aglyn.ScreenLinkContext);
173
+ const links = useMemo(()=>({
174
+ suppressNavigation,
175
+ screens
176
+ }), [
177
+ suppressNavigation,
178
+ screens
179
+ ]);
180
+ /**
181
+ * The site being rendered, for image blocks (AGL-1686). Read once here
182
+ * rather than per block: hooks cannot run inside the `blocks.map` below,
183
+ * and a document may hold any number of images.
184
+ */ const { hostId } = Aglyn.useSite();
185
+ const source = (content != null ? content : '').trim();
186
+ const blocks = useMemo(()=>source ? Aglyn.parseMarkdownLite(source) : [], [
187
+ source
188
+ ]);
189
+ // Slugs are derived rather than stored (see collectMarkdownHeadings), and
190
+ // keyed by block index so the ids land on the right headings even when two
191
+ // of them carry the same words. The map is built in `markdown-lite` now,
192
+ // because every renderer needs exactly this and five of the six were not
193
+ // getting it (AGL-1162).
194
+ const slugs = useMemo(()=>Aglyn.markdownHeadingSlugs(blocks), [
195
+ blocks
196
+ ]);
197
+ if (!source) {
198
+ // Editing surfaces get somewhere to click; the published page renders
199
+ // nothing rather than a placeholder nobody meant to publish.
200
+ if (!suppressNavigation) return /*#__PURE__*/ _jsx(Box, _extends({
201
+ ref: ref,
202
+ sx: sx
203
+ }, rest));
204
+ return /*#__PURE__*/ _jsx(Box, _extends({
205
+ ref: ref
206
+ }, rest, {
207
+ sx: [
208
+ {
209
+ p: 2,
210
+ border: '1px dashed',
211
+ borderColor: 'divider',
212
+ color: 'text.secondary',
213
+ fontSize: 12
214
+ },
215
+ ...Array.isArray(sx) ? sx : sx ? [
216
+ sx
217
+ ] : []
218
+ ],
219
+ children: 'Markdown — paste the document into the Content attribute'
220
+ }));
221
+ }
222
+ return /*#__PURE__*/ _jsx(Box, _extends({
223
+ ref: ref,
224
+ sx: sx
225
+ }, rest, {
226
+ children: blocks.map((block, index)=>{
227
+ if (block.type === 'heading') {
228
+ return /*#__PURE__*/ _jsx(Typography, {
229
+ // The anchor a table of contents links to. `component` is set
230
+ // explicitly because a Typography with only an `sx` fontSize
231
+ // still renders a <p>: the page would screenshot correctly and
232
+ // have no headings in it at all.
233
+ id: slugs[index],
234
+ component: block.level === 2 ? 'h2' : 'h3',
235
+ sx: _extends({}, HEADING_SX[block.level], {
236
+ color: 'text.primary',
237
+ scrollMarginTop: `${ANCHOR_SCROLL_MARGIN}px`,
238
+ mt: block.level === 2 ? 5 : 3.5,
239
+ mb: 1.5,
240
+ '&:first-of-type': {
241
+ mt: 0
242
+ }
243
+ }),
244
+ children: renderInlines(block.inlines, links)
245
+ }, index);
246
+ }
247
+ if (block.type === 'image') {
248
+ return /*#__PURE__*/ _jsx(Box, _extends({
249
+ component: "img"
250
+ }, Aglyn.mediaBodyImageAttributes({
251
+ src: block.src,
252
+ hostId,
253
+ size: intrinsicSizes == null ? void 0 : intrinsicSizes[block.src]
254
+ }), {
255
+ alt: block.alt,
256
+ // `height: 'auto'` is load-bearing beside the pair above, not
257
+ // tidiness: the pair's `height` arrives as a presentational hint
258
+ // too, and a hint that survives the `maxWidth` cap squashes the
259
+ // picture instead of scaling it. It is what `auto` already
260
+ // resolved to before the pair existed, so this changes nothing
261
+ // for an image the composition could not measure.
262
+ sx: {
263
+ maxWidth: '100%',
264
+ height: 'auto',
265
+ borderRadius: 1,
266
+ my: 2
267
+ }
268
+ }, Aglyn.DEFERRED_IMAGE_ATTRIBUTES), index);
269
+ }
270
+ if (block.type === 'list') {
271
+ return /*#__PURE__*/ _jsx(Box, {
272
+ component: "ul",
273
+ sx: _extends({}, BODY_SX, {
274
+ my: 2,
275
+ pl: 3,
276
+ '& li': {
277
+ mb: 1
278
+ }
279
+ }),
280
+ children: block.items.map((item, itemIndex)=>/*#__PURE__*/ _jsx("li", {
281
+ children: renderInlines(item, links)
282
+ }, itemIndex))
283
+ }, index);
284
+ }
285
+ // A numbered list (AGL-1320): the same measure as the bullet list,
286
+ // as a real `<ol>` carrying `start` — a legal document's enumerated
287
+ // elements are the reason this block exists.
288
+ if (block.type === 'orderedList') {
289
+ return /*#__PURE__*/ _jsx(Box, {
290
+ component: "ol",
291
+ start: block.start,
292
+ sx: _extends({}, BODY_SX, {
293
+ my: 2,
294
+ pl: 3,
295
+ '& li': {
296
+ mb: 1
297
+ }
298
+ }),
299
+ children: block.items.map((item, itemIndex)=>/*#__PURE__*/ _jsx("li", {
300
+ children: renderInlines(item, links)
301
+ }, itemIndex))
302
+ }, index);
303
+ }
304
+ // Code and tables scroll rather than wrap, like every other
305
+ // markdown-lite renderer here (AGL-974): a wrapped command line
306
+ // reads as two commands, and a squeezed table column loses the
307
+ // structure that made it a table.
308
+ if (block.type === 'code') {
309
+ return /*#__PURE__*/ _jsx(Box, {
310
+ component: "pre",
311
+ sx: {
312
+ my: 2,
313
+ p: 2,
314
+ overflowX: 'auto',
315
+ borderRadius: 1,
316
+ bgcolor: 'action.hover',
317
+ fontFamily: 'monospace',
318
+ fontSize: 14
319
+ },
320
+ children: /*#__PURE__*/ _jsx("code", {
321
+ children: block.text
322
+ })
323
+ }, index);
324
+ }
325
+ if (block.type === 'table') {
326
+ return /*#__PURE__*/ _jsx(Box, _extends({}, scrollRegionProps(TABLE_REGION_LABEL), {
327
+ sx: _extends({
328
+ my: 2
329
+ }, scrollableTableWrapperSx),
330
+ children: /*#__PURE__*/ _jsxs(Box, {
331
+ component: "table",
332
+ sx: _extends({}, BODY_SX, {
333
+ fontSize: 16,
334
+ borderCollapse: 'collapse'
335
+ }, scrollableTableSx, {
336
+ '& th, & td': {
337
+ border: '1px solid',
338
+ borderColor: 'divider',
339
+ px: 1.5,
340
+ py: 1
341
+ },
342
+ '& th': {
343
+ bgcolor: 'action.hover',
344
+ fontWeight: 600
345
+ }
346
+ }),
347
+ children: [
348
+ /*#__PURE__*/ _jsx("thead", {
349
+ children: /*#__PURE__*/ _jsx("tr", {
350
+ children: block.header.map((cell, cellIndex)=>{
351
+ var _block_align_cellIndex;
352
+ return /*#__PURE__*/ _jsx("th", {
353
+ style: {
354
+ textAlign: (_block_align_cellIndex = block.align[cellIndex]) != null ? _block_align_cellIndex : 'left'
355
+ },
356
+ children: renderInlines(cell, links)
357
+ }, cellIndex);
358
+ })
359
+ })
360
+ }),
361
+ /*#__PURE__*/ _jsx("tbody", {
362
+ children: block.rows.map((row, rowIndex)=>/*#__PURE__*/ _jsx("tr", {
363
+ children: row.map((cell, cellIndex)=>{
364
+ var _block_align_cellIndex;
365
+ return /*#__PURE__*/ _jsx("td", {
366
+ style: {
367
+ textAlign: (_block_align_cellIndex = block.align[cellIndex]) != null ? _block_align_cellIndex : 'left'
368
+ },
369
+ children: renderInlines(cell, links)
370
+ }, cellIndex);
371
+ })
372
+ }, rowIndex))
373
+ })
374
+ ]
375
+ })
376
+ }), index);
377
+ }
378
+ // A pull-quote (AGL-1315): the document's body measure, one size up
379
+ // and italic, behind a left accent — palette tokens keep it right in
380
+ // both modes.
381
+ if (block.type === 'quote') {
382
+ return /*#__PURE__*/ _jsx(Typography, {
383
+ component: "blockquote",
384
+ sx: _extends({}, BODY_SX, {
385
+ my: 3,
386
+ mx: 0,
387
+ pl: 2.5,
388
+ borderLeft: '3px solid',
389
+ borderColor: 'primary.main',
390
+ fontStyle: 'italic',
391
+ fontSize: 21,
392
+ lineHeight: 1.6
393
+ }),
394
+ children: renderInlines(block.inlines, links)
395
+ }, index);
396
+ }
397
+ return /*#__PURE__*/ _jsx(Typography, {
398
+ component: "p",
399
+ sx: _extends({}, BODY_SX, {
400
+ my: 2
401
+ }),
402
+ children: renderInlines(block.inlines, links)
403
+ }, index);
404
+ })
405
+ }));
406
+ });
407
+ Markdown.displayName = 'AglynMarkdown';
408
+ /**
409
+ * Which Markdown element a table of contents speaks for (AGL-1162).
410
+ *
411
+ * Resolved through the NODE TREE, never the DOM: the besigner canvas renders
412
+ * inside a closed shadow root, so a `document.querySelector` from a component
413
+ * finds nothing there and the aside would be empty in the one place it is
414
+ * being authored.
415
+ *
416
+ * The tree is walked from the root in document order, so "the first Markdown
417
+ * element" means the first one a reader meets — not the first key of a node
418
+ * map, whose order is storage detail.
419
+ *
420
+ * An explicit `forNodeId` wins, compared with `leafIdsMatch` because the
421
+ * stored id is the raw canvas id while a composed tree namespaces layout and
422
+ * reusable-component grafts (AGL-573/1229). A pick that no longer resolves —
423
+ * the element was deleted and re-added, which is exactly what re-pasting a
424
+ * document looks like — falls back to the first Markdown element rather than
425
+ * leaving a published page with an empty aside.
426
+ */ export function resolveMarkdownSource(root, forNodeId) {
427
+ var _ref;
428
+ var _found_;
429
+ const found = [];
430
+ const walk = (node)=>{
431
+ var _node_children;
432
+ if (!node) return;
433
+ // Two element types hold a markdown-lite document, and an aside beside a
434
+ // blog article is the case this issue was opened for (AGL-1162): the
435
+ // Collection Entry Body carries the post, under `markdown` rather than
436
+ // `content`, and used to be invisible here — so "On this page" on an
437
+ // article template rendered its authoring affordance forever.
438
+ const source = node.componentId === MARKDOWN_ID ? 'content' : node.componentId === Aglyn.COLLECTION_ENTRY_BODY_COMPONENT_ID ? 'markdown' : undefined;
439
+ if (source) {
440
+ var _ref, _node_resolvedProps, _props_source;
441
+ const props = (_ref = (_node_resolvedProps = node.resolvedProps) != null ? _node_resolvedProps : node.props) != null ? _ref : {};
442
+ const content = String((_props_source = props[source]) != null ? _props_source : '');
443
+ // An entry body on an unresolved surface is the literal
444
+ // `{{entry.body}}` token. It is not a document, and treating it as one
445
+ // would let it win over a real Markdown element further down the page
446
+ // and empty the aside on the canvas.
447
+ if (!UNRESOLVED_TOKEN.test(content.trim())) {
448
+ found.push({
449
+ $id: node.$id,
450
+ content
451
+ });
452
+ }
453
+ }
454
+ for (const child of (_node_children = node.children) != null ? _node_children : [])walk(child);
455
+ };
456
+ walk(root);
457
+ if (forNodeId) {
458
+ const picked = found.find((entry)=>Aglyn.leafIdsMatch(entry.$id, forNodeId));
459
+ if (picked) return picked.content;
460
+ }
461
+ return (_ref = (_found_ = found[0]) == null ? void 0 : _found_.content) != null ? _ref : '';
462
+ }
463
+ /**
464
+ * Scrolls to a heading in the cases the browser cannot reach, and ONLY those
465
+ * (AGL-1162). Returns whether it handled the click.
466
+ *
467
+ * In `document` it deliberately does nothing and lets the plain `#slug`
468
+ * anchor work: native fragment navigation updates the address bar, adds a
469
+ * history entry the back button understands, and honours the site's CSS
470
+ * `scroll-behavior` — none of which a hand-rolled `scrollIntoView` gives
471
+ * back. It is also the only version that works with JavaScript off.
472
+ *
473
+ * (`behavior: 'smooth'` was the first attempt at the whole job, and it is
474
+ * exactly the wrong shape: a browser that declines to animate — a background
475
+ * tab, reduced-motion — leaves the click prevented and the page unmoved, so
476
+ * a working link reads as a broken one.)
477
+ *
478
+ * The besigner canvas renders inside a CLOSED shadow root, where the heading
479
+ * is not in `document` at all and a fragment navigation finds nothing. There
480
+ * the link's own `getRootNode()` is the shadow root holding both ends, and
481
+ * `ShadowRoot.getElementById` finds the heading.
482
+ */ export function scrollToHeading(anchor, slug) {
483
+ const root = anchor.getRootNode();
484
+ if (root === anchor.ownerDocument || !root.getElementById) {
485
+ return false;
486
+ }
487
+ const target = root.getElementById(slug);
488
+ if (!target) return false;
489
+ // No explicit `behavior`: 'auto' follows the scrolling box's CSS
490
+ // `scroll-behavior`, so a site that asked for smooth still gets it.
491
+ target.scrollIntoView({
492
+ block: 'start'
493
+ });
494
+ return true;
495
+ }
496
+ /**
497
+ * What the sidebar's chrome costs, above and below the list (AGL-2486).
498
+ *
499
+ * The list's bound is `100dvh` MINUS this, so it is a function of the window
500
+ * rather than a height somebody picked. Measured on the live
501
+ * `/legal/marketplace-publisher-agreement` sidebar, which is the shape every
502
+ * legal page uses: the card is `position: sticky; top: 96px` under the app
503
+ * bar, then 24px of card padding and 31px of "ON THIS PAGE" label sit above
504
+ * the list and 31px of padding below it — 182px of chrome. 200 leaves the
505
+ * card's bottom BORDER inside the window rather than flush against it, so
506
+ * the card reads as a card and not as a page that ran out.
507
+ *
508
+ * It is an allowance, not a contract: this component renders inside whatever
509
+ * the author built around it, and it cannot read that card's `top` offset.
510
+ * Being a MAX height, an allowance a little too generous only means a few
511
+ * pixels of the card sit below the fold; one a little too tight only means
512
+ * the scroll box starts a line sooner. Both are recoverable, which is the
513
+ * whole reason this is a `max-height` and not a `height`.
514
+ */ const TOC_VIEWPORT_ALLOWANCE = '200px';
515
+ /**
516
+ * The list is its own scroll box once it outgrows the window (AGL-2486).
517
+ *
518
+ * The bug: nothing here was bounded, and the card the author wraps this in is
519
+ * `position: sticky`. A sticky box taller than the viewport does not scroll
520
+ * into view — it pins at its `top` offset and everything past the window's
521
+ * bottom edge is simply unreachable. Measured on the Marketplace Publisher
522
+ * Agreement (14 `h2`s) in a 1100x480 window: the card stood 502px tall from
523
+ * `top: 96px` and overhung the fold by 118px, entry 11 was cut through the
524
+ * middle of its own text at the window edge, and 12 to 14 could not be
525
+ * reached by any scroll — `ol.scrollTop` stayed 0, because the list was not a
526
+ * scroll box at all. Which row gets cut moves with the window height and the
527
+ * browser zoom; the reported sighting was entry 8. Either way it did not read
528
+ * as "there is more", it read as a document with fewer sections than it has.
529
+ *
530
+ * Three things this deliberately is NOT:
531
+ *
532
+ * - NOT a `height`. A `max-height` is inert until the content exceeds it, so
533
+ * the four-item TOCs (`/legal/dmca`, `/legal/subprocessors`) keep their
534
+ * exact present box: no scroll region, no reserved gutter, no dead space.
535
+ * That is also why `overflow-y` is `auto` and never `scroll`.
536
+ *
537
+ * - NOT applied below `md`. The bound only makes sense for a sidebar. In the
538
+ * stacked narrow layout the TOC is a full-width block in the page flow, and
539
+ * bounding it there would plant a scroll trap in the middle of an article
540
+ * to solve a clipping problem that layout does not have.
541
+ *
542
+ * - NOT silent, and the FADE is the part that carries that. A scroll box a
543
+ * reader cannot see is the same bug wearing a scrollbar: measured in Chrome
544
+ * on macOS, `offsetWidth - clientWidth` on this list is 0 even with
545
+ * `scrollbar-color` set — the platform draws an OVERLAY scrollbar, which is
546
+ * invisible until you have already guessed to scroll. So the thumb styling
547
+ * is the secondary cue, for the platforms that draw one at rest, and the
548
+ * primary cue is a bottom fade: the cut stops being a slice through the
549
+ * middle of a word and becomes an edge that visibly continues.
550
+ *
551
+ * The fade rides a scroll-driven animation on purpose: a `scroll()` timeline
552
+ * on a box with nothing to scroll is INACTIVE, so its animation applies no
553
+ * styles at all. That is the only way to say "fade only when overflowing" in
554
+ * CSS with no measuring and no JavaScript, and it degrades to plain
555
+ * unfaded-but-scrollable in a browser that lacks it. Verified both ways at
556
+ * 1100x480: the 14-entry list fades and scrolls, the 4-entry
557
+ * `/legal/subprocessors` list computes `mask-image: none` and does not.
558
+ *
559
+ * NO new attribute goes with this, deliberately. The three the element has —
560
+ * `forNodeId`, `heading`, `depth` — all answer "which headings does this
561
+ * list", and a "list height" field would hand the author back the very
562
+ * decision this bug is made of. The right answer is "as much of the window as
563
+ * there is", which is a thing CSS can work out and an author cannot type.
564
+ */ const TABLE_OF_CONTENTS_LIST_SX = (theme)=>_extends({
565
+ listStyle: 'none',
566
+ m: 0,
567
+ p: 0,
568
+ [theme.breakpoints.up('md')]: _extends({
569
+ maxHeight: `calc(100vh - ${TOC_VIEWPORT_ALLOWANCE})`,
570
+ // `dvh` over `vh` where it exists: `vh` is the LARGEST viewport, so a
571
+ // window with a visible toolbar gets a bound taller than the space it
572
+ // has — which is the bug again, in miniature.
573
+ '@supports (height: 100dvh)': {
574
+ maxHeight: `calc(100dvh - ${TOC_VIEWPORT_ALLOWANCE})`
575
+ },
576
+ overflowY: 'auto',
577
+ // Reaching the end of the list must not then throw the page down a
578
+ // screen — the reader was navigating the sidebar, not the document.
579
+ overscrollBehavior: 'contain',
580
+ scrollbarWidth: 'thin',
581
+ // `text.disabled`, not `divider`: a 12%-black thumb is one you have to
582
+ // already know is there. `3px` is QUOTED because a bare 3 is a theme
583
+ // radius STEP and lands as 12px on a 6px-wide thumb.
584
+ scrollbarColor: `${theme.palette.text.disabled} transparent`,
585
+ '&::-webkit-scrollbar': {
586
+ width: 6
587
+ },
588
+ '&::-webkit-scrollbar-thumb': {
589
+ backgroundColor: theme.palette.text.disabled,
590
+ borderRadius: '3px'
591
+ }
592
+ }, scrollOverflowFadeTimeline('block'))
593
+ }, scrollOverflowFadeKeyframes('block'));
594
+ /**
595
+ * "On this page" (AGL-1162) — the headings of a Markdown element on the same
596
+ * screen, as working anchor links.
597
+ *
598
+ * A mobx `observer` because it reads ANOTHER node's props: the renderer's
599
+ * Leaf re-renders on changes to the node it is rendering, and nothing else,
600
+ * so without this the aside in the besigner would keep listing the headings
601
+ * of the document as it was when the aside mounted.
602
+ */ const TableOfContents = observer(/*#__PURE__*/ forwardRef((props, ref)=>{
603
+ const { forNodeId, heading, depth, sx } = props, rawRest = _object_without_properties_loose(props, [
604
+ "forNodeId",
605
+ "heading",
606
+ "depth",
607
+ "sx"
608
+ ]);
609
+ /**
610
+ * The cleared-prop guard, applied to the props that LEAVE this
611
+ * component rather than to all of them (AGL-1451).
612
+ *
613
+ * A props-wide `dropClearedProps` would be wrong here, and this is the
614
+ * component that shows why the wrapper is not a reflex: `heading` reads
615
+ * an EMPTY value as a real author choice — "clear it to render no
616
+ * label", which is what its help text promises and what the `heading
617
+ * === undefined ? 'On this page' : heading` line below implements. A
618
+ * guard over the whole props object would strip the cleared heading and
619
+ * put the default label back, i.e. eat the choice the author made. So
620
+ * `heading` and `depth` are read as authored, and the guard covers only
621
+ * what is spread onto the Box.
622
+ */ const rest = dropClearedProps(rawRest);
623
+ const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
624
+ const source = resolveMarkdownSource(Aglyn.canvas.rootNode, forNodeId);
625
+ const entries = useMemo(()=>{
626
+ const headings = Aglyn.collectMarkdownHeadings(Aglyn.parseMarkdownLite(source));
627
+ return depth === '2' ? headings.filter((entry)=>entry.level === 2) : headings;
628
+ }, [
629
+ source,
630
+ depth
631
+ ]);
632
+ const title = heading === undefined ? 'On this page' : heading;
633
+ if (!entries.length) {
634
+ // Same split as the Markdown element: an affordance while authoring,
635
+ // nothing at all on the published page — and no empty `nav` landmark.
636
+ if (!suppressNavigation) return /*#__PURE__*/ _jsx(Box, _extends({
637
+ ref: ref,
638
+ sx: sx
639
+ }, rest));
640
+ return /*#__PURE__*/ _jsx(Box, _extends({
641
+ ref: ref,
642
+ component: "nav",
643
+ sx: [
644
+ {
645
+ p: 2,
646
+ border: '1px dashed',
647
+ borderColor: 'divider',
648
+ color: 'text.secondary',
649
+ fontSize: 12
650
+ },
651
+ ...Array.isArray(sx) ? sx : sx ? [
652
+ sx
653
+ ] : []
654
+ ]
655
+ }, rest, {
656
+ children: 'Table of contents — add ## headings to the Markdown element'
657
+ }));
658
+ }
659
+ return /*#__PURE__*/ _jsxs(Box, _extends({
660
+ ref: ref,
661
+ component: "nav",
662
+ "aria-label": title || 'Table of contents',
663
+ sx: sx
664
+ }, rest, {
665
+ children: [
666
+ title ? /*#__PURE__*/ _jsx(Typography, {
667
+ component: "p",
668
+ sx: {
669
+ fontSize: 12,
670
+ fontWeight: 700,
671
+ // Positive tracking here, unlike the document headings: this is
672
+ // a small uppercase label, where the letters need pushing apart
673
+ // rather than pulling together.
674
+ letterSpacing: '0.8px',
675
+ textTransform: 'uppercase',
676
+ color: 'text.secondary',
677
+ mb: 1.5
678
+ },
679
+ children: title
680
+ }) : null,
681
+ /*#__PURE__*/ _jsx(Box, {
682
+ component: "ol",
683
+ sx: TABLE_OF_CONTENTS_LIST_SX,
684
+ children: entries.map((entry)=>/*#__PURE__*/ _jsx(Box, {
685
+ component: "li",
686
+ sx: {
687
+ mb: 0.75
688
+ },
689
+ children: /*#__PURE__*/ _jsx(MuiLink, {
690
+ // A real href, so the entry is a link to a crawler, works
691
+ // with no JavaScript, and can be copied out of the page.
692
+ href: `#${entry.slug}`,
693
+ underline: "hover",
694
+ color: "text.secondary",
695
+ onClick: (event)=>{
696
+ // Prevented ONLY when this actually moved the page — on a
697
+ // published page it does nothing and the anchor works the
698
+ // way anchors do.
699
+ if (scrollToHeading(event.currentTarget, entry.slug)) {
700
+ event.preventDefault();
701
+ }
702
+ },
703
+ sx: {
704
+ display: 'block',
705
+ fontSize: 15,
706
+ lineHeight: 1.5,
707
+ // Sub-headings indent; nothing else distinguishes them, so
708
+ // a flat list of both levels reads as one long list.
709
+ pl: entry.level === 3 ? 2 : 0,
710
+ '&:hover': {
711
+ color: 'text.primary'
712
+ }
713
+ },
714
+ children: entry.text
715
+ })
716
+ }, entry.slug))
717
+ })
718
+ ]
719
+ }));
720
+ }));
721
+ TableOfContents.displayName = 'AglynTableOfContents';
722
+ export const markdownSchema = {
723
+ $id: MARKDOWN_ID,
724
+ pluginId: BUNDLE_ID,
725
+ displayName: 'Markdown',
726
+ description: 'A whole document written as markdown. It takes no child elements.',
727
+ category: Aglyn.ComponentCategory.TEXT,
728
+ icon: {
729
+ path: mdiLanguageMarkdown.path,
730
+ sx: {
731
+ color: '#455a64'
732
+ }
733
+ },
734
+ flags: {
735
+ // The document is the `content` attribute; dropping elements inside a
736
+ // rendered document would put them somewhere the markdown cannot say.
737
+ dropping: Aglyn.FEATURE_FLAG.DISABLED
738
+ },
739
+ attributes: [
740
+ {
741
+ name: 'content',
742
+ label: 'Content',
743
+ description: 'The document, as markdown. Headings (## and ###), paragraphs, ' + 'bold/italic, links, bullet and 1. numbered lists, images, fenced ' + 'code, pipe tables and > quotes. Paste the whole source file — a ' + 'Table of contents element on the same screen lists the ## and ### ' + 'headings automatically.',
744
+ // The WYSIWYG rather than a raw textarea (AGL-1616): this attribute is
745
+ // a whole document — the published Privacy Policy body is one of them —
746
+ // and editing it as raw markdown-lite meant a 13 KB paste (AGL-1594).
747
+ // The stored value is unchanged, so every renderer is untouched.
748
+ component: Aglyn.FieldComponentType.MARKDOWN
749
+ }
750
+ ]
751
+ };
752
+ export const tableOfContentsSchema = {
753
+ $id: TABLE_OF_CONTENTS_ID,
754
+ pluginId: BUNDLE_ID,
755
+ displayName: 'Table of Contents',
756
+ description: "An on-this-page list linking to a Markdown element's headings.",
757
+ category: Aglyn.ComponentCategory.NAVIGATION,
758
+ icon: {
759
+ path: mdiTableOfContents.path,
760
+ sx: {
761
+ color: '#455a64'
762
+ }
763
+ },
764
+ flags: {
765
+ selfClosing: Aglyn.FEATURE_FLAG.ENABLED
766
+ },
767
+ attributes: [
768
+ {
769
+ name: 'forNodeId',
770
+ label: 'Markdown element',
771
+ description: 'The Markdown element to list the headings of. Leave empty on a ' + 'page with one Markdown element — the first one on the screen is ' + 'used, and a pick that no longer exists falls back to it too.',
772
+ component: Aglyn.FieldComponentType.NODE_SELECT
773
+ },
774
+ {
775
+ name: 'heading',
776
+ label: 'Heading',
777
+ description: 'Label above the list. Clear it to render no label.',
778
+ component: Aglyn.FieldComponentType.TEXT_FIELD
779
+ },
780
+ {
781
+ name: 'depth',
782
+ label: 'Levels',
783
+ description: 'How deep the list goes.',
784
+ component: Aglyn.FieldComponentType.SELECT,
785
+ // `depth` never reaches MUI — it is read here, as `depth === '2'`.
786
+ // So the `''` was not a rendering defect; it was an option that
787
+ // could not survive a save (AGL-1191), which meant an author who
788
+ // set "## headings only" and then changed their mind could not put
789
+ // it back. `'3'` states the same thing as a real, persistable
790
+ // value — and is what `TableOfContentsProps.depth` has declared
791
+ // all along, so the option list was the half that had drifted.
792
+ // Both levels remain what an unset field means (AGL-1451).
793
+ options: [
794
+ {
795
+ value: '3',
796
+ label: '## and ### headings'
797
+ },
798
+ {
799
+ value: '2',
800
+ label: '## headings only'
801
+ }
802
+ ]
803
+ }
804
+ ]
805
+ };
806
+ export const markdownPresets = [
807
+ {
808
+ $id: generatePresetId(MARKDOWN_ID),
809
+ type: Aglyn.NodeType.PRESET,
810
+ displayName: 'Markdown',
811
+ pluginId: BUNDLE_ID,
812
+ description: 'A whole document, authored as markdown',
813
+ category: Aglyn.ComponentCategory.TEXT,
814
+ icon: {
815
+ path: mdiLanguageMarkdown.path,
816
+ sx: {
817
+ color: '#455a64'
818
+ }
819
+ },
820
+ data: {
821
+ $id: null,
822
+ componentId: MARKDOWN_ID,
823
+ pluginId: BUNDLE_ID,
824
+ props: {
825
+ content: '## First section\n\nReplace this with your document. Paste ' + 'markdown straight from the source file.\n\n' + '### A sub-section\n\nHeadings become anchors, and a Table of ' + 'contents element on the same screen links to them.'
826
+ }
827
+ }
828
+ },
829
+ {
830
+ $id: generatePresetId(TABLE_OF_CONTENTS_ID),
831
+ type: Aglyn.NodeType.PRESET,
832
+ displayName: 'Table of Contents',
833
+ pluginId: BUNDLE_ID,
834
+ description: 'On this page — links to a Markdown element’s headings',
835
+ category: Aglyn.ComponentCategory.NAVIGATION,
836
+ icon: {
837
+ path: mdiTableOfContents.path,
838
+ sx: {
839
+ color: '#455a64'
840
+ }
841
+ },
842
+ data: {
843
+ $id: null,
844
+ componentId: TABLE_OF_CONTENTS_ID,
845
+ pluginId: BUNDLE_ID,
846
+ props: {}
847
+ }
848
+ }
849
+ ];
850
+ export { Markdown, TableOfContents };
851
+ export default Markdown;
852
+
853
+ //# sourceMappingURL=markdown.js.map