@aglyn/besigner-ui 1.0.0-beta.217 → 1.0.0-beta.219
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 +21 -21
- package/src/lib/components/accordion-list.component.d.ts +2 -2
- package/src/lib/components/app-bar-breadcrumbs.component.js +2 -2
- package/src/lib/components/app-bar-breadcrumbs.component.js.map +1 -1
- package/src/lib/components/aside-panel.component.js +2 -2
- package/src/lib/components/aside-panel.component.js.map +1 -1
- package/src/lib/components/component-accordion-list.d.ts +2 -2
- package/src/lib/components/component-icon.component.d.ts +2 -2
- package/src/lib/components/component-picker.d.ts +3 -1
- package/src/lib/components/custom-css-form.component.d.ts +2 -2
- package/src/lib/components/dnd/canvas-drop-indicator.d.ts +2 -2
- package/src/lib/components/dnd/draggable-droppable.d.ts +2 -2
- package/src/lib/components/dnd/draggable.d.ts +8 -2
- package/src/lib/components/dnd/droppable.d.ts +8 -2
- package/src/lib/components/element-classes-field.component.d.ts +2 -2
- package/src/lib/components/element-classes-field.component.js +63 -40
- package/src/lib/components/element-classes-field.component.js.map +1 -1
- package/src/lib/components/element-detail.component.d.ts +12 -0
- package/src/lib/components/element-detail.component.js +12 -19
- package/src/lib/components/element-detail.component.js.map +1 -1
- package/src/lib/components/element-interactions-form.component.d.ts +2 -2
- package/src/lib/components/element-preview.component.d.ts +2 -2
- package/src/lib/components/element-props-form.component.d.ts +3 -1
- package/src/lib/components/element-props-form.component.js +4 -4
- package/src/lib/components/element-props-form.component.js.map +1 -1
- package/src/lib/components/element-styles-form.component.d.ts +3 -1
- package/src/lib/components/empty-document-slot.js +1 -1
- package/src/lib/components/empty-document-slot.js.map +1 -1
- package/src/lib/components/history-controls.component.d.ts +3 -1
- package/src/lib/components/inline-markdown-editor.component.d.ts +2 -2
- package/src/lib/components/inline-text-editor.component.d.ts +2 -2
- package/src/lib/components/instance-attr-overrides.component.d.ts +2 -2
- package/src/lib/components/layout-style-picker.component.d.ts +2 -2
- package/src/lib/components/layout-style-picker.component.js +2 -2
- package/src/lib/components/layout-style-picker.component.js.map +1 -1
- package/src/lib/components/node-card.d.ts +3 -1
- package/src/lib/components/node-context-menu.d.ts +3 -1
- package/src/lib/components/node-leaf.d.ts +3 -1
- package/src/lib/components/node-leaf.js +1 -1
- package/src/lib/components/node-leaf.js.map +1 -1
- package/src/lib/components/node-outline.d.ts +3 -1
- package/src/lib/components/node-overlay.d.ts +3 -1
- package/src/lib/components/node-quick-actions.d.ts +3 -1
- package/src/lib/components/node-tree-view.d.ts +3 -1
- package/src/lib/components/properties-dialog.component.js +1 -1
- package/src/lib/components/properties-dialog.component.js.map +1 -1
- package/src/lib/components/property-values-form.component.d.ts +13 -0
- package/src/lib/components/property-values-form.component.js +76 -10
- package/src/lib/components/property-values-form.component.js.map +1 -1
- package/src/lib/components/screen-link-field.component.js +1 -1
- package/src/lib/components/screen-link-field.component.js.map +1 -1
- package/src/lib/components/subtree-json-dialog.component.d.ts +2 -2
- package/src/lib/components/subtree-json-dialog.component.js +1 -1
- package/src/lib/components/subtree-json-dialog.component.js.map +1 -1
- package/src/lib/components/token-pill.component.js +1 -1
- package/src/lib/components/token-pill.component.js.map +1 -1
- package/src/lib/components/tree/tree-list.d.ts +3 -1
- package/src/lib/contexts/element-drawer-context.d.ts +3 -3
- package/src/lib/drafts/besigner-draft-store.d.ts +6 -1
- package/src/lib/drafts/besigner-draft-store.js.map +1 -1
- package/src/lib/hooks/use-aglyn-besigner-flag.js +9 -2
- package/src/lib/hooks/use-aglyn-besigner-flag.js.map +1 -1
- package/src/lib/hooks/use-insert-token-options.d.ts +10 -6
- package/src/lib/hooks/use-insert-token-options.js +64 -53
- package/src/lib/hooks/use-insert-token-options.js.map +1 -1
- package/src/lib/utils/docs-help.d.ts +1 -1
- package/src/lib/utils/docs-help.generated.d.ts +2 -2
- package/src/lib/utils/docs-help.generated.js +7 -1
- package/src/lib/utils/docs-help.generated.js.map +1 -1
- package/src/lib/utils/docs-help.js +1 -1
- package/src/lib/utils/docs-help.js.map +1 -1
- package/src/lib/utils/inline-markdown-edit.store.d.ts +1 -1
- package/src/lib/utils/inline-markdown-edit.store.js +3 -3
- package/src/lib/utils/inline-markdown-edit.store.js.map +1 -1
- package/src/lib/utils/inline-text-edit.store.d.ts +1 -1
- package/src/lib/utils/inline-text-edit.store.js +3 -3
- package/src/lib/utils/inline-text-edit.store.js.map +1 -1
- package/src/lib/utils/token-segments.d.ts +6 -4
- package/src/lib/utils/token-segments.js +3 -3
- package/src/lib/utils/token-segments.js.map +1 -1
|
@@ -20,12 +20,69 @@ import { FieldMuteButton } from "@aglyn/shared-ui-jsx-forms";
|
|
|
20
20
|
import { Autocomplete, Chip, TextField } from "@mui/material";
|
|
21
21
|
import { action } from "mobx";
|
|
22
22
|
import { observer } from "mobx-react-lite";
|
|
23
|
-
import { useCallback, useMemo } from "react";
|
|
23
|
+
import { memo, useCallback, useMemo } from "react";
|
|
24
24
|
import useAglynBesignerFlag from "../hooks/use-aglyn-besigner-flag.js";
|
|
25
25
|
import { toggleRevealedNodeId } from "../utils/canvas-reveal.js";
|
|
26
26
|
import { isClassMuted, isClassSwitchable, toggleMutedClass } from "../utils/muted-classes.js";
|
|
27
27
|
/** Valid CSS class identifier (letters, digits, hyphen, underscore). */ const CLASS_NAME_PATTERN = /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/;
|
|
28
28
|
export const isValidClassName = (name)=>CLASS_NAME_PATTERN.test(name);
|
|
29
|
+
/** Free-text only: there is no list of classes to choose from. */ const NO_OPTIONS = [];
|
|
30
|
+
/**
|
|
31
|
+
* The class chips themselves, MEMOIZED on props that hold still while the
|
|
32
|
+
* classes and their switches do (AGL-3423).
|
|
33
|
+
*
|
|
34
|
+
* A multiple Autocomplete hands its input a new chip array as
|
|
35
|
+
* `startAdornment` on every render, and MUI's `InputBase` copies that into
|
|
36
|
+
* its `FormControl` from a passive effect: a state update left pending after
|
|
37
|
+
* every commit the field takes part in. React 19 counts each such commit as
|
|
38
|
+
* a nested update, and keystrokes delivered back to back elsewhere in the
|
|
39
|
+
* panel commit one after another with nothing to clear the count, so the
|
|
40
|
+
* fifty-first throws "Maximum update depth exceeded" (#185). The field above
|
|
41
|
+
* is an `observer` of `node.props`, which every attribute commit replaces;
|
|
42
|
+
* kept out of those renders, the chips commit only when they change.
|
|
43
|
+
*/ const ElementClassesChips = /*#__PURE__*/ memo(function ElementClassesChips(props) {
|
|
44
|
+
const { classes, isSwitchedOff, onToggle, onChange } = props;
|
|
45
|
+
return /*#__PURE__*/ _jsx(Autocomplete, {
|
|
46
|
+
multiple: true,
|
|
47
|
+
freeSolo: true,
|
|
48
|
+
size: "small",
|
|
49
|
+
options: NO_OPTIONS,
|
|
50
|
+
value: classes,
|
|
51
|
+
onChange: onChange,
|
|
52
|
+
renderValue: (value, getItemProps)=>value.map((option, index)=>{
|
|
53
|
+
const off = isSwitchedOff(option);
|
|
54
|
+
const switchable = isClassSwitchable(option);
|
|
55
|
+
return /*#__PURE__*/ _createElement(Chip, _extends({
|
|
56
|
+
label: option,
|
|
57
|
+
size: "small"
|
|
58
|
+
}, getItemProps({
|
|
59
|
+
index
|
|
60
|
+
}), {
|
|
61
|
+
key: option,
|
|
62
|
+
variant: off ? 'outlined' : 'filled',
|
|
63
|
+
sx: off ? {
|
|
64
|
+
textDecoration: 'line-through',
|
|
65
|
+
opacity: 0.6
|
|
66
|
+
} : undefined,
|
|
67
|
+
icon: /*#__PURE__*/ _jsx(FieldMuteButton, {
|
|
68
|
+
mute: {
|
|
69
|
+
muted: off,
|
|
70
|
+
label: switchable ? off ? `Apply ${option} again` : `Stop applying ${option} while designing` : off ? `Stop showing this element on the canvas` : `Show this element on the canvas`,
|
|
71
|
+
onToggle: ()=>onToggle(option)
|
|
72
|
+
},
|
|
73
|
+
sx: {
|
|
74
|
+
ml: 0.5
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}));
|
|
78
|
+
}),
|
|
79
|
+
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
80
|
+
label: "Classes",
|
|
81
|
+
placeholder: "Add class…",
|
|
82
|
+
helperText: "Custom CSS classes — targetable from theme styles and interactions"
|
|
83
|
+
}))
|
|
84
|
+
});
|
|
85
|
+
});
|
|
29
86
|
/**
|
|
30
87
|
* Custom CSS classes on the selected element (AGL-335): chips persisted
|
|
31
88
|
* into `node.props.className` (space-separated), merged into the
|
|
@@ -93,45 +150,11 @@ export const isValidClassName = (name)=>CLASS_NAME_PATTERN.test(name);
|
|
|
93
150
|
}, [
|
|
94
151
|
node
|
|
95
152
|
]);
|
|
96
|
-
return /*#__PURE__*/ _jsx(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
value: classes,
|
|
102
|
-
onChange: handleChange,
|
|
103
|
-
renderValue: (value, getItemProps)=>value.map((option, index)=>{
|
|
104
|
-
const off = isSwitchedOff(option);
|
|
105
|
-
const switchable = isClassSwitchable(option);
|
|
106
|
-
return /*#__PURE__*/ _createElement(Chip, _extends({
|
|
107
|
-
label: option,
|
|
108
|
-
size: "small"
|
|
109
|
-
}, getItemProps({
|
|
110
|
-
index
|
|
111
|
-
}), {
|
|
112
|
-
key: option,
|
|
113
|
-
variant: off ? 'outlined' : 'filled',
|
|
114
|
-
sx: off ? {
|
|
115
|
-
textDecoration: 'line-through',
|
|
116
|
-
opacity: 0.6
|
|
117
|
-
} : undefined,
|
|
118
|
-
icon: /*#__PURE__*/ _jsx(FieldMuteButton, {
|
|
119
|
-
mute: {
|
|
120
|
-
muted: off,
|
|
121
|
-
label: switchable ? off ? `Apply ${option} again` : `Stop applying ${option} while designing` : off ? `Stop showing this element on the canvas` : `Show this element on the canvas`,
|
|
122
|
-
onToggle: ()=>toggleClass(option)
|
|
123
|
-
},
|
|
124
|
-
sx: {
|
|
125
|
-
ml: 0.5
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
}));
|
|
129
|
-
}),
|
|
130
|
-
renderInput: (params)=>/*#__PURE__*/ _jsx(TextField, _extends({}, params, {
|
|
131
|
-
label: "Classes",
|
|
132
|
-
placeholder: "Add class…",
|
|
133
|
-
helperText: "Custom CSS classes — targetable from theme styles and interactions"
|
|
134
|
-
}))
|
|
153
|
+
return /*#__PURE__*/ _jsx(ElementClassesChips, {
|
|
154
|
+
classes: classes,
|
|
155
|
+
isSwitchedOff: isSwitchedOff,
|
|
156
|
+
onToggle: toggleClass,
|
|
157
|
+
onChange: handleChange
|
|
135
158
|
});
|
|
136
159
|
});
|
|
137
160
|
ElementClassesField.displayName = 'ElementClassesField';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/element-classes-field.component.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 type * as Aglyn from '@aglyn/aglyn'\nimport { FieldMuteButton } from '@aglyn/shared-ui-jsx-forms'\nimport { Autocomplete, Chip, TextField } from '@mui/material'\nimport { action } from 'mobx'\nimport { observer } from 'mobx-react-lite'\nimport { useCallback, useMemo } from 'react'\n\nimport useAglynBesignerFlag from '../hooks/use-aglyn-besigner-flag'\nimport { toggleRevealedNodeId } from '../utils/canvas-reveal'\nimport {\n isClassMuted,\n isClassSwitchable,\n toggleMutedClass,\n} from '../utils/muted-classes'\n\n/** Valid CSS class identifier (letters, digits, hyphen, underscore). */\nconst CLASS_NAME_PATTERN = /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/\n\nexport const isValidClassName = (name: string): boolean =>\n CLASS_NAME_PATTERN.test(name)\n\nexport interface ElementClassesFieldProps {\n node?: Aglyn.NodeSchema\n}\n\n/**\n * Custom CSS classes on the selected element (AGL-335): chips persisted\n * into `node.props.className` (space-separated), merged into the\n * rendered className by the node renderer. Pairs with theme stylesheet\n * classes and the interaction builder's class actions.\n *\n * Each chip carries an eye as well as its ✕ (AGL-2486). The eye stops the\n * class applying ON THE CANVAS and keeps it on the element; the ✕ is still\n * the one control that takes a class off. Nothing about the eye is written\n * down, so the chips are always the class list that ships.\n *\n * The hidden class is the exception, and deliberately so: switching it off\n * on the canvas is the same act as the hierarchy's visibility eye (AGL-592),\n * so its chip drives THAT state rather than a second one that could\n * disagree with it.\n */\nexport const ElementClassesField = observer(\n (props: ElementClassesFieldProps) => {\n const { node } = props\n const classes = useMemo(\n () =>\n String((node?.props as any)?.className ?? '')\n .split(/\\s+/)\n .filter(Boolean),\n [(node?.props as any)?.className],\n )\n\n const [mutedClasses, setMutedClasses] = useAglynBesignerFlag('mutedClasses')\n const [revealedNodeIds, setRevealedNodeIds] =\n useAglynBesignerFlag('revealedNodeIds')\n\n const nodeId = node?.$id\n\n /** Whether the canvas is currently rendering without this class. */\n const isSwitchedOff = useCallback(\n (className: string) => {\n if (!nodeId) return false\n return isClassSwitchable(className)\n ? isClassMuted(mutedClasses, { nodeId, className })\n : Boolean(revealedNodeIds?.some((id) => id === nodeId))\n },\n [nodeId, mutedClasses, revealedNodeIds],\n )\n\n const toggleClass = useCallback(\n (className: string) => {\n if (!nodeId) return\n if (isClassSwitchable(className)) {\n setMutedClasses((current) =>\n toggleMutedClass(current, { nodeId, className }),\n )\n return\n }\n // One switch, two places to reach it.\n setRevealedNodeIds((current) => toggleRevealedNodeId(current, nodeId))\n },\n [nodeId, setMutedClasses, setRevealedNodeIds],\n )\n\n const handleChange = useCallback(\n (event: unknown, value: string[]) => {\n if (!node) return\n const cleaned = value\n .map((name) => name.trim())\n .filter((name) => isValidClassName(name))\n action(() => {\n const nextProps: Record<string, unknown> = { ...(node.props as any) }\n if (cleaned.length) nextProps['className'] = cleaned.join(' ')\n else delete nextProps['className']\n node.props = nextProps as any\n })()\n },\n [node],\n )\n\n return (\n <Autocomplete\n multiple\n freeSolo\n size=\"small\"\n options={[] as string[]}\n value={classes}\n onChange={handleChange}\n renderValue={(value, getItemProps) =>\n value.map((option, index) => {\n const off = isSwitchedOff(option)\n const switchable = isClassSwitchable(option)\n return (\n <Chip\n label={option}\n size=\"small\"\n {...getItemProps({ index })}\n key={option}\n variant={off ? 'outlined' : 'filled'}\n sx={\n off\n ? { textDecoration: 'line-through', opacity: 0.6 }\n : undefined\n }\n icon={\n <FieldMuteButton\n mute={{\n muted: off,\n label: switchable\n ? off\n ? `Apply ${option} again`\n : `Stop applying ${option} while designing`\n : off\n ? `Stop showing this element on the canvas`\n : `Show this element on the canvas`,\n onToggle: () => toggleClass(option),\n }}\n sx={{ ml: 0.5 }}\n />\n }\n />\n )\n })\n }\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"Classes\"\n placeholder=\"Add class…\"\n helperText=\"Custom CSS classes — targetable from theme styles and interactions\"\n />\n )}\n />\n )\n },\n)\nElementClassesField.displayName = 'ElementClassesField'\n\nexport default ElementClassesField\n"],"names":["FieldMuteButton","Autocomplete","Chip","TextField","action","observer","useCallback","useMemo","useAglynBesignerFlag","toggleRevealedNodeId","isClassMuted","isClassSwitchable","toggleMutedClass","CLASS_NAME_PATTERN","isValidClassName","name","test","ElementClassesField","props","node","classes","String","className","split","filter","Boolean","mutedClasses","setMutedClasses","revealedNodeIds","setRevealedNodeIds","nodeId","$id","isSwitchedOff","some","id","toggleClass","current","handleChange","event","value","cleaned","map","trim","nextProps","length","join","multiple","freeSolo","size","options","onChange","renderValue","getItemProps","option","index","off","switchable","label","key","variant","sx","textDecoration","opacity","undefined","icon","mute","muted","onToggle","ml","renderInput","params","placeholder","helperText","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/element-classes-field.component.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 type * as Aglyn from '@aglyn/aglyn'\nimport { FieldMuteButton } from '@aglyn/shared-ui-jsx-forms'\nimport { Autocomplete, Chip, TextField } from '@mui/material'\nimport { action } from 'mobx'\nimport { observer } from 'mobx-react-lite'\nimport { memo, useCallback, useMemo } from 'react'\n\nimport useAglynBesignerFlag from '../hooks/use-aglyn-besigner-flag'\nimport { toggleRevealedNodeId } from '../utils/canvas-reveal'\nimport {\n isClassMuted,\n isClassSwitchable,\n toggleMutedClass,\n} from '../utils/muted-classes'\n\n/** Valid CSS class identifier (letters, digits, hyphen, underscore). */\nconst CLASS_NAME_PATTERN = /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/\n\nexport const isValidClassName = (name: string): boolean =>\n CLASS_NAME_PATTERN.test(name)\n\n/** Free-text only: there is no list of classes to choose from. */\nconst NO_OPTIONS: string[] = []\n\ninterface ElementClassesChipsProps {\n classes: readonly string[]\n isSwitchedOff(className: string): boolean\n onToggle(className: string): void\n onChange(event: unknown, value: string[]): void\n}\n\n/**\n * The class chips themselves, MEMOIZED on props that hold still while the\n * classes and their switches do (AGL-3423).\n *\n * A multiple Autocomplete hands its input a new chip array as\n * `startAdornment` on every render, and MUI's `InputBase` copies that into\n * its `FormControl` from a passive effect: a state update left pending after\n * every commit the field takes part in. React 19 counts each such commit as\n * a nested update, and keystrokes delivered back to back elsewhere in the\n * panel commit one after another with nothing to clear the count, so the\n * fifty-first throws \"Maximum update depth exceeded\" (#185). The field above\n * is an `observer` of `node.props`, which every attribute commit replaces;\n * kept out of those renders, the chips commit only when they change.\n */\nconst ElementClassesChips = memo(function ElementClassesChips(\n props: ElementClassesChipsProps,\n) {\n const { classes, isSwitchedOff, onToggle, onChange } = props\n return (\n <Autocomplete\n multiple\n freeSolo\n size=\"small\"\n options={NO_OPTIONS}\n value={classes as string[]}\n onChange={onChange}\n renderValue={(value, getItemProps) =>\n value.map((option, index) => {\n const off = isSwitchedOff(option)\n const switchable = isClassSwitchable(option)\n return (\n <Chip\n label={option}\n size=\"small\"\n {...getItemProps({ index })}\n key={option}\n variant={off ? 'outlined' : 'filled'}\n sx={\n off\n ? { textDecoration: 'line-through', opacity: 0.6 }\n : undefined\n }\n icon={\n <FieldMuteButton\n mute={{\n muted: off,\n label: switchable\n ? off\n ? `Apply ${option} again`\n : `Stop applying ${option} while designing`\n : off\n ? `Stop showing this element on the canvas`\n : `Show this element on the canvas`,\n onToggle: () => onToggle(option),\n }}\n sx={{ ml: 0.5 }}\n />\n }\n />\n )\n })\n }\n renderInput={(params) => (\n <TextField\n {...params}\n label=\"Classes\"\n placeholder=\"Add class…\"\n helperText=\"Custom CSS classes — targetable from theme styles and interactions\"\n />\n )}\n />\n )\n})\n\n\nexport interface ElementClassesFieldProps {\n node?: Aglyn.NodeSchema\n}\n\n/**\n * Custom CSS classes on the selected element (AGL-335): chips persisted\n * into `node.props.className` (space-separated), merged into the\n * rendered className by the node renderer. Pairs with theme stylesheet\n * classes and the interaction builder's class actions.\n *\n * Each chip carries an eye as well as its ✕ (AGL-2486). The eye stops the\n * class applying ON THE CANVAS and keeps it on the element; the ✕ is still\n * the one control that takes a class off. Nothing about the eye is written\n * down, so the chips are always the class list that ships.\n *\n * The hidden class is the exception, and deliberately so: switching it off\n * on the canvas is the same act as the hierarchy's visibility eye (AGL-592),\n * so its chip drives THAT state rather than a second one that could\n * disagree with it.\n */\nexport const ElementClassesField = observer(\n (props: ElementClassesFieldProps) => {\n const { node } = props\n const classes = useMemo(\n () =>\n String((node?.props as any)?.className ?? '')\n .split(/\\s+/)\n .filter(Boolean),\n [(node?.props as any)?.className],\n )\n\n const [mutedClasses, setMutedClasses] = useAglynBesignerFlag('mutedClasses')\n const [revealedNodeIds, setRevealedNodeIds] =\n useAglynBesignerFlag('revealedNodeIds')\n\n const nodeId = node?.$id\n\n /** Whether the canvas is currently rendering without this class. */\n const isSwitchedOff = useCallback(\n (className: string) => {\n if (!nodeId) return false\n return isClassSwitchable(className)\n ? isClassMuted(mutedClasses, { nodeId, className })\n : Boolean(revealedNodeIds?.some((id) => id === nodeId))\n },\n [nodeId, mutedClasses, revealedNodeIds],\n )\n\n const toggleClass = useCallback(\n (className: string) => {\n if (!nodeId) return\n if (isClassSwitchable(className)) {\n setMutedClasses((current) =>\n toggleMutedClass(current, { nodeId, className }),\n )\n return\n }\n // One switch, two places to reach it.\n setRevealedNodeIds((current) => toggleRevealedNodeId(current, nodeId))\n },\n [nodeId, setMutedClasses, setRevealedNodeIds],\n )\n\n const handleChange = useCallback(\n (event: unknown, value: string[]) => {\n if (!node) return\n const cleaned = value\n .map((name) => name.trim())\n .filter((name) => isValidClassName(name))\n action(() => {\n const nextProps: Record<string, unknown> = { ...(node.props as any) }\n if (cleaned.length) nextProps['className'] = cleaned.join(' ')\n else delete nextProps['className']\n node.props = nextProps as any\n })()\n },\n [node],\n )\n\n return (\n <ElementClassesChips\n classes={classes}\n isSwitchedOff={isSwitchedOff}\n onToggle={toggleClass}\n onChange={handleChange}\n />\n )\n },\n)\nElementClassesField.displayName = 'ElementClassesField'\n\nexport default ElementClassesField\n"],"names":["FieldMuteButton","Autocomplete","Chip","TextField","action","observer","memo","useCallback","useMemo","useAglynBesignerFlag","toggleRevealedNodeId","isClassMuted","isClassSwitchable","toggleMutedClass","CLASS_NAME_PATTERN","isValidClassName","name","test","NO_OPTIONS","ElementClassesChips","props","classes","isSwitchedOff","onToggle","onChange","multiple","freeSolo","size","options","value","renderValue","getItemProps","map","option","index","off","switchable","label","key","variant","sx","textDecoration","opacity","undefined","icon","mute","muted","ml","renderInput","params","placeholder","helperText","ElementClassesField","node","String","className","split","filter","Boolean","mutedClasses","setMutedClasses","revealedNodeIds","setRevealedNodeIds","nodeId","$id","some","id","toggleClass","current","handleChange","event","cleaned","trim","nextProps","length","join","displayName"],"mappings":"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"}
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
import type { ElementDetail } from '../utils/describe-element';
|
|
18
|
+
import { type BesignerDocsAnchor } from '../utils/docs-help';
|
|
19
|
+
/**
|
|
20
|
+
* Element category → its section of the element catalog page.
|
|
21
|
+
*
|
|
22
|
+
* The catalog's H2s ARE the drawer's categories, so the deep link is derived
|
|
23
|
+
* from the page's own headings rather than mapped by hand per category — a
|
|
24
|
+
* category is its heading's slug (`Data Display` → `#data-display`). A
|
|
25
|
+
* category the page has no section for — a plugin-registered label, "Your
|
|
26
|
+
* components" — lands on the page itself, which is correct rather than
|
|
27
|
+
* broken.
|
|
28
|
+
*/
|
|
29
|
+
export declare function elementCatalogAnchor(category: string | undefined): BesignerDocsAnchor<'elementCatalog'> | undefined;
|
|
18
30
|
export interface ElementDetailViewProps {
|
|
19
31
|
detail: ElementDetail | null;
|
|
20
32
|
/**
|
|
@@ -16,27 +16,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/ import { Box, Chip, Link, Stack, Typography } from "@mui/material";
|
|
18
18
|
import ElementPreview from "./element-preview.component.js";
|
|
19
|
-
import { besignerDocsUrl } from "../utils/docs-help.js";
|
|
19
|
+
import { BESIGNER_DOCS_ANCHORS, besignerDocsUrl } from "../utils/docs-help.js";
|
|
20
20
|
/**
|
|
21
21
|
* Element category → its section of the element catalog page.
|
|
22
22
|
*
|
|
23
23
|
* The catalog's H2s ARE the drawer's categories, so the deep link is derived
|
|
24
|
-
* rather than mapped by hand per
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* rather than
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Media: '#media',
|
|
35
|
-
Forms: '#forms-input-commerce-members',
|
|
36
|
-
Input: '#forms-input-commerce-members',
|
|
37
|
-
Commerce: '#forms-input-commerce-members',
|
|
38
|
-
Members: '#forms-input-commerce-members'
|
|
39
|
-
};
|
|
24
|
+
* from the page's own headings rather than mapped by hand per category — a
|
|
25
|
+
* category is its heading's slug (`Data Display` → `#data-display`). A
|
|
26
|
+
* category the page has no section for — a plugin-registered label, "Your
|
|
27
|
+
* components" — lands on the page itself, which is correct rather than
|
|
28
|
+
* broken.
|
|
29
|
+
*/ export function elementCatalogAnchor(category) {
|
|
30
|
+
const slug = (category != null ? category : '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
31
|
+
if (!slug) return undefined;
|
|
32
|
+
return BESIGNER_DOCS_ANCHORS.elementCatalog.find((anchor)=>anchor === `#${slug}`);
|
|
33
|
+
}
|
|
40
34
|
/**
|
|
41
35
|
* What a selected element actually is, shown before you commit to it
|
|
42
36
|
* (AGL-2486).
|
|
@@ -50,7 +44,6 @@ import { besignerDocsUrl } from "../utils/docs-help.js";
|
|
|
50
44
|
* Everything under the description is DERIVED from the schema, so it cannot
|
|
51
45
|
* go stale and third-party elements get it for free.
|
|
52
46
|
*/ export function ElementDetailView(props) {
|
|
53
|
-
var _detail_category;
|
|
54
47
|
const { detail, dense, node, previewHeight } = props;
|
|
55
48
|
if (!detail) return null;
|
|
56
49
|
return /*#__PURE__*/ _jsxs(Stack, {
|
|
@@ -153,7 +146,7 @@ import { besignerDocsUrl } from "../utils/docs-help.js";
|
|
|
153
146
|
]
|
|
154
147
|
}) : null,
|
|
155
148
|
/*#__PURE__*/ _jsx(Link, {
|
|
156
|
-
href: besignerDocsUrl('elementCatalog',
|
|
149
|
+
href: besignerDocsUrl('elementCatalog', elementCatalogAnchor(detail.category)),
|
|
157
150
|
target: "_blank",
|
|
158
151
|
rel: "noopener noreferrer",
|
|
159
152
|
variant: "caption",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/element-detail.component.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 { Box, Chip, Link, Stack, Typography } from '@mui/material'\nimport type { ElementDetail } from '../utils/describe-element'\nimport ElementPreview from './element-preview.component'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/components/element-detail.component.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 { Box, Chip, Link, Stack, Typography } from '@mui/material'\nimport type { ElementDetail } from '../utils/describe-element'\nimport ElementPreview from './element-preview.component'\nimport {\n BESIGNER_DOCS_ANCHORS,\n besignerDocsUrl,\n type BesignerDocsAnchor,\n} from '../utils/docs-help'\n\n/**\n * Element category → its section of the element catalog page.\n *\n * The catalog's H2s ARE the drawer's categories, so the deep link is derived\n * from the page's own headings rather than mapped by hand per category — a\n * category is its heading's slug (`Data Display` → `#data-display`). A\n * category the page has no section for — a plugin-registered label, \"Your\n * components\" — lands on the page itself, which is correct rather than\n * broken.\n */\nexport function elementCatalogAnchor(\n category: string | undefined,\n): BesignerDocsAnchor<'elementCatalog'> | undefined {\n const slug = (category ?? '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n if (!slug) return undefined\n return BESIGNER_DOCS_ANCHORS.elementCatalog.find(\n (anchor) => anchor === `#${slug}`,\n )\n}\n\nexport interface ElementDetailViewProps {\n detail: ElementDetail | null\n /**\n * Narrow presentation for the docked Elements column. Same CONTENT either\n * way — the content is designed once and the two surfaces present it\n * differently, rather than there being two detail views to keep in step.\n */\n dense?: boolean\n /**\n * Height the preview may take. Both surfaces now float or pane the detail,\n * so the preview is no longer squeezed into whatever the text leaves — it\n * gets the room, because it is the part that needs it.\n */\n previewHeight?: number\n /**\n * The picker item itself, when the surface wants a rendered preview above\n * the text. Only ever the one selected or hovered element — the detail\n * region is single-tenant by construction, so the preview is too.\n */\n node?: any\n}\n\n/**\n * What a selected element actually is, shown before you commit to it\n * (AGL-2486).\n *\n * Deliberately a DOCKED REGION rather than a hover popup. A popup over the\n * grid would have to solve three problems this does not have: it can swallow\n * the click meant for the card beneath it, it can cover the very item you\n * are pointing at, and several can open at once. A region that lives outside\n * the grid cannot do any of those by construction.\n *\n * Everything under the description is DERIVED from the schema, so it cannot\n * go stale and third-party elements get it for free.\n */\nexport function ElementDetailView(props: ElementDetailViewProps) {\n const { detail, dense, node, previewHeight } = props\n if (!detail) return null\n\n return (\n <Stack\n spacing={dense ? 0.5 : 0.75}\n sx={{ minWidth: 0, width: 1 }}\n aria-live=\"polite\"\n data-testid=\"element-detail\"\n >\n {node ? (\n <ElementPreview\n node={node}\n height={previewHeight ?? (dense ? 116 : 168)}\n requiredParents={detail.requiredParents}\n />\n ) : null}\n\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', minWidth: 0 }}\n >\n <Typography\n variant={dense ? 'subtitle2' : 'subtitle1'}\n noWrap\n sx={{ textOverflow: 'ellipsis', fontWeight: 'fontWeightMedium' }}\n >\n {detail.name}\n </Typography>\n {detail.category ? (\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={detail.category}\n sx={{ textTransform: 'capitalize', flex: '0 0 auto' }}\n />\n ) : null}\n </Stack>\n\n {detail.description ? (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {detail.description}\n </Typography>\n ) : null}\n\n {/* Derived facts. No heading — in a narrow column a heading costs a\n line and explains nothing the list does not. */}\n <Box component=\"ul\" sx={{ m: 0, pl: 0, listStyle: 'none' }}>\n {detail.facts.map((fact) => (\n <Stack\n key={fact.id}\n component=\"li\"\n direction=\"row\"\n spacing={0.5}\n sx={{ alignItems: 'flex-start' }}\n >\n <Box\n aria-hidden\n sx={{\n flex: '0 0 auto',\n width: 4,\n height: 4,\n mt: '0.45em',\n borderRadius: '50%',\n backgroundColor: 'text.disabled',\n }}\n />\n <Typography variant=\"caption\" color=\"textSecondary\">\n {fact.label}\n </Typography>\n </Stack>\n ))}\n </Box>\n\n {detail.attributes.length ? (\n <Typography variant=\"caption\" color=\"textSecondary\" sx={{ mt: 0.25 }}>\n <Box component=\"span\" sx={{ fontWeight: 'fontWeightMedium' }}>\n {'Attributes: '}\n </Box>\n {detail.attributes.slice(0, dense ? 4 : 8).join(', ')}\n {detail.attributes.length > (dense ? 4 : 8) ? '…' : ''}\n </Typography>\n ) : null}\n\n {/* Links to the catalog rather than restating it. Duplicated\n documentation drifts, and the docs page is the thing that is\n actually maintained. */}\n <Link\n href={besignerDocsUrl(\n 'elementCatalog',\n elementCatalogAnchor(detail.category),\n )}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n variant=\"caption\"\n sx={{ fontWeight: 600 }}\n >\n {'Learn more'}\n </Link>\n </Stack>\n )\n}\nElementDetailView.displayName = 'ElementDetailView'\n\nexport default ElementDetailView\n"],"names":["Box","Chip","Link","Stack","Typography","ElementPreview","BESIGNER_DOCS_ANCHORS","besignerDocsUrl","elementCatalogAnchor","category","slug","toLowerCase","replace","undefined","elementCatalog","find","anchor","ElementDetailView","props","detail","dense","node","previewHeight","spacing","sx","minWidth","width","aria-live","data-testid","height","requiredParents","direction","alignItems","variant","noWrap","textOverflow","fontWeight","name","size","label","textTransform","flex","description","color","component","m","pl","listStyle","facts","map","fact","aria-hidden","mt","borderRadius","backgroundColor","id","attributes","length","slice","join","href","target","rel","displayName"],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ export interface ElementInteractionsFormProps {
|
|
|
15
15
|
* The list, the trigger picker and the section experiment move verbatim; what
|
|
16
16
|
* changes is where they are.
|
|
17
17
|
*/
|
|
18
|
-
export declare const ElementInteractionsForm: ((props: ElementInteractionsFormProps) => import("react").JSX.Element) & {
|
|
19
|
-
|
|
18
|
+
export declare const ElementInteractionsForm: ((props: ElementInteractionsFormProps) => import("react").JSX.Element) & import("react").NamedExoticComponent<ElementInteractionsFormProps> & {
|
|
19
|
+
readonly type: (props: ElementInteractionsFormProps) => import("react").JSX.Element;
|
|
20
20
|
};
|
|
21
21
|
export default ElementInteractionsForm;
|
|
@@ -54,8 +54,8 @@ export interface ElementPreviewProps {
|
|
|
54
54
|
* second list of which elements are self-contained: each element already
|
|
55
55
|
* says so itself.
|
|
56
56
|
*/
|
|
57
|
-
export declare const ElementPreview: ((props: ElementPreviewProps) => import("react").JSX.Element) & {
|
|
58
|
-
|
|
57
|
+
export declare const ElementPreview: ((props: ElementPreviewProps) => import("react").JSX.Element) & import("react").NamedExoticComponent<ElementPreviewProps> & {
|
|
58
|
+
readonly type: (props: ElementPreviewProps) => import("react").JSX.Element;
|
|
59
59
|
};
|
|
60
60
|
/**
|
|
61
61
|
* Whether the rendered preview drew anything a person can actually see.
|
|
@@ -571,5 +571,7 @@ export declare function buildEntityPickerField<T extends Aglyn.AglynAttributeSch
|
|
|
571
571
|
* which looks exactly like a site with no products.
|
|
572
572
|
*/
|
|
573
573
|
export declare function entityKindsForAttributes(attributes: readonly Aglyn.AglynAttributeSchema[] | undefined): Aglyn.EntityPickerKind[];
|
|
574
|
-
export declare const ElementPropsForm: import("react").
|
|
574
|
+
export declare const ElementPropsForm: import("react").ForwardRefExoticComponent<ElementPropsFormProps & import("react").RefAttributes<any>> & import("react").NamedExoticComponent<ElementPropsFormProps & import("react").RefAttributes<any>> & {
|
|
575
|
+
readonly type: import("react").ForwardRefExoticComponent<ElementPropsFormProps & import("react").RefAttributes<any>>;
|
|
576
|
+
};
|
|
575
577
|
export default ElementPropsForm;
|
|
@@ -798,12 +798,12 @@ export const elementPropsComponentMapper = _extends({}, simpleComponentMapper, {
|
|
|
798
798
|
}
|
|
799
799
|
if (field.component === FieldComponentType.DATASET_FIELD_SELECT) {
|
|
800
800
|
var _ref;
|
|
801
|
-
var
|
|
802
|
-
//
|
|
801
|
+
var _entityOptions_entityFields_datasets, _entityOptions_entityFields;
|
|
802
|
+
// Declared order, never alphabetized — it mirrors the schema dialog. A
|
|
803
803
|
// field naming its own dataset (a Dataset field property) reads that
|
|
804
804
|
// one; every other reads the nearest ancestor's.
|
|
805
|
-
const
|
|
806
|
-
const modelFields =
|
|
805
|
+
const boundId = typeof field['datasetId'] === 'string' && field['datasetId'] ? field['datasetId'] : ancestorDatasetId;
|
|
806
|
+
const modelFields = boundId ? (_ref = (_entityOptions_entityFields = entityOptions.entityFields) == null ? void 0 : (_entityOptions_entityFields_datasets = _entityOptions_entityFields.datasets) == null ? void 0 : _entityOptions_entityFields_datasets[boundId]) != null ? _ref : [] : [];
|
|
807
807
|
return _extends({}, field, {
|
|
808
808
|
component: FieldComponentType.SELECT,
|
|
809
809
|
options: [
|