@aglyn/plugins-mui 1.0.0-beta.229 → 1.0.0-beta.231
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -7
- package/src/lib/components/data-table.js +9 -12
- package/src/lib/components/data-table.js.map +1 -1
- package/src/lib/components/icon.js +2 -1
- package/src/lib/components/icon.js.map +1 -1
- package/src/lib/components/layout-slot.js +9 -12
- package/src/lib/components/layout-slot.js.map +1 -1
- package/src/lib/components/stack.js +3 -1
- package/src/lib/components/stack.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/plugins-mui",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.231",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aglyn/aglyn": "1.0.0-beta.
|
|
29
|
-
"@aglyn/shared-data-enums": "1.0.0-beta.
|
|
30
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
31
|
-
"@aglyn/shared-ui-jsx": "1.0.0-beta.
|
|
32
|
-
"@aglyn/shared-ui-theme": "1.0.0-beta.
|
|
33
|
-
"@aglyn/shared-util-vendor": "1.0.0-beta.
|
|
28
|
+
"@aglyn/aglyn": "1.0.0-beta.231",
|
|
29
|
+
"@aglyn/shared-data-enums": "1.0.0-beta.231",
|
|
30
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.231",
|
|
31
|
+
"@aglyn/shared-ui-jsx": "1.0.0-beta.231",
|
|
32
|
+
"@aglyn/shared-ui-theme": "1.0.0-beta.231",
|
|
33
|
+
"@aglyn/shared-util-vendor": "1.0.0-beta.231",
|
|
34
34
|
"@swc/helpers": "0.5.23",
|
|
35
35
|
"mobx": "^7.0.5",
|
|
36
36
|
"mobx-react-lite": "^5.1.0"
|
|
@@ -32,6 +32,13 @@ import { generatePresetId } from "../utils/generate-preset-id.js";
|
|
|
32
32
|
// Component ids are persisted in screen documents; never rename.
|
|
33
33
|
export const DATA_TABLE_ID = 'dataTable';
|
|
34
34
|
/** What a screen reader announces on reaching the grid's scroll box. */ const TABLE_REGION_LABEL = 'Table';
|
|
35
|
+
// The component and its preset show the same drawer glyph.
|
|
36
|
+
const TABLE_ICON = {
|
|
37
|
+
path: mdiTable.path,
|
|
38
|
+
sx: {
|
|
39
|
+
color: '#0288d1'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
35
42
|
/**
|
|
36
43
|
* A comparison table (AGL-2543).
|
|
37
44
|
*
|
|
@@ -150,12 +157,7 @@ export const dataTableSchema = {
|
|
|
150
157
|
displayName: 'Table',
|
|
151
158
|
description: 'A grid of rows and columns — a feature matrix, a spec sheet, a comparison.',
|
|
152
159
|
category: Aglyn.ComponentCategory.BLOCKS,
|
|
153
|
-
icon:
|
|
154
|
-
path: mdiTable.path,
|
|
155
|
-
sx: {
|
|
156
|
-
color: '#0288d1'
|
|
157
|
-
}
|
|
158
|
-
},
|
|
160
|
+
icon: TABLE_ICON,
|
|
159
161
|
flags: {
|
|
160
162
|
selfClosing: Aglyn.FEATURE_FLAG.ENABLED
|
|
161
163
|
},
|
|
@@ -188,12 +190,7 @@ export const dataTablePresets = [
|
|
|
188
190
|
pluginId: BUNDLE_ID,
|
|
189
191
|
description: 'Comparison grid with a header row',
|
|
190
192
|
category: Aglyn.ComponentCategory.BLOCKS,
|
|
191
|
-
icon:
|
|
192
|
-
path: mdiTable.path,
|
|
193
|
-
sx: {
|
|
194
|
-
color: '#0288d1'
|
|
195
|
-
}
|
|
196
|
-
},
|
|
193
|
+
icon: TABLE_ICON,
|
|
197
194
|
data: {
|
|
198
195
|
$id: null,
|
|
199
196
|
componentId: DATA_TABLE_ID,
|
|
@@ -1 +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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"}
|
|
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\n// The component and its preset show the same drawer glyph.\nconst TABLE_ICON = { path: mdiTable.path, sx: { color: '#0288d1' } }\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: TABLE_ICON,\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: TABLE_ICON,\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","TABLE_ICON","path","sx","color","DataTable","props","ref","grid","rows","headerRow","emphasizeColumn","rest","nodeSx","Array","isArray","suppressNavigation","ScreenLinkContext","width","length","alignments","emphasis","padding","border","borderColor","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","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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"}
|
|
@@ -91,7 +91,8 @@ export const ID = 'icon';
|
|
|
91
91
|
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
92
92
|
path: icon.path,
|
|
93
93
|
sx: _extends({
|
|
94
|
-
|
|
94
|
+
// A size stored as text (an AI-built page stores every prop as text) is still pixels.
|
|
95
|
+
fontSize: Number(size) > 0 ? Number(size) : 24
|
|
95
96
|
}, color ? {
|
|
96
97
|
color
|
|
97
98
|
} : {})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/icon.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 { getMdiIconPath, mdiShapePlus } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport Box from '@mui/material/Box'\nimport type { SxProps } from '@mui/material/styles'\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 ID: Aglyn.ComponentId = 'icon'\n\nexport interface IconProps {\n /** mdi icon id from the picker (AGL-146). */\n iconId?: string\n /**\n * Resolved SVG path for `iconId`, denormalized at author time (AGL-1212).\n * Render surfaces read this and never load the icon catalog.\n */\n iconPath?: string\n /** Icon size in px; defaults to 24. */\n size?: number\n /** CSS color; defaults to the inherited text color. */\n color?: string\n /**\n * Authored node styles, handed over by the renderer rather than typed\n * into an attribute — recomposed below so the Styles panel's values are\n * merged rather than replaced (AGL-1284).\n */\n sx?: SxProps\n}\n\n/**\n * Icon element (AGL-146): renders a picked mdi icon with size/color\n * controls; an empty pick shows a labeled placeholder so the element stays\n * selectable in the editor.\n *\n * Path resolution order (AGL-1212): the persisted `iconPath` first, then the\n * in-memory catalog for documents authored before paths were stored. The\n * catalog is ~2.9 MB and is only loaded by picker surfaces, so on the tenant\n * site and in preview the second lookup misses — which is why it must NOT go\n * through `getMdiIconFromId`, whose `DEFAULT_ICON` fallback carries a real\n * path and rendered a \"help\" glyph on every published page.\n */\nconst Icon = forwardRef<HTMLElement, IconProps>((props, ref) => {\n const { iconId, iconPath, size, color, ...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 path = iconPath || getMdiIconPath(iconId)\n const icon = path ? { path } : undefined\n if (!icon?.path) {\n // The labeled box is for the author, so only editing surfaces draw it; a\n // published page renders the bare element, as the span a picked icon is.\n if (!suppressNavigation) return <Box ref={ref} component=\"span\" {...rest} />\n return (\n <Box\n ref={ref}\n {...rest}\n sx={[\n {\n width: 48,\n height: 48,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px dashed',\n borderColor: 'divider',\n borderRadius: 1,\n color: 'text.secondary',\n fontSize: 10,\n fontFamily: 'system-ui, sans-serif',\n },\n ...nodeSx,\n ]}\n >\n {'Icon'}\n </Box>\n )\n }\n return (\n <Box ref={ref} component=\"span\" sx={{ display: 'inline-flex' }} {...rest}>\n <MdiIcon\n path={icon.path}\n sx={{\n
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/icon.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 { getMdiIconPath, mdiShapePlus } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport Box from '@mui/material/Box'\nimport type { SxProps } from '@mui/material/styles'\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 ID: Aglyn.ComponentId = 'icon'\n\nexport interface IconProps {\n /** mdi icon id from the picker (AGL-146). */\n iconId?: string\n /**\n * Resolved SVG path for `iconId`, denormalized at author time (AGL-1212).\n * Render surfaces read this and never load the icon catalog.\n */\n iconPath?: string\n /** Icon size in px; defaults to 24. */\n size?: number\n /** CSS color; defaults to the inherited text color. */\n color?: string\n /**\n * Authored node styles, handed over by the renderer rather than typed\n * into an attribute — recomposed below so the Styles panel's values are\n * merged rather than replaced (AGL-1284).\n */\n sx?: SxProps\n}\n\n/**\n * Icon element (AGL-146): renders a picked mdi icon with size/color\n * controls; an empty pick shows a labeled placeholder so the element stays\n * selectable in the editor.\n *\n * Path resolution order (AGL-1212): the persisted `iconPath` first, then the\n * in-memory catalog for documents authored before paths were stored. The\n * catalog is ~2.9 MB and is only loaded by picker surfaces, so on the tenant\n * site and in preview the second lookup misses — which is why it must NOT go\n * through `getMdiIconFromId`, whose `DEFAULT_ICON` fallback carries a real\n * path and rendered a \"help\" glyph on every published page.\n */\nconst Icon = forwardRef<HTMLElement, IconProps>((props, ref) => {\n const { iconId, iconPath, size, color, ...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 path = iconPath || getMdiIconPath(iconId)\n const icon = path ? { path } : undefined\n if (!icon?.path) {\n // The labeled box is for the author, so only editing surfaces draw it; a\n // published page renders the bare element, as the span a picked icon is.\n if (!suppressNavigation) return <Box ref={ref} component=\"span\" {...rest} />\n return (\n <Box\n ref={ref}\n {...rest}\n sx={[\n {\n width: 48,\n height: 48,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px dashed',\n borderColor: 'divider',\n borderRadius: 1,\n color: 'text.secondary',\n fontSize: 10,\n fontFamily: 'system-ui, sans-serif',\n },\n ...nodeSx,\n ]}\n >\n {'Icon'}\n </Box>\n )\n }\n return (\n <Box ref={ref} component=\"span\" sx={{ display: 'inline-flex' }} {...rest}>\n <MdiIcon\n path={icon.path}\n sx={{\n // A size stored as text (an AI-built page stores every prop as text) is still pixels.\n fontSize: Number(size) > 0 ? Number(size) : 24,\n ...(color ? { color } : {}),\n }}\n />\n </Box>\n )\n})\nIcon.displayName = 'Icon'\n\nexport const schema: Aglyn.ComponentSchema<IconProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Icon',\n description:\n 'A single icon from the library, at the size and color you pick.',\n category: Aglyn.ComponentCategory.MEDIA,\n icon: {\n path: mdiShapePlus.path,\n sx: { color: '#7b1fa2' },\n },\n flags: {\n // Static: may sit in a subtree that keeps its server HTML (AGL-3581).\n lazyHydration: Aglyn.FEATURE_FLAG.ENABLED,\n selfClosing: Aglyn.FEATURE_FLAG.ENABLED,\n },\n attributes: [\n {\n name: 'iconId',\n description: 'Pick any icon from the library.',\n component: Aglyn.FieldComponentType.ICON_PICKER,\n label: 'Icon',\n },\n {\n name: 'size',\n description: 'Icon size in pixels (default 24).',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Size (px)',\n type: 'number',\n },\n {\n name: 'color',\n description: 'CSS color, e.g. #7b1fa2; empty inherits the text color.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Color',\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Icon',\n pluginId: BUNDLE_ID,\n description: 'A single icon from the mdi library',\n category: Aglyn.ComponentCategory.MEDIA,\n icon: {\n path: mdiShapePlus.path,\n sx: { color: '#7b1fa2' },\n },\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n]\n\nexport default Icon\n"],"names":["Aglyn","getMdiIconPath","mdiShapePlus","MdiIcon","Box","forwardRef","useContext","BUNDLE_ID","generatePresetId","ID","Icon","props","ref","iconId","iconPath","size","color","rest","nodeSx","Array","isArray","suppressNavigation","ScreenLinkContext","path","icon","undefined","component","sx","width","height","display","alignItems","justifyContent","border","borderColor","borderRadius","fontSize","fontFamily","Number","displayName","schema","$id","pluginId","description","category","ComponentCategory","MEDIA","flags","lazyHydration","FEATURE_FLAG","ENABLED","selfClosing","attributes","name","FieldComponentType","ICON_PICKER","label","TEXT_FIELD","type","presets","NodeType","PRESET","data","componentId"],"mappings":"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"}
|
|
@@ -25,6 +25,13 @@ import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
|
25
25
|
import { generatePresetId } from "../utils/generate-preset-id.js";
|
|
26
26
|
// Component ids are persisted in layout documents; never rename.
|
|
27
27
|
export const ID = 'layoutSlot';
|
|
28
|
+
// The component and its preset show the same drawer glyph.
|
|
29
|
+
const SLOT_ICON = {
|
|
30
|
+
path: mdiPageLayoutBody.path,
|
|
31
|
+
sx: {
|
|
32
|
+
color: '#9c27b0'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
28
35
|
/**
|
|
29
36
|
* Elements the slot may render as (AGL-2486).
|
|
30
37
|
*
|
|
@@ -130,12 +137,7 @@ export const schema = {
|
|
|
130
137
|
displayName: 'Layout Slot',
|
|
131
138
|
description: "Marks where each bound page's content renders inside this layout. One per layout.",
|
|
132
139
|
category: Aglyn.ComponentCategory.LAYOUT,
|
|
133
|
-
icon:
|
|
134
|
-
path: mdiPageLayoutBody.path,
|
|
135
|
-
sx: {
|
|
136
|
-
color: '#9c27b0'
|
|
137
|
-
}
|
|
138
|
-
},
|
|
140
|
+
icon: SLOT_ICON,
|
|
139
141
|
// The slot's children come from screen composition, never from the canvas.
|
|
140
142
|
restrictChildren: [
|
|
141
143
|
Aglyn.LinealDirectiveFlag.LIMIT_TO,
|
|
@@ -176,12 +178,7 @@ export const presets = [
|
|
|
176
178
|
$id: generatePresetId(ID),
|
|
177
179
|
type: Aglyn.NodeType.PRESET,
|
|
178
180
|
displayName: 'Layout Slot',
|
|
179
|
-
icon:
|
|
180
|
-
path: mdiPageLayoutBody.path,
|
|
181
|
-
sx: {
|
|
182
|
-
color: '#9c27b0'
|
|
183
|
-
}
|
|
184
|
-
},
|
|
181
|
+
icon: SLOT_ICON,
|
|
185
182
|
category: Aglyn.ComponentCategory.LAYOUT,
|
|
186
183
|
data: {
|
|
187
184
|
$id: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/layout-slot.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 { mdiPageLayoutBody } from '@aglyn/shared-data-mdi'\nimport Box, { type BoxProps } from '@mui/material/Box'\nimport { alpha } from '@mui/material/styles'\nimport { Children, 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 layout documents; never rename.\nexport const ID: Aglyn.ComponentId = 'layoutSlot'\n\n/**\n * Elements the slot may render as (AGL-2486).\n *\n * `main` is here, and is the DEFAULT composition assigns, because the slot is\n * by construction the page content between the layout's chrome — which is the\n * definition of the landmark. It is the one place on the platform that may\n * choose it: `SECTION_ELEMENTS` and `ALLOWED_AUTHOR_HTML_ELEMENTS` both drop\n * `main` so a document can never carry two, and `stampDocumentLandmark`\n * decides which single node gets it.\n */\nexport const LAYOUT_SLOT_ELEMENTS = [\n 'main',\n 'div',\n 'section',\n 'article',\n] as const\nexport type LayoutSlotElement = (typeof LAYOUT_SLOT_ELEMENTS)[number]\n\nexport interface LayoutSlotProps extends Omit<BoxProps, 'component'> {\n /**\n * The DOM element the slot renders as. Left unset, composition fills in\n * `main` — see {@link LAYOUT_SLOT_ELEMENTS}. Unknown values degrade to\n * `div` rather than reaching the DOM as an invented tag.\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.\n * Narrower than the `ElementType` Box accepts — a canvas attribute is a\n * persisted STRING, and an allow-list is what keeps `script` out of it —\n * so `BoxProps`' own `component` is omitted rather than widened.\n */\n component?: LayoutSlotElement | string\n /**\n * Editor-only caption under the slot marker. Layouts render different\n * kinds of content — a doc body, a narrow article measure, a full page —\n * and naming it is the difference between four identical dashed boxes and\n * a layout you can read at a glance.\n */\n caption?: string\n}\n\n/**\n * The slot marker is EDITOR CHROME, so it holds the brand accent literally\n * rather than reading `secondary` from the theme: the canvas renders under\n * the host's palette, so a token would repaint the editor's own furniture\n * whenever a subscriber restyles their site — and it already rendered pink\n * instead of the design's blue.\n */\nconst SLOT_ACCENT = '#00B0FF'\n/** Shown when a layout hasn't named its slot. */\nexport const DEFAULT_SLOT_CAPTION = 'Page content renders here'\n\n/**\n * Content outlet for shared layouts: marks where a bound screen's nodes are\n * grafted into the layout tree at composition time. With children (composed\n * or previewed) it is a plain passthrough region; empty, it renders a\n * dashed placeholder so layout designers can see the slot on the canvas.\n *\n * The placeholder is editor chrome, so it is drawn on editing surfaces only.\n * A published screen with no content of its own still composes an empty\n * slot, and that renders as the plain region.\n */\nconst LayoutSlot = forwardRef<HTMLDivElement, LayoutSlotProps>(\n (props, ref) => {\n const { children, sx, caption, component, ...rest } = props\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const hasChildren = Children.count(children) > 0\n const element = (LAYOUT_SLOT_ELEMENTS as readonly string[]).includes(\n String(component ?? ''),\n )\n ? (component as LayoutSlotElement)\n : 'div'\n\n if (hasChildren || !suppressNavigation) {\n return (\n <Box\n ref={ref}\n component={element}\n data-aglyn-layout-slot=\"\"\n sx={sx}\n {...rest}\n >\n {children}\n </Box>\n )\n }\n\n return (\n <Box\n ref={ref}\n data-aglyn-layout-slot=\"\"\n sx={[\n {\n minHeight: 160,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 0.5,\n borderWidth: 2,\n borderStyle: 'dashed',\n // The slot is not an ordinary dashed container — it is the one\n // region a layout does NOT own. Brand blue on a faint tint says\n // that at a glance, and matches the design's slot convention.\n borderColor: SLOT_ACCENT,\n backgroundColor: alpha(SLOT_ACCENT, 0.06),\n borderRadius: 1,\n color: 'text.secondary',\n fontFamily: 'sans-serif',\n fontSize: 13,\n textAlign: 'center',\n p: 2,\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n {...rest}\n >\n <Box\n component=\"span\"\n sx={{ color: SLOT_ACCENT, fontWeight: 700 }}\n >\n {'◇ layout-slot'}\n </Box>\n <Box component=\"span\">{caption || DEFAULT_SLOT_CAPTION}</Box>\n </Box>\n )\n },\n)\nLayoutSlot.displayName = 'LayoutSlot'\n\nexport const schema: Aglyn.ComponentSchema<LayoutSlotProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Layout Slot',\n description:\n \"Marks where each bound page's content renders inside this layout. One per layout.\",\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: {\n path: mdiPageLayoutBody.path,\n sx: { color: '#9c27b0' },\n },\n // The slot's children come from screen composition, never from the canvas.\n restrictChildren: [Aglyn.LinealDirectiveFlag.LIMIT_TO, { components: [] }],\n flags: {\n // Static: may sit in a subtree that keeps its server HTML (AGL-3581).\n // Not `childrenInRoot` — it draws its own placeholder when it has\n // no children, which is what a held root looks like.\n lazyHydration: Aglyn.FEATURE_FLAG.ENABLED,\n cloning: Aglyn.FEATURE_FLAG.DISABLED,\n dropping: Aglyn.FEATURE_FLAG.DISABLED,\n },\n attributes: [\n {\n name: 'caption',\n label: 'Slot caption',\n description:\n 'Editor-only label for what renders here — e.g. \"Doc body renders ' +\n 'here\". Never shown on the published site.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n placeholder: DEFAULT_SLOT_CAPTION,\n },\n {\n name: 'component',\n label: 'Component',\n description:\n 'The DOM element the page content renders inside. Blank is ' +\n '\"main\" — the page-content landmark assistive tech skips the ' +\n 'chrome with. Choose another only if this layout’s slot is not the ' +\n 'page’s main content.',\n component: Aglyn.FieldComponentType.SELECT,\n options: LAYOUT_SLOT_ELEMENTS.map((value) => ({\n value,\n label: value,\n })),\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Layout Slot',\n icon: {\n path: mdiPageLayoutBody.path,\n sx: { color: '#9c27b0' },\n },\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n]\n\nexport default LayoutSlot\n"],"names":["Aglyn","mdiPageLayoutBody","Box","alpha","Children","forwardRef","useContext","BUNDLE_ID","generatePresetId","ID","LAYOUT_SLOT_ELEMENTS","SLOT_ACCENT","DEFAULT_SLOT_CAPTION","LayoutSlot","props","ref","children","sx","caption","component","rest","suppressNavigation","ScreenLinkContext","hasChildren","count","element","includes","String","data-aglyn-layout-slot","minHeight","display","flexDirection","alignItems","justifyContent","gap","borderWidth","borderStyle","borderColor","backgroundColor","borderRadius","color","fontFamily","fontSize","textAlign","p","Array","isArray","fontWeight","displayName","schema","$id","pluginId","description","category","ComponentCategory","LAYOUT","icon","path","restrictChildren","LinealDirectiveFlag","LIMIT_TO","components","flags","lazyHydration","FEATURE_FLAG","ENABLED","cloning","DISABLED","dropping","attributes","name","label","FieldComponentType","TEXT_FIELD","placeholder","SELECT","options","map","value","presets","type","NodeType","PRESET","data","componentId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/layout-slot.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 { mdiPageLayoutBody } from '@aglyn/shared-data-mdi'\nimport Box, { type BoxProps } from '@mui/material/Box'\nimport { alpha } from '@mui/material/styles'\nimport { Children, 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 layout documents; never rename.\nexport const ID: Aglyn.ComponentId = 'layoutSlot'\n\n// The component and its preset show the same drawer glyph.\nconst SLOT_ICON = { path: mdiPageLayoutBody.path, sx: { color: '#9c27b0' } }\n\n/**\n * Elements the slot may render as (AGL-2486).\n *\n * `main` is here, and is the DEFAULT composition assigns, because the slot is\n * by construction the page content between the layout's chrome — which is the\n * definition of the landmark. It is the one place on the platform that may\n * choose it: `SECTION_ELEMENTS` and `ALLOWED_AUTHOR_HTML_ELEMENTS` both drop\n * `main` so a document can never carry two, and `stampDocumentLandmark`\n * decides which single node gets it.\n */\nexport const LAYOUT_SLOT_ELEMENTS = [\n 'main',\n 'div',\n 'section',\n 'article',\n] as const\nexport type LayoutSlotElement = (typeof LAYOUT_SLOT_ELEMENTS)[number]\n\nexport interface LayoutSlotProps extends Omit<BoxProps, 'component'> {\n /**\n * The DOM element the slot renders as. Left unset, composition fills in\n * `main` — see {@link LAYOUT_SLOT_ELEMENTS}. Unknown values degrade to\n * `div` rather than reaching the DOM as an invented tag.\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.\n * Narrower than the `ElementType` Box accepts — a canvas attribute is a\n * persisted STRING, and an allow-list is what keeps `script` out of it —\n * so `BoxProps`' own `component` is omitted rather than widened.\n */\n component?: LayoutSlotElement | string\n /**\n * Editor-only caption under the slot marker. Layouts render different\n * kinds of content — a doc body, a narrow article measure, a full page —\n * and naming it is the difference between four identical dashed boxes and\n * a layout you can read at a glance.\n */\n caption?: string\n}\n\n/**\n * The slot marker is EDITOR CHROME, so it holds the brand accent literally\n * rather than reading `secondary` from the theme: the canvas renders under\n * the host's palette, so a token would repaint the editor's own furniture\n * whenever a subscriber restyles their site — and it already rendered pink\n * instead of the design's blue.\n */\nconst SLOT_ACCENT = '#00B0FF'\n/** Shown when a layout hasn't named its slot. */\nexport const DEFAULT_SLOT_CAPTION = 'Page content renders here'\n\n/**\n * Content outlet for shared layouts: marks where a bound screen's nodes are\n * grafted into the layout tree at composition time. With children (composed\n * or previewed) it is a plain passthrough region; empty, it renders a\n * dashed placeholder so layout designers can see the slot on the canvas.\n *\n * The placeholder is editor chrome, so it is drawn on editing surfaces only.\n * A published screen with no content of its own still composes an empty\n * slot, and that renders as the plain region.\n */\nconst LayoutSlot = forwardRef<HTMLDivElement, LayoutSlotProps>(\n (props, ref) => {\n const { children, sx, caption, component, ...rest } = props\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const hasChildren = Children.count(children) > 0\n const element = (LAYOUT_SLOT_ELEMENTS as readonly string[]).includes(\n String(component ?? ''),\n )\n ? (component as LayoutSlotElement)\n : 'div'\n\n if (hasChildren || !suppressNavigation) {\n return (\n <Box\n ref={ref}\n component={element}\n data-aglyn-layout-slot=\"\"\n sx={sx}\n {...rest}\n >\n {children}\n </Box>\n )\n }\n\n return (\n <Box\n ref={ref}\n data-aglyn-layout-slot=\"\"\n sx={[\n {\n minHeight: 160,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 0.5,\n borderWidth: 2,\n borderStyle: 'dashed',\n // The slot is not an ordinary dashed container — it is the one\n // region a layout does NOT own. Brand blue on a faint tint says\n // that at a glance, and matches the design's slot convention.\n borderColor: SLOT_ACCENT,\n backgroundColor: alpha(SLOT_ACCENT, 0.06),\n borderRadius: 1,\n color: 'text.secondary',\n fontFamily: 'sans-serif',\n fontSize: 13,\n textAlign: 'center',\n p: 2,\n },\n ...(Array.isArray(sx) ? sx : [sx]),\n ]}\n {...rest}\n >\n <Box\n component=\"span\"\n sx={{ color: SLOT_ACCENT, fontWeight: 700 }}\n >\n {'◇ layout-slot'}\n </Box>\n <Box component=\"span\">{caption || DEFAULT_SLOT_CAPTION}</Box>\n </Box>\n )\n },\n)\nLayoutSlot.displayName = 'LayoutSlot'\n\nexport const schema: Aglyn.ComponentSchema<LayoutSlotProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Layout Slot',\n description:\n \"Marks where each bound page's content renders inside this layout. One per layout.\",\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: SLOT_ICON,\n // The slot's children come from screen composition, never from the canvas.\n restrictChildren: [Aglyn.LinealDirectiveFlag.LIMIT_TO, { components: [] }],\n flags: {\n // Static: may sit in a subtree that keeps its server HTML (AGL-3581).\n // Not `childrenInRoot` — it draws its own placeholder when it has\n // no children, which is what a held root looks like.\n lazyHydration: Aglyn.FEATURE_FLAG.ENABLED,\n cloning: Aglyn.FEATURE_FLAG.DISABLED,\n dropping: Aglyn.FEATURE_FLAG.DISABLED,\n },\n attributes: [\n {\n name: 'caption',\n label: 'Slot caption',\n description:\n 'Editor-only label for what renders here — e.g. \"Doc body renders ' +\n 'here\". Never shown on the published site.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n placeholder: DEFAULT_SLOT_CAPTION,\n },\n {\n name: 'component',\n label: 'Component',\n description:\n 'The DOM element the page content renders inside. Blank is ' +\n '\"main\" — the page-content landmark assistive tech skips the ' +\n 'chrome with. Choose another only if this layout’s slot is not the ' +\n 'page’s main content.',\n component: Aglyn.FieldComponentType.SELECT,\n options: LAYOUT_SLOT_ELEMENTS.map((value) => ({\n value,\n label: value,\n })),\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Layout Slot',\n icon: SLOT_ICON,\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n]\n\nexport default LayoutSlot\n"],"names":["Aglyn","mdiPageLayoutBody","Box","alpha","Children","forwardRef","useContext","BUNDLE_ID","generatePresetId","ID","SLOT_ICON","path","sx","color","LAYOUT_SLOT_ELEMENTS","SLOT_ACCENT","DEFAULT_SLOT_CAPTION","LayoutSlot","props","ref","children","caption","component","rest","suppressNavigation","ScreenLinkContext","hasChildren","count","element","includes","String","data-aglyn-layout-slot","minHeight","display","flexDirection","alignItems","justifyContent","gap","borderWidth","borderStyle","borderColor","backgroundColor","borderRadius","fontFamily","fontSize","textAlign","p","Array","isArray","fontWeight","displayName","schema","$id","pluginId","description","category","ComponentCategory","LAYOUT","icon","restrictChildren","LinealDirectiveFlag","LIMIT_TO","components","flags","lazyHydration","FEATURE_FLAG","ENABLED","cloning","DISABLED","dropping","attributes","name","label","FieldComponentType","TEXT_FIELD","placeholder","SELECT","options","map","value","presets","type","NodeType","PRESET","data","componentId"],"mappings":"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"}
|
|
@@ -116,7 +116,9 @@ const Stack = forwardRef(// repeatDataset/repeatLimit are compose-time attribute
|
|
|
116
116
|
],
|
|
117
117
|
// The stored value is a style NAME; MUI wants a node (AGL-2486).
|
|
118
118
|
divider: buildDivider(divider, props.direction)
|
|
119
|
-
}, applySemanticElement(dropClearedProps(props)), {
|
|
119
|
+
}, applySemanticElement(dropClearedProps(props)), typeof props.spacing === 'string' && props.spacing.trim() && Number.isFinite(Number(props.spacing)) ? {
|
|
120
|
+
spacing: Number(props.spacing)
|
|
121
|
+
} : {}, {
|
|
120
122
|
// After the spread, so the element picker cannot carry a `useFlexGap`
|
|
121
123
|
// past it. `spacing` reaches children as `margin-left` unless this is
|
|
122
124
|
// on, and those margins assume flex: on a grid they land INSIDE the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/stack.ts"],"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 mdiViewColumn,\n mdiViewSequential,\n} from '@aglyn/shared-data-mdi'\nimport MuiDivider from '@mui/material/Divider'\nimport MuiStack, { type StackProps } from '@mui/material/Stack'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { createElement, forwardRef } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { colorSchemeAttribute } from '../utils/color-scheme-attribute'\nimport {\n applySemanticElement,\n semanticElementAttribute,\n semanticElementLabelAttribute,\n} from '../utils/element-picker'\nimport { dropClearedProps } from '../utils/drop-cleared-props'\nimport { generatePresetId } from '../utils/generate-preset-id'\n\n/**\n * The dividers the `divider` attribute can name (AGL-2486).\n *\n * MUI's own `divider` prop takes a NODE, which an attributes panel cannot\n * author — so the persisted value is a style name and this file builds the\n * element. Anything else (an author's stray string, a paste) renders no\n * divider rather than the literal text between every pair of children.\n */\nconst DIVIDER_STYLES = {\n line: {},\n dashed: { borderStyle: 'dashed' },\n} as const\n\nexport type StackDivider = keyof typeof DIVIDER_STYLES\n\n// justifyContent/alignItems/flexWrap are not direct StackProps in MUI v6+;\n// pass them through sx.\ntype StackWithFlexProps = Omit<StackProps, 'divider'> & {\n justifyContent?: CSSProperties['justifyContent']\n alignItems?: CSSProperties['alignItems']\n flexWrap?: CSSProperties['flexWrap']\n /** Divider STYLE name, not a node — see {@link DIVIDER_STYLES}. */\n divider?: StackDivider | string\n /**\n * A repeat's directives (AGL-103, AGL-181). The published page's\n * composition consumes them before anything renders; a surface that renders\n * the stored node as written, like a component editor, still hands them over.\n */\n repeatDataset?: string\n repeatLimit?: number | string\n repeatFilter?: string\n repeatSort?: string\n}\n\n/**\n * A Stack's divider runs ACROSS the flow, so its orientation is the\n * opposite of the stack's own axis. A responsive `direction` (an array or\n * object) is not authorable here, so only the string form is inspected;\n * anything else falls back to MUI's default horizontal rule.\n */\nfunction buildDivider(\n divider: unknown,\n direction: unknown,\n): ReactElement | undefined {\n if (typeof divider !== 'string') return undefined\n // `hasOwnProperty`, not a truthiness test on the lookup: `\"constructor\"`\n // and friends resolve through Object.prototype and would sail past one.\n if (!Object.prototype.hasOwnProperty.call(DIVIDER_STYLES, divider)) {\n return undefined\n }\n const style = DIVIDER_STYLES[divider as StackDivider]\n const horizontal =\n typeof direction === 'string' && direction.startsWith('row')\n return createElement(MuiDivider, {\n orientation: horizontal ? 'vertical' : 'horizontal',\n // Without it a vertical divider collapses to zero height in a flex row.\n flexItem: horizontal,\n sx: style,\n })\n}\n\n/**\n * Displays that make a Stack the flex container MUI's `spacing` assumes.\n */\nconst FLEX_DISPLAYS = new Set(['flex', 'inline-flex'])\n\n/**\n * Whether an author's `sx` takes the Stack out of flex at any breakpoint\n * (AGL-3214).\n *\n * A function `sx` cannot be read without a theme, so it counts as flex and\n * the stack keeps MUI's own behaviour.\n */\nfunction hasNonFlexDisplay(sx: unknown): boolean {\n if (Array.isArray(sx)) return sx.some(hasNonFlexDisplay)\n if (!sx || typeof sx !== 'object') return false\n const display = (sx as Record<string, unknown>).display\n const notFlex = (value: unknown) =>\n typeof value === 'string' && !FLEX_DISPLAYS.has(value)\n if (typeof display === 'string') return notFlex(display)\n // Responsive, in either of the forms the styles panel writes: an array of\n // breakpoint values, or a `{ xs, md }` map.\n if (Array.isArray(display)) return display.some(notFlex)\n if (display && typeof display === 'object')\n return Object.values(display).some(notFlex)\n return false\n}\n\nconst Stack = forwardRef<HTMLDivElement, StackWithFlexProps>(\n // repeatDataset/repeatLimit are compose-time attributes (AGL-103): the\n // tenant expands them before render; strip so they never hit the DOM.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ({ justifyContent, alignItems, flexWrap, divider, useFlexGap, repeatDataset, repeatLimit, repeatFilter, repeatSort, sx, ...props }, ref) =>\n createElement(MuiStack, {\n ref,\n sx: [\n { justifyContent, alignItems, flexWrap },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ],\n // The stored value is a style NAME; MUI wants a node (AGL-2486).\n divider: buildDivider(divider, props.direction),\n // A cleared `direction` persists as null, and MUI resolves it as a\n // responsive value — `null.xs` throws during SSR and 500s the page.\n // Same class as the AGL-1226 button colour, different sharp edge.\n // Last, so an author's element wins over anything `props` carried\n // (AGL-2525). A stack IS the nav row on most sites; before this it\n // could only be wrapped in one.\n ...applySemanticElement(dropClearedProps(props) as Record<string, unknown>),\n // After the spread, so the element picker cannot carry a `useFlexGap`\n // past it. `spacing` reaches children as `margin-left` unless this is\n // on, and those margins assume flex: on a grid they land INSIDE the\n // track, so every item but the first sits a spacing-step right of its\n // column and the left gutter goes ragged (AGL-3214). `gap` is correct\n // for grid, multi-column and flex alike, and an author's own `sx` gap\n // still wins over it. A cleared switch persists as null, which is why\n // this reads `??` and not `||` — an author's explicit OFF stands.\n useFlexGap: useFlexGap ?? (hasNonFlexDisplay(sx) || undefined),\n }),\n)\n\n// Component ids are persisted in screen documents; keep the legacy ids.\nexport const ID: Aglyn.ComponentId = 'muiStack'\n\nexport const schema: Aglyn.ComponentSchema = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Stack',\n // Static: may sit in a subtree that keeps its server HTML (AGL-3581).\n flags: { lazyHydration: Aglyn.FEATURE_FLAG.ENABLED },\n description:\n 'Lays children out in a row or column with even spacing — the workhorse for most layouts.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: {\n path: mdiViewColumn.path,\n sx: { color: '#2196f3' },\n },\n attributes: [\n semanticElementAttribute('this stack'),\n semanticElementLabelAttribute(),\n {\n name: 'direction',\n label: 'Direction',\n description:\n 'Defines the directional flow using the `flex-direction` style property. It is applied for all screen sizes.',\n component: Aglyn.FieldComponentType.SELECT,\n // \"Default\" deleted (AGL-1453): unpersistable, and a second name for\n // `column`, MUI Stack's own default, already on the list.\n options: [\n { value: 'column', label: 'Column' },\n { value: 'column-reverse', label: 'Column Reversed' },\n { value: 'row', label: 'Row' },\n { value: 'row-reverse', label: 'Row Reversed' },\n ],\n },\n {\n name: 'justifyContent',\n label: 'Justify Content',\n description:\n 'Defines how the browser distributes space between and around content items along the main-axis of the container.',\n component: Aglyn.FieldComponentType.SELECT,\n // \"Default\" deleted (AGL-1453). Unpersistable, and a second name for\n // `flex-start`: CSS's initial `justify-content` is `normal`, which on a\n // flex container — which a Stack always is — behaves as `flex-start`.\n //\n // Deleted rather than sentinelled for a second reason specific to this\n // prop: `justifyContent` is destructured out ABOVE and pushed into\n // `sx`, so it never passes through `dropClearedProps`. It is the one\n // attribute on this component the guard does not cover, so the right\n // move is to stop minting values it would have to catch.\n options: [\n { value: 'flex-start', label: 'Flex Start' },\n { value: 'center', label: 'Center' },\n { value: 'flex-end', label: 'Flex End' },\n { value: 'space-between', label: 'Space Between' },\n { value: 'space-around', label: 'Space Around' },\n { value: 'space-evenly', label: 'Space Evenly' },\n ],\n },\n {\n name: 'alignItems',\n label: 'Align Items',\n description:\n 'Defines how the browser distributes space between and around ' +\n 'content items along the cross-axis of the container — the axis ' +\n 'across the Direction.',\n component: Aglyn.FieldComponentType.SELECT,\n // No \"Default\" sentinel (AGL-1453): `stretch` is CSS's own initial\n // `align-items` and is already on the list, and like `justifyContent`\n // this prop is pushed into `sx` rather than through\n // `dropClearedProps`, so an unpersistable `''` would not be caught.\n options: [\n { value: 'stretch', label: 'Stretch' },\n { value: 'flex-start', label: 'Flex Start' },\n { value: 'center', label: 'Center' },\n { value: 'flex-end', label: 'Flex End' },\n { value: 'baseline', label: 'Baseline' },\n ],\n },\n {\n name: 'spacing',\n label: 'Spacing',\n description: 'Defines the space/gap between its immediate children.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'useFlexGap',\n label: 'Use flex gap',\n description:\n 'Space children with the CSS `gap` property instead of margins. ' +\n 'Required for Spacing to survive wrapping, and it leaves child ' +\n 'margins alone — but `gap` is unsupported in some older browsers.',\n component: Aglyn.FieldComponentType.SWITCH,\n },\n {\n name: 'flexWrap',\n label: 'Wrap',\n description:\n 'Whether children that do not fit move onto a new line. Turn on ' +\n 'Use flex gap as well, or Spacing is applied as margins and the ' +\n 'wrapped rows get an uneven gap.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'nowrap', label: 'No Wrap' },\n { value: 'wrap', label: 'Wrap' },\n { value: 'wrap-reverse', label: 'Wrap Reversed' },\n ],\n },\n {\n name: 'divider',\n label: 'Divider',\n description:\n 'Draws a rule between each pair of children, across the ' +\n 'Direction. Clear the field for no divider.',\n component: Aglyn.FieldComponentType.SELECT,\n // MUI's own prop takes a node; the persisted value is a style name and\n // the component builds the element. No `''` option (AGL-1453) — \"no\n // divider\" is the field's ✕, which persists as cleared.\n options: [\n { value: 'line', label: 'Line' },\n { value: 'dashed', label: 'Dashed' },\n ],\n },\n // No Repeat fields: every element's Attributes panel draws the same Repeat\n // section (AGL-3111), writing the props a Stack has always stored.\n colorSchemeAttribute(),\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Stack Horizontal',\n icon: {\n path: mdiViewColumn.path,\n sx: { color: '#2196f3' },\n },\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: { direction: 'row' },\n },\n },\n {\n $id: generatePresetId(ID, 'vertical'),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Stack Vertical',\n icon: {\n path: mdiViewSequential.path,\n sx: { color: '#2196f3' },\n },\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: { direction: 'column' },\n },\n },\n]\n\nexport default Stack\n"],"names":["Aglyn","mdiViewColumn","mdiViewSequential","MuiDivider","MuiStack","createElement","forwardRef","BUNDLE_ID","colorSchemeAttribute","applySemanticElement","semanticElementAttribute","semanticElementLabelAttribute","dropClearedProps","generatePresetId","DIVIDER_STYLES","line","dashed","borderStyle","buildDivider","divider","direction","undefined","Object","prototype","hasOwnProperty","call","style","horizontal","startsWith","orientation","flexItem","sx","FLEX_DISPLAYS","Set","hasNonFlexDisplay","Array","isArray","some","display","notFlex","value","has","values","Stack","justifyContent","alignItems","flexWrap","useFlexGap","repeatDataset","repeatLimit","repeatFilter","repeatSort","props","ref","ID","schema","$id","pluginId","displayName","flags","lazyHydration","FEATURE_FLAG","ENABLED","description","category","ComponentCategory","LAYOUT","icon","path","color","attributes","name","label","component","FieldComponentType","SELECT","options","TEXT_FIELD","type","SWITCH","presets","NodeType","PRESET","data","componentId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/stack.ts"],"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 mdiViewColumn,\n mdiViewSequential,\n} from '@aglyn/shared-data-mdi'\nimport MuiDivider from '@mui/material/Divider'\nimport MuiStack, { type StackProps } from '@mui/material/Stack'\nimport type { CSSProperties, ReactElement } from 'react'\nimport { createElement, forwardRef } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { colorSchemeAttribute } from '../utils/color-scheme-attribute'\nimport {\n applySemanticElement,\n semanticElementAttribute,\n semanticElementLabelAttribute,\n} from '../utils/element-picker'\nimport { dropClearedProps } from '../utils/drop-cleared-props'\nimport { generatePresetId } from '../utils/generate-preset-id'\n\n/**\n * The dividers the `divider` attribute can name (AGL-2486).\n *\n * MUI's own `divider` prop takes a NODE, which an attributes panel cannot\n * author — so the persisted value is a style name and this file builds the\n * element. Anything else (an author's stray string, a paste) renders no\n * divider rather than the literal text between every pair of children.\n */\nconst DIVIDER_STYLES = {\n line: {},\n dashed: { borderStyle: 'dashed' },\n} as const\n\nexport type StackDivider = keyof typeof DIVIDER_STYLES\n\n// justifyContent/alignItems/flexWrap are not direct StackProps in MUI v6+;\n// pass them through sx.\ntype StackWithFlexProps = Omit<StackProps, 'divider'> & {\n justifyContent?: CSSProperties['justifyContent']\n alignItems?: CSSProperties['alignItems']\n flexWrap?: CSSProperties['flexWrap']\n /** Divider STYLE name, not a node — see {@link DIVIDER_STYLES}. */\n divider?: StackDivider | string\n /**\n * A repeat's directives (AGL-103, AGL-181). The published page's\n * composition consumes them before anything renders; a surface that renders\n * the stored node as written, like a component editor, still hands them over.\n */\n repeatDataset?: string\n repeatLimit?: number | string\n repeatFilter?: string\n repeatSort?: string\n}\n\n/**\n * A Stack's divider runs ACROSS the flow, so its orientation is the\n * opposite of the stack's own axis. A responsive `direction` (an array or\n * object) is not authorable here, so only the string form is inspected;\n * anything else falls back to MUI's default horizontal rule.\n */\nfunction buildDivider(\n divider: unknown,\n direction: unknown,\n): ReactElement | undefined {\n if (typeof divider !== 'string') return undefined\n // `hasOwnProperty`, not a truthiness test on the lookup: `\"constructor\"`\n // and friends resolve through Object.prototype and would sail past one.\n if (!Object.prototype.hasOwnProperty.call(DIVIDER_STYLES, divider)) {\n return undefined\n }\n const style = DIVIDER_STYLES[divider as StackDivider]\n const horizontal =\n typeof direction === 'string' && direction.startsWith('row')\n return createElement(MuiDivider, {\n orientation: horizontal ? 'vertical' : 'horizontal',\n // Without it a vertical divider collapses to zero height in a flex row.\n flexItem: horizontal,\n sx: style,\n })\n}\n\n/**\n * Displays that make a Stack the flex container MUI's `spacing` assumes.\n */\nconst FLEX_DISPLAYS = new Set(['flex', 'inline-flex'])\n\n/**\n * Whether an author's `sx` takes the Stack out of flex at any breakpoint\n * (AGL-3214).\n *\n * A function `sx` cannot be read without a theme, so it counts as flex and\n * the stack keeps MUI's own behaviour.\n */\nfunction hasNonFlexDisplay(sx: unknown): boolean {\n if (Array.isArray(sx)) return sx.some(hasNonFlexDisplay)\n if (!sx || typeof sx !== 'object') return false\n const display = (sx as Record<string, unknown>).display\n const notFlex = (value: unknown) =>\n typeof value === 'string' && !FLEX_DISPLAYS.has(value)\n if (typeof display === 'string') return notFlex(display)\n // Responsive, in either of the forms the styles panel writes: an array of\n // breakpoint values, or a `{ xs, md }` map.\n if (Array.isArray(display)) return display.some(notFlex)\n if (display && typeof display === 'object')\n return Object.values(display).some(notFlex)\n return false\n}\n\nconst Stack = forwardRef<HTMLDivElement, StackWithFlexProps>(\n // repeatDataset/repeatLimit are compose-time attributes (AGL-103): the\n // tenant expands them before render; strip so they never hit the DOM.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ({ justifyContent, alignItems, flexWrap, divider, useFlexGap, repeatDataset, repeatLimit, repeatFilter, repeatSort, sx, ...props }, ref) =>\n createElement(MuiStack, {\n ref,\n sx: [\n { justifyContent, alignItems, flexWrap },\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ],\n // The stored value is a style NAME; MUI wants a node (AGL-2486).\n divider: buildDivider(divider, props.direction),\n // A cleared `direction` persists as null, and MUI resolves it as a\n // responsive value — `null.xs` throws during SSR and 500s the page.\n // Same class as the AGL-1226 button colour, different sharp edge.\n // Last, so an author's element wins over anything `props` carried\n // (AGL-2525). A stack IS the nav row on most sites; before this it\n // could only be wrapped in one.\n ...applySemanticElement(dropClearedProps(props) as Record<string, unknown>),\n // A spacing stored as text — every AI-built page stores its props as\n // text — is still a step on the spacing scale: MUI reads \"2\" as a CSS\n // length and spaces nothing (AGL-3660).\n ...(typeof props.spacing === 'string' && props.spacing.trim() && Number.isFinite(Number(props.spacing))\n ? { spacing: Number(props.spacing) }\n : {}),\n // After the spread, so the element picker cannot carry a `useFlexGap`\n // past it. `spacing` reaches children as `margin-left` unless this is\n // on, and those margins assume flex: on a grid they land INSIDE the\n // track, so every item but the first sits a spacing-step right of its\n // column and the left gutter goes ragged (AGL-3214). `gap` is correct\n // for grid, multi-column and flex alike, and an author's own `sx` gap\n // still wins over it. A cleared switch persists as null, which is why\n // this reads `??` and not `||` — an author's explicit OFF stands.\n useFlexGap: useFlexGap ?? (hasNonFlexDisplay(sx) || undefined),\n }),\n)\n\n// Component ids are persisted in screen documents; keep the legacy ids.\nexport const ID: Aglyn.ComponentId = 'muiStack'\n\nexport const schema: Aglyn.ComponentSchema = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Stack',\n // Static: may sit in a subtree that keeps its server HTML (AGL-3581).\n flags: { lazyHydration: Aglyn.FEATURE_FLAG.ENABLED },\n description:\n 'Lays children out in a row or column with even spacing — the workhorse for most layouts.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: {\n path: mdiViewColumn.path,\n sx: { color: '#2196f3' },\n },\n attributes: [\n semanticElementAttribute('this stack'),\n semanticElementLabelAttribute(),\n {\n name: 'direction',\n label: 'Direction',\n description:\n 'Defines the directional flow using the `flex-direction` style property. It is applied for all screen sizes.',\n component: Aglyn.FieldComponentType.SELECT,\n // \"Default\" deleted (AGL-1453): unpersistable, and a second name for\n // `column`, MUI Stack's own default, already on the list.\n options: [\n { value: 'column', label: 'Column' },\n { value: 'column-reverse', label: 'Column Reversed' },\n { value: 'row', label: 'Row' },\n { value: 'row-reverse', label: 'Row Reversed' },\n ],\n },\n {\n name: 'justifyContent',\n label: 'Justify Content',\n description:\n 'Defines how the browser distributes space between and around content items along the main-axis of the container.',\n component: Aglyn.FieldComponentType.SELECT,\n // \"Default\" deleted (AGL-1453). Unpersistable, and a second name for\n // `flex-start`: CSS's initial `justify-content` is `normal`, which on a\n // flex container — which a Stack always is — behaves as `flex-start`.\n //\n // Deleted rather than sentinelled for a second reason specific to this\n // prop: `justifyContent` is destructured out ABOVE and pushed into\n // `sx`, so it never passes through `dropClearedProps`. It is the one\n // attribute on this component the guard does not cover, so the right\n // move is to stop minting values it would have to catch.\n options: [\n { value: 'flex-start', label: 'Flex Start' },\n { value: 'center', label: 'Center' },\n { value: 'flex-end', label: 'Flex End' },\n { value: 'space-between', label: 'Space Between' },\n { value: 'space-around', label: 'Space Around' },\n { value: 'space-evenly', label: 'Space Evenly' },\n ],\n },\n {\n name: 'alignItems',\n label: 'Align Items',\n description:\n 'Defines how the browser distributes space between and around ' +\n 'content items along the cross-axis of the container — the axis ' +\n 'across the Direction.',\n component: Aglyn.FieldComponentType.SELECT,\n // No \"Default\" sentinel (AGL-1453): `stretch` is CSS's own initial\n // `align-items` and is already on the list, and like `justifyContent`\n // this prop is pushed into `sx` rather than through\n // `dropClearedProps`, so an unpersistable `''` would not be caught.\n options: [\n { value: 'stretch', label: 'Stretch' },\n { value: 'flex-start', label: 'Flex Start' },\n { value: 'center', label: 'Center' },\n { value: 'flex-end', label: 'Flex End' },\n { value: 'baseline', label: 'Baseline' },\n ],\n },\n {\n name: 'spacing',\n label: 'Spacing',\n description: 'Defines the space/gap between its immediate children.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'useFlexGap',\n label: 'Use flex gap',\n description:\n 'Space children with the CSS `gap` property instead of margins. ' +\n 'Required for Spacing to survive wrapping, and it leaves child ' +\n 'margins alone — but `gap` is unsupported in some older browsers.',\n component: Aglyn.FieldComponentType.SWITCH,\n },\n {\n name: 'flexWrap',\n label: 'Wrap',\n description:\n 'Whether children that do not fit move onto a new line. Turn on ' +\n 'Use flex gap as well, or Spacing is applied as margins and the ' +\n 'wrapped rows get an uneven gap.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'nowrap', label: 'No Wrap' },\n { value: 'wrap', label: 'Wrap' },\n { value: 'wrap-reverse', label: 'Wrap Reversed' },\n ],\n },\n {\n name: 'divider',\n label: 'Divider',\n description:\n 'Draws a rule between each pair of children, across the ' +\n 'Direction. Clear the field for no divider.',\n component: Aglyn.FieldComponentType.SELECT,\n // MUI's own prop takes a node; the persisted value is a style name and\n // the component builds the element. No `''` option (AGL-1453) — \"no\n // divider\" is the field's ✕, which persists as cleared.\n options: [\n { value: 'line', label: 'Line' },\n { value: 'dashed', label: 'Dashed' },\n ],\n },\n // No Repeat fields: every element's Attributes panel draws the same Repeat\n // section (AGL-3111), writing the props a Stack has always stored.\n colorSchemeAttribute(),\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Stack Horizontal',\n icon: {\n path: mdiViewColumn.path,\n sx: { color: '#2196f3' },\n },\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: { direction: 'row' },\n },\n },\n {\n $id: generatePresetId(ID, 'vertical'),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Stack Vertical',\n icon: {\n path: mdiViewSequential.path,\n sx: { color: '#2196f3' },\n },\n category: Aglyn.ComponentCategory.LAYOUT,\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: { direction: 'column' },\n },\n },\n]\n\nexport default Stack\n"],"names":["Aglyn","mdiViewColumn","mdiViewSequential","MuiDivider","MuiStack","createElement","forwardRef","BUNDLE_ID","colorSchemeAttribute","applySemanticElement","semanticElementAttribute","semanticElementLabelAttribute","dropClearedProps","generatePresetId","DIVIDER_STYLES","line","dashed","borderStyle","buildDivider","divider","direction","undefined","Object","prototype","hasOwnProperty","call","style","horizontal","startsWith","orientation","flexItem","sx","FLEX_DISPLAYS","Set","hasNonFlexDisplay","Array","isArray","some","display","notFlex","value","has","values","Stack","justifyContent","alignItems","flexWrap","useFlexGap","repeatDataset","repeatLimit","repeatFilter","repeatSort","props","ref","spacing","trim","Number","isFinite","ID","schema","$id","pluginId","displayName","flags","lazyHydration","FEATURE_FLAG","ENABLED","description","category","ComponentCategory","LAYOUT","icon","path","color","attributes","name","label","component","FieldComponentType","SELECT","options","TEXT_FIELD","type","SWITCH","presets","NodeType","PRESET","data","componentId"],"mappings":"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"}
|