@uipath/apollo-wind 2.79.1 → 2.80.0
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/dist/components/forms/metadata-form.cjs +3 -2
- package/dist/components/forms/metadata-form.js +3 -2
- package/dist/components/ui/editable-text.cjs +251 -0
- package/dist/components/ui/editable-text.d.ts +48 -0
- package/dist/components/ui/editable-text.js +217 -0
- package/dist/components/ui/field-actions/ai-assist-action.cjs +7 -5
- package/dist/components/ui/field-actions/ai-assist-action.js +7 -5
- package/dist/components/ui/field-actions/collapse.cjs +7 -7
- package/dist/components/ui/field-actions/collapse.d.ts +6 -3
- package/dist/components/ui/field-actions/collapse.js +3 -3
- package/dist/components/ui/field-actions/insert-variable-action.cjs +7 -7
- package/dist/components/ui/field-actions/insert-variable-action.js +8 -8
- package/dist/components/ui/field-addons/field-menu.cjs +2 -1
- package/dist/components/ui/field-addons/field-menu.d.ts +6 -1
- package/dist/components/ui/field-addons/field-menu.js +2 -1
- package/dist/components/ui/field-addons/value-mode-switch-dialog.cjs +2 -1
- package/dist/components/ui/field-addons/value-mode-switch-dialog.d.ts +6 -1
- package/dist/components/ui/field-addons/value-mode-switch-dialog.js +2 -1
- package/dist/components/ui/index.cjs +215 -202
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/input-group.cjs +7 -3
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/input-group.js +7 -3
- package/dist/components/ui/quick-form-field/components/field-header.cjs +55 -52
- package/dist/components/ui/quick-form-field/components/field-header.d.ts +13 -4
- package/dist/components/ui/quick-form-field/components/field-header.js +53 -53
- package/dist/components/ui/quick-form-field/index.d.ts +1 -1
- package/dist/components/ui/quick-form-field/quick-form-field.cjs +134 -17
- package/dist/components/ui/quick-form-field/quick-form-field.d.ts +6 -3
- package/dist/components/ui/quick-form-field/quick-form-field.js +136 -19
- package/dist/components/ui/quick-form-field/types.cjs +8 -0
- package/dist/components/ui/quick-form-field/types.d.ts +81 -14
- package/dist/components/ui/quick-form-field/types.js +8 -0
- package/dist/components/ui/quick-form-field/utils.cjs +30 -1
- package/dist/components/ui/quick-form-field/utils.d.ts +8 -0
- package/dist/components/ui/quick-form-field/utils.js +27 -1
- package/dist/components/ui/variable-value-control.cjs +7 -4
- package/dist/components/ui/variable-value-control.d.ts +5 -1
- package/dist/components/ui/variable-value-control.js +7 -4
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/styles.css +74 -22
- package/dist/tailwind.css +2 -1
- package/package.json +1 -1
|
@@ -31,20 +31,29 @@ const external_lucide_react_namespaceObject = require("lucide-react");
|
|
|
31
31
|
const external_react_namespaceObject = require("react");
|
|
32
32
|
const external_calendar_cjs_namespaceObject = require("../calendar.cjs");
|
|
33
33
|
const external_datetime_picker_cjs_namespaceObject = require("../datetime-picker.cjs");
|
|
34
|
+
const external_editable_text_cjs_namespaceObject = require("../editable-text.cjs");
|
|
34
35
|
const external_file_upload_cjs_namespaceObject = require("../file-upload.cjs");
|
|
35
36
|
const external_input_group_cjs_namespaceObject = require("../input-group.cjs");
|
|
37
|
+
const external_label_cjs_namespaceObject = require("../label.cjs");
|
|
36
38
|
const external_multi_select_cjs_namespaceObject = require("../multi-select.cjs");
|
|
37
39
|
const external_popover_cjs_namespaceObject = require("../popover.cjs");
|
|
40
|
+
const external_prompt_value_control_cjs_namespaceObject = require("../prompt-value-control.cjs");
|
|
38
41
|
const external_select_cjs_namespaceObject = require("../select.cjs");
|
|
39
42
|
const external_switch_cjs_namespaceObject = require("../switch.cjs");
|
|
43
|
+
const external_variable_value_control_cjs_namespaceObject = require("../variable-value-control.cjs");
|
|
40
44
|
const index_cjs_namespaceObject = require("../../../lib/index.cjs");
|
|
41
45
|
const date_value_cjs_namespaceObject = require("../../../lib/date-value.cjs");
|
|
42
46
|
const field_menu_cjs_namespaceObject = require("../field-addons/field-menu.cjs");
|
|
47
|
+
const value_mode_switch_dialog_cjs_namespaceObject = require("../field-addons/value-mode-switch-dialog.cjs");
|
|
43
48
|
const field_header_cjs_namespaceObject = require("./components/field-header.cjs");
|
|
44
49
|
const lock_toggle_button_cjs_namespaceObject = require("./components/lock-toggle-button.cjs");
|
|
45
50
|
const external_types_cjs_namespaceObject = require("./types.cjs");
|
|
46
51
|
const external_utils_cjs_namespaceObject = require("./utils.cjs");
|
|
47
|
-
|
|
52
|
+
const DEFAULT_VALUE_MODES = [
|
|
53
|
+
'literal',
|
|
54
|
+
'expression'
|
|
55
|
+
];
|
|
56
|
+
function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true, onLockedChange, showLock = true, disabled = false, leadingAddon, trailingAddon, more, mode = 'literal', onModeChange, valueModes = DEFAULT_VALUE_MODES, confirmModeChange, renderExpressionEditor, renderModeControl, fieldType = 'string', fieldTypes, onFieldTypeChange, required, onRequiredChange, label, onLabelChange, isEditingLabel, onIsEditingLabelChange, labelAddon, tooltip, strings: stringOverrides, placeholder, error, errorId, belowValue, fileUploadAriaLabel, headerActions, compact, showFieldActions = true, options = external_utils_cjs_namespaceObject.DEFAULT_SELECT_OPTIONS, onGenerateWithAi, onInsertVariable, variables = [], id, className }) {
|
|
48
57
|
const strings = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
49
58
|
...external_types_cjs_namespaceObject.DEFAULT_QUICK_FORM_FIELD_STRINGS,
|
|
50
59
|
...stringOverrides
|
|
@@ -55,8 +64,17 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
55
64
|
const valueInputRef = (0, external_react_namespaceObject.useRef)(null);
|
|
56
65
|
const committedRef = (0, external_react_namespaceObject.useRef)(value);
|
|
57
66
|
const caretRef = (0, external_react_namespaceObject.useRef)(null);
|
|
67
|
+
const modeControlRef = (0, external_react_namespaceObject.useRef)(null);
|
|
68
|
+
const setModeControl = (0, external_react_namespaceObject.useCallback)((el)=>{
|
|
69
|
+
modeControlRef.current = el;
|
|
70
|
+
}, []);
|
|
58
71
|
const [datePopoverOpen, setDatePopoverOpen] = (0, external_react_namespaceObject.useState)(false);
|
|
59
72
|
const [selectOpen, setSelectOpen] = (0, external_react_namespaceObject.useState)(false);
|
|
73
|
+
const [labelDraft, setLabelDraft] = (0, external_react_namespaceObject.useState)(null);
|
|
74
|
+
const [pendingSwitch, setPendingSwitch] = (0, external_react_namespaceObject.useState)();
|
|
75
|
+
const variablePicker = (0, external_react_namespaceObject.useMemo)(()=>(0, external_utils_cjs_namespaceObject.toVariablePickerSource)(variables), [
|
|
76
|
+
variables
|
|
77
|
+
]);
|
|
60
78
|
const fieldId = id ?? generatedId;
|
|
61
79
|
const validationId = errorId ?? `${fieldId}-error`;
|
|
62
80
|
const typeMeta = external_types_cjs_namespaceObject.FIELD_TYPE_META[fieldType];
|
|
@@ -70,6 +88,7 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
70
88
|
id: 'clear',
|
|
71
89
|
label: strings.clearValue,
|
|
72
90
|
icon: external_lucide_react_namespaceObject.Trash2,
|
|
91
|
+
destructive: true,
|
|
73
92
|
onSelect: more.onClear
|
|
74
93
|
}
|
|
75
94
|
] : [],
|
|
@@ -82,20 +101,44 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
82
101
|
}
|
|
83
102
|
] : []
|
|
84
103
|
];
|
|
104
|
+
const valueModeStrings = {
|
|
105
|
+
...strings.valueModes,
|
|
106
|
+
literalTitle: strings.literalLabels[fieldType] ?? typeMeta.fixedLabel,
|
|
107
|
+
expressionTitle: strings.expressionLabel,
|
|
108
|
+
expressionDescription: strings.expressionDescription,
|
|
109
|
+
fieldActions: strings.moreActionsAriaLabel
|
|
110
|
+
};
|
|
111
|
+
const focusControlOnClose = (0, external_react_namespaceObject.useRef)(false);
|
|
112
|
+
const keepControlFocus = (event)=>{
|
|
113
|
+
if (!focusControlOnClose.current) return;
|
|
114
|
+
focusControlOnClose.current = false;
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
(valueInputRef.current ?? modeControlRef.current)?.focus();
|
|
117
|
+
};
|
|
118
|
+
const selectMode = (next)=>{
|
|
119
|
+
if (!onModeChange) return;
|
|
120
|
+
const confirm = next !== mode && confirmModeChange?.(mode, next);
|
|
121
|
+
if (confirm) return void setPendingSwitch({
|
|
122
|
+
...true === confirm ? {} : confirm,
|
|
123
|
+
to: next
|
|
124
|
+
});
|
|
125
|
+
focusControlOnClose.current = next !== mode;
|
|
126
|
+
onModeChange(next);
|
|
127
|
+
};
|
|
128
|
+
const switchable = !!onModeChange && valueModes.length > 1;
|
|
85
129
|
const builtInMenu = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(field_menu_cjs_namespaceObject.FieldMenu, {
|
|
86
130
|
mode: mode,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
131
|
+
modes: [
|
|
132
|
+
...valueModes
|
|
133
|
+
],
|
|
134
|
+
onSelect: selectMode,
|
|
135
|
+
modesDisabled: !switchable && menuActions.length > 0,
|
|
136
|
+
disabled: disabled || !switchable && 0 === menuActions.length,
|
|
90
137
|
actions: menuActions,
|
|
91
138
|
triggerLabel: strings.valueModeAriaLabel,
|
|
92
139
|
literalDescription: strings.literalDescriptions[fieldType] ?? typeMeta.fixedDescription,
|
|
93
|
-
strings:
|
|
94
|
-
|
|
95
|
-
expressionTitle: strings.expressionLabel,
|
|
96
|
-
expressionDescription: strings.expressionDescription,
|
|
97
|
-
fieldActions: strings.moreActionsAriaLabel
|
|
98
|
-
}
|
|
140
|
+
strings: valueModeStrings,
|
|
141
|
+
onCloseAutoFocus: keepControlFocus
|
|
99
142
|
});
|
|
100
143
|
const controlProps = {
|
|
101
144
|
id: fieldId,
|
|
@@ -112,11 +155,14 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
112
155
|
'data-slot': 'input-group-control'
|
|
113
156
|
};
|
|
114
157
|
const modeControl = renderModeControl?.(mode, controlProps) ?? null;
|
|
158
|
+
const builtInVariable = null === modeControl && 'variable' === mode;
|
|
159
|
+
const builtInPrompt = null === modeControl && 'prompt' === mode;
|
|
115
160
|
const modeOnMount = (0, external_react_namespaceObject.useRef)(mode);
|
|
116
161
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
117
162
|
if (modeOnMount.current === mode) return;
|
|
118
163
|
modeOnMount.current = mode;
|
|
119
|
-
valueInputRef.current?.focus();
|
|
164
|
+
const frame = requestAnimationFrame(()=>(valueInputRef.current ?? modeControlRef.current)?.focus());
|
|
165
|
+
return ()=>cancelAnimationFrame(frame);
|
|
120
166
|
}, [
|
|
121
167
|
mode
|
|
122
168
|
]);
|
|
@@ -279,6 +325,11 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
279
325
|
selected: (0, external_utils_cjs_namespaceObject.parseListValue)(value),
|
|
280
326
|
onChange: (selected)=>editableOnValueChange?.(JSON.stringify(selected)),
|
|
281
327
|
placeholder: strings.selectOptions,
|
|
328
|
+
searchPlaceholder: strings.multiSelectSearchPlaceholder,
|
|
329
|
+
emptyMessage: strings.multiSelectEmpty,
|
|
330
|
+
clearAllText: strings.multiSelectClearAll,
|
|
331
|
+
strings: strings.multiSelect,
|
|
332
|
+
overflow: "collapse",
|
|
282
333
|
disabled: !editableOnValueChange,
|
|
283
334
|
onBlur: onValueBlur
|
|
284
335
|
}) : 'textarea' === fieldType ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_input_group_cjs_namespaceObject.InputGroupTextarea, {
|
|
@@ -292,11 +343,60 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
292
343
|
type: 'integer' === fieldType || 'double' === fieldType ? 'number' : 'text',
|
|
293
344
|
step: 'double' === fieldType ? 'any' : void 0
|
|
294
345
|
});
|
|
346
|
+
const canPickVariable = !disabled && (!!onInsertVariable || !!onValueChange);
|
|
347
|
+
const variableControl = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_variable_value_control_cjs_namespaceObject.VariableValueControl, {
|
|
348
|
+
id: fieldId,
|
|
349
|
+
value: value,
|
|
350
|
+
onChange: (reference, item)=>onInsertVariable && item ? onInsertVariable(variablePicker.resolve(item), {
|
|
351
|
+
value,
|
|
352
|
+
caret: null
|
|
353
|
+
}) : onValueChange?.(reference),
|
|
354
|
+
onBlur: onValueBlur,
|
|
355
|
+
inputRef: setModeControl,
|
|
356
|
+
variables: variablePicker.items,
|
|
357
|
+
disabled: !canPickVariable,
|
|
358
|
+
placeholder: placeholder,
|
|
359
|
+
strings: strings.valueModes,
|
|
360
|
+
"aria-describedby": controlProps['aria-describedby']
|
|
361
|
+
});
|
|
362
|
+
const promptControl = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_prompt_value_control_cjs_namespaceObject.PromptValueControl, {
|
|
363
|
+
id: fieldId,
|
|
364
|
+
value: value,
|
|
365
|
+
onChange: (next)=>editableOnValueChange?.(next),
|
|
366
|
+
onBlur: onValueBlur,
|
|
367
|
+
inputRef: setModeControl,
|
|
368
|
+
disabled: !editableOnValueChange,
|
|
369
|
+
placeholder: placeholder,
|
|
370
|
+
strings: strings.valueModes,
|
|
371
|
+
"aria-describedby": controlProps['aria-describedby']
|
|
372
|
+
});
|
|
373
|
+
const editableLabel = 'string' == typeof label && onLabelChange ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
|
|
374
|
+
className: (0, index_cjs_namespaceObject.cn)('flex min-w-0 items-center', field_header_cjs_namespaceObject.GROW_WHILE_EDITING),
|
|
375
|
+
children: [
|
|
376
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_editable_text_cjs_namespaceObject.EditableText, {
|
|
377
|
+
size: "label",
|
|
378
|
+
value: labelDraft ?? label,
|
|
379
|
+
placeholder: strings.labelPlaceholder,
|
|
380
|
+
"aria-label": strings.labelAriaLabel,
|
|
381
|
+
editing: isEditingLabel,
|
|
382
|
+
onEditingChange: onIsEditingLabelChange,
|
|
383
|
+
disabled: disabled,
|
|
384
|
+
onChange: (next)=>setLabelDraft(next === label ? null : next),
|
|
385
|
+
onSubmit: (next)=>{
|
|
386
|
+
setLabelDraft(null);
|
|
387
|
+
onLabelChange(next);
|
|
388
|
+
}
|
|
389
|
+
}),
|
|
390
|
+
required && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_label_cjs_namespaceObject.RequiredIndicator, {})
|
|
391
|
+
]
|
|
392
|
+
}) : void 0;
|
|
295
393
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
296
394
|
className: (0, index_cjs_namespaceObject.cn)('@container group flex flex-col gap-1.5 [&>[data-slot=form-field-error]]:mt-0', className),
|
|
297
395
|
children: [
|
|
298
396
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(field_header_cjs_namespaceObject.FieldHeader, {
|
|
299
|
-
label: label,
|
|
397
|
+
label: editableLabel ?? label,
|
|
398
|
+
labelAddon: labelAddon,
|
|
399
|
+
tooltip: tooltip,
|
|
300
400
|
fieldId: fieldId,
|
|
301
401
|
fieldLabel: fieldLabel,
|
|
302
402
|
required: required,
|
|
@@ -309,9 +409,9 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
309
409
|
isExpression: 'expression' === mode,
|
|
310
410
|
showFieldActions: showFieldActions,
|
|
311
411
|
onValueChange: editableOnValueChange,
|
|
312
|
-
variables:
|
|
412
|
+
variables: variablePicker,
|
|
313
413
|
onGenerateWithAi: onGenerateWithAi,
|
|
314
|
-
onInsertVariable: (variable)=>onInsertVariable ? onInsertVariable(variable, {
|
|
414
|
+
onInsertVariable: builtInVariable ? void 0 : (variable)=>onInsertVariable ? onInsertVariable(variable, {
|
|
315
415
|
value,
|
|
316
416
|
caret: caretRef.current
|
|
317
417
|
}) : insertVariableAtCaret(variable.value),
|
|
@@ -322,7 +422,8 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
322
422
|
error: error,
|
|
323
423
|
errorId: validationId,
|
|
324
424
|
disabled: disabled,
|
|
325
|
-
|
|
425
|
+
variant: builtInPrompt ? 'agent' : void 0,
|
|
426
|
+
layout: builtInPrompt || 'literal' === mode && ('file' === fieldType || 'textarea' === fieldType) ? 'grow' : 'row',
|
|
326
427
|
children: [
|
|
327
428
|
(showLock || void 0 !== leadingAddon) && null !== leadingAddon && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_input_group_cjs_namespaceObject.InputGroupAddon, {
|
|
328
429
|
align: "inline-start",
|
|
@@ -336,7 +437,7 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
336
437
|
modeControl ?? ('expression' === mode ? renderExpressionEditor ? renderExpressionEditor(controlProps) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_input_group_cjs_namespaceObject.InputGroupInput, {
|
|
337
438
|
...textInputProps,
|
|
338
439
|
className: "font-mono"
|
|
339
|
-
}) : literalControl),
|
|
440
|
+
}) : builtInVariable ? variableControl : builtInPrompt ? promptControl : literalControl),
|
|
340
441
|
null !== trailingAddon && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_input_group_cjs_namespaceObject.InputGroupAddon, {
|
|
341
442
|
align: "inline-end",
|
|
342
443
|
className: "cursor-default",
|
|
@@ -344,7 +445,23 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
344
445
|
})
|
|
345
446
|
]
|
|
346
447
|
}),
|
|
347
|
-
belowValue
|
|
448
|
+
belowValue,
|
|
449
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(value_mode_switch_dialog_cjs_namespaceObject.ValueModeSwitchDialog, {
|
|
450
|
+
open: !!pendingSwitch,
|
|
451
|
+
title: pendingSwitch?.title,
|
|
452
|
+
description: pendingSwitch?.description,
|
|
453
|
+
confirmLabel: pendingSwitch?.confirmLabel,
|
|
454
|
+
strings: strings.valueModes,
|
|
455
|
+
onCancel: ()=>setPendingSwitch(void 0),
|
|
456
|
+
onConfirm: ()=>{
|
|
457
|
+
if (pendingSwitch && !disabled) {
|
|
458
|
+
focusControlOnClose.current = true;
|
|
459
|
+
onModeChange?.(pendingSwitch.to);
|
|
460
|
+
}
|
|
461
|
+
setPendingSwitch(void 0);
|
|
462
|
+
},
|
|
463
|
+
onCloseAutoFocus: keepControlFocus
|
|
464
|
+
})
|
|
348
465
|
]
|
|
349
466
|
});
|
|
350
467
|
}
|
|
@@ -10,11 +10,14 @@ import type { QuickFormFieldProps } from './types';
|
|
|
10
10
|
* form-field anatomy (`FormField`, `FormFieldLabel`, `InputGroup`, …) or
|
|
11
11
|
* describe them to `MetadataForm`.
|
|
12
12
|
*
|
|
13
|
-
* -
|
|
14
|
-
*
|
|
13
|
+
* - Every mode has a built-in control: `variable` is a picker over
|
|
14
|
+
* `variables`, `prompt` an agent textarea. `valueModes` chooses which the
|
|
15
|
+
* menu offers, and `renderModeControl` replaces the control for any mode.
|
|
16
|
+
* - `confirmModeChange` asks before a switch the consumer knows is lossy.
|
|
15
17
|
* - `locked` is configuration the author sets, so the value stays editable;
|
|
16
18
|
* `disabled` is what stops the author editing the field.
|
|
17
19
|
* - `fieldTypes` chooses which types the picker offers.
|
|
20
|
+
* - `onLabelChange` makes a string `label` editable in place.
|
|
18
21
|
* - Insert variable renders `variables` as supplied and splices at the caret;
|
|
19
22
|
* `onInsertVariable` takes over what inserting means.
|
|
20
23
|
* - Enter commits through `onValueBlur`, Escape restores the value as of focus.
|
|
@@ -26,4 +29,4 @@ import type { QuickFormFieldProps } from './types';
|
|
|
26
29
|
* AI-assist button renders only with `onGenerateWithAi`, and file uploads
|
|
27
30
|
* aren't persisted anywhere.
|
|
28
31
|
*/
|
|
29
|
-
export declare function QuickFormField({ value, onValueChange, onValueBlur, locked, onLockedChange, showLock, disabled, leadingAddon, trailingAddon, more, mode, onModeChange, renderExpressionEditor, renderModeControl, fieldType, fieldTypes, onFieldTypeChange, required, onRequiredChange, label, strings: stringOverrides, placeholder, error, errorId, belowValue, fileUploadAriaLabel, headerActions, compact, showFieldActions, options, onGenerateWithAi, onInsertVariable, variables, id, className, }: QuickFormFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export declare function QuickFormField({ value, onValueChange, onValueBlur, locked, onLockedChange, showLock, disabled, leadingAddon, trailingAddon, more, mode, onModeChange, valueModes, confirmModeChange, renderExpressionEditor, renderModeControl, fieldType, fieldTypes, onFieldTypeChange, required, onRequiredChange, label, onLabelChange, isEditingLabel, onIsEditingLabelChange, labelAddon, tooltip, strings: stringOverrides, placeholder, error, errorId, belowValue, fileUploadAriaLabel, headerActions, compact, showFieldActions, options, onGenerateWithAi, onInsertVariable, variables, id, className, }: QuickFormFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,20 +3,29 @@ import { RefreshCw, Trash2 } from "lucide-react";
|
|
|
3
3
|
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Calendar } from "../calendar.js";
|
|
5
5
|
import { DateTimePicker } from "../datetime-picker.js";
|
|
6
|
+
import { EditableText } from "../editable-text.js";
|
|
6
7
|
import { FileUpload } from "../file-upload.js";
|
|
7
8
|
import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupTextarea } from "../input-group.js";
|
|
9
|
+
import { RequiredIndicator } from "../label.js";
|
|
8
10
|
import { MultiSelect } from "../multi-select.js";
|
|
9
11
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover.js";
|
|
12
|
+
import { PromptValueControl } from "../prompt-value-control.js";
|
|
10
13
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../select.js";
|
|
11
14
|
import { Switch } from "../switch.js";
|
|
15
|
+
import { VariableValueControl } from "../variable-value-control.js";
|
|
12
16
|
import { cn } from "../../../lib/index.js";
|
|
13
17
|
import { toDateValue } from "../../../lib/date-value.js";
|
|
14
18
|
import { FieldMenu } from "../field-addons/field-menu.js";
|
|
15
|
-
import {
|
|
19
|
+
import { ValueModeSwitchDialog } from "../field-addons/value-mode-switch-dialog.js";
|
|
20
|
+
import { FieldHeader, GROW_WHILE_EDITING } from "./components/field-header.js";
|
|
16
21
|
import { LockToggleButton } from "./components/lock-toggle-button.js";
|
|
17
22
|
import { DEFAULT_QUICK_FORM_FIELD_STRINGS, FIELD_TYPE_META } from "./types.js";
|
|
18
|
-
import { DEFAULT_SELECT_OPTIONS, formatDateValue, parseListValue, toDateOnlyString } from "./utils.js";
|
|
19
|
-
|
|
23
|
+
import { DEFAULT_SELECT_OPTIONS, formatDateValue, parseListValue, toDateOnlyString, toVariablePickerSource } from "./utils.js";
|
|
24
|
+
const DEFAULT_VALUE_MODES = [
|
|
25
|
+
'literal',
|
|
26
|
+
'expression'
|
|
27
|
+
];
|
|
28
|
+
function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true, onLockedChange, showLock = true, disabled = false, leadingAddon, trailingAddon, more, mode = 'literal', onModeChange, valueModes = DEFAULT_VALUE_MODES, confirmModeChange, renderExpressionEditor, renderModeControl, fieldType = 'string', fieldTypes, onFieldTypeChange, required, onRequiredChange, label, onLabelChange, isEditingLabel, onIsEditingLabelChange, labelAddon, tooltip, strings: stringOverrides, placeholder, error, errorId, belowValue, fileUploadAriaLabel, headerActions, compact, showFieldActions = true, options = DEFAULT_SELECT_OPTIONS, onGenerateWithAi, onInsertVariable, variables = [], id, className }) {
|
|
20
29
|
const strings = useMemo(()=>({
|
|
21
30
|
...DEFAULT_QUICK_FORM_FIELD_STRINGS,
|
|
22
31
|
...stringOverrides
|
|
@@ -27,8 +36,17 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
27
36
|
const valueInputRef = useRef(null);
|
|
28
37
|
const committedRef = useRef(value);
|
|
29
38
|
const caretRef = useRef(null);
|
|
39
|
+
const modeControlRef = useRef(null);
|
|
40
|
+
const setModeControl = useCallback((el)=>{
|
|
41
|
+
modeControlRef.current = el;
|
|
42
|
+
}, []);
|
|
30
43
|
const [datePopoverOpen, setDatePopoverOpen] = useState(false);
|
|
31
44
|
const [selectOpen, setSelectOpen] = useState(false);
|
|
45
|
+
const [labelDraft, setLabelDraft] = useState(null);
|
|
46
|
+
const [pendingSwitch, setPendingSwitch] = useState();
|
|
47
|
+
const variablePicker = useMemo(()=>toVariablePickerSource(variables), [
|
|
48
|
+
variables
|
|
49
|
+
]);
|
|
32
50
|
const fieldId = id ?? generatedId;
|
|
33
51
|
const validationId = errorId ?? `${fieldId}-error`;
|
|
34
52
|
const typeMeta = FIELD_TYPE_META[fieldType];
|
|
@@ -42,6 +60,7 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
42
60
|
id: 'clear',
|
|
43
61
|
label: strings.clearValue,
|
|
44
62
|
icon: Trash2,
|
|
63
|
+
destructive: true,
|
|
45
64
|
onSelect: more.onClear
|
|
46
65
|
}
|
|
47
66
|
] : [],
|
|
@@ -54,20 +73,44 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
54
73
|
}
|
|
55
74
|
] : []
|
|
56
75
|
];
|
|
76
|
+
const valueModeStrings = {
|
|
77
|
+
...strings.valueModes,
|
|
78
|
+
literalTitle: strings.literalLabels[fieldType] ?? typeMeta.fixedLabel,
|
|
79
|
+
expressionTitle: strings.expressionLabel,
|
|
80
|
+
expressionDescription: strings.expressionDescription,
|
|
81
|
+
fieldActions: strings.moreActionsAriaLabel
|
|
82
|
+
};
|
|
83
|
+
const focusControlOnClose = useRef(false);
|
|
84
|
+
const keepControlFocus = (event)=>{
|
|
85
|
+
if (!focusControlOnClose.current) return;
|
|
86
|
+
focusControlOnClose.current = false;
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
(valueInputRef.current ?? modeControlRef.current)?.focus();
|
|
89
|
+
};
|
|
90
|
+
const selectMode = (next)=>{
|
|
91
|
+
if (!onModeChange) return;
|
|
92
|
+
const confirm = next !== mode && confirmModeChange?.(mode, next);
|
|
93
|
+
if (confirm) return void setPendingSwitch({
|
|
94
|
+
...true === confirm ? {} : confirm,
|
|
95
|
+
to: next
|
|
96
|
+
});
|
|
97
|
+
focusControlOnClose.current = next !== mode;
|
|
98
|
+
onModeChange(next);
|
|
99
|
+
};
|
|
100
|
+
const switchable = !!onModeChange && valueModes.length > 1;
|
|
57
101
|
const builtInMenu = /*#__PURE__*/ jsx(FieldMenu, {
|
|
58
102
|
mode: mode,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
103
|
+
modes: [
|
|
104
|
+
...valueModes
|
|
105
|
+
],
|
|
106
|
+
onSelect: selectMode,
|
|
107
|
+
modesDisabled: !switchable && menuActions.length > 0,
|
|
108
|
+
disabled: disabled || !switchable && 0 === menuActions.length,
|
|
62
109
|
actions: menuActions,
|
|
63
110
|
triggerLabel: strings.valueModeAriaLabel,
|
|
64
111
|
literalDescription: strings.literalDescriptions[fieldType] ?? typeMeta.fixedDescription,
|
|
65
|
-
strings:
|
|
66
|
-
|
|
67
|
-
expressionTitle: strings.expressionLabel,
|
|
68
|
-
expressionDescription: strings.expressionDescription,
|
|
69
|
-
fieldActions: strings.moreActionsAriaLabel
|
|
70
|
-
}
|
|
112
|
+
strings: valueModeStrings,
|
|
113
|
+
onCloseAutoFocus: keepControlFocus
|
|
71
114
|
});
|
|
72
115
|
const controlProps = {
|
|
73
116
|
id: fieldId,
|
|
@@ -84,11 +127,14 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
84
127
|
'data-slot': 'input-group-control'
|
|
85
128
|
};
|
|
86
129
|
const modeControl = renderModeControl?.(mode, controlProps) ?? null;
|
|
130
|
+
const builtInVariable = null === modeControl && 'variable' === mode;
|
|
131
|
+
const builtInPrompt = null === modeControl && 'prompt' === mode;
|
|
87
132
|
const modeOnMount = useRef(mode);
|
|
88
133
|
useEffect(()=>{
|
|
89
134
|
if (modeOnMount.current === mode) return;
|
|
90
135
|
modeOnMount.current = mode;
|
|
91
|
-
valueInputRef.current?.focus();
|
|
136
|
+
const frame = requestAnimationFrame(()=>(valueInputRef.current ?? modeControlRef.current)?.focus());
|
|
137
|
+
return ()=>cancelAnimationFrame(frame);
|
|
92
138
|
}, [
|
|
93
139
|
mode
|
|
94
140
|
]);
|
|
@@ -251,6 +297,11 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
251
297
|
selected: parseListValue(value),
|
|
252
298
|
onChange: (selected)=>editableOnValueChange?.(JSON.stringify(selected)),
|
|
253
299
|
placeholder: strings.selectOptions,
|
|
300
|
+
searchPlaceholder: strings.multiSelectSearchPlaceholder,
|
|
301
|
+
emptyMessage: strings.multiSelectEmpty,
|
|
302
|
+
clearAllText: strings.multiSelectClearAll,
|
|
303
|
+
strings: strings.multiSelect,
|
|
304
|
+
overflow: "collapse",
|
|
254
305
|
disabled: !editableOnValueChange,
|
|
255
306
|
onBlur: onValueBlur
|
|
256
307
|
}) : 'textarea' === fieldType ? /*#__PURE__*/ jsx(InputGroupTextarea, {
|
|
@@ -264,11 +315,60 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
264
315
|
type: 'integer' === fieldType || 'double' === fieldType ? 'number' : 'text',
|
|
265
316
|
step: 'double' === fieldType ? 'any' : void 0
|
|
266
317
|
});
|
|
318
|
+
const canPickVariable = !disabled && (!!onInsertVariable || !!onValueChange);
|
|
319
|
+
const variableControl = /*#__PURE__*/ jsx(VariableValueControl, {
|
|
320
|
+
id: fieldId,
|
|
321
|
+
value: value,
|
|
322
|
+
onChange: (reference, item)=>onInsertVariable && item ? onInsertVariable(variablePicker.resolve(item), {
|
|
323
|
+
value,
|
|
324
|
+
caret: null
|
|
325
|
+
}) : onValueChange?.(reference),
|
|
326
|
+
onBlur: onValueBlur,
|
|
327
|
+
inputRef: setModeControl,
|
|
328
|
+
variables: variablePicker.items,
|
|
329
|
+
disabled: !canPickVariable,
|
|
330
|
+
placeholder: placeholder,
|
|
331
|
+
strings: strings.valueModes,
|
|
332
|
+
"aria-describedby": controlProps['aria-describedby']
|
|
333
|
+
});
|
|
334
|
+
const promptControl = /*#__PURE__*/ jsx(PromptValueControl, {
|
|
335
|
+
id: fieldId,
|
|
336
|
+
value: value,
|
|
337
|
+
onChange: (next)=>editableOnValueChange?.(next),
|
|
338
|
+
onBlur: onValueBlur,
|
|
339
|
+
inputRef: setModeControl,
|
|
340
|
+
disabled: !editableOnValueChange,
|
|
341
|
+
placeholder: placeholder,
|
|
342
|
+
strings: strings.valueModes,
|
|
343
|
+
"aria-describedby": controlProps['aria-describedby']
|
|
344
|
+
});
|
|
345
|
+
const editableLabel = 'string' == typeof label && onLabelChange ? /*#__PURE__*/ jsxs("span", {
|
|
346
|
+
className: cn('flex min-w-0 items-center', GROW_WHILE_EDITING),
|
|
347
|
+
children: [
|
|
348
|
+
/*#__PURE__*/ jsx(EditableText, {
|
|
349
|
+
size: "label",
|
|
350
|
+
value: labelDraft ?? label,
|
|
351
|
+
placeholder: strings.labelPlaceholder,
|
|
352
|
+
"aria-label": strings.labelAriaLabel,
|
|
353
|
+
editing: isEditingLabel,
|
|
354
|
+
onEditingChange: onIsEditingLabelChange,
|
|
355
|
+
disabled: disabled,
|
|
356
|
+
onChange: (next)=>setLabelDraft(next === label ? null : next),
|
|
357
|
+
onSubmit: (next)=>{
|
|
358
|
+
setLabelDraft(null);
|
|
359
|
+
onLabelChange(next);
|
|
360
|
+
}
|
|
361
|
+
}),
|
|
362
|
+
required && /*#__PURE__*/ jsx(RequiredIndicator, {})
|
|
363
|
+
]
|
|
364
|
+
}) : void 0;
|
|
267
365
|
return /*#__PURE__*/ jsxs("div", {
|
|
268
366
|
className: cn('@container group flex flex-col gap-1.5 [&>[data-slot=form-field-error]]:mt-0', className),
|
|
269
367
|
children: [
|
|
270
368
|
/*#__PURE__*/ jsx(FieldHeader, {
|
|
271
|
-
label: label,
|
|
369
|
+
label: editableLabel ?? label,
|
|
370
|
+
labelAddon: labelAddon,
|
|
371
|
+
tooltip: tooltip,
|
|
272
372
|
fieldId: fieldId,
|
|
273
373
|
fieldLabel: fieldLabel,
|
|
274
374
|
required: required,
|
|
@@ -281,9 +381,9 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
281
381
|
isExpression: 'expression' === mode,
|
|
282
382
|
showFieldActions: showFieldActions,
|
|
283
383
|
onValueChange: editableOnValueChange,
|
|
284
|
-
variables:
|
|
384
|
+
variables: variablePicker,
|
|
285
385
|
onGenerateWithAi: onGenerateWithAi,
|
|
286
|
-
onInsertVariable: (variable)=>onInsertVariable ? onInsertVariable(variable, {
|
|
386
|
+
onInsertVariable: builtInVariable ? void 0 : (variable)=>onInsertVariable ? onInsertVariable(variable, {
|
|
287
387
|
value,
|
|
288
388
|
caret: caretRef.current
|
|
289
389
|
}) : insertVariableAtCaret(variable.value),
|
|
@@ -294,7 +394,8 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
294
394
|
error: error,
|
|
295
395
|
errorId: validationId,
|
|
296
396
|
disabled: disabled,
|
|
297
|
-
|
|
397
|
+
variant: builtInPrompt ? 'agent' : void 0,
|
|
398
|
+
layout: builtInPrompt || 'literal' === mode && ('file' === fieldType || 'textarea' === fieldType) ? 'grow' : 'row',
|
|
298
399
|
children: [
|
|
299
400
|
(showLock || void 0 !== leadingAddon) && null !== leadingAddon && /*#__PURE__*/ jsx(InputGroupAddon, {
|
|
300
401
|
align: "inline-start",
|
|
@@ -308,7 +409,7 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
308
409
|
modeControl ?? ('expression' === mode ? renderExpressionEditor ? renderExpressionEditor(controlProps) : /*#__PURE__*/ jsx(InputGroupInput, {
|
|
309
410
|
...textInputProps,
|
|
310
411
|
className: "font-mono"
|
|
311
|
-
}) : literalControl),
|
|
412
|
+
}) : builtInVariable ? variableControl : builtInPrompt ? promptControl : literalControl),
|
|
312
413
|
null !== trailingAddon && /*#__PURE__*/ jsx(InputGroupAddon, {
|
|
313
414
|
align: "inline-end",
|
|
314
415
|
className: "cursor-default",
|
|
@@ -316,7 +417,23 @@ function QuickFormField({ value = '', onValueChange, onValueBlur, locked = true,
|
|
|
316
417
|
})
|
|
317
418
|
]
|
|
318
419
|
}),
|
|
319
|
-
belowValue
|
|
420
|
+
belowValue,
|
|
421
|
+
/*#__PURE__*/ jsx(ValueModeSwitchDialog, {
|
|
422
|
+
open: !!pendingSwitch,
|
|
423
|
+
title: pendingSwitch?.title,
|
|
424
|
+
description: pendingSwitch?.description,
|
|
425
|
+
confirmLabel: pendingSwitch?.confirmLabel,
|
|
426
|
+
strings: strings.valueModes,
|
|
427
|
+
onCancel: ()=>setPendingSwitch(void 0),
|
|
428
|
+
onConfirm: ()=>{
|
|
429
|
+
if (pendingSwitch && !disabled) {
|
|
430
|
+
focusControlOnClose.current = true;
|
|
431
|
+
onModeChange?.(pendingSwitch.to);
|
|
432
|
+
}
|
|
433
|
+
setPendingSwitch(void 0);
|
|
434
|
+
},
|
|
435
|
+
onCloseAutoFocus: keepControlFocus
|
|
436
|
+
})
|
|
320
437
|
]
|
|
321
438
|
});
|
|
322
439
|
}
|
|
@@ -144,6 +144,9 @@ const DEFAULT_QUICK_FORM_FIELD_STRINGS = {
|
|
|
144
144
|
falseLabel: 'False',
|
|
145
145
|
requiredTooltip: 'Required',
|
|
146
146
|
requiredAriaLabel: 'Required field',
|
|
147
|
+
labelAriaLabel: 'Field label',
|
|
148
|
+
labelPlaceholder: 'Untitled field',
|
|
149
|
+
tooltipAriaLabel: 'More information',
|
|
147
150
|
optionalAriaLabel: 'Optional field',
|
|
148
151
|
insertLabel: 'Insert',
|
|
149
152
|
insertAriaLabel: 'Insert variable',
|
|
@@ -152,9 +155,14 @@ const DEFAULT_QUICK_FORM_FIELD_STRINGS = {
|
|
|
152
155
|
valueModeAriaLabel: 'Choose value mode',
|
|
153
156
|
expressionLabel: 'Expression',
|
|
154
157
|
expressionDescription: 'Use a JS expression',
|
|
158
|
+
valueModes: {},
|
|
155
159
|
pickDate: 'Pick a date',
|
|
156
160
|
selectOption: 'Select an option',
|
|
157
161
|
selectOptions: 'Select options...',
|
|
162
|
+
multiSelectSearchPlaceholder: 'Search...',
|
|
163
|
+
multiSelectEmpty: 'No items found.',
|
|
164
|
+
multiSelectClearAll: (count)=>`Clear all (${count})`,
|
|
165
|
+
multiSelect: {},
|
|
158
166
|
moreActionsAriaLabel: 'More value actions',
|
|
159
167
|
clearValue: 'Clear value',
|
|
160
168
|
forceRefresh: 'Force refresh',
|