@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,216 @@
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 { normalizeEmphasisColumn, parseDataTableRows, readDataTableAlignments } from "@aglyn/shared-data-enums";
21
+ import { mdiTable } from "@aglyn/shared-data-mdi";
22
+ import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
23
+ import { scrollRegionProps, scrollableTableSx } from "@aglyn/shared-ui-jsx/utils/scroll-overflow";
24
+ import Box from "@mui/material/Box";
25
+ import TableBody from "@mui/material/TableBody";
26
+ import TableCell from "@mui/material/TableCell";
27
+ import TableHead from "@mui/material/TableHead";
28
+ import TableRow from "@mui/material/TableRow";
29
+ import { forwardRef, useContext } from "react";
30
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
31
+ import { generatePresetId } from "../utils/generate-preset-id.js";
32
+ // Component ids are persisted in screen documents; never rename.
33
+ export const DATA_TABLE_ID = 'dataTable';
34
+ /** What a screen reader announces on reaching the grid's scroll box. */ const TABLE_REGION_LABEL = 'Table';
35
+ /**
36
+ * A comparison table (AGL-2543).
37
+ *
38
+ * The feature matrix is the load-bearing block on a competitor comparison
39
+ * page, and the palette had no way to build one: searching `table` returned
40
+ * **Table of Contents** and **Pricing Table**, neither of which is a general
41
+ * grid. The only route was to author markdown pipe syntax inside a Markdown
42
+ * element — which renders correctly and is exactly the audience the besigner
43
+ * exists to spare.
44
+ *
45
+ * Three things the Markdown route could not give, and the reason this is an
46
+ * element rather than a docs note:
47
+ *
48
+ * - **Header emphasis**, without asking an author to remember that the first
49
+ * row is special.
50
+ * - **A highlighted column** — the "ours" column on a comparison page is the
51
+ * entire point of the block, and markdown has no way to say it.
52
+ * - **A grid to edit**, rather than pipe syntax in a text box — see the
53
+ * `DATA_TABLE` field this element's `rows` attribute asks for.
54
+ *
55
+ * Narrow-screen behaviour is NOT one of them (AGL-2568). Both routes draw the
56
+ * same block, so both take the same treatment from `scroll-overflow`: the
57
+ * grid scrolls inside its own box once it is too wide to read, and says so.
58
+ */ const DataTable = /*#__PURE__*/ forwardRef((props, ref)=>{
59
+ var _ref;
60
+ var _grid_;
61
+ const { rows, headerRow = true, emphasizeColumn } = props, rest = _object_without_properties_loose(props, [
62
+ "rows",
63
+ "headerRow",
64
+ "emphasizeColumn"
65
+ ]);
66
+ // Node styles ride the renderer-merged sx; recompose (stack.ts pattern).
67
+ const nodeSx = Array.isArray(props['sx']) ? props['sx'] : [
68
+ props['sx']
69
+ ];
70
+ const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
71
+ const grid = parseDataTableRows(rows);
72
+ const width = (_ref = (_grid_ = grid[0]) == null ? void 0 : _grid_.length) != null ? _ref : 0;
73
+ const alignments = readDataTableAlignments(rows, width);
74
+ const emphasis = normalizeEmphasisColumn(emphasizeColumn, width);
75
+ if (grid.length === 0) {
76
+ // The hint is for the author, so only editing surfaces draw it; a
77
+ // published page renders the bare element.
78
+ if (!suppressNavigation) return /*#__PURE__*/ _jsx(Box, _extends({
79
+ ref: ref
80
+ }, rest));
81
+ return /*#__PURE__*/ _jsx(Box, _extends({
82
+ ref: ref
83
+ }, rest, {
84
+ sx: [
85
+ {
86
+ padding: 2,
87
+ border: '1px dashed',
88
+ borderColor: 'divider',
89
+ color: 'text.secondary',
90
+ fontSize: 12,
91
+ fontFamily: 'system-ui, sans-serif'
92
+ },
93
+ ...nodeSx
94
+ ],
95
+ children: 'Table — add rows in Attributes'
96
+ }));
97
+ }
98
+ const [first, ...body] = grid;
99
+ const dataRows = headerRow ? body : grid;
100
+ // An emphasised column reads as emphasised in BOTH halves of the table: a
101
+ // header cell that is bold anyway would otherwise show no highlight at all,
102
+ // which is the one row an author looks at first.
103
+ const cellSx = (columnIndex)=>emphasis === columnIndex + 1 ? {
104
+ backgroundColor: 'action.hover',
105
+ fontWeight: 600
106
+ } : undefined;
107
+ return /*#__PURE__*/ _jsxs(ScrollTable, {
108
+ ref: ref,
109
+ size: "small",
110
+ // The box scrolls the grid, and the grid is sized so that it can
111
+ // (AGL-2568). The box's `overflow-x` is half of it: it does nothing at
112
+ // all while the table inside is `width: 100%`, because a table of prose
113
+ // cells that cannot exceed its box never overflows it — it crushes its
114
+ // columns instead. `max-content` is the other half, and the box's fade
115
+ // is what makes an overlay-scrollbar platform admit that it scrolled.
116
+ sx: scrollableTableSx,
117
+ ContainerProps: _extends({}, rest, scrollRegionProps(TABLE_REGION_LABEL), {
118
+ // The node's styles merge after the box's own, never instead of them.
119
+ sx: nodeSx
120
+ }),
121
+ children: [
122
+ headerRow ? /*#__PURE__*/ _jsx(TableHead, {
123
+ children: /*#__PURE__*/ _jsx(TableRow, {
124
+ children: first.map((cell, columnIndex)=>/*#__PURE__*/ _jsx(TableCell, {
125
+ align: alignments[columnIndex],
126
+ sx: _extends({
127
+ fontWeight: 700
128
+ }, cellSx(columnIndex)),
129
+ children: cell
130
+ }, columnIndex))
131
+ })
132
+ }) : null,
133
+ /*#__PURE__*/ _jsx(TableBody, {
134
+ children: dataRows.map((row, rowIndex)=>/*#__PURE__*/ _jsx(TableRow, {
135
+ children: row.map((cell, columnIndex)=>/*#__PURE__*/ _jsx(TableCell, {
136
+ align: alignments[columnIndex],
137
+ sx: cellSx(columnIndex),
138
+ children: cell
139
+ }, columnIndex))
140
+ }, rowIndex))
141
+ })
142
+ ]
143
+ });
144
+ });
145
+ DataTable.displayName = 'AglynDataTable';
146
+ export default DataTable;
147
+ export const dataTableSchema = {
148
+ $id: DATA_TABLE_ID,
149
+ pluginId: BUNDLE_ID,
150
+ displayName: 'Table',
151
+ description: 'A grid of rows and columns — a feature matrix, a spec sheet, a comparison.',
152
+ category: Aglyn.ComponentCategory.BLOCKS,
153
+ icon: {
154
+ path: mdiTable.path,
155
+ sx: {
156
+ color: '#0288d1'
157
+ }
158
+ },
159
+ flags: {
160
+ selfClosing: Aglyn.FEATURE_FLAG.ENABLED
161
+ },
162
+ attributes: [
163
+ {
164
+ name: 'rows',
165
+ description: 'The table contents. Paste a markdown table to import one you already have.',
166
+ component: Aglyn.FieldComponentType.DATA_TABLE,
167
+ label: 'Rows'
168
+ },
169
+ {
170
+ name: 'headerRow',
171
+ description: 'Render the first row as a header.',
172
+ component: Aglyn.FieldComponentType.CHECKBOX,
173
+ label: 'First row is a header'
174
+ },
175
+ {
176
+ name: 'emphasizeColumn',
177
+ description: 'Highlight one column — on a comparison table, usually your own. 0 for none.',
178
+ component: Aglyn.FieldComponentType.TEXT_FIELD,
179
+ label: 'Emphasize column'
180
+ }
181
+ ]
182
+ };
183
+ export const dataTablePresets = [
184
+ {
185
+ $id: generatePresetId(DATA_TABLE_ID),
186
+ type: Aglyn.NodeType.PRESET,
187
+ displayName: 'Table',
188
+ pluginId: BUNDLE_ID,
189
+ description: 'Comparison grid with a header row',
190
+ category: Aglyn.ComponentCategory.BLOCKS,
191
+ icon: {
192
+ path: mdiTable.path,
193
+ sx: {
194
+ color: '#0288d1'
195
+ }
196
+ },
197
+ data: {
198
+ $id: null,
199
+ componentId: DATA_TABLE_ID,
200
+ pluginId: BUNDLE_ID,
201
+ props: {
202
+ headerRow: true,
203
+ emphasizeColumn: 2,
204
+ rows: [
205
+ 'Feature | Us | Them',
206
+ '--- | :---: | :---:',
207
+ 'Open source | Yes | No',
208
+ 'Self-hostable | Yes | No',
209
+ 'One platform | Yes | No'
210
+ ].join('\n')
211
+ }
212
+ }
213
+ }
214
+ ];
215
+
216
+ //# sourceMappingURL=data-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/data-table.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport {\n normalizeEmphasisColumn,\n parseDataTableRows,\n readDataTableAlignments,\n} from '@aglyn/shared-data-enums'\nimport { mdiTable } from '@aglyn/shared-data-mdi'\nimport { ScrollTable } from '@aglyn/shared-ui-jsx/components/scroll-table.component'\nimport {\n scrollRegionProps,\n scrollableTableSx,\n} from '@aglyn/shared-ui-jsx/utils/scroll-overflow'\nimport Box from '@mui/material/Box'\nimport TableBody from '@mui/material/TableBody'\nimport TableCell from '@mui/material/TableCell'\nimport TableHead from '@mui/material/TableHead'\nimport TableRow from '@mui/material/TableRow'\nimport { forwardRef, useContext } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\n\n// Component ids are persisted in screen documents; never rename.\nexport const DATA_TABLE_ID: Aglyn.ComponentId = 'dataTable'\n\n/** What a screen reader announces on reaching the grid's scroll box. */\nconst TABLE_REGION_LABEL = 'Table'\n\nexport interface DataTableProps {\n /**\n * The grid, pipe-delimited, one row per line — and its column alignment,\n * as a markdown divider row. See `@aglyn/shared-data-enums`'s `data-table` utilities.\n */\n rows?: string\n /** Render the first row as a header. */\n headerRow?: boolean\n /** 1-based column to emphasise, or 0/absent for none. */\n emphasizeColumn?: number | string\n}\n\n/**\n * A comparison table (AGL-2543).\n *\n * The feature matrix is the load-bearing block on a competitor comparison\n * page, and the palette had no way to build one: searching `table` returned\n * **Table of Contents** and **Pricing Table**, neither of which is a general\n * grid. The only route was to author markdown pipe syntax inside a Markdown\n * element — which renders correctly and is exactly the audience the besigner\n * exists to spare.\n *\n * Three things the Markdown route could not give, and the reason this is an\n * element rather than a docs note:\n *\n * - **Header emphasis**, without asking an author to remember that the first\n * row is special.\n * - **A highlighted column** — the \"ours\" column on a comparison page is the\n * entire point of the block, and markdown has no way to say it.\n * - **A grid to edit**, rather than pipe syntax in a text box — see the\n * `DATA_TABLE` field this element's `rows` attribute asks for.\n *\n * Narrow-screen behaviour is NOT one of them (AGL-2568). Both routes draw the\n * same block, so both take the same treatment from `scroll-overflow`: the\n * grid scrolls inside its own box once it is too wide to read, and says so.\n */\nconst DataTable = forwardRef<HTMLDivElement, DataTableProps>((props, ref) => {\n const { rows, headerRow = true, emphasizeColumn, ...rest } = props\n // Node styles ride the renderer-merged sx; recompose (stack.ts pattern).\n const nodeSx = Array.isArray(props['sx']) ? props['sx'] : [props['sx']]\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const grid = parseDataTableRows(rows)\n const width = grid[0]?.length ?? 0\n const alignments = readDataTableAlignments(rows, width)\n const emphasis = normalizeEmphasisColumn(emphasizeColumn, width)\n\n if (grid.length === 0) {\n // The hint is for the author, so only editing surfaces draw it; a\n // published page renders the bare element.\n if (!suppressNavigation) return <Box ref={ref} {...rest} />\n return (\n <Box\n ref={ref}\n {...rest}\n sx={[\n {\n padding: 2,\n border: '1px dashed',\n borderColor: 'divider',\n color: 'text.secondary',\n fontSize: 12,\n fontFamily: 'system-ui, sans-serif',\n },\n ...nodeSx,\n ]}\n >\n {'Table — add rows in Attributes'}\n </Box>\n )\n }\n\n const [first, ...body] = grid\n const dataRows = headerRow ? body : grid\n // An emphasised column reads as emphasised in BOTH halves of the table: a\n // header cell that is bold anyway would otherwise show no highlight at all,\n // which is the one row an author looks at first.\n const cellSx = (columnIndex: number) =>\n emphasis === columnIndex + 1\n ? { backgroundColor: 'action.hover', fontWeight: 600 }\n : undefined\n\n return (\n <ScrollTable\n ref={ref}\n size=\"small\"\n // The box scrolls the grid, and the grid is sized so that it can\n // (AGL-2568). The box's `overflow-x` is half of it: it does nothing at\n // all while the table inside is `width: 100%`, because a table of prose\n // cells that cannot exceed its box never overflows it — it crushes its\n // columns instead. `max-content` is the other half, and the box's fade\n // is what makes an overlay-scrollbar platform admit that it scrolled.\n sx={scrollableTableSx}\n ContainerProps={{\n ...rest,\n ...scrollRegionProps(TABLE_REGION_LABEL),\n // The node's styles merge after the box's own, never instead of them.\n sx: nodeSx,\n }}\n >\n {headerRow ? (\n <TableHead>\n <TableRow>\n {first.map((cell, columnIndex) => (\n <TableCell\n key={columnIndex}\n align={alignments[columnIndex]}\n sx={{ fontWeight: 700, ...cellSx(columnIndex) }}\n >\n {cell}\n </TableCell>\n ))}\n </TableRow>\n </TableHead>\n ) : null}\n <TableBody>\n {dataRows.map((row, rowIndex) => (\n <TableRow key={rowIndex}>\n {row.map((cell, columnIndex) => (\n <TableCell\n key={columnIndex}\n align={alignments[columnIndex]}\n sx={cellSx(columnIndex)}\n >\n {cell}\n </TableCell>\n ))}\n </TableRow>\n ))}\n </TableBody>\n </ScrollTable>\n )\n})\nDataTable.displayName = 'AglynDataTable'\n\nexport default DataTable\n\nexport const dataTableSchema: Aglyn.ComponentSchema<DataTableProps> = {\n $id: DATA_TABLE_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Table',\n description:\n 'A grid of rows and columns — a feature matrix, a spec sheet, a comparison.',\n category: Aglyn.ComponentCategory.BLOCKS,\n icon: { path: mdiTable.path, sx: { color: '#0288d1' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'rows',\n description:\n 'The table contents. Paste a markdown table to import one you already have.',\n component: Aglyn.FieldComponentType.DATA_TABLE,\n label: 'Rows',\n },\n {\n name: 'headerRow',\n description: 'Render the first row as a header.',\n component: Aglyn.FieldComponentType.CHECKBOX,\n label: 'First row is a header',\n },\n {\n name: 'emphasizeColumn',\n description:\n 'Highlight one column — on a comparison table, usually your own. 0 for none.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Emphasize column',\n },\n ],\n}\n\nexport const dataTablePresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(DATA_TABLE_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Table',\n pluginId: BUNDLE_ID,\n description: 'Comparison grid with a header row',\n category: Aglyn.ComponentCategory.BLOCKS,\n icon: { path: mdiTable.path, sx: { color: '#0288d1' } },\n data: {\n $id: null,\n componentId: DATA_TABLE_ID,\n pluginId: BUNDLE_ID,\n props: {\n headerRow: true,\n emphasizeColumn: 2,\n rows: [\n 'Feature | Us | Them',\n '--- | :---: | :---:',\n 'Open source | Yes | No',\n 'Self-hostable | Yes | No',\n 'One platform | Yes | No',\n ].join('\\n'),\n },\n },\n },\n]\n"],"names":["Aglyn","normalizeEmphasisColumn","parseDataTableRows","readDataTableAlignments","mdiTable","ScrollTable","scrollRegionProps","scrollableTableSx","Box","TableBody","TableCell","TableHead","TableRow","forwardRef","useContext","BUNDLE_ID","generatePresetId","DATA_TABLE_ID","TABLE_REGION_LABEL","DataTable","props","ref","grid","rows","headerRow","emphasizeColumn","rest","nodeSx","Array","isArray","suppressNavigation","ScreenLinkContext","width","length","alignments","emphasis","sx","padding","border","borderColor","color","fontSize","fontFamily","first","body","dataRows","cellSx","columnIndex","backgroundColor","fontWeight","undefined","size","ContainerProps","map","cell","align","row","rowIndex","displayName","dataTableSchema","$id","pluginId","description","category","ComponentCategory","BLOCKS","icon","path","flags","selfClosing","FEATURE_FLAG","ENABLED","attributes","name","component","FieldComponentType","DATA_TABLE","label","CHECKBOX","TEXT_FIELD","dataTablePresets","type","NodeType","PRESET","data","componentId","join"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as Aglyn from '@aglyn/aglyn';
18
+ import { type ReactNode } from 'react';
19
+ /**
20
+ * The canvas ROOT's component id — the `Document` layer at the top of every
21
+ * hierarchy (`NODE_ROOT_ID`). Persisted in screen and layout documents since
22
+ * the first seed; never rename.
23
+ *
24
+ * Until now nothing was registered under it, so the renderer fell through to
25
+ * its unstyled `styled('div')` fallback and the besigner's attributes panel
26
+ * had no schema to draw: the Document layer could be styled and could not be
27
+ * given an element. Registering the id changes no stored document — the same
28
+ * `div` renders — and gives the root the one attribute it has always needed.
29
+ */
30
+ export declare const ID: Aglyn.ComponentId;
31
+ /**
32
+ * Elements the document root may render as (AGL-2486, widened by AGL-2514).
33
+ *
34
+ * `main` is offered here and on the Layout Slot, and nowhere else: those two
35
+ * are the only nodes that can BE the page's content region, and
36
+ * `stampDocumentLandmark` guarantees exactly one of them carries it.
37
+ *
38
+ * The rest of the list is the sectioning set `SECTION_ELEMENTS` offers, for
39
+ * the same reason it offers them: the root is an element like any other, and
40
+ * a document whose whole body is one region — a layout that is nothing but
41
+ * chrome, a fragment composed into a larger page — had no way to say so. It
42
+ * stayed `div` and the region went unnamed. A root that is `header` or
43
+ * `footer` is a document with no `main`, which `stampDocumentLandmark`
44
+ * already treats as the author's choice rather than a state to repair: it
45
+ * hands the landmark to the slot when there is one, and otherwise ships the
46
+ * page without.
47
+ *
48
+ * An allow-list rather than free text: the value is persisted and rendered
49
+ * verbatim, so a typed one would put `script` into every visitor's page.
50
+ */
51
+ export declare const DOCUMENT_ROOT_ELEMENTS: readonly ["div", "main", "header", "footer", "nav", "aside", "section", "article"];
52
+ export type DocumentRootElement = (typeof DOCUMENT_ROOT_ELEMENTS)[number];
53
+ export interface DocumentRootProps {
54
+ /**
55
+ * The DOM element rendered; defaults to `div`. On a screen with no shared
56
+ * layout, composition fills in `main` — with no slot to carry it, the root
57
+ * IS the page's content region.
58
+ *
59
+ * Named `component` like Box's and Typography's, not `element` like
60
+ * Section's: the attribute means the same thing everywhere it appears, and
61
+ * two names for it is one the author has to learn twice.
62
+ */
63
+ component?: DocumentRootElement | string;
64
+ children?: ReactNode;
65
+ }
66
+ /**
67
+ * The document root: the outermost node of a screen or layout tree.
68
+ *
69
+ * A plain container, as it has always been. It exists as a registered
70
+ * component so the root can answer the two questions every other node can —
71
+ * what element am I, and what does the attributes panel show — rather than
72
+ * being the one node in the tree with no schema.
73
+ */
74
+ declare const DocumentRoot: import("react").ForwardRefExoticComponent<DocumentRootProps & import("react").RefAttributes<HTMLDivElement>>;
75
+ export declare const schema: Aglyn.ComponentSchema<DocumentRootProps>;
76
+ export { DocumentRoot };
77
+ export default DocumentRoot;
@@ -0,0 +1,118 @@
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 } 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 { mdiFileDocumentOutline } from "@aglyn/shared-data-mdi";
21
+ import MuiBox from "@mui/material/Box";
22
+ import { forwardRef } from "react";
23
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
24
+ /**
25
+ * The canvas ROOT's component id — the `Document` layer at the top of every
26
+ * hierarchy (`NODE_ROOT_ID`). Persisted in screen and layout documents since
27
+ * the first seed; never rename.
28
+ *
29
+ * Until now nothing was registered under it, so the renderer fell through to
30
+ * its unstyled `styled('div')` fallback and the besigner's attributes panel
31
+ * had no schema to draw: the Document layer could be styled and could not be
32
+ * given an element. Registering the id changes no stored document — the same
33
+ * `div` renders — and gives the root the one attribute it has always needed.
34
+ */ export const ID = 'div';
35
+ /**
36
+ * Elements the document root may render as (AGL-2486, widened by AGL-2514).
37
+ *
38
+ * `main` is offered here and on the Layout Slot, and nowhere else: those two
39
+ * are the only nodes that can BE the page's content region, and
40
+ * `stampDocumentLandmark` guarantees exactly one of them carries it.
41
+ *
42
+ * The rest of the list is the sectioning set `SECTION_ELEMENTS` offers, for
43
+ * the same reason it offers them: the root is an element like any other, and
44
+ * a document whose whole body is one region — a layout that is nothing but
45
+ * chrome, a fragment composed into a larger page — had no way to say so. It
46
+ * stayed `div` and the region went unnamed. A root that is `header` or
47
+ * `footer` is a document with no `main`, which `stampDocumentLandmark`
48
+ * already treats as the author's choice rather than a state to repair: it
49
+ * hands the landmark to the slot when there is one, and otherwise ships the
50
+ * page without.
51
+ *
52
+ * An allow-list rather than free text: the value is persisted and rendered
53
+ * verbatim, so a typed one would put `script` into every visitor's page.
54
+ */ export const DOCUMENT_ROOT_ELEMENTS = [
55
+ 'div',
56
+ 'main',
57
+ 'header',
58
+ 'footer',
59
+ 'nav',
60
+ 'aside',
61
+ 'section',
62
+ 'article'
63
+ ];
64
+ /**
65
+ * The document root: the outermost node of a screen or layout tree.
66
+ *
67
+ * A plain container, as it has always been. It exists as a registered
68
+ * component so the root can answer the two questions every other node can —
69
+ * what element am I, and what does the attributes panel show — rather than
70
+ * being the one node in the tree with no schema.
71
+ */ const DocumentRoot = /*#__PURE__*/ forwardRef((props, ref)=>{
72
+ const { component, children } = props, rest = _object_without_properties_loose(props, [
73
+ "component",
74
+ "children"
75
+ ]);
76
+ // Unknown values degrade to `div` rather than reaching the DOM as an
77
+ // invented tag — the resolver pattern `Section` uses.
78
+ const element = DOCUMENT_ROOT_ELEMENTS.includes(String(component != null ? component : '')) ? component : 'div';
79
+ return /*#__PURE__*/ _jsx(MuiBox, _extends({
80
+ ref: ref,
81
+ component: element
82
+ }, rest, {
83
+ children: children
84
+ }));
85
+ });
86
+ DocumentRoot.displayName = 'AglynDocumentRoot';
87
+ export const schema = {
88
+ $id: ID,
89
+ pluginId: BUNDLE_ID,
90
+ displayName: Aglyn.NODE_ROOT_LABEL,
91
+ description: 'The page itself — the outermost element every other element sits in.',
92
+ category: Aglyn.ComponentCategory.LAYOUT,
93
+ icon: {
94
+ path: mdiFileDocumentOutline.path,
95
+ sx: {
96
+ color: 'text.secondary'
97
+ }
98
+ },
99
+ attributes: [
100
+ {
101
+ name: 'component',
102
+ label: 'Component',
103
+ description: 'The DOM element the page renders as. On a screen framed by a ' + 'shared layout the layout’s slot carries "main" instead, so this ' + 'stays a plain container unless you say otherwise. Choosing a ' + 'landmark other than "main" leaves the page without one.',
104
+ component: Aglyn.FieldComponentType.SELECT,
105
+ options: DOCUMENT_ROOT_ELEMENTS.map((value)=>({
106
+ value,
107
+ label: value
108
+ }))
109
+ }
110
+ ]
111
+ };
112
+ // No preset, deliberately: the root is not an element anybody drops. The
113
+ // element drawer lists presets, so registering the schema alone keeps it out
114
+ // of the palette while giving the node its attributes panel.
115
+ export { DocumentRoot };
116
+ export default DocumentRoot;
117
+
118
+ //# sourceMappingURL=document-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/document-root.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport { mdiFileDocumentOutline } from '@aglyn/shared-data-mdi'\nimport MuiBox from '@mui/material/Box'\nimport { forwardRef, type ReactNode } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\n\n/**\n * The canvas ROOT's component id — the `Document` layer at the top of every\n * hierarchy (`NODE_ROOT_ID`). Persisted in screen and layout documents since\n * the first seed; never rename.\n *\n * Until now nothing was registered under it, so the renderer fell through to\n * its unstyled `styled('div')` fallback and the besigner's attributes panel\n * had no schema to draw: the Document layer could be styled and could not be\n * given an element. Registering the id changes no stored document — the same\n * `div` renders — and gives the root the one attribute it has always needed.\n */\nexport const ID: Aglyn.ComponentId = 'div'\n\n/**\n * Elements the document root may render as (AGL-2486, widened by AGL-2514).\n *\n * `main` is offered here and on the Layout Slot, and nowhere else: those two\n * are the only nodes that can BE the page's content region, and\n * `stampDocumentLandmark` guarantees exactly one of them carries it.\n *\n * The rest of the list is the sectioning set `SECTION_ELEMENTS` offers, for\n * the same reason it offers them: the root is an element like any other, and\n * a document whose whole body is one region — a layout that is nothing but\n * chrome, a fragment composed into a larger page — had no way to say so. It\n * stayed `div` and the region went unnamed. A root that is `header` or\n * `footer` is a document with no `main`, which `stampDocumentLandmark`\n * already treats as the author's choice rather than a state to repair: it\n * hands the landmark to the slot when there is one, and otherwise ships the\n * page without.\n *\n * An allow-list rather than free text: the value is persisted and rendered\n * verbatim, so a typed one would put `script` into every visitor's page.\n */\nexport const DOCUMENT_ROOT_ELEMENTS = [\n 'div',\n 'main',\n 'header',\n 'footer',\n 'nav',\n 'aside',\n 'section',\n 'article',\n] as const\nexport type DocumentRootElement = (typeof DOCUMENT_ROOT_ELEMENTS)[number]\n\nexport interface DocumentRootProps {\n /**\n * The DOM element rendered; defaults to `div`. On a screen with no shared\n * layout, composition fills in `main` — with no slot to carry it, the root\n * IS the page's content region.\n *\n * Named `component` like Box's and Typography's, not `element` like\n * Section's: the attribute means the same thing everywhere it appears, and\n * two names for it is one the author has to learn twice.\n */\n component?: DocumentRootElement | string\n children?: ReactNode\n}\n\n/**\n * The document root: the outermost node of a screen or layout tree.\n *\n * A plain container, as it has always been. It exists as a registered\n * component so the root can answer the two questions every other node can —\n * what element am I, and what does the attributes panel show — rather than\n * being the one node in the tree with no schema.\n */\nconst DocumentRoot = forwardRef<HTMLDivElement, DocumentRootProps>(\n (props, ref) => {\n const { component, children, ...rest } = props\n // Unknown values degrade to `div` rather than reaching the DOM as an\n // invented tag — the resolver pattern `Section` uses.\n const element = (DOCUMENT_ROOT_ELEMENTS as readonly string[]).includes(\n String(component ?? ''),\n )\n ? (component as DocumentRootElement)\n : 'div'\n return (\n <MuiBox ref={ref} component={element} {...rest}>\n {children}\n </MuiBox>\n )\n },\n)\nDocumentRoot.displayName = 'AglynDocumentRoot'\n\nexport const schema: Aglyn.ComponentSchema<DocumentRootProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: Aglyn.NODE_ROOT_LABEL,\n description:\n 'The page itself — the outermost element every other element sits in.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiFileDocumentOutline.path, sx: { color: 'text.secondary' } },\n attributes: [\n {\n name: 'component',\n label: 'Component',\n description:\n 'The DOM element the page renders as. On a screen framed by a ' +\n 'shared layout the layout’s slot carries \"main\" instead, so this ' +\n 'stays a plain container unless you say otherwise. Choosing a ' +\n 'landmark other than \"main\" leaves the page without one.',\n component: Aglyn.FieldComponentType.SELECT,\n options: DOCUMENT_ROOT_ELEMENTS.map((value) => ({\n value,\n label: value,\n })),\n },\n ],\n}\n\n// No preset, deliberately: the root is not an element anybody drops. The\n// element drawer lists presets, so registering the schema alone keeps it out\n// of the palette while giving the node its attributes panel.\n\nexport { DocumentRoot }\nexport default DocumentRoot\n"],"names":["Aglyn","mdiFileDocumentOutline","MuiBox","forwardRef","BUNDLE_ID","ID","DOCUMENT_ROOT_ELEMENTS","DocumentRoot","props","ref","component","children","rest","element","includes","String","displayName","schema","$id","pluginId","NODE_ROOT_LABEL","description","category","ComponentCategory","LAYOUT","icon","path","sx","color","attributes","name","label","FieldComponentType","SELECT","options","map","value"],"mappings":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,YAAYA,WAAW,eAAc;AACrC,SAASC,sBAAsB,QAAQ,yBAAwB;AAC/D,OAAOC,YAAY,oBAAmB;AACtC,SAASC,UAAU,QAAwB,QAAO;AAClD,SAASC,SAAS,QAAQ,gCAA4B;AAEtD;;;;;;;;;;CAUC,GACD,OAAO,MAAMC,KAAwB,MAAK;AAE1C;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,MAAMC,yBAAyB;IACpC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAS;AAiBV;;;;;;;CAOC,GACD,MAAMC,6BAAeJ,WACnB,CAACK,OAAOC;IACN,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAW,GAAGH,OAATI,wCAASJ;;;;IACzC,qEAAqE;IACrE,sDAAsD;IACtD,MAAMK,UAAU,AAACP,uBAA6CQ,QAAQ,CACpEC,OAAOL,oBAAAA,YAAa,OAEjBA,YACD;IACJ,qBACE,KAACR;QAAOO,KAAKA;QAAKC,WAAWG;OAAaD;kBACvCD;;AAGP;AAEFJ,aAAaS,WAAW,GAAG;AAE3B,OAAO,MAAMC,SAAmD;IAC9DC,KAAKb;IACLc,UAAUf;IACVY,aAAahB,MAAMoB,eAAe;IAClCC,aACE;IACFC,UAAUtB,MAAMuB,iBAAiB,CAACC,MAAM;IACxCC,MAAM;QAAEC,MAAMzB,uBAAuByB,IAAI;QAAEC,IAAI;YAAEC,OAAO;QAAiB;IAAE;IAC3EC,YAAY;QACV;YACEC,MAAM;YACNC,OAAO;YACPV,aACE,kEACA,qEACA,kEACA;YACFX,WAAWV,MAAMgC,kBAAkB,CAACC,MAAM;YAC1CC,SAAS5B,uBAAuB6B,GAAG,CAAC,CAACC,QAAW,CAAA;oBAC9CA;oBACAL,OAAOK;gBACT,CAAA;QACF;KACD;AACH,EAAC;AAED,yEAAyE;AACzE,6EAA6E;AAC7E,6DAA6D;AAE7D,SAAS7B,YAAY,GAAE;AACvB,eAAeA,aAAY"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as Aglyn from '@aglyn/aglyn';
18
+ import type { SxProps } from '@mui/material/styles';
19
+ import { type ReactNode } from 'react';
20
+ export declare const DRAWER_ID: Aglyn.ComponentId;
21
+ export declare const DRAWER_TOGGLE_ID: Aglyn.ComponentId;
22
+ export type DrawerAnchor = 'left' | 'right' | 'top' | 'bottom';
23
+ /** All four edges MUI's Drawer supports. */
24
+ export declare const DRAWER_ANCHORS: DrawerAnchor[];
25
+ /** Horizontal anchors are the ones the `width` setting applies to. */
26
+ export declare function isSideAnchor(anchor: unknown): boolean;
27
+ export interface DrawerElementProps {
28
+ /** Which edge the drawer slides in from. */
29
+ anchor?: DrawerAnchor;
30
+ /** CSS width of the open panel (default 280px). Side anchors only. */
31
+ width?: string;
32
+ /**
33
+ * Authored node styles, handed over by the renderer rather than typed into
34
+ * an attribute — recomposed below so the panel's own sx is merged, not
35
+ * replaced (AGL-1323 declared it; the merge predates it).
36
+ */
37
+ sx?: SxProps;
38
+ children?: ReactNode;
39
+ }
40
+ export interface DrawerToggleProps {
41
+ /**
42
+ * Legacy pre-AGL-572 binding attribute. Persisted values are accepted
43
+ * and silently ignored (no migration): behavior config rides the
44
+ * interactions system (AGL-568), so explicit targeting is authored as
45
+ * *When clicked → Open/close a drawer* on the button instead.
46
+ */
47
+ targetNodeId?: string;
48
+ /** Accessible name for the icon button. */
49
+ ariaLabel?: string;
50
+ }
51
+ /**
52
+ * The node id encoded in the renderer's stable `data-aglyn="leaf:<id>"`
53
+ * attribute (the same selector contract the interactions system uses).
54
+ */
55
+ export declare function parseLeafNodeId(dataAglyn: unknown): string | undefined;
56
+ /**
57
+ * True while the besigner canvas flags this leaf's subtree as holding the
58
+ * current selection (AGL-571): the renderer stamps
59
+ * `data-aglyn-selected-within` on a leaf whenever the node itself or any
60
+ * descendant is selected, and drops it when selection leaves the subtree.
61
+ * Live surfaces never set it, so absence simply means "render collapsed" —
62
+ * the same neutral `data-aglyn*` leaf contract `parseLeafNodeId` reads.
63
+ */
64
+ export declare function isLeafSelectedWithin(rest: Record<string, unknown>): boolean;
65
+ /** Test seam: the current broadcast owner (first mounted drawer). */
66
+ export declare function firstMountedDrawer(): string | undefined;
67
+ /**
68
+ * Slide-in drawer (AGL-562): a canvas children slot that opens from the
69
+ * page edge — the mobile-menu building block. Opens/closes/toggles via
70
+ * the shared window event bus (`dispatchDrawerCommand`), reachable from
71
+ * the interactions system's drawer steps and the Menu Button element.
72
+ * SSR ships it closed; the canvas shows a slim collapsed placeholder that
73
+ * expands its contents inline only while the drawer or one of its
74
+ * descendants is selected (AGL-571) — full drawer designability is
75
+ * AGL-572.
76
+ */
77
+ declare const DrawerElement: import("react").ForwardRefExoticComponent<DrawerElementProps & import("react").RefAttributes<HTMLDivElement>>;
78
+ /**
79
+ * Menu button (AGL-562, targeting moved to interactions in AGL-572): a
80
+ * hamburger icon button whose click broadcast-toggles the page's first
81
+ * drawer over the shared command bus — the zero-config default that
82
+ * makes the one-insert Mobile Nav preset work. Targeting a specific
83
+ * drawer is an interaction (*When clicked → Open/close a drawer*), the
84
+ * same openDrawer/closeDrawer/toggleDrawer steps any element can use;
85
+ * the legacy `targetNodeId` attribute is discarded here so persisted
86
+ * values neither retarget the click nor leak into the DOM. Inert on the
87
+ * static canvas so canvas clicks only select; live (incl. Preview) it toggles.
88
+ */
89
+ export declare const DrawerToggle: import("react").ForwardRefExoticComponent<DrawerToggleProps & import("react").RefAttributes<HTMLButtonElement>>;
90
+ export declare const drawerSchema: Aglyn.ComponentSchema<DrawerElementProps>;
91
+ export declare const drawerToggleSchema: Aglyn.ComponentSchema<DrawerToggleProps>;
92
+ export declare const drawerPresets: Aglyn.PresetSchema[];
93
+ export default DrawerElement;