@aglyn/plugins-mui 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +22 -0
  3. package/package.json +47 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +22 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/accordion.d.ts +96 -0
  8. package/src/lib/components/accordion.js +392 -0
  9. package/src/lib/components/accordion.js.map +1 -0
  10. package/src/lib/components/app-bar.d.ts +32 -0
  11. package/src/lib/components/app-bar.js +86 -0
  12. package/src/lib/components/app-bar.js.map +1 -0
  13. package/src/lib/components/blocks.d.ts +46 -0
  14. package/src/lib/components/blocks.js +1007 -0
  15. package/src/lib/components/blocks.js.map +1 -0
  16. package/src/lib/components/box.d.ts +47 -0
  17. package/src/lib/components/box.js +125 -0
  18. package/src/lib/components/box.js.map +1 -0
  19. package/src/lib/components/breadcrumbs.d.ts +44 -0
  20. package/src/lib/components/breadcrumbs.js +172 -0
  21. package/src/lib/components/breadcrumbs.js.map +1 -0
  22. package/src/lib/components/button.d.ts +89 -0
  23. package/src/lib/components/button.js +272 -0
  24. package/src/lib/components/button.js.map +1 -0
  25. package/src/lib/components/card.d.ts +61 -0
  26. package/src/lib/components/card.js +336 -0
  27. package/src/lib/components/card.js.map +1 -0
  28. package/src/lib/components/collection.d.ts +514 -0
  29. package/src/lib/components/collection.js +2999 -0
  30. package/src/lib/components/collection.js.map +1 -0
  31. package/src/lib/components/container.d.ts +42 -0
  32. package/src/lib/components/container.js +169 -0
  33. package/src/lib/components/container.js.map +1 -0
  34. package/src/lib/components/custom-html.d.ts +78 -0
  35. package/src/lib/components/custom-html.js +219 -0
  36. package/src/lib/components/custom-html.js.map +1 -0
  37. package/src/lib/components/data-table.d.ts +57 -0
  38. package/src/lib/components/data-table.js +216 -0
  39. package/src/lib/components/data-table.js.map +1 -0
  40. package/src/lib/components/document-root.d.ts +77 -0
  41. package/src/lib/components/document-root.js +118 -0
  42. package/src/lib/components/document-root.js.map +1 -0
  43. package/src/lib/components/drawer.d.ts +93 -0
  44. package/src/lib/components/drawer.js +566 -0
  45. package/src/lib/components/drawer.js.map +1 -0
  46. package/src/lib/components/function-controls.d.ts +66 -0
  47. package/src/lib/components/function-controls.js +207 -0
  48. package/src/lib/components/function-controls.js.map +1 -0
  49. package/src/lib/components/function-scope.d.ts +110 -0
  50. package/src/lib/components/function-scope.js +478 -0
  51. package/src/lib/components/function-scope.js.map +1 -0
  52. package/src/lib/components/function-widget.d.ts +75 -0
  53. package/src/lib/components/function-widget.js +307 -0
  54. package/src/lib/components/function-widget.js.map +1 -0
  55. package/src/lib/components/grid.d.ts +91 -0
  56. package/src/lib/components/grid.js +322 -0
  57. package/src/lib/components/grid.js.map +1 -0
  58. package/src/lib/components/icon.d.ts +54 -0
  59. package/src/lib/components/icon.js +163 -0
  60. package/src/lib/components/icon.js.map +1 -0
  61. package/src/lib/components/image-list.d.ts +58 -0
  62. package/src/lib/components/image-list.js +336 -0
  63. package/src/lib/components/image-list.js.map +1 -0
  64. package/src/lib/components/image.d.ts +154 -0
  65. package/src/lib/components/image.js +451 -0
  66. package/src/lib/components/image.js.map +1 -0
  67. package/src/lib/components/inline-text.d.ts +74 -0
  68. package/src/lib/components/inline-text.js +407 -0
  69. package/src/lib/components/inline-text.js.map +1 -0
  70. package/src/lib/components/language-switcher.d.ts +35 -0
  71. package/src/lib/components/language-switcher.js +179 -0
  72. package/src/lib/components/language-switcher.js.map +1 -0
  73. package/src/lib/components/layout-slot.d.ts +68 -0
  74. package/src/lib/components/layout-slot.js +192 -0
  75. package/src/lib/components/layout-slot.js.map +1 -0
  76. package/src/lib/components/link-box-accessible-name.d.ts +79 -0
  77. package/src/lib/components/link-box-accessible-name.js +158 -0
  78. package/src/lib/components/link-box-accessible-name.js.map +1 -0
  79. package/src/lib/components/link-box.d.ts +66 -0
  80. package/src/lib/components/link-box.js +212 -0
  81. package/src/lib/components/link-box.js.map +1 -0
  82. package/src/lib/components/list-item-text.d.ts +22 -0
  83. package/src/lib/components/list-item-text.js +86 -0
  84. package/src/lib/components/list-item-text.js.map +1 -0
  85. package/src/lib/components/list-item.d.ts +32 -0
  86. package/src/lib/components/list-item.js +127 -0
  87. package/src/lib/components/list-item.js.map +1 -0
  88. package/src/lib/components/list.d.ts +34 -0
  89. package/src/lib/components/list.js +108 -0
  90. package/src/lib/components/list.js.map +1 -0
  91. package/src/lib/components/markdown.d.ts +129 -0
  92. package/src/lib/components/markdown.js +853 -0
  93. package/src/lib/components/markdown.js.map +1 -0
  94. package/src/lib/components/nav-menu.d.ts +68 -0
  95. package/src/lib/components/nav-menu.js +683 -0
  96. package/src/lib/components/nav-menu.js.map +1 -0
  97. package/src/lib/components/pagination.d.ts +59 -0
  98. package/src/lib/components/pagination.js +243 -0
  99. package/src/lib/components/pagination.js.map +1 -0
  100. package/src/lib/components/paper.d.ts +47 -0
  101. package/src/lib/components/paper.js +202 -0
  102. package/src/lib/components/paper.js.map +1 -0
  103. package/src/lib/components/plugin-frame.d.ts +64 -0
  104. package/src/lib/components/plugin-frame.js +335 -0
  105. package/src/lib/components/plugin-frame.js.map +1 -0
  106. package/src/lib/components/plugin.d.ts +95 -0
  107. package/src/lib/components/plugin.js +304 -0
  108. package/src/lib/components/plugin.js.map +1 -0
  109. package/src/lib/components/product.d.ts +40 -0
  110. package/src/lib/components/product.js +287 -0
  111. package/src/lib/components/product.js.map +1 -0
  112. package/src/lib/components/reusable-instance.d.ts +57 -0
  113. package/src/lib/components/reusable-instance.js +126 -0
  114. package/src/lib/components/reusable-instance.js.map +1 -0
  115. package/src/lib/components/screen-link.d.ts +85 -0
  116. package/src/lib/components/screen-link.js +324 -0
  117. package/src/lib/components/screen-link.js.map +1 -0
  118. package/src/lib/components/search-box.d.ts +41 -0
  119. package/src/lib/components/search-box.js +125 -0
  120. package/src/lib/components/search-box.js.map +1 -0
  121. package/src/lib/components/section.d.ts +56 -0
  122. package/src/lib/components/section.js +132 -0
  123. package/src/lib/components/section.js.map +1 -0
  124. package/src/lib/components/stack.d.ts +55 -0
  125. package/src/lib/components/stack.js +309 -0
  126. package/src/lib/components/stack.js.map +1 -0
  127. package/src/lib/components/tabs.d.ts +288 -0
  128. package/src/lib/components/tabs.js +788 -0
  129. package/src/lib/components/tabs.js.map +1 -0
  130. package/src/lib/components/theme-mode-switcher.d.ts +38 -0
  131. package/src/lib/components/theme-mode-switcher.js +168 -0
  132. package/src/lib/components/theme-mode-switcher.js.map +1 -0
  133. package/src/lib/components/toolbar.d.ts +37 -0
  134. package/src/lib/components/toolbar.js +117 -0
  135. package/src/lib/components/toolbar.js.map +1 -0
  136. package/src/lib/components/typography.d.ts +33 -0
  137. package/src/lib/components/typography.js +433 -0
  138. package/src/lib/components/typography.js.map +1 -0
  139. package/src/lib/components/video-lightbox-controls.d.ts +131 -0
  140. package/src/lib/components/video-lightbox-controls.js +536 -0
  141. package/src/lib/components/video-lightbox-controls.js.map +1 -0
  142. package/src/lib/components/video-lightbox.d.ts +60 -0
  143. package/src/lib/components/video-lightbox.js +247 -0
  144. package/src/lib/components/video-lightbox.js.map +1 -0
  145. package/src/lib/components/video-playback-beacon.d.ts +80 -0
  146. package/src/lib/components/video-playback-beacon.js +128 -0
  147. package/src/lib/components/video-playback-beacon.js.map +1 -0
  148. package/src/lib/components/video-player-frame.d.ts +58 -0
  149. package/src/lib/components/video-player-frame.js +51 -0
  150. package/src/lib/components/video-player-frame.js.map +1 -0
  151. package/src/lib/components/video.d.ts +220 -0
  152. package/src/lib/components/video.js +874 -0
  153. package/src/lib/components/video.js.map +1 -0
  154. package/src/lib/constants/bundle-common.d.ts +17 -0
  155. package/src/lib/constants/bundle-common.js +18 -0
  156. package/src/lib/constants/bundle-common.js.map +1 -0
  157. package/src/lib/constants/field-presets.d.ts +93 -0
  158. package/src/lib/constants/field-presets.js +248 -0
  159. package/src/lib/constants/field-presets.js.map +1 -0
  160. package/src/lib/plugin.d.ts +80 -0
  161. package/src/lib/plugin.js +599 -0
  162. package/src/lib/plugin.js.map +1 -0
  163. package/src/lib/utils/author-html-label.d.ts +73 -0
  164. package/src/lib/utils/author-html-label.js +89 -0
  165. package/src/lib/utils/author-html-label.js.map +1 -0
  166. package/src/lib/utils/drop-cleared-props.d.ts +18 -0
  167. package/src/lib/utils/drop-cleared-props.js +74 -0
  168. package/src/lib/utils/drop-cleared-props.js.map +1 -0
  169. package/src/lib/utils/element-picker.d.ts +99 -0
  170. package/src/lib/utils/element-picker.js +140 -0
  171. package/src/lib/utils/element-picker.js.map +1 -0
  172. package/src/lib/utils/generate-preset-id.d.ts +19 -0
  173. package/src/lib/utils/generate-preset-id.js +25 -0
  174. package/src/lib/utils/generate-preset-id.js.map +1 -0
  175. package/src/lib/utils/link-target-props.d.ts +53 -0
  176. package/src/lib/utils/link-target-props.js +53 -0
  177. package/src/lib/utils/link-target-props.js.map +1 -0
@@ -0,0 +1,307 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2026 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import * as Aglyn from "@aglyn/aglyn";
20
+ import { mdiFunctionVariant } from "@aglyn/shared-data-mdi";
21
+ import Alert from "@mui/material/Alert";
22
+ import Button from "@mui/material/Button";
23
+ import Divider from "@mui/material/Divider";
24
+ import Stack from "@mui/material/Stack";
25
+ import Typography from "@mui/material/Typography";
26
+ import { forwardRef, useCallback, useContext, useMemo, useState } from "react";
27
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
28
+ import { generatePresetId } from "../utils/generate-preset-id.js";
29
+ import { FunctionParameterControl, displayFunctionValue as displayValue, initialFunctionArguments as initialArguments } from "./function-controls.js";
30
+ // Component ids are persisted in screen documents; never rename.
31
+ export const ID = 'functionWidget';
32
+ /**
33
+ * `name | Label` per line. A line with no bar labels the row with the name,
34
+ * and a name may appear once: the second copy of a row is a typo, not a
35
+ * second result.
36
+ */ export function parseFunctionWidgetOutputs(text) {
37
+ const rows = [];
38
+ const seen = new Set();
39
+ for (const line of String(text != null ? text : '').split('\n')){
40
+ const [rawName, ...rest] = line.split('|');
41
+ const name = rawName.trim();
42
+ if (!name || seen.has(name)) continue;
43
+ seen.add(name);
44
+ rows.push({
45
+ name,
46
+ label: rest.join('|').trim() || name
47
+ });
48
+ }
49
+ return rows;
50
+ }
51
+ /**
52
+ * Interactive function widget (Component Builder wiring, AGL-93): renders
53
+ * an input per function parameter and runs the host function client-side
54
+ * through the shared safe evaluator — a no-code calculator/logic block
55
+ * (quote estimators, eligibility checks, counters). The definition is
56
+ * injected server-side at compose; in the besigner the widget shows a
57
+ * static preview.
58
+ *
59
+ * WHAT A REAL CALCULATOR NEEDED (AGL-3202). The first one built on this
60
+ * compared five platforms, and the widget could ask for nothing but free
61
+ * text, labeled with the parameter's identifier, and could answer with
62
+ * nothing but one line. So a parameter now renders as what it IS — a number
63
+ * box, a yes/no switch, a choice list — under the label its author wrote;
64
+ * `outputs` lists several named results; and `autoRun` recomputes as the
65
+ * visitor types. All three are opt-in: a widget that sets none of them
66
+ * renders and behaves exactly as it did.
67
+ */ const FunctionWidget = /*#__PURE__*/ forwardRef((props, ref)=>{
68
+ var _ref;
69
+ const { functionName, title, buttonLabel, resultLabel, outputs, autoRun, definition, globals } = props, rest = _object_without_properties_loose(props, [
70
+ "functionName",
71
+ "title",
72
+ "buttonLabel",
73
+ "resultLabel",
74
+ "outputs",
75
+ "autoRun",
76
+ "definition",
77
+ "globals"
78
+ ]);
79
+ const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
80
+ const [args, setArgs] = useState(()=>initialArguments(definition));
81
+ // Button mode answers for what was typed WHEN the button was pressed, so
82
+ // the line under it does not change while the visitor edits a number.
83
+ const [submitted, setSubmitted] = useState(null);
84
+ const outputRows = useMemo(()=>parseFunctionWidgetOutputs(outputs), [
85
+ outputs
86
+ ]);
87
+ const live = Boolean(autoRun);
88
+ const evaluated = live ? args : submitted;
89
+ const run = useMemo(()=>definition && evaluated ? Aglyn.evaluateHostFunction(definition, evaluated, {
90
+ globals
91
+ }) : null, [
92
+ definition,
93
+ evaluated,
94
+ globals
95
+ ]);
96
+ const handleRun = useCallback(()=>{
97
+ if (!definition) return;
98
+ setSubmitted(_extends({}, args));
99
+ }, [
100
+ definition,
101
+ args
102
+ ]);
103
+ const setArgument = useCallback((name, value)=>{
104
+ setArgs((previous)=>_extends({}, previous, {
105
+ [name]: value
106
+ }));
107
+ }, []);
108
+ // With no definition there is nothing to run, and the line drawn in its
109
+ // place is addressed to the author: a published page renders the bare
110
+ // element.
111
+ if (!definition && !suppressNavigation) return /*#__PURE__*/ _jsx(Stack, _extends({
112
+ ref: ref
113
+ }, rest));
114
+ const parameters = (_ref = definition == null ? void 0 : definition.parameters) != null ? _ref : [];
115
+ // Typing toward a valid answer is not a mistake. In live mode a required
116
+ // input that is still empty shows nothing rather than a warning that
117
+ // fires on the first keystroke of every visit.
118
+ const waiting = live && (run == null ? void 0 : run.ok) === false && parameters.some((parameter)=>{
119
+ var _args_parameter_name;
120
+ return parameter.required && !String((_args_parameter_name = args[parameter.name]) != null ? _args_parameter_name : '').trim() && !parameter.defaultValue;
121
+ });
122
+ return /*#__PURE__*/ _jsxs(Stack, _extends({
123
+ ref: ref,
124
+ spacing: 1.5,
125
+ sx: {
126
+ maxWidth: 420
127
+ }
128
+ }, rest, {
129
+ children: [
130
+ title ? /*#__PURE__*/ _jsx(Typography, {
131
+ variant: "h6",
132
+ children: title
133
+ }) : null,
134
+ definition ? /*#__PURE__*/ _jsxs(_Fragment, {
135
+ children: [
136
+ /*#__PURE__*/ _jsx(Stack, {
137
+ direction: "row",
138
+ spacing: 1,
139
+ sx: {
140
+ flexWrap: 'wrap',
141
+ rowGap: 1.5,
142
+ alignItems: 'center'
143
+ },
144
+ children: parameters.map((parameter)=>{
145
+ var _args_parameter_name;
146
+ return /*#__PURE__*/ _jsx(FunctionParameterControl, {
147
+ name: parameter.name,
148
+ type: parameter.type,
149
+ required: parameter.required,
150
+ label: parameter.label,
151
+ options: parameter.options,
152
+ value: (_args_parameter_name = args[parameter.name]) != null ? _args_parameter_name : '',
153
+ onChange: (value)=>setArgument(parameter.name, value)
154
+ }, parameter.name);
155
+ })
156
+ }),
157
+ live ? null : /*#__PURE__*/ _jsx(Button, {
158
+ variant: "contained",
159
+ onClick: handleRun,
160
+ sx: {
161
+ alignSelf: 'flex-start'
162
+ },
163
+ children: buttonLabel || 'Calculate'
164
+ }),
165
+ /*#__PURE__*/ _jsxs(Stack, {
166
+ spacing: 1,
167
+ "aria-live": "polite",
168
+ children: [
169
+ run && run.ok === false && !waiting ? /*#__PURE__*/ _jsx(Alert, {
170
+ severity: "warning",
171
+ children: `Error: ${run.error}`
172
+ }) : null,
173
+ run && run.ok && outputRows.length ? /*#__PURE__*/ _jsxs(_Fragment, {
174
+ children: [
175
+ /*#__PURE__*/ _jsx(Stack, {
176
+ divider: /*#__PURE__*/ _jsx(Divider, {
177
+ flexItem: true
178
+ }),
179
+ spacing: 0.75,
180
+ children: outputRows.map((row)=>/*#__PURE__*/ _jsxs(Stack, {
181
+ direction: "row",
182
+ spacing: 2,
183
+ sx: {
184
+ justifyContent: 'space-between'
185
+ },
186
+ children: [
187
+ /*#__PURE__*/ _jsx(Typography, {
188
+ variant: "body2",
189
+ color: "text.secondary",
190
+ children: row.label
191
+ }),
192
+ /*#__PURE__*/ _jsx(Typography, {
193
+ variant: "body2",
194
+ "data-aglyn-function-output": row.name,
195
+ sx: {
196
+ fontWeight: 600,
197
+ textAlign: 'right'
198
+ },
199
+ children: displayValue(run.scope[row.name])
200
+ })
201
+ ]
202
+ }, row.name))
203
+ }),
204
+ definition.returnValue && displayValue(run.value) ? /*#__PURE__*/ _jsx(Typography, {
205
+ variant: "body2",
206
+ "data-aglyn-function-output": "returnValue",
207
+ children: resultLabel ? `${resultLabel}: ${displayValue(run.value)}` : displayValue(run.value)
208
+ }) : null
209
+ ]
210
+ }) : null,
211
+ run && run.ok && !outputRows.length ? /*#__PURE__*/ _jsx(Alert, {
212
+ severity: "success",
213
+ children: `${resultLabel || 'Result'}: ${String(run.value)}`
214
+ }) : null
215
+ ]
216
+ })
217
+ ]
218
+ }) : /*#__PURE__*/ _jsx(Typography, {
219
+ variant: "body2",
220
+ color: "text.secondary",
221
+ children: functionName ? `Function widget "${functionName}" — interactive on the published site.` : 'Function widget — set the Function name attribute to a function from your dashboard.'
222
+ })
223
+ ]
224
+ }));
225
+ });
226
+ FunctionWidget.displayName = 'AglynFunctionWidget';
227
+ export const schema = {
228
+ $id: ID,
229
+ pluginId: BUNDLE_ID,
230
+ displayName: 'Function Widget',
231
+ description: 'Runs one of your no-code functions and shows the result — calculators, quotes.',
232
+ category: Aglyn.ComponentCategory.INPUT,
233
+ icon: {
234
+ path: mdiFunctionVariant.path,
235
+ sx: {
236
+ color: '#7b1fa2'
237
+ }
238
+ },
239
+ flags: {
240
+ selfClosing: Aglyn.FEATURE_FLAG.ENABLED
241
+ },
242
+ attributes: [
243
+ {
244
+ name: 'functionName',
245
+ description: 'Name of a function from the dashboard Functions card to run.',
246
+ component: Aglyn.FieldComponentType.TEXT_FIELD,
247
+ label: 'Function name'
248
+ },
249
+ {
250
+ name: 'title',
251
+ description: 'Heading shown above the inputs.',
252
+ component: Aglyn.FieldComponentType.TEXT_FIELD,
253
+ label: 'Title'
254
+ },
255
+ {
256
+ name: 'buttonLabel',
257
+ description: 'Label on the run button.',
258
+ component: Aglyn.FieldComponentType.TEXT_FIELD,
259
+ label: 'Button label'
260
+ },
261
+ {
262
+ name: 'resultLabel',
263
+ description: 'Prefix shown before the result value.',
264
+ component: Aglyn.FieldComponentType.TEXT_FIELD,
265
+ label: 'Result label'
266
+ },
267
+ {
268
+ name: 'outputs',
269
+ description: 'Show several results instead of one. One per line, as ' + '"name | Label": the name of a parameter or variable of the ' + 'function, then what visitors should read beside it. Leave empty ' + 'to show only the function’s return value.',
270
+ component: Aglyn.FieldComponentType.TEXTAREA,
271
+ label: 'Results to show'
272
+ },
273
+ {
274
+ name: 'autoRun',
275
+ description: 'If true, the results update as the visitor types and the button ' + 'is not shown.',
276
+ component: Aglyn.FieldComponentType.SWITCH,
277
+ label: 'Update as the visitor types?'
278
+ }
279
+ ]
280
+ };
281
+ export const presets = [
282
+ {
283
+ $id: generatePresetId(ID),
284
+ type: Aglyn.NodeType.PRESET,
285
+ displayName: 'Function Widget',
286
+ pluginId: BUNDLE_ID,
287
+ description: 'Run a no-code function — calculators, quotes, checks',
288
+ category: Aglyn.ComponentCategory.INPUT,
289
+ icon: {
290
+ path: mdiFunctionVariant.path,
291
+ sx: {
292
+ color: '#7b1fa2'
293
+ }
294
+ },
295
+ data: {
296
+ $id: null,
297
+ componentId: ID,
298
+ pluginId: BUNDLE_ID,
299
+ props: {
300
+ buttonLabel: 'Calculate'
301
+ }
302
+ }
303
+ }
304
+ ];
305
+ export default FunctionWidget;
306
+
307
+ //# sourceMappingURL=function-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/function-widget.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 { mdiFunctionVariant } from '@aglyn/shared-data-mdi'\nimport Alert from '@mui/material/Alert'\nimport Button from '@mui/material/Button'\nimport Divider from '@mui/material/Divider'\nimport Stack from '@mui/material/Stack'\nimport Typography from '@mui/material/Typography'\nimport { forwardRef, useCallback, useContext, useMemo, useState } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\nimport {\n FunctionParameterControl,\n displayFunctionValue as displayValue,\n initialFunctionArguments as initialArguments,\n} from './function-controls'\n\n// Component ids are persisted in screen documents; never rename.\nexport const ID: Aglyn.ComponentId = 'functionWidget'\n\nexport interface FunctionWidgetProps {\n /** Name of the host function to run (Functions card on the dashboard). */\n functionName?: string\n title?: string\n buttonLabel?: string\n resultLabel?: string\n /**\n * Several named results instead of one (AGL-3202): one per line, as\n * `name | Label`, where the name is a parameter or variable of the\n * function. Empty shows the return value alone, as it always has.\n */\n outputs?: string\n /** Recompute as the visitor types; no button (AGL-3202). */\n autoRun?: boolean\n /**\n * Injected at tenant compose time (attachFunctionDefinitions) — never\n * authored directly. Editor canvas renders without it (inert preview).\n */\n definition?: Aglyn.HostFunction\n /**\n * The site variables this function reads, by name (AGL-3202). Injected\n * beside `definition`, and only the ones its expressions name.\n */\n globals?: Record<string, number | string | boolean>\n}\n\n/** One row of the `outputs` attribute. */\nexport interface FunctionWidgetOutput {\n name: string\n label: string\n}\n\n/**\n * `name | Label` per line. A line with no bar labels the row with the name,\n * and a name may appear once: the second copy of a row is a typo, not a\n * second result.\n */\nexport function parseFunctionWidgetOutputs(\n text: string | undefined,\n): FunctionWidgetOutput[] {\n const rows: FunctionWidgetOutput[] = []\n const seen = new Set<string>()\n for (const line of String(text ?? '').split('\\n')) {\n const [rawName, ...rest] = line.split('|')\n const name = rawName.trim()\n if (!name || seen.has(name)) continue\n seen.add(name)\n rows.push({ name, label: rest.join('|').trim() || name })\n }\n return rows\n}\n\n/**\n * Interactive function widget (Component Builder wiring, AGL-93): renders\n * an input per function parameter and runs the host function client-side\n * through the shared safe evaluator — a no-code calculator/logic block\n * (quote estimators, eligibility checks, counters). The definition is\n * injected server-side at compose; in the besigner the widget shows a\n * static preview.\n *\n * WHAT A REAL CALCULATOR NEEDED (AGL-3202). The first one built on this\n * compared five platforms, and the widget could ask for nothing but free\n * text, labeled with the parameter's identifier, and could answer with\n * nothing but one line. So a parameter now renders as what it IS — a number\n * box, a yes/no switch, a choice list — under the label its author wrote;\n * `outputs` lists several named results; and `autoRun` recomputes as the\n * visitor types. All three are opt-in: a widget that sets none of them\n * renders and behaves exactly as it did.\n */\nconst FunctionWidget = forwardRef<HTMLDivElement, FunctionWidgetProps>(\n (props, ref) => {\n const {\n functionName,\n title,\n buttonLabel,\n resultLabel,\n outputs,\n autoRun,\n definition,\n globals,\n ...rest\n } = props\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const [args, setArgs] = useState<Record<string, string>>(() =>\n initialArguments(definition),\n )\n // Button mode answers for what was typed WHEN the button was pressed, so\n // the line under it does not change while the visitor edits a number.\n const [submitted, setSubmitted] = useState<Record<string, string> | null>(\n null,\n )\n const outputRows = useMemo(\n () => parseFunctionWidgetOutputs(outputs),\n [outputs],\n )\n const live = Boolean(autoRun)\n const evaluated = live ? args : submitted\n const run = useMemo(\n () =>\n definition && evaluated\n ? Aglyn.evaluateHostFunction(definition, evaluated, { globals })\n : null,\n [definition, evaluated, globals],\n )\n const handleRun = useCallback(() => {\n if (!definition) return\n setSubmitted({ ...args })\n }, [definition, args])\n const setArgument = useCallback((name: string, value: string) => {\n setArgs((previous) => ({ ...previous, [name]: value }))\n }, [])\n // With no definition there is nothing to run, and the line drawn in its\n // place is addressed to the author: a published page renders the bare\n // element.\n if (!definition && !suppressNavigation) return <Stack ref={ref} {...rest} />\n const parameters = definition?.parameters ?? []\n // Typing toward a valid answer is not a mistake. In live mode a required\n // input that is still empty shows nothing rather than a warning that\n // fires on the first keystroke of every visit.\n const waiting =\n live &&\n run?.ok === false &&\n parameters.some(\n (parameter) =>\n parameter.required &&\n !String(args[parameter.name] ?? '').trim() &&\n !parameter.defaultValue,\n )\n return (\n <Stack ref={ref} spacing={1.5} sx={{ maxWidth: 420 }} {...rest}>\n {title ? <Typography variant=\"h6\">{title}</Typography> : null}\n {definition ? (\n <>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1.5, alignItems: 'center' }}\n >\n {parameters.map((parameter) => (\n <FunctionParameterControl\n key={parameter.name}\n name={parameter.name}\n type={parameter.type}\n required={parameter.required}\n label={parameter.label}\n options={parameter.options}\n value={args[parameter.name] ?? ''}\n onChange={(value) => setArgument(parameter.name, value)}\n />\n ))}\n </Stack>\n {live ? null : (\n <Button\n variant=\"contained\"\n onClick={handleRun}\n sx={{ alignSelf: 'flex-start' }}\n >\n {buttonLabel || 'Calculate'}\n </Button>\n )}\n <Stack spacing={1} aria-live=\"polite\">\n {run && run.ok === false && !waiting ? (\n <Alert severity=\"warning\">{`Error: ${run.error}`}</Alert>\n ) : null}\n {run && run.ok && outputRows.length ? (\n <>\n <Stack divider={<Divider flexItem />} spacing={0.75}>\n {outputRows.map((row) => (\n <Stack\n key={row.name}\n direction=\"row\"\n spacing={2}\n sx={{ justifyContent: 'space-between' }}\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n {row.label}\n </Typography>\n <Typography\n variant=\"body2\"\n data-aglyn-function-output={row.name}\n sx={{ fontWeight: 600, textAlign: 'right' }}\n >\n {displayValue(run.scope[row.name])}\n </Typography>\n </Stack>\n ))}\n </Stack>\n {definition.returnValue && displayValue(run.value) ? (\n <Typography\n variant=\"body2\"\n data-aglyn-function-output=\"returnValue\"\n >\n {resultLabel\n ? `${resultLabel}: ${displayValue(run.value)}`\n : displayValue(run.value)}\n </Typography>\n ) : null}\n </>\n ) : null}\n {run && run.ok && !outputRows.length ? (\n <Alert severity=\"success\">\n {`${resultLabel || 'Result'}: ${String(run.value)}`}\n </Alert>\n ) : null}\n </Stack>\n </>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {functionName\n ? `Function widget \"${functionName}\" — interactive on the published site.`\n : 'Function widget — set the Function name attribute to a function from your dashboard.'}\n </Typography>\n )}\n </Stack>\n )\n },\n)\nFunctionWidget.displayName = 'AglynFunctionWidget'\n\nexport const schema: Aglyn.ComponentSchema<FunctionWidgetProps> = {\n $id: ID,\n pluginId: BUNDLE_ID,\n displayName: 'Function Widget',\n description:\n 'Runs one of your no-code functions and shows the result — calculators, quotes.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFunctionVariant.path, sx: { color: '#7b1fa2' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'functionName',\n description:\n 'Name of a function from the dashboard Functions card to run.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Function name',\n },\n {\n name: 'title',\n description: 'Heading shown above the inputs.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Title',\n },\n {\n name: 'buttonLabel',\n description: 'Label on the run button.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Button label',\n },\n {\n name: 'resultLabel',\n description: 'Prefix shown before the result value.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Result label',\n },\n {\n name: 'outputs',\n description:\n 'Show several results instead of one. One per line, as ' +\n '\"name | Label\": the name of a parameter or variable of the ' +\n 'function, then what visitors should read beside it. Leave empty ' +\n 'to show only the function’s return value.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n label: 'Results to show',\n },\n {\n name: 'autoRun',\n description:\n 'If true, the results update as the visitor types and the button ' +\n 'is not shown.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Update as the visitor types?',\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Function Widget',\n pluginId: BUNDLE_ID,\n description: 'Run a no-code function — calculators, quotes, checks',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFunctionVariant.path, sx: { color: '#7b1fa2' } },\n data: {\n $id: null,\n componentId: ID,\n pluginId: BUNDLE_ID,\n props: { buttonLabel: 'Calculate' },\n },\n },\n]\n\nexport default FunctionWidget\n"],"names":["Aglyn","mdiFunctionVariant","Alert","Button","Divider","Stack","Typography","forwardRef","useCallback","useContext","useMemo","useState","BUNDLE_ID","generatePresetId","FunctionParameterControl","displayFunctionValue","displayValue","initialFunctionArguments","initialArguments","ID","parseFunctionWidgetOutputs","text","rows","seen","Set","line","String","split","rawName","rest","name","trim","has","add","push","label","join","FunctionWidget","props","ref","functionName","title","buttonLabel","resultLabel","outputs","autoRun","definition","globals","suppressNavigation","ScreenLinkContext","args","setArgs","submitted","setSubmitted","outputRows","live","Boolean","evaluated","run","evaluateHostFunction","handleRun","setArgument","value","previous","parameters","waiting","ok","some","parameter","required","defaultValue","spacing","sx","maxWidth","variant","direction","flexWrap","rowGap","alignItems","map","type","options","onChange","onClick","alignSelf","aria-live","severity","error","length","divider","flexItem","row","justifyContent","color","data-aglyn-function-output","fontWeight","textAlign","scope","returnValue","displayName","schema","$id","pluginId","description","category","ComponentCategory","INPUT","icon","path","flags","selfClosing","FEATURE_FLAG","ENABLED","attributes","component","FieldComponentType","TEXT_FIELD","TEXTAREA","SWITCH","presets","NodeType","PRESET","data","componentId"],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import * as Aglyn from '@aglyn/aglyn';
18
+ import { type SpanBreakpoint } from '@aglyn/shared-data-enums/breakpoint-span';
19
+ import { type ReactNode } from 'react';
20
+ export declare const ID: Aglyn.ComponentId;
21
+ /**
22
+ * Breakpoint keys MUI's responsive `size`/`offset` objects accept.
23
+ *
24
+ * Re-exported from `@aglyn/shared-data-enums` rather than declared twice
25
+ * (AGL-2486): the attributes panel's breakpoint row and this parser have to
26
+ * agree on the list, and two copies is how they stop agreeing.
27
+ */
28
+ export declare const BREAKPOINTS: readonly ["xs", "sm", "md", "lg", "xl"];
29
+ export type Breakpoint = SpanBreakpoint;
30
+ export interface GridElementProps {
31
+ /** Flex container behavior; items are its direct Grid children. */
32
+ container?: boolean;
33
+ /**
34
+ * Column span. Persisted as one string: a bare span (`6`), the keywords
35
+ * `auto`/`grow`, or per-breakpoint pairs (`xs:12 md:6`). Authored through
36
+ * the breakpoint row in the attributes panel (AGL-2486); the stored
37
+ * format is unchanged from when it was a text box.
38
+ */
39
+ size?: string | number;
40
+ /** Empty columns before the item; same syntax as `size`, minus `grow`. */
41
+ offset?: string | number;
42
+ spacing?: number | string;
43
+ rowSpacing?: number | string;
44
+ columnSpacing?: number | string;
45
+ /** Total columns in the container; MUI's default is 12. */
46
+ columns?: number | string;
47
+ /**
48
+ * Container flow. MUI supports `row`/`row-reverse` ONLY — Grid subdivides
49
+ * a layout into columns, and `column`/`column-reverse` are documented as
50
+ * unsupported (use a Stack for a vertical layout).
51
+ */
52
+ direction?: 'row' | 'row-reverse';
53
+ /** `flex-wrap` for the container; MUI's default is `wrap`. */
54
+ wrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
55
+ children?: ReactNode;
56
+ }
57
+ /**
58
+ * Parses the authored span syntax into what MUI v6+ Grid expects.
59
+ *
60
+ * MUI dropped the `item` prop and the per-breakpoint `xs=`/`md=` props in
61
+ * v6; v9 (installed here) takes a single `size` that is either a value or
62
+ * a `{ xs, md, … }` object. One STORED string covers both, and this parser
63
+ * owns the translation:
64
+ *
65
+ * `6` → 6
66
+ * `auto` → 'auto'
67
+ * `grow` → 'grow'
68
+ * `xs:12 md:6` → { xs: 12, md: 6 }
69
+ *
70
+ * Anything unparseable returns `undefined` rather than a partial object:
71
+ * a half-applied breakpoint map is a layout that silently differs from
72
+ * what the author typed.
73
+ */
74
+ export declare function parseSpan(value: unknown): number | 'auto' | 'grow' | Record<string, number | 'auto' | 'grow'> | undefined;
75
+ /**
76
+ * Same syntax as `parseSpan`, minus `grow`.
77
+ *
78
+ * MUI's `GridOffset` is `'auto' | number` only — a `grow` offset is not
79
+ * a wider gap, it is a value the layout cannot use, so it is dropped
80
+ * here rather than passed through to be ignored.
81
+ */
82
+ export declare function parseOffset(value: unknown): number | "auto" | Record<string, number | "auto">;
83
+ /**
84
+ * Responsive 12-column grid (https://mui.com/material-ui/react-grid/).
85
+ * One element covers both roles, matching MUI v6+: switch **Container**
86
+ * on for the row, leave it off and set a **Span** for each cell.
87
+ */
88
+ declare const GridElement: import("react").ForwardRefExoticComponent<GridElementProps & import("react").RefAttributes<HTMLDivElement>>;
89
+ export declare const schema: Aglyn.ComponentSchema<GridElementProps>;
90
+ export declare const presets: Aglyn.PresetSchema[];
91
+ export default GridElement;