@aglyn/plugins-mui 1.0.0-beta.216 → 1.0.0-beta.218
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/README.md +2 -1
- package/package.json +9 -9
- package/src/lib/components/markdown.d.ts +3 -1
- package/src/lib/components/pagination.d.ts +1 -1
- package/src/lib/components/pagination.js +4 -0
- package/src/lib/components/pagination.js.map +1 -1
- package/src/lib/components/tabs.d.ts +1 -1
- package/src/lib/components/tabs.js +4 -0
- package/src/lib/components/tabs.js.map +1 -1
- package/src/lib/constants/field-presets.js +4 -0
- package/src/lib/constants/field-presets.js.map +1 -1
- package/src/lib/element-tier.d.ts +0 -2
- package/src/lib/element-tier.js +0 -2
- package/src/lib/element-tier.js.map +1 -1
- package/src/lib/plugin.js +0 -32
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/components/function-controls.d.ts +0 -66
- package/src/lib/components/function-controls.js +0 -207
- package/src/lib/components/function-controls.js.map +0 -1
- package/src/lib/components/function-scope.d.ts +0 -110
- package/src/lib/components/function-scope.js +0 -478
- package/src/lib/components/function-scope.js.map +0 -1
- package/src/lib/components/function-widget.d.ts +0 -75
- package/src/lib/components/function-widget.js +0 -307
- package/src/lib/components/function-widget.js.map +0 -1
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2026 Aglyn LLC
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
|
-
import * as Aglyn from '@aglyn/aglyn';
|
|
18
|
-
import { type ReactNode } from 'react';
|
|
19
|
-
import { type FunctionControlKind } from './function-controls';
|
|
20
|
-
/**
|
|
21
|
-
* A CALCULATOR AN AUTHOR LAYS OUT (AGL-3202).
|
|
22
|
-
*
|
|
23
|
-
* The Function Widget draws a whole calculator itself: inputs in a row, a
|
|
24
|
-
* button, a result. That is the right block for "a quote in a sidebar" and
|
|
25
|
-
* the wrong one for the page that prompted this — a comparison with a number
|
|
26
|
-
* box AND quick picks on the same value, two questions asked as lists, a
|
|
27
|
-
* table of five rows where four can be filtered away, one row highlighted, a
|
|
28
|
-
* sentence under it and a footnote that changes with the choices. No amount
|
|
29
|
-
* of options on one block reaches that, and it should not have to: laying
|
|
30
|
-
* things out is what the canvas is for.
|
|
31
|
-
*
|
|
32
|
-
* So the pieces are separate elements, and one function binds them:
|
|
33
|
-
*
|
|
34
|
-
* - **Calculator** (`functionScope`) holds the function, the visitor's
|
|
35
|
-
* answers and the live result, and is an ordinary container.
|
|
36
|
-
* - **Calculator Input** (`functionInput`) asks ONE parameter, as a number
|
|
37
|
-
* box, a list, a switch or a row of quick-pick chips. Two inputs may ask
|
|
38
|
-
* the same parameter; they stay in step because the answer lives above
|
|
39
|
-
* them.
|
|
40
|
-
* - **Calculator Result** (`functionOutput`) shows one named value, styled
|
|
41
|
-
* like any text.
|
|
42
|
-
* - **Show When** (`functionShow`) is a container that appears only while a
|
|
43
|
-
* named value is truthy — a table row a filter can remove.
|
|
44
|
-
*
|
|
45
|
-
* Everything between them is whatever the author builds: stacks, grids,
|
|
46
|
-
* headings, borders. The design is theirs and the arithmetic is the site's
|
|
47
|
-
* function, reading the site's variables.
|
|
48
|
-
*/
|
|
49
|
-
export declare const SCOPE_ID: Aglyn.ComponentId;
|
|
50
|
-
export declare const INPUT_ID: Aglyn.ComponentId;
|
|
51
|
-
export declare const OUTPUT_ID: Aglyn.ComponentId;
|
|
52
|
-
export declare const SHOW_ID: Aglyn.ComponentId;
|
|
53
|
-
export interface FunctionScopeProps {
|
|
54
|
-
/** Name of the site function every element inside is bound to. */
|
|
55
|
-
functionName?: string;
|
|
56
|
-
children?: ReactNode;
|
|
57
|
-
/** Injected at compose (attachFunctionDefinitions); never authored. */
|
|
58
|
-
definition?: Aglyn.HostFunction;
|
|
59
|
-
/** The site variables the function names; injected beside `definition`. */
|
|
60
|
-
globals?: Record<string, number | string | boolean>;
|
|
61
|
-
}
|
|
62
|
-
declare const FunctionScope: import("react").ForwardRefExoticComponent<FunctionScopeProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
63
|
-
export interface FunctionInputProps {
|
|
64
|
-
/** The function parameter this control asks. */
|
|
65
|
-
parameter?: string;
|
|
66
|
-
control?: FunctionControlKind;
|
|
67
|
-
/** Overrides the parameter's own label. */
|
|
68
|
-
label?: string;
|
|
69
|
-
hideLabel?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Overrides the parameter's own choices, as `value: Label, value: Label`.
|
|
72
|
-
* This is how quick picks are given: `10, 25, 50, 100` beside a number box.
|
|
73
|
-
*/
|
|
74
|
-
choices?: string;
|
|
75
|
-
}
|
|
76
|
-
declare const FunctionInput: import("react").ForwardRefExoticComponent<FunctionInputProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
77
|
-
export interface FunctionOutputProps {
|
|
78
|
-
/** A parameter or variable of the function; empty is its return value. */
|
|
79
|
-
name?: string;
|
|
80
|
-
/** What the besigner shows in the result's place, e.g. `$625`. */
|
|
81
|
-
placeholder?: string;
|
|
82
|
-
/** Read a change aloud. One result per calculator, usually the sentence. */
|
|
83
|
-
announce?: boolean;
|
|
84
|
-
element?: 'div' | 'p' | 'span';
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* `**like this**` becomes emphasis, and nothing else is markup. The value is
|
|
88
|
-
* text a function built — often from what a visitor typed — so it is split
|
|
89
|
-
* into React nodes and never parsed as HTML.
|
|
90
|
-
*/
|
|
91
|
-
export declare function renderFunctionEmphasis(text: string): ReactNode;
|
|
92
|
-
declare const FunctionOutput: import("react").ForwardRefExoticComponent<FunctionOutputProps & import("react").RefAttributes<HTMLElement>>;
|
|
93
|
-
export interface FunctionShowProps {
|
|
94
|
-
/** A parameter or variable of the function. */
|
|
95
|
-
when?: string;
|
|
96
|
-
/** Show while the value is NOT truthy instead. */
|
|
97
|
-
invert?: boolean;
|
|
98
|
-
children?: ReactNode;
|
|
99
|
-
}
|
|
100
|
-
declare const FunctionShow: import("react").ForwardRefExoticComponent<FunctionShowProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
101
|
-
export declare const schema: Aglyn.ComponentSchema<FunctionScopeProps>;
|
|
102
|
-
export declare const functionInputSchema: Aglyn.ComponentSchema<FunctionInputProps>;
|
|
103
|
-
export declare const functionOutputSchema: Aglyn.ComponentSchema<FunctionOutputProps>;
|
|
104
|
-
export declare const functionShowSchema: Aglyn.ComponentSchema<FunctionShowProps>;
|
|
105
|
-
export declare const presets: Aglyn.PresetSchema[];
|
|
106
|
-
export declare const functionInputPresets: Aglyn.PresetSchema[];
|
|
107
|
-
export declare const functionOutputPresets: Aglyn.PresetSchema[];
|
|
108
|
-
export declare const functionShowPresets: Aglyn.PresetSchema[];
|
|
109
|
-
export { FunctionInput, FunctionOutput, FunctionShow };
|
|
110
|
-
export default FunctionScope;
|
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
-
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
3
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
-
/**
|
|
5
|
-
* @license
|
|
6
|
-
* Copyright 2026 Aglyn LLC
|
|
7
|
-
*
|
|
8
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
-
* you may not use this file except in compliance with the License.
|
|
10
|
-
* You may obtain a copy of the License at
|
|
11
|
-
*
|
|
12
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
-
*
|
|
14
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
-
* See the License for the specific language governing permissions and
|
|
18
|
-
* limitations under the License.
|
|
19
|
-
*/ import * as Aglyn from "@aglyn/aglyn";
|
|
20
|
-
import { mdiCalculatorVariantOutline, mdiEyeOutline, mdiFormTextbox, mdiFunctionVariant } from "@aglyn/shared-data-mdi";
|
|
21
|
-
import Box from "@mui/material/Box";
|
|
22
|
-
import { createContext, forwardRef, Fragment, useCallback, useContext, useMemo, useState } from "react";
|
|
23
|
-
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
24
|
-
import { generatePresetId } from "../utils/generate-preset-id.js";
|
|
25
|
-
import { FUNCTION_CONTROL_KINDS, FunctionParameterControl, displayFunctionValue, initialFunctionArguments, isFunctionValueTruthy } from "./function-controls.js";
|
|
26
|
-
/**
|
|
27
|
-
* A CALCULATOR AN AUTHOR LAYS OUT (AGL-3202).
|
|
28
|
-
*
|
|
29
|
-
* The Function Widget draws a whole calculator itself: inputs in a row, a
|
|
30
|
-
* button, a result. That is the right block for "a quote in a sidebar" and
|
|
31
|
-
* the wrong one for the page that prompted this — a comparison with a number
|
|
32
|
-
* box AND quick picks on the same value, two questions asked as lists, a
|
|
33
|
-
* table of five rows where four can be filtered away, one row highlighted, a
|
|
34
|
-
* sentence under it and a footnote that changes with the choices. No amount
|
|
35
|
-
* of options on one block reaches that, and it should not have to: laying
|
|
36
|
-
* things out is what the canvas is for.
|
|
37
|
-
*
|
|
38
|
-
* So the pieces are separate elements, and one function binds them:
|
|
39
|
-
*
|
|
40
|
-
* - **Calculator** (`functionScope`) holds the function, the visitor's
|
|
41
|
-
* answers and the live result, and is an ordinary container.
|
|
42
|
-
* - **Calculator Input** (`functionInput`) asks ONE parameter, as a number
|
|
43
|
-
* box, a list, a switch or a row of quick-pick chips. Two inputs may ask
|
|
44
|
-
* the same parameter; they stay in step because the answer lives above
|
|
45
|
-
* them.
|
|
46
|
-
* - **Calculator Result** (`functionOutput`) shows one named value, styled
|
|
47
|
-
* like any text.
|
|
48
|
-
* - **Show When** (`functionShow`) is a container that appears only while a
|
|
49
|
-
* named value is truthy — a table row a filter can remove.
|
|
50
|
-
*
|
|
51
|
-
* Everything between them is whatever the author builds: stacks, grids,
|
|
52
|
-
* headings, borders. The design is theirs and the arithmetic is the site's
|
|
53
|
-
* function, reading the site's variables.
|
|
54
|
-
*/ // Component ids are persisted in screen documents; never rename.
|
|
55
|
-
export const SCOPE_ID = 'functionScope';
|
|
56
|
-
export const INPUT_ID = 'functionInput';
|
|
57
|
-
export const OUTPUT_ID = 'functionOutput';
|
|
58
|
-
export const SHOW_ID = 'functionShow';
|
|
59
|
-
const FunctionScopeContext = /*#__PURE__*/ createContext(null);
|
|
60
|
-
const FunctionScope = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
61
|
-
const { functionName: _functionName, children, definition, globals } = props, rest = _object_without_properties_loose(props, [
|
|
62
|
-
"functionName",
|
|
63
|
-
"children",
|
|
64
|
-
"definition",
|
|
65
|
-
"globals"
|
|
66
|
-
]);
|
|
67
|
-
const [args, setArgs] = useState(()=>initialFunctionArguments(definition));
|
|
68
|
-
const setArgument = useCallback((name, value)=>{
|
|
69
|
-
setArgs((previous)=>_extends({}, previous, {
|
|
70
|
-
[name]: value
|
|
71
|
-
}));
|
|
72
|
-
}, []);
|
|
73
|
-
// Always live: a calculator laid out on a page has no single place a
|
|
74
|
-
// "Calculate" button would obviously go, and every result can be on
|
|
75
|
-
// screen at once. The Function Widget is the block with a button.
|
|
76
|
-
const run = useMemo(()=>definition ? Aglyn.evaluateHostFunction(definition, args, {
|
|
77
|
-
globals
|
|
78
|
-
}) : null, [
|
|
79
|
-
definition,
|
|
80
|
-
args,
|
|
81
|
-
globals
|
|
82
|
-
]);
|
|
83
|
-
const value = useMemo(()=>({
|
|
84
|
-
definition,
|
|
85
|
-
args,
|
|
86
|
-
setArgument,
|
|
87
|
-
run
|
|
88
|
-
}), [
|
|
89
|
-
definition,
|
|
90
|
-
args,
|
|
91
|
-
setArgument,
|
|
92
|
-
run
|
|
93
|
-
]);
|
|
94
|
-
return /*#__PURE__*/ _jsx(FunctionScopeContext.Provider, {
|
|
95
|
-
value: value,
|
|
96
|
-
children: /*#__PURE__*/ _jsx(Box, _extends({
|
|
97
|
-
ref: ref
|
|
98
|
-
}, rest, {
|
|
99
|
-
children: children
|
|
100
|
-
}))
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
FunctionScope.displayName = 'AglynFunctionScope';
|
|
104
|
-
const FunctionInput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
105
|
-
var _ref, _ref1;
|
|
106
|
-
var _scope_definition_parameters, _scope_definition;
|
|
107
|
-
const { parameter, control, label, hideLabel, choices } = props, rest = _object_without_properties_loose(props, [
|
|
108
|
-
"parameter",
|
|
109
|
-
"control",
|
|
110
|
-
"label",
|
|
111
|
-
"hideLabel",
|
|
112
|
-
"choices"
|
|
113
|
-
]);
|
|
114
|
-
const scope = useContext(FunctionScopeContext);
|
|
115
|
-
const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
|
|
116
|
-
const name = String(parameter != null ? parameter : '').trim();
|
|
117
|
-
const declared = scope == null ? void 0 : (_scope_definition = scope.definition) == null ? void 0 : (_scope_definition_parameters = _scope_definition.parameters) == null ? void 0 : _scope_definition_parameters.find((candidate)=>candidate.name === name);
|
|
118
|
-
const ownChoices = useMemo(()=>Aglyn.parseFunctionParameterOptions(choices), [
|
|
119
|
-
choices
|
|
120
|
-
]);
|
|
121
|
-
const options = ownChoices.length ? ownChoices : (_ref = declared == null ? void 0 : declared.options) != null ? _ref : [];
|
|
122
|
-
// No function to ask on behalf of: the besigner, or a page whose function
|
|
123
|
-
// was deleted. In the besigner the control is still DRAWN, from its own
|
|
124
|
-
// attributes, so a calculator can be designed before it works. On a
|
|
125
|
-
// published page a control that can set nothing is residue, not a
|
|
126
|
-
// question, and a visitor is shown nothing.
|
|
127
|
-
const inert = !(scope == null ? void 0 : scope.definition) || !declared;
|
|
128
|
-
if (inert && !suppressNavigation) return null;
|
|
129
|
-
return /*#__PURE__*/ _jsx(Box, _extends({
|
|
130
|
-
ref: ref
|
|
131
|
-
}, rest, {
|
|
132
|
-
children: /*#__PURE__*/ _jsx(FunctionParameterControl, {
|
|
133
|
-
name: name || 'parameter',
|
|
134
|
-
type: declared == null ? void 0 : declared.type,
|
|
135
|
-
required: declared == null ? void 0 : declared.required,
|
|
136
|
-
control: control,
|
|
137
|
-
label: (label == null ? void 0 : label.trim()) || (declared == null ? void 0 : declared.label),
|
|
138
|
-
hideLabel: Boolean(hideLabel),
|
|
139
|
-
options: options,
|
|
140
|
-
value: inert ? '' : (_ref1 = scope == null ? void 0 : scope.args[name]) != null ? _ref1 : '',
|
|
141
|
-
onChange: (next)=>scope == null ? void 0 : scope.setArgument(name, next),
|
|
142
|
-
disabled: inert,
|
|
143
|
-
width: "100%"
|
|
144
|
-
})
|
|
145
|
-
}));
|
|
146
|
-
});
|
|
147
|
-
FunctionInput.displayName = 'AglynFunctionInput';
|
|
148
|
-
const OUTPUT_ELEMENTS = [
|
|
149
|
-
'div',
|
|
150
|
-
'p',
|
|
151
|
-
'span'
|
|
152
|
-
];
|
|
153
|
-
/**
|
|
154
|
-
* `**like this**` becomes emphasis, and nothing else is markup. The value is
|
|
155
|
-
* text a function built — often from what a visitor typed — so it is split
|
|
156
|
-
* into React nodes and never parsed as HTML.
|
|
157
|
-
*/ export function renderFunctionEmphasis(text) {
|
|
158
|
-
const parts = text.split(/\*\*(.+?)\*\*/g);
|
|
159
|
-
if (parts.length === 1) return text;
|
|
160
|
-
return parts.map((part, index)=>index % 2 === 1 ? /*#__PURE__*/ _jsx("strong", {
|
|
161
|
-
children: part
|
|
162
|
-
}, index) : /*#__PURE__*/ _jsx(Fragment, {
|
|
163
|
-
children: part
|
|
164
|
-
}, index));
|
|
165
|
-
}
|
|
166
|
-
const FunctionOutput = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
167
|
-
const { name, placeholder, announce, element } = props, rest = _object_without_properties_loose(props, [
|
|
168
|
-
"name",
|
|
169
|
-
"placeholder",
|
|
170
|
-
"announce",
|
|
171
|
-
"element"
|
|
172
|
-
]);
|
|
173
|
-
const scope = useContext(FunctionScopeContext);
|
|
174
|
-
const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext);
|
|
175
|
-
const key = String(name != null ? name : '').trim();
|
|
176
|
-
const run = scope == null ? void 0 : scope.run;
|
|
177
|
-
let text = '';
|
|
178
|
-
if (run == null ? void 0 : run.ok) {
|
|
179
|
-
text = displayFunctionValue(key ? run.scope[key] : run.value);
|
|
180
|
-
} else if (suppressNavigation || !(scope == null ? void 0 : scope.definition)) {
|
|
181
|
-
// Designing: show what will stand here. On a published page a missing
|
|
182
|
-
// function shows nothing rather than a placeholder dressed as a price.
|
|
183
|
-
text = suppressNavigation ? placeholder || (key ? `{${key}}` : '{result}') : '';
|
|
184
|
-
}
|
|
185
|
-
if (!text) return null;
|
|
186
|
-
const tag = OUTPUT_ELEMENTS.includes(element) ? element : 'div';
|
|
187
|
-
return /*#__PURE__*/ _jsx(Box, _extends({
|
|
188
|
-
ref: ref,
|
|
189
|
-
component: tag
|
|
190
|
-
}, announce ? {
|
|
191
|
-
'aria-live': 'polite'
|
|
192
|
-
} : {}, rest, {
|
|
193
|
-
children: renderFunctionEmphasis(text)
|
|
194
|
-
}));
|
|
195
|
-
});
|
|
196
|
-
FunctionOutput.displayName = 'AglynFunctionOutput';
|
|
197
|
-
const FunctionShow = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
198
|
-
const { when, invert, children } = props, rest = _object_without_properties_loose(props, [
|
|
199
|
-
"when",
|
|
200
|
-
"invert",
|
|
201
|
-
"children"
|
|
202
|
-
]);
|
|
203
|
-
const scope = useContext(FunctionScopeContext);
|
|
204
|
-
const key = String(when != null ? when : '').trim();
|
|
205
|
-
const run = scope == null ? void 0 : scope.run;
|
|
206
|
-
// With nothing to decide on — no function, a failed run, no name — the
|
|
207
|
-
// contents SHOW. Hiding is the exceptional state, and a designer has to
|
|
208
|
-
// be able to see the row they are laying out.
|
|
209
|
-
const decided = Boolean((run == null ? void 0 : run.ok) && key);
|
|
210
|
-
const truthy = (run == null ? void 0 : run.ok) ? isFunctionValueTruthy(run.scope[key]) : true;
|
|
211
|
-
if (decided && truthy === Boolean(invert)) return null;
|
|
212
|
-
return /*#__PURE__*/ _jsx(Box, _extends({
|
|
213
|
-
ref: ref
|
|
214
|
-
}, rest, {
|
|
215
|
-
children: children
|
|
216
|
-
}));
|
|
217
|
-
});
|
|
218
|
-
FunctionShow.displayName = 'AglynFunctionShow';
|
|
219
|
-
// ── Schemas ────────────────────────────────────────────────────────────────
|
|
220
|
-
const ICON_COLOR = '#7b1fa2';
|
|
221
|
-
const CONTROL_LABELS = {
|
|
222
|
-
auto: 'Automatic',
|
|
223
|
-
number: 'Number box',
|
|
224
|
-
text: 'Text box',
|
|
225
|
-
select: 'List',
|
|
226
|
-
chips: 'Quick picks',
|
|
227
|
-
switch: 'Switch'
|
|
228
|
-
};
|
|
229
|
-
export const schema = {
|
|
230
|
-
$id: SCOPE_ID,
|
|
231
|
-
pluginId: BUNDLE_ID,
|
|
232
|
-
displayName: 'Calculator',
|
|
233
|
-
description: 'A container bound to one of your functions. Put Calculator Inputs and ' + 'Calculator Results anywhere inside it and lay them out however you like.',
|
|
234
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
235
|
-
icon: {
|
|
236
|
-
path: mdiCalculatorVariantOutline.path,
|
|
237
|
-
sx: {
|
|
238
|
-
color: ICON_COLOR
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
attributes: [
|
|
242
|
-
{
|
|
243
|
-
name: 'functionName',
|
|
244
|
-
description: 'Name of a function from the site’s Functions card. Every input and ' + 'result inside this container reads it.',
|
|
245
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
246
|
-
label: 'Function name'
|
|
247
|
-
}
|
|
248
|
-
]
|
|
249
|
-
};
|
|
250
|
-
export const functionInputSchema = {
|
|
251
|
-
$id: INPUT_ID,
|
|
252
|
-
pluginId: BUNDLE_ID,
|
|
253
|
-
displayName: 'Calculator Input',
|
|
254
|
-
description: 'Asks one parameter of the Calculator it sits in: a number box, a list, ' + 'a switch, or quick-pick chips.',
|
|
255
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
256
|
-
icon: {
|
|
257
|
-
path: mdiFormTextbox.path,
|
|
258
|
-
sx: {
|
|
259
|
-
color: ICON_COLOR
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
flags: {
|
|
263
|
-
selfClosing: Aglyn.FEATURE_FLAG.ENABLED
|
|
264
|
-
},
|
|
265
|
-
attributes: [
|
|
266
|
-
{
|
|
267
|
-
name: 'parameter',
|
|
268
|
-
description: 'The function parameter this control sets.',
|
|
269
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
270
|
-
label: 'Parameter'
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
name: 'control',
|
|
274
|
-
description: 'Automatic follows the parameter: a list when it has choices, a ' + 'number box for a number, a switch for a true/false. Quick picks ' + 'are buttons that set the value, for beside a number box.',
|
|
275
|
-
component: Aglyn.FieldComponentType.SELECT,
|
|
276
|
-
label: 'Ask as',
|
|
277
|
-
options: FUNCTION_CONTROL_KINDS.map((kind)=>({
|
|
278
|
-
value: kind,
|
|
279
|
-
label: CONTROL_LABELS[kind]
|
|
280
|
-
}))
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
name: 'choices',
|
|
284
|
-
description: 'The choices for a list or quick picks, as "value: Label, value: ' + 'Label" — or just "10, 25, 50, 100". Leave empty to use the ' + 'choices the function gives the parameter.',
|
|
285
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
286
|
-
label: 'Choices'
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
name: 'label',
|
|
290
|
-
description: 'Shown above the control instead of the parameter’s own label.',
|
|
291
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
292
|
-
label: 'Label'
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
name: 'hideLabel',
|
|
296
|
-
description: 'If true, the label is not drawn. It is still read to assistive ' + 'technology, so give one either way.',
|
|
297
|
-
component: Aglyn.FieldComponentType.SWITCH,
|
|
298
|
-
label: 'Hide the label?'
|
|
299
|
-
}
|
|
300
|
-
]
|
|
301
|
-
};
|
|
302
|
-
export const functionOutputSchema = {
|
|
303
|
-
$id: OUTPUT_ID,
|
|
304
|
-
pluginId: BUNDLE_ID,
|
|
305
|
-
displayName: 'Calculator Result',
|
|
306
|
-
description: 'Shows one value from the Calculator it sits in, updated as the visitor ' + 'answers. Style it like any text.',
|
|
307
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
308
|
-
icon: {
|
|
309
|
-
path: mdiFunctionVariant.path,
|
|
310
|
-
sx: {
|
|
311
|
-
color: ICON_COLOR
|
|
312
|
-
}
|
|
313
|
-
},
|
|
314
|
-
flags: {
|
|
315
|
-
selfClosing: Aglyn.FEATURE_FLAG.ENABLED
|
|
316
|
-
},
|
|
317
|
-
attributes: [
|
|
318
|
-
{
|
|
319
|
-
name: 'name',
|
|
320
|
-
description: 'A parameter or variable of the function. Leave empty for the ' + 'function’s return value. Text the function wraps in **two ' + 'asterisks** is emphasized; nothing appears while the value is empty.',
|
|
321
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
322
|
-
label: 'Value'
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
name: 'placeholder',
|
|
326
|
-
description: 'What the besigner shows here, e.g. $625. Visitors never see it.',
|
|
327
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
328
|
-
label: 'Placeholder'
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
name: 'element',
|
|
332
|
-
description: 'The HTML element. Use span inside a line of text.',
|
|
333
|
-
component: Aglyn.FieldComponentType.SELECT,
|
|
334
|
-
label: 'Element',
|
|
335
|
-
options: [
|
|
336
|
-
{
|
|
337
|
-
value: 'div',
|
|
338
|
-
label: 'Block (div)'
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
value: 'p',
|
|
342
|
-
label: 'Paragraph (p)'
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
value: 'span',
|
|
346
|
-
label: 'Inline (span)'
|
|
347
|
-
}
|
|
348
|
-
]
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
name: 'announce',
|
|
352
|
-
description: 'If true, a screen reader reads each change. Turn it on for one ' + 'result per calculator — usually the sentence, not every number.',
|
|
353
|
-
component: Aglyn.FieldComponentType.SWITCH,
|
|
354
|
-
label: 'Read changes aloud?'
|
|
355
|
-
}
|
|
356
|
-
]
|
|
357
|
-
};
|
|
358
|
-
export const functionShowSchema = {
|
|
359
|
-
$id: SHOW_ID,
|
|
360
|
-
pluginId: BUNDLE_ID,
|
|
361
|
-
displayName: 'Show When',
|
|
362
|
-
description: 'A container inside a Calculator that appears only while one of the ' + 'function’s values is true, non-zero or non-empty.',
|
|
363
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
364
|
-
icon: {
|
|
365
|
-
path: mdiEyeOutline.path,
|
|
366
|
-
sx: {
|
|
367
|
-
color: ICON_COLOR
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
attributes: [
|
|
371
|
-
{
|
|
372
|
-
name: 'when',
|
|
373
|
-
description: 'A parameter or variable of the function. The contents show while ' + 'it is true, a number other than zero, or text that is not empty.',
|
|
374
|
-
component: Aglyn.FieldComponentType.TEXT_FIELD,
|
|
375
|
-
label: 'Show when'
|
|
376
|
-
},
|
|
377
|
-
{
|
|
378
|
-
name: 'invert',
|
|
379
|
-
description: 'If true, the contents show while the value is NOT true.',
|
|
380
|
-
component: Aglyn.FieldComponentType.SWITCH,
|
|
381
|
-
label: 'Show when it is not?'
|
|
382
|
-
}
|
|
383
|
-
]
|
|
384
|
-
};
|
|
385
|
-
export const presets = [
|
|
386
|
-
{
|
|
387
|
-
$id: generatePresetId(SCOPE_ID),
|
|
388
|
-
type: Aglyn.NodeType.PRESET,
|
|
389
|
-
displayName: 'Calculator',
|
|
390
|
-
pluginId: BUNDLE_ID,
|
|
391
|
-
description: 'A container bound to a function — lay out inputs and results inside',
|
|
392
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
393
|
-
icon: {
|
|
394
|
-
path: mdiCalculatorVariantOutline.path,
|
|
395
|
-
sx: {
|
|
396
|
-
color: ICON_COLOR
|
|
397
|
-
}
|
|
398
|
-
},
|
|
399
|
-
data: {
|
|
400
|
-
$id: null,
|
|
401
|
-
componentId: SCOPE_ID,
|
|
402
|
-
pluginId: BUNDLE_ID,
|
|
403
|
-
props: {}
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
];
|
|
407
|
-
export const functionInputPresets = [
|
|
408
|
-
{
|
|
409
|
-
$id: generatePresetId(INPUT_ID),
|
|
410
|
-
type: Aglyn.NodeType.PRESET,
|
|
411
|
-
displayName: 'Calculator Input',
|
|
412
|
-
pluginId: BUNDLE_ID,
|
|
413
|
-
description: 'Asks one parameter of the Calculator it sits in',
|
|
414
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
415
|
-
icon: {
|
|
416
|
-
path: mdiFormTextbox.path,
|
|
417
|
-
sx: {
|
|
418
|
-
color: ICON_COLOR
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
data: {
|
|
422
|
-
$id: null,
|
|
423
|
-
componentId: INPUT_ID,
|
|
424
|
-
pluginId: BUNDLE_ID,
|
|
425
|
-
props: {
|
|
426
|
-
control: 'auto'
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
];
|
|
431
|
-
export const functionOutputPresets = [
|
|
432
|
-
{
|
|
433
|
-
$id: generatePresetId(OUTPUT_ID),
|
|
434
|
-
type: Aglyn.NodeType.PRESET,
|
|
435
|
-
displayName: 'Calculator Result',
|
|
436
|
-
pluginId: BUNDLE_ID,
|
|
437
|
-
description: 'Shows one value from the Calculator it sits in',
|
|
438
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
439
|
-
icon: {
|
|
440
|
-
path: mdiFunctionVariant.path,
|
|
441
|
-
sx: {
|
|
442
|
-
color: ICON_COLOR
|
|
443
|
-
}
|
|
444
|
-
},
|
|
445
|
-
data: {
|
|
446
|
-
$id: null,
|
|
447
|
-
componentId: OUTPUT_ID,
|
|
448
|
-
pluginId: BUNDLE_ID,
|
|
449
|
-
props: {}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
];
|
|
453
|
-
export const functionShowPresets = [
|
|
454
|
-
{
|
|
455
|
-
$id: generatePresetId(SHOW_ID),
|
|
456
|
-
type: Aglyn.NodeType.PRESET,
|
|
457
|
-
displayName: 'Show When',
|
|
458
|
-
pluginId: BUNDLE_ID,
|
|
459
|
-
description: 'Appears only while a Calculator value is true',
|
|
460
|
-
category: Aglyn.ComponentCategory.INPUT,
|
|
461
|
-
icon: {
|
|
462
|
-
path: mdiEyeOutline.path,
|
|
463
|
-
sx: {
|
|
464
|
-
color: ICON_COLOR
|
|
465
|
-
}
|
|
466
|
-
},
|
|
467
|
-
data: {
|
|
468
|
-
$id: null,
|
|
469
|
-
componentId: SHOW_ID,
|
|
470
|
-
pluginId: BUNDLE_ID,
|
|
471
|
-
props: {}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
];
|
|
475
|
-
export { FunctionInput, FunctionOutput, FunctionShow };
|
|
476
|
-
export default FunctionScope;
|
|
477
|
-
|
|
478
|
-
//# sourceMappingURL=function-scope.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/mui/src/lib/components/function-scope.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 mdiCalculatorVariantOutline,\n mdiEyeOutline,\n mdiFormTextbox,\n mdiFunctionVariant,\n} from '@aglyn/shared-data-mdi'\nimport Box from '@mui/material/Box'\nimport {\n createContext,\n forwardRef,\n Fragment,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\nimport {\n FUNCTION_CONTROL_KINDS,\n FunctionParameterControl,\n displayFunctionValue,\n initialFunctionArguments,\n isFunctionValueTruthy,\n type FunctionControlKind,\n} from './function-controls'\n\n/**\n * A CALCULATOR AN AUTHOR LAYS OUT (AGL-3202).\n *\n * The Function Widget draws a whole calculator itself: inputs in a row, a\n * button, a result. That is the right block for \"a quote in a sidebar\" and\n * the wrong one for the page that prompted this — a comparison with a number\n * box AND quick picks on the same value, two questions asked as lists, a\n * table of five rows where four can be filtered away, one row highlighted, a\n * sentence under it and a footnote that changes with the choices. No amount\n * of options on one block reaches that, and it should not have to: laying\n * things out is what the canvas is for.\n *\n * So the pieces are separate elements, and one function binds them:\n *\n * - **Calculator** (`functionScope`) holds the function, the visitor's\n * answers and the live result, and is an ordinary container.\n * - **Calculator Input** (`functionInput`) asks ONE parameter, as a number\n * box, a list, a switch or a row of quick-pick chips. Two inputs may ask\n * the same parameter; they stay in step because the answer lives above\n * them.\n * - **Calculator Result** (`functionOutput`) shows one named value, styled\n * like any text.\n * - **Show When** (`functionShow`) is a container that appears only while a\n * named value is truthy — a table row a filter can remove.\n *\n * Everything between them is whatever the author builds: stacks, grids,\n * headings, borders. The design is theirs and the arithmetic is the site's\n * function, reading the site's variables.\n */\n\n// Component ids are persisted in screen documents; never rename.\nexport const SCOPE_ID: Aglyn.ComponentId = 'functionScope'\nexport const INPUT_ID: Aglyn.ComponentId = 'functionInput'\nexport const OUTPUT_ID: Aglyn.ComponentId = 'functionOutput'\nexport const SHOW_ID: Aglyn.ComponentId = 'functionShow'\n\ninterface FunctionScopeValue {\n definition?: Aglyn.HostFunction\n args: Record<string, string>\n setArgument: (name: string, value: string) => void\n run: Aglyn.FunctionRunResult | null\n}\n\nconst FunctionScopeContext = createContext<FunctionScopeValue | null>(null)\n\n// ── Calculator ─────────────────────────────────────────────────────────────\n\nexport interface FunctionScopeProps {\n /** Name of the site function every element inside is bound to. */\n functionName?: string\n children?: ReactNode\n /** Injected at compose (attachFunctionDefinitions); never authored. */\n definition?: Aglyn.HostFunction\n /** The site variables the function names; injected beside `definition`. */\n globals?: Record<string, number | string | boolean>\n}\n\nconst FunctionScope = forwardRef<HTMLDivElement, FunctionScopeProps>(\n (props, ref) => {\n const { functionName: _functionName, children, definition, globals, ...rest } = props\n const [args, setArgs] = useState<Record<string, string>>(() =>\n initialFunctionArguments(definition),\n )\n const setArgument = useCallback((name: string, value: string) => {\n setArgs((previous) => ({ ...previous, [name]: value }))\n }, [])\n // Always live: a calculator laid out on a page has no single place a\n // \"Calculate\" button would obviously go, and every result can be on\n // screen at once. The Function Widget is the block with a button.\n const run = useMemo(\n () =>\n definition\n ? Aglyn.evaluateHostFunction(definition, args, { globals })\n : null,\n [definition, args, globals],\n )\n const value = useMemo(\n () => ({ definition, args, setArgument, run }),\n [definition, args, setArgument, run],\n )\n return (\n <FunctionScopeContext.Provider value={value}>\n <Box ref={ref} {...rest}>\n {children}\n </Box>\n </FunctionScopeContext.Provider>\n )\n },\n)\nFunctionScope.displayName = 'AglynFunctionScope'\n\n// ── Calculator Input ───────────────────────────────────────────────────────\n\nexport interface FunctionInputProps {\n /** The function parameter this control asks. */\n parameter?: string\n control?: FunctionControlKind\n /** Overrides the parameter's own label. */\n label?: string\n hideLabel?: boolean\n /**\n * Overrides the parameter's own choices, as `value: Label, value: Label`.\n * This is how quick picks are given: `10, 25, 50, 100` beside a number box.\n */\n choices?: string\n}\n\nconst FunctionInput = forwardRef<HTMLDivElement, FunctionInputProps>(\n (props, ref) => {\n const { parameter, control, label, hideLabel, choices, ...rest } = props\n const scope = useContext(FunctionScopeContext)\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const name = String(parameter ?? '').trim()\n const declared = scope?.definition?.parameters?.find(\n (candidate) => candidate.name === name,\n )\n const ownChoices = useMemo(\n () => Aglyn.parseFunctionParameterOptions(choices),\n [choices],\n )\n const options = ownChoices.length ? ownChoices : (declared?.options ?? [])\n // No function to ask on behalf of: the besigner, or a page whose function\n // was deleted. In the besigner the control is still DRAWN, from its own\n // attributes, so a calculator can be designed before it works. On a\n // published page a control that can set nothing is residue, not a\n // question, and a visitor is shown nothing.\n const inert = !scope?.definition || !declared\n if (inert && !suppressNavigation) return null\n return (\n <Box ref={ref} {...rest}>\n <FunctionParameterControl\n name={name || 'parameter'}\n type={declared?.type}\n required={declared?.required}\n control={control}\n label={label?.trim() || declared?.label}\n hideLabel={Boolean(hideLabel)}\n options={options}\n value={inert ? '' : (scope?.args[name] ?? '')}\n onChange={(next) => scope?.setArgument(name, next)}\n disabled={inert}\n width=\"100%\"\n />\n </Box>\n )\n },\n)\nFunctionInput.displayName = 'AglynFunctionInput'\n\n// ── Calculator Result ──────────────────────────────────────────────────────\n\nexport interface FunctionOutputProps {\n /** A parameter or variable of the function; empty is its return value. */\n name?: string\n /** What the besigner shows in the result's place, e.g. `$625`. */\n placeholder?: string\n /** Read a change aloud. One result per calculator, usually the sentence. */\n announce?: boolean\n element?: 'div' | 'p' | 'span'\n}\n\nconst OUTPUT_ELEMENTS = ['div', 'p', 'span'] as const\n\n/**\n * `**like this**` becomes emphasis, and nothing else is markup. The value is\n * text a function built — often from what a visitor typed — so it is split\n * into React nodes and never parsed as HTML.\n */\nexport function renderFunctionEmphasis(text: string): ReactNode {\n const parts = text.split(/\\*\\*(.+?)\\*\\*/g)\n if (parts.length === 1) return text\n return parts.map((part, index) =>\n index % 2 === 1 ? (\n <strong key={index}>{part}</strong>\n ) : (\n <Fragment key={index}>{part}</Fragment>\n ),\n )\n}\n\nconst FunctionOutput = forwardRef<HTMLElement, FunctionOutputProps>(\n (props, ref) => {\n const { name, placeholder, announce, element, ...rest } = props\n const scope = useContext(FunctionScopeContext)\n const { suppressNavigation } = useContext(Aglyn.ScreenLinkContext)\n const key = String(name ?? '').trim()\n const run = scope?.run\n let text = ''\n if (run?.ok) {\n text = displayFunctionValue(key ? run.scope[key] : run.value)\n } else if (suppressNavigation || !scope?.definition) {\n // Designing: show what will stand here. On a published page a missing\n // function shows nothing rather than a placeholder dressed as a price.\n text = suppressNavigation ? placeholder || (key ? `{${key}}` : '{result}') : ''\n }\n if (!text) return null\n const tag = OUTPUT_ELEMENTS.includes(element as (typeof OUTPUT_ELEMENTS)[number])\n ? element\n : 'div'\n return (\n <Box\n ref={ref}\n component={tag}\n {...(announce ? { 'aria-live': 'polite' as const } : {})}\n {...rest}\n >\n {renderFunctionEmphasis(text)}\n </Box>\n )\n },\n)\nFunctionOutput.displayName = 'AglynFunctionOutput'\n\n// ── Show When ──────────────────────────────────────────────────────────────\n\nexport interface FunctionShowProps {\n /** A parameter or variable of the function. */\n when?: string\n /** Show while the value is NOT truthy instead. */\n invert?: boolean\n children?: ReactNode\n}\n\nconst FunctionShow = forwardRef<HTMLDivElement, FunctionShowProps>(\n (props, ref) => {\n const { when, invert, children, ...rest } = props\n const scope = useContext(FunctionScopeContext)\n const key = String(when ?? '').trim()\n const run = scope?.run\n // With nothing to decide on — no function, a failed run, no name — the\n // contents SHOW. Hiding is the exceptional state, and a designer has to\n // be able to see the row they are laying out.\n const decided = Boolean(run?.ok && key)\n const truthy = run?.ok ? isFunctionValueTruthy(run.scope[key]) : true\n if (decided && truthy === Boolean(invert)) return null\n return (\n <Box ref={ref} {...rest}>\n {children}\n </Box>\n )\n },\n)\nFunctionShow.displayName = 'AglynFunctionShow'\n\n// ── Schemas ────────────────────────────────────────────────────────────────\n\nconst ICON_COLOR = '#7b1fa2'\n\nconst CONTROL_LABELS: Record<FunctionControlKind, string> = {\n auto: 'Automatic',\n number: 'Number box',\n text: 'Text box',\n select: 'List',\n chips: 'Quick picks',\n switch: 'Switch',\n}\n\nexport const schema: Aglyn.ComponentSchema<FunctionScopeProps> = {\n $id: SCOPE_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Calculator',\n description:\n 'A container bound to one of your functions. Put Calculator Inputs and ' +\n 'Calculator Results anywhere inside it and lay them out however you like.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiCalculatorVariantOutline.path, sx: { color: ICON_COLOR } },\n attributes: [\n {\n name: 'functionName',\n description:\n 'Name of a function from the site’s Functions card. Every input and ' +\n 'result inside this container reads it.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Function name',\n },\n ],\n}\n\nexport const functionInputSchema: Aglyn.ComponentSchema<FunctionInputProps> = {\n $id: INPUT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Calculator Input',\n description:\n 'Asks one parameter of the Calculator it sits in: a number box, a list, ' +\n 'a switch, or quick-pick chips.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFormTextbox.path, sx: { color: ICON_COLOR } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'parameter',\n description: 'The function parameter this control sets.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Parameter',\n },\n {\n name: 'control',\n description:\n 'Automatic follows the parameter: a list when it has choices, a ' +\n 'number box for a number, a switch for a true/false. Quick picks ' +\n 'are buttons that set the value, for beside a number box.',\n component: Aglyn.FieldComponentType.SELECT,\n label: 'Ask as',\n options: FUNCTION_CONTROL_KINDS.map((kind) => ({\n value: kind,\n label: CONTROL_LABELS[kind],\n })),\n },\n {\n name: 'choices',\n description:\n 'The choices for a list or quick picks, as \"value: Label, value: ' +\n 'Label\" — or just \"10, 25, 50, 100\". Leave empty to use the ' +\n 'choices the function gives the parameter.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Choices',\n },\n {\n name: 'label',\n description: 'Shown above the control instead of the parameter’s own label.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Label',\n },\n {\n name: 'hideLabel',\n description:\n 'If true, the label is not drawn. It is still read to assistive ' +\n 'technology, so give one either way.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Hide the label?',\n },\n ],\n}\n\nexport const functionOutputSchema: Aglyn.ComponentSchema<FunctionOutputProps> = {\n $id: OUTPUT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Calculator Result',\n description:\n 'Shows one value from the Calculator it sits in, updated as the visitor ' +\n 'answers. Style it like any text.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFunctionVariant.path, sx: { color: ICON_COLOR } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'name',\n description:\n 'A parameter or variable of the function. Leave empty for the ' +\n 'function’s return value. Text the function wraps in **two ' +\n 'asterisks** is emphasized; nothing appears while the value is empty.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Value',\n },\n {\n name: 'placeholder',\n description: 'What the besigner shows here, e.g. $625. Visitors never see it.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Placeholder',\n },\n {\n name: 'element',\n description: 'The HTML element. Use span inside a line of text.',\n component: Aglyn.FieldComponentType.SELECT,\n label: 'Element',\n options: [\n { value: 'div', label: 'Block (div)' },\n { value: 'p', label: 'Paragraph (p)' },\n { value: 'span', label: 'Inline (span)' },\n ],\n },\n {\n name: 'announce',\n description:\n 'If true, a screen reader reads each change. Turn it on for one ' +\n 'result per calculator — usually the sentence, not every number.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Read changes aloud?',\n },\n ],\n}\n\nexport const functionShowSchema: Aglyn.ComponentSchema<FunctionShowProps> = {\n $id: SHOW_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Show When',\n description:\n 'A container inside a Calculator that appears only while one of the ' +\n 'function’s values is true, non-zero or non-empty.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiEyeOutline.path, sx: { color: ICON_COLOR } },\n attributes: [\n {\n name: 'when',\n description:\n 'A parameter or variable of the function. The contents show while ' +\n 'it is true, a number other than zero, or text that is not empty.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n label: 'Show when',\n },\n {\n name: 'invert',\n description: 'If true, the contents show while the value is NOT true.',\n component: Aglyn.FieldComponentType.SWITCH,\n label: 'Show when it is not?',\n },\n ],\n}\n\nexport const presets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(SCOPE_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Calculator',\n pluginId: BUNDLE_ID,\n description: 'A container bound to a function — lay out inputs and results inside',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiCalculatorVariantOutline.path, sx: { color: ICON_COLOR } },\n data: { $id: null, componentId: SCOPE_ID, pluginId: BUNDLE_ID, props: {} },\n },\n]\n\nexport const functionInputPresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(INPUT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Calculator Input',\n pluginId: BUNDLE_ID,\n description: 'Asks one parameter of the Calculator it sits in',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFormTextbox.path, sx: { color: ICON_COLOR } },\n data: { $id: null, componentId: INPUT_ID, pluginId: BUNDLE_ID, props: { control: 'auto' } },\n },\n]\n\nexport const functionOutputPresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(OUTPUT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Calculator Result',\n pluginId: BUNDLE_ID,\n description: 'Shows one value from the Calculator it sits in',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiFunctionVariant.path, sx: { color: ICON_COLOR } },\n data: { $id: null, componentId: OUTPUT_ID, pluginId: BUNDLE_ID, props: {} },\n },\n]\n\nexport const functionShowPresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(SHOW_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Show When',\n pluginId: BUNDLE_ID,\n description: 'Appears only while a Calculator value is true',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiEyeOutline.path, sx: { color: ICON_COLOR } },\n data: { $id: null, componentId: SHOW_ID, pluginId: BUNDLE_ID, props: {} },\n },\n]\n\nexport { FunctionInput, FunctionOutput, FunctionShow }\nexport default FunctionScope\n"],"names":["Aglyn","mdiCalculatorVariantOutline","mdiEyeOutline","mdiFormTextbox","mdiFunctionVariant","Box","createContext","forwardRef","Fragment","useCallback","useContext","useMemo","useState","BUNDLE_ID","generatePresetId","FUNCTION_CONTROL_KINDS","FunctionParameterControl","displayFunctionValue","initialFunctionArguments","isFunctionValueTruthy","SCOPE_ID","INPUT_ID","OUTPUT_ID","SHOW_ID","FunctionScopeContext","FunctionScope","props","ref","functionName","_functionName","children","definition","globals","rest","args","setArgs","setArgument","name","value","previous","run","evaluateHostFunction","Provider","displayName","FunctionInput","scope","parameter","control","label","hideLabel","choices","suppressNavigation","ScreenLinkContext","String","trim","declared","parameters","find","candidate","ownChoices","parseFunctionParameterOptions","options","length","inert","type","required","Boolean","onChange","next","disabled","width","OUTPUT_ELEMENTS","renderFunctionEmphasis","text","parts","split","map","part","index","strong","FunctionOutput","placeholder","announce","element","key","ok","tag","includes","component","FunctionShow","when","invert","decided","truthy","ICON_COLOR","CONTROL_LABELS","auto","number","select","chips","switch","schema","$id","pluginId","description","category","ComponentCategory","INPUT","icon","path","sx","color","attributes","FieldComponentType","TEXT_FIELD","functionInputSchema","flags","selfClosing","FEATURE_FLAG","ENABLED","SELECT","kind","SWITCH","functionOutputSchema","functionShowSchema","presets","NodeType","PRESET","data","componentId","functionInputPresets","functionOutputPresets","functionShowPresets"],"mappings":"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"}
|