@uipath/apollo-wind 2.29.0 → 2.31.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/form-schema.d.ts +8 -0
- package/dist/components/forms/metadata-form.cjs +104 -39
- package/dist/components/forms/metadata-form.d.ts +25 -1
- package/dist/components/forms/metadata-form.js +106 -41
- package/dist/components/ui/dropdown-menu.cjs +7 -2
- package/dist/components/ui/dropdown-menu.d.ts +4 -1
- package/dist/components/ui/dropdown-menu.js +7 -2
- package/dist/components/ui/index.cjs +14 -14
- package/dist/components/ui/popover.cjs +8 -2
- package/dist/components/ui/popover.d.ts +4 -1
- package/dist/components/ui/popover.js +8 -2
- package/dist/components/ui/portal-container.cjs +62 -0
- package/dist/components/ui/portal-container.d.ts +31 -0
- package/dist/components/ui/portal-container.js +25 -0
- package/dist/components/ui/select.cjs +8 -2
- package/dist/components/ui/select.d.ts +4 -1
- package/dist/components/ui/select.js +8 -2
- package/dist/index.cjs +7 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -1
- package/dist/styles.css +53 -1
- package/package.json +2 -2
|
@@ -255,6 +255,14 @@ export interface FormStep {
|
|
|
255
255
|
validation?: 'onChange' | 'onBlur' | 'onSubmit';
|
|
256
256
|
canSkip?: boolean;
|
|
257
257
|
conditions?: FieldCondition[];
|
|
258
|
+
/**
|
|
259
|
+
* Message shown (in the `tabs` step variant) when this step has no visible
|
|
260
|
+
* sections. A step that sets this stays in the tab bar even while empty and
|
|
261
|
+
* renders the message in place of its content — e.g. a "Parameters" tab that
|
|
262
|
+
* always shows, reading "No available parameters" for a node with no inputs.
|
|
263
|
+
* Steps without both sections and `emptyState` are hidden from the tab bar.
|
|
264
|
+
*/
|
|
265
|
+
emptyState?: string;
|
|
258
266
|
}
|
|
259
267
|
export interface FormAction {
|
|
260
268
|
id: string;
|
|
@@ -39,7 +39,7 @@ const external_field_renderer_cjs_namespaceObject = require("./field-renderer.cj
|
|
|
39
39
|
const external_rules_engine_cjs_namespaceObject = require("./rules-engine.cjs");
|
|
40
40
|
const external_validation_converter_cjs_namespaceObject = require("./validation-converter.cjs");
|
|
41
41
|
const DEFAULT_PLUGINS = [];
|
|
42
|
-
function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className, disabled = false, autoComplete, stepVariant = 'wizard' }) {
|
|
42
|
+
function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className, disabled = false, autoComplete, stepVariant = 'wizard', sectionVariant = 'card', activeStepId, onActiveStepChange }) {
|
|
43
43
|
const [currentStep, setCurrentStep] = (0, external_react_namespaceObject.useState)(0);
|
|
44
44
|
const [customComponents, setCustomComponents] = (0, external_react_namespaceObject.useState)({});
|
|
45
45
|
const [isInitialized, setIsInitialized] = (0, external_react_namespaceObject.useState)(false);
|
|
@@ -131,6 +131,9 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
131
131
|
context: context,
|
|
132
132
|
customComponents: customComponents,
|
|
133
133
|
disabled: disabled,
|
|
134
|
+
sectionVariant: sectionVariant,
|
|
135
|
+
activeStepId: activeStepId,
|
|
136
|
+
onActiveStepChange: onActiveStepChange,
|
|
134
137
|
onReset: ()=>reset()
|
|
135
138
|
});
|
|
136
139
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(MultiStepForm, {
|
|
@@ -139,14 +142,16 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
139
142
|
currentStep: currentStep,
|
|
140
143
|
setCurrentStep: setCurrentStep,
|
|
141
144
|
customComponents: customComponents,
|
|
142
|
-
disabled: disabled
|
|
145
|
+
disabled: disabled,
|
|
146
|
+
sectionVariant: sectionVariant
|
|
143
147
|
});
|
|
144
148
|
}
|
|
145
149
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(SinglePageForm, {
|
|
146
150
|
schema: schema,
|
|
147
151
|
context: context,
|
|
148
152
|
customComponents: customComponents,
|
|
149
|
-
disabled: disabled
|
|
153
|
+
disabled: disabled,
|
|
154
|
+
sectionVariant: sectionVariant
|
|
150
155
|
});
|
|
151
156
|
};
|
|
152
157
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_react_hook_form_namespaceObject.FormProvider, {
|
|
@@ -166,20 +171,21 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
166
171
|
})
|
|
167
172
|
});
|
|
168
173
|
}
|
|
169
|
-
function SinglePageForm({ schema, context, customComponents, disabled }) {
|
|
174
|
+
function SinglePageForm({ schema, context, customComponents, disabled, sectionVariant }) {
|
|
170
175
|
const sections = schema.sections || [];
|
|
171
176
|
const visibleSections = sections.filter((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
172
177
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
173
|
-
className:
|
|
178
|
+
className: 'plain' === sectionVariant ? void 0 : 'space-y-2',
|
|
174
179
|
children: visibleSections.map((section)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(FormSection, {
|
|
175
180
|
section: section,
|
|
176
181
|
context: context,
|
|
177
182
|
customComponents: customComponents,
|
|
178
|
-
disabled: disabled
|
|
183
|
+
disabled: disabled,
|
|
184
|
+
sectionVariant: sectionVariant
|
|
179
185
|
}, section.id))
|
|
180
186
|
});
|
|
181
187
|
}
|
|
182
|
-
function MultiStepForm({ schema, context, currentStep, setCurrentStep, customComponents, disabled }) {
|
|
188
|
+
function MultiStepForm({ schema, context, currentStep, setCurrentStep, customComponents, disabled, sectionVariant }) {
|
|
183
189
|
const steps = schema.steps || [];
|
|
184
190
|
const step = steps[currentStep];
|
|
185
191
|
if (!step) return null;
|
|
@@ -217,12 +223,13 @@ function MultiStepForm({ schema, context, currentStep, setCurrentStep, customCom
|
|
|
217
223
|
]
|
|
218
224
|
}),
|
|
219
225
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
220
|
-
className:
|
|
226
|
+
className: 'plain' === sectionVariant ? void 0 : 'space-y-2',
|
|
221
227
|
children: step.sections.map((section)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(FormSection, {
|
|
222
228
|
section: section,
|
|
223
229
|
context: context,
|
|
224
230
|
customComponents: customComponents,
|
|
225
|
-
disabled: disabled
|
|
231
|
+
disabled: disabled,
|
|
232
|
+
sectionVariant: sectionVariant
|
|
226
233
|
}, section.id))
|
|
227
234
|
}),
|
|
228
235
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
@@ -250,15 +257,39 @@ function MultiStepForm({ schema, context, currentStep, setCurrentStep, customCom
|
|
|
250
257
|
]
|
|
251
258
|
});
|
|
252
259
|
}
|
|
253
|
-
function TabbedStepForm({ schema, context, customComponents, disabled, onReset }) {
|
|
260
|
+
function TabbedStepForm({ schema, context, customComponents, disabled, sectionVariant, onReset, activeStepId, onActiveStepChange }) {
|
|
254
261
|
const steps = schema.steps || [];
|
|
255
|
-
const visibleSteps = steps.filter((step)=>
|
|
256
|
-
|
|
257
|
-
|
|
262
|
+
const visibleSteps = steps.filter((step)=>{
|
|
263
|
+
if (step.conditions && !context.evaluateConditions(step.conditions)) return false;
|
|
264
|
+
const hasVisibleSection = step.sections.some((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
265
|
+
return hasVisibleSection || void 0 !== step.emptyState;
|
|
266
|
+
});
|
|
267
|
+
const formState = (0, external_react_hook_form_namespaceObject.useFormState)({
|
|
268
|
+
control: context.form.control
|
|
269
|
+
});
|
|
270
|
+
const errorCountByStepId = {};
|
|
271
|
+
for (const step of visibleSteps){
|
|
272
|
+
let count = 0;
|
|
273
|
+
for (const section of step.sections)if (!section.conditions || context.evaluateConditions(section.conditions)) for (const field of section.fields){
|
|
274
|
+
if (field.rules && !external_rules_engine_cjs_namespaceObject.RulesEngine.isFieldVisible(field.rules, context.values)) continue;
|
|
275
|
+
const fieldError = context.form.getFieldState(field.name, formState).error;
|
|
276
|
+
if (fieldError) count += Array.isArray(fieldError) ? fieldError.filter(Boolean).length : 1;
|
|
277
|
+
}
|
|
278
|
+
errorCountByStepId[step.id] = count;
|
|
279
|
+
}
|
|
280
|
+
const [internalTab, setInternalTab] = (0, external_react_namespaceObject.useState)('');
|
|
281
|
+
const controlled = void 0 !== activeStepId;
|
|
282
|
+
const requestedTab = controlled ? activeStepId : internalTab;
|
|
283
|
+
const currentTab = visibleSteps.some((step)=>step.id === requestedTab) ? requestedTab : visibleSteps[0]?.id ?? '';
|
|
284
|
+
const selectTab = (stepId)=>{
|
|
285
|
+
if (!controlled) setInternalTab(stepId);
|
|
286
|
+
onActiveStepChange?.(stepId);
|
|
287
|
+
};
|
|
258
288
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
259
|
-
if (
|
|
289
|
+
if (!controlled && internalTab !== currentTab) setInternalTab(currentTab);
|
|
260
290
|
}, [
|
|
261
|
-
|
|
291
|
+
controlled,
|
|
292
|
+
internalTab,
|
|
262
293
|
currentTab
|
|
263
294
|
]);
|
|
264
295
|
if (0 === visibleSteps.length) return null;
|
|
@@ -266,27 +297,53 @@ function TabbedStepForm({ schema, context, customComponents, disabled, onReset }
|
|
|
266
297
|
children: [
|
|
267
298
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(tabs_cjs_namespaceObject.Tabs, {
|
|
268
299
|
value: currentTab,
|
|
269
|
-
onValueChange:
|
|
270
|
-
className: "flex flex-col gap-
|
|
300
|
+
onValueChange: selectTab,
|
|
301
|
+
className: "flex min-h-0 flex-1 flex-col gap-1",
|
|
271
302
|
children: [
|
|
272
|
-
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(
|
|
273
|
-
className: "
|
|
274
|
-
children:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
303
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
304
|
+
className: "shrink-0 pt-3 [padding-inline:var(--mf-content-inset,0px)]",
|
|
305
|
+
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(tabs_cjs_namespaceObject.ScrollableTabsList, {
|
|
306
|
+
className: "h-auto justify-start gap-0.5 rounded-lg bg-transparent px-0 py-0.5 text-muted-foreground",
|
|
307
|
+
scrollButtonClassName: "size-6 hover:bg-surface-overlay",
|
|
308
|
+
children: visibleSteps.map((step)=>{
|
|
309
|
+
const errorCount = errorCountByStepId[step.id] ?? 0;
|
|
310
|
+
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(tabs_cjs_namespaceObject.TabsTrigger, {
|
|
311
|
+
value: step.id,
|
|
312
|
+
className: "inline-flex h-6 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md px-2.5 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:text-foreground data-[state=active]:bg-surface-overlay data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
313
|
+
children: [
|
|
314
|
+
step.title,
|
|
315
|
+
errorCount > 0 && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
|
|
316
|
+
role: "img",
|
|
317
|
+
"aria-label": `${errorCount} ${1 === errorCount ? 'issue' : 'issues'}`,
|
|
318
|
+
title: `${errorCount} ${1 === errorCount ? 'issue' : 'issues'}`,
|
|
319
|
+
className: "grid h-4 min-w-4 place-items-center rounded-full bg-error px-1 text-[10px] font-semibold leading-none text-foreground-on-accent",
|
|
320
|
+
children: errorCount
|
|
321
|
+
})
|
|
322
|
+
]
|
|
323
|
+
}, step.id);
|
|
324
|
+
})
|
|
325
|
+
})
|
|
279
326
|
}),
|
|
280
|
-
visibleSteps.map((step)
|
|
327
|
+
visibleSteps.map((step)=>{
|
|
328
|
+
const stepSections = step.sections.filter((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
329
|
+
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(tabs_cjs_namespaceObject.TabsContent, {
|
|
281
330
|
value: step.id,
|
|
282
|
-
className: "
|
|
283
|
-
children: step.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
331
|
+
className: "mt-0 min-h-0 flex-1 overflow-auto",
|
|
332
|
+
children: 0 === stepSections.length && void 0 !== step.emptyState ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
333
|
+
className: "pt-4 text-sm text-muted-foreground [padding-inline:var(--mf-content-inset,0px)]",
|
|
334
|
+
children: step.emptyState
|
|
335
|
+
}) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
336
|
+
className: 'plain' === sectionVariant ? 'pb-6 [padding-inline:var(--mf-content-inset,0px)]' : 'space-y-2 pb-6 pt-4 [padding-inline:var(--mf-content-inset,0px)]',
|
|
337
|
+
children: stepSections.map((section)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(FormSection, {
|
|
338
|
+
section: section,
|
|
339
|
+
context: context,
|
|
340
|
+
customComponents: customComponents,
|
|
341
|
+
disabled: disabled,
|
|
342
|
+
sectionVariant: sectionVariant
|
|
343
|
+
}, section.id))
|
|
344
|
+
})
|
|
345
|
+
}, step.id);
|
|
346
|
+
})
|
|
290
347
|
]
|
|
291
348
|
}),
|
|
292
349
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(FormActions, {
|
|
@@ -297,9 +354,13 @@ function TabbedStepForm({ schema, context, customComponents, disabled, onReset }
|
|
|
297
354
|
]
|
|
298
355
|
});
|
|
299
356
|
}
|
|
300
|
-
function FormSection({ section, context, customComponents, disabled }) {
|
|
357
|
+
function FormSection({ section, context, customComponents, disabled, sectionVariant = 'card' }) {
|
|
301
358
|
const gridColumns = context.schema.layout?.columns || 1;
|
|
302
359
|
const gap = context.schema.layout?.gap || 4;
|
|
360
|
+
const isPlain = 'plain' === sectionVariant;
|
|
361
|
+
const dividerClassName = 'border-t first:border-t-0';
|
|
362
|
+
const wrapperClassName = isPlain ? 'border-b-0' : 'border rounded-lg px-3';
|
|
363
|
+
const triggerClassName = isPlain ? 'justify-start gap-2 py-4 text-sm font-semibold hover:no-underline' : 'text-sm font-medium';
|
|
303
364
|
const fieldsGrid = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
304
365
|
className: "grid",
|
|
305
366
|
style: {
|
|
@@ -313,7 +374,10 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
313
374
|
disabled: disabled
|
|
314
375
|
}, field.name))
|
|
315
376
|
});
|
|
316
|
-
if (!section.title) return
|
|
377
|
+
if (!section.title) return isPlain ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
378
|
+
className: `${dividerClassName} pb-4 pt-4`,
|
|
379
|
+
children: fieldsGrid
|
|
380
|
+
}) : fieldsGrid;
|
|
317
381
|
const innerContent = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
318
382
|
className: "flex flex-col gap-4",
|
|
319
383
|
children: [
|
|
@@ -331,12 +395,13 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
331
395
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(accordion_cjs_namespaceObject.Accordion, {
|
|
332
396
|
type: "multiple",
|
|
333
397
|
defaultValue: defaultValue,
|
|
398
|
+
className: isPlain ? dividerClassName : void 0,
|
|
334
399
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(accordion_cjs_namespaceObject.AccordionItem, {
|
|
335
400
|
value: section.id,
|
|
336
|
-
className:
|
|
401
|
+
className: wrapperClassName,
|
|
337
402
|
children: [
|
|
338
403
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(accordion_cjs_namespaceObject.AccordionTrigger, {
|
|
339
|
-
className:
|
|
404
|
+
className: triggerClassName,
|
|
340
405
|
children: section.title
|
|
341
406
|
}),
|
|
342
407
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(accordion_cjs_namespaceObject.AccordionContent, {
|
|
@@ -347,12 +412,12 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
347
412
|
});
|
|
348
413
|
}
|
|
349
414
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
350
|
-
className:
|
|
415
|
+
className: isPlain ? dividerClassName : wrapperClassName,
|
|
351
416
|
children: [
|
|
352
417
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
353
418
|
className: "flex",
|
|
354
419
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
355
|
-
className:
|
|
420
|
+
className: isPlain ? 'flex flex-1 items-center justify-start gap-2 py-4 text-sm font-semibold' : 'flex flex-1 items-center justify-between py-4 text-sm font-medium',
|
|
356
421
|
children: section.title
|
|
357
422
|
})
|
|
358
423
|
}),
|
|
@@ -18,6 +18,30 @@ interface MetadataFormProps {
|
|
|
18
18
|
* across every step. Ignored for single-page (`sections`) schemas.
|
|
19
19
|
*/
|
|
20
20
|
stepVariant?: 'wizard' | 'tabs';
|
|
21
|
+
/**
|
|
22
|
+
* Visual treatment for each titled section. `'card'` (default) wraps every
|
|
23
|
+
* section in a bordered, rounded, horizontally-padded box. `'plain'` drops the
|
|
24
|
+
* border, rounding, and horizontal padding so sections read as flush headers
|
|
25
|
+
* over their content, separated by a full-width hairline divider between
|
|
26
|
+
* consecutive sections — used by hosts (e.g. the canvas properties panel) that
|
|
27
|
+
* already frame the form and want a borderless list. Applies to both
|
|
28
|
+
* collapsible (accordion) and non-collapsible sections across every layout
|
|
29
|
+
* (single-page, wizard, tabs).
|
|
30
|
+
*/
|
|
31
|
+
sectionVariant?: 'card' | 'plain';
|
|
32
|
+
/**
|
|
33
|
+
* Controlled active step id for the `tabs` step variant. When provided the
|
|
34
|
+
* caller owns which tab is selected — persist it across remounts to keep the
|
|
35
|
+
* user on the same tab when switching between nodes. If the id isn't one of
|
|
36
|
+
* the currently visible steps, the form shows the first tab without mutating
|
|
37
|
+
* the caller's value. Omit for uncontrolled (internal) tab state.
|
|
38
|
+
*/
|
|
39
|
+
activeStepId?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Fires with the step id whenever the user selects a tab, in both controlled
|
|
42
|
+
* and uncontrolled mode. Pair it with `activeStepId` to persist the selection.
|
|
43
|
+
*/
|
|
44
|
+
onActiveStepChange?: (stepId: string) => void;
|
|
21
45
|
}
|
|
22
|
-
export declare function MetadataForm({ schema, plugins, onSubmit, className, disabled, autoComplete, stepVariant, }: MetadataFormProps): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
export declare function MetadataForm({ schema, plugins, onSubmit, className, disabled, autoComplete, stepVariant, sectionVariant, activeStepId, onActiveStepChange, }: MetadataFormProps): import("react/jsx-runtime").JSX.Element;
|
|
23
47
|
export {};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema";
|
|
3
3
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { FormProvider, useForm } from "react-hook-form";
|
|
4
|
+
import { FormProvider, useForm, useFormState } from "react-hook-form";
|
|
5
5
|
import { z } from "zod/v4";
|
|
6
6
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../ui/accordion.js";
|
|
7
7
|
import { Button } from "../ui/button.js";
|
|
8
|
-
import { Tabs, TabsContent,
|
|
8
|
+
import { ScrollableTabsList, Tabs, TabsContent, TabsTrigger } from "../ui/tabs.js";
|
|
9
9
|
import { DataFetcher } from "./data-fetcher.js";
|
|
10
10
|
import { FormFieldRenderer } from "./field-renderer.js";
|
|
11
11
|
import { RulesEngine } from "./rules-engine.js";
|
|
12
12
|
import { validationConfigToZod } from "./validation-converter.js";
|
|
13
13
|
const DEFAULT_PLUGINS = [];
|
|
14
|
-
function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className, disabled = false, autoComplete, stepVariant = 'wizard' }) {
|
|
14
|
+
function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className, disabled = false, autoComplete, stepVariant = 'wizard', sectionVariant = 'card', activeStepId, onActiveStepChange }) {
|
|
15
15
|
const [currentStep, setCurrentStep] = useState(0);
|
|
16
16
|
const [customComponents, setCustomComponents] = useState({});
|
|
17
17
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
@@ -103,6 +103,9 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
103
103
|
context: context,
|
|
104
104
|
customComponents: customComponents,
|
|
105
105
|
disabled: disabled,
|
|
106
|
+
sectionVariant: sectionVariant,
|
|
107
|
+
activeStepId: activeStepId,
|
|
108
|
+
onActiveStepChange: onActiveStepChange,
|
|
106
109
|
onReset: ()=>reset()
|
|
107
110
|
});
|
|
108
111
|
return /*#__PURE__*/ jsx(MultiStepForm, {
|
|
@@ -111,14 +114,16 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
111
114
|
currentStep: currentStep,
|
|
112
115
|
setCurrentStep: setCurrentStep,
|
|
113
116
|
customComponents: customComponents,
|
|
114
|
-
disabled: disabled
|
|
117
|
+
disabled: disabled,
|
|
118
|
+
sectionVariant: sectionVariant
|
|
115
119
|
});
|
|
116
120
|
}
|
|
117
121
|
return /*#__PURE__*/ jsx(SinglePageForm, {
|
|
118
122
|
schema: schema,
|
|
119
123
|
context: context,
|
|
120
124
|
customComponents: customComponents,
|
|
121
|
-
disabled: disabled
|
|
125
|
+
disabled: disabled,
|
|
126
|
+
sectionVariant: sectionVariant
|
|
122
127
|
});
|
|
123
128
|
};
|
|
124
129
|
return /*#__PURE__*/ jsx(FormProvider, {
|
|
@@ -138,20 +143,21 @@ function MetadataForm({ schema, plugins = DEFAULT_PLUGINS, onSubmit, className,
|
|
|
138
143
|
})
|
|
139
144
|
});
|
|
140
145
|
}
|
|
141
|
-
function SinglePageForm({ schema, context, customComponents, disabled }) {
|
|
146
|
+
function SinglePageForm({ schema, context, customComponents, disabled, sectionVariant }) {
|
|
142
147
|
const sections = schema.sections || [];
|
|
143
148
|
const visibleSections = sections.filter((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
144
149
|
return /*#__PURE__*/ jsx("div", {
|
|
145
|
-
className:
|
|
150
|
+
className: 'plain' === sectionVariant ? void 0 : 'space-y-2',
|
|
146
151
|
children: visibleSections.map((section)=>/*#__PURE__*/ jsx(FormSection, {
|
|
147
152
|
section: section,
|
|
148
153
|
context: context,
|
|
149
154
|
customComponents: customComponents,
|
|
150
|
-
disabled: disabled
|
|
155
|
+
disabled: disabled,
|
|
156
|
+
sectionVariant: sectionVariant
|
|
151
157
|
}, section.id))
|
|
152
158
|
});
|
|
153
159
|
}
|
|
154
|
-
function MultiStepForm({ schema, context, currentStep, setCurrentStep, customComponents, disabled }) {
|
|
160
|
+
function MultiStepForm({ schema, context, currentStep, setCurrentStep, customComponents, disabled, sectionVariant }) {
|
|
155
161
|
const steps = schema.steps || [];
|
|
156
162
|
const step = steps[currentStep];
|
|
157
163
|
if (!step) return null;
|
|
@@ -189,12 +195,13 @@ function MultiStepForm({ schema, context, currentStep, setCurrentStep, customCom
|
|
|
189
195
|
]
|
|
190
196
|
}),
|
|
191
197
|
/*#__PURE__*/ jsx("div", {
|
|
192
|
-
className:
|
|
198
|
+
className: 'plain' === sectionVariant ? void 0 : 'space-y-2',
|
|
193
199
|
children: step.sections.map((section)=>/*#__PURE__*/ jsx(FormSection, {
|
|
194
200
|
section: section,
|
|
195
201
|
context: context,
|
|
196
202
|
customComponents: customComponents,
|
|
197
|
-
disabled: disabled
|
|
203
|
+
disabled: disabled,
|
|
204
|
+
sectionVariant: sectionVariant
|
|
198
205
|
}, section.id))
|
|
199
206
|
}),
|
|
200
207
|
/*#__PURE__*/ jsxs("div", {
|
|
@@ -222,15 +229,39 @@ function MultiStepForm({ schema, context, currentStep, setCurrentStep, customCom
|
|
|
222
229
|
]
|
|
223
230
|
});
|
|
224
231
|
}
|
|
225
|
-
function TabbedStepForm({ schema, context, customComponents, disabled, onReset }) {
|
|
232
|
+
function TabbedStepForm({ schema, context, customComponents, disabled, sectionVariant, onReset, activeStepId, onActiveStepChange }) {
|
|
226
233
|
const steps = schema.steps || [];
|
|
227
|
-
const visibleSteps = steps.filter((step)=>
|
|
228
|
-
|
|
229
|
-
|
|
234
|
+
const visibleSteps = steps.filter((step)=>{
|
|
235
|
+
if (step.conditions && !context.evaluateConditions(step.conditions)) return false;
|
|
236
|
+
const hasVisibleSection = step.sections.some((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
237
|
+
return hasVisibleSection || void 0 !== step.emptyState;
|
|
238
|
+
});
|
|
239
|
+
const formState = useFormState({
|
|
240
|
+
control: context.form.control
|
|
241
|
+
});
|
|
242
|
+
const errorCountByStepId = {};
|
|
243
|
+
for (const step of visibleSteps){
|
|
244
|
+
let count = 0;
|
|
245
|
+
for (const section of step.sections)if (!section.conditions || context.evaluateConditions(section.conditions)) for (const field of section.fields){
|
|
246
|
+
if (field.rules && !RulesEngine.isFieldVisible(field.rules, context.values)) continue;
|
|
247
|
+
const fieldError = context.form.getFieldState(field.name, formState).error;
|
|
248
|
+
if (fieldError) count += Array.isArray(fieldError) ? fieldError.filter(Boolean).length : 1;
|
|
249
|
+
}
|
|
250
|
+
errorCountByStepId[step.id] = count;
|
|
251
|
+
}
|
|
252
|
+
const [internalTab, setInternalTab] = useState('');
|
|
253
|
+
const controlled = void 0 !== activeStepId;
|
|
254
|
+
const requestedTab = controlled ? activeStepId : internalTab;
|
|
255
|
+
const currentTab = visibleSteps.some((step)=>step.id === requestedTab) ? requestedTab : visibleSteps[0]?.id ?? '';
|
|
256
|
+
const selectTab = (stepId)=>{
|
|
257
|
+
if (!controlled) setInternalTab(stepId);
|
|
258
|
+
onActiveStepChange?.(stepId);
|
|
259
|
+
};
|
|
230
260
|
useEffect(()=>{
|
|
231
|
-
if (
|
|
261
|
+
if (!controlled && internalTab !== currentTab) setInternalTab(currentTab);
|
|
232
262
|
}, [
|
|
233
|
-
|
|
263
|
+
controlled,
|
|
264
|
+
internalTab,
|
|
234
265
|
currentTab
|
|
235
266
|
]);
|
|
236
267
|
if (0 === visibleSteps.length) return null;
|
|
@@ -238,27 +269,53 @@ function TabbedStepForm({ schema, context, customComponents, disabled, onReset }
|
|
|
238
269
|
children: [
|
|
239
270
|
/*#__PURE__*/ jsxs(Tabs, {
|
|
240
271
|
value: currentTab,
|
|
241
|
-
onValueChange:
|
|
242
|
-
className: "flex flex-col gap-
|
|
272
|
+
onValueChange: selectTab,
|
|
273
|
+
className: "flex min-h-0 flex-1 flex-col gap-1",
|
|
243
274
|
children: [
|
|
244
|
-
/*#__PURE__*/ jsx(
|
|
245
|
-
className: "
|
|
246
|
-
children:
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
275
|
+
/*#__PURE__*/ jsx("div", {
|
|
276
|
+
className: "shrink-0 pt-3 [padding-inline:var(--mf-content-inset,0px)]",
|
|
277
|
+
children: /*#__PURE__*/ jsx(ScrollableTabsList, {
|
|
278
|
+
className: "h-auto justify-start gap-0.5 rounded-lg bg-transparent px-0 py-0.5 text-muted-foreground",
|
|
279
|
+
scrollButtonClassName: "size-6 hover:bg-surface-overlay",
|
|
280
|
+
children: visibleSteps.map((step)=>{
|
|
281
|
+
const errorCount = errorCountByStepId[step.id] ?? 0;
|
|
282
|
+
return /*#__PURE__*/ jsxs(TabsTrigger, {
|
|
283
|
+
value: step.id,
|
|
284
|
+
className: "inline-flex h-6 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md px-2.5 text-xs font-medium text-muted-foreground shadow-none transition-colors hover:text-foreground data-[state=active]:bg-surface-overlay data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
285
|
+
children: [
|
|
286
|
+
step.title,
|
|
287
|
+
errorCount > 0 && /*#__PURE__*/ jsx("span", {
|
|
288
|
+
role: "img",
|
|
289
|
+
"aria-label": `${errorCount} ${1 === errorCount ? 'issue' : 'issues'}`,
|
|
290
|
+
title: `${errorCount} ${1 === errorCount ? 'issue' : 'issues'}`,
|
|
291
|
+
className: "grid h-4 min-w-4 place-items-center rounded-full bg-error px-1 text-[10px] font-semibold leading-none text-foreground-on-accent",
|
|
292
|
+
children: errorCount
|
|
293
|
+
})
|
|
294
|
+
]
|
|
295
|
+
}, step.id);
|
|
296
|
+
})
|
|
297
|
+
})
|
|
251
298
|
}),
|
|
252
|
-
visibleSteps.map((step)
|
|
299
|
+
visibleSteps.map((step)=>{
|
|
300
|
+
const stepSections = step.sections.filter((section)=>!section.conditions || context.evaluateConditions(section.conditions));
|
|
301
|
+
return /*#__PURE__*/ jsx(TabsContent, {
|
|
253
302
|
value: step.id,
|
|
254
|
-
className: "
|
|
255
|
-
children: step.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
303
|
+
className: "mt-0 min-h-0 flex-1 overflow-auto",
|
|
304
|
+
children: 0 === stepSections.length && void 0 !== step.emptyState ? /*#__PURE__*/ jsx("div", {
|
|
305
|
+
className: "pt-4 text-sm text-muted-foreground [padding-inline:var(--mf-content-inset,0px)]",
|
|
306
|
+
children: step.emptyState
|
|
307
|
+
}) : /*#__PURE__*/ jsx("div", {
|
|
308
|
+
className: 'plain' === sectionVariant ? 'pb-6 [padding-inline:var(--mf-content-inset,0px)]' : 'space-y-2 pb-6 pt-4 [padding-inline:var(--mf-content-inset,0px)]',
|
|
309
|
+
children: stepSections.map((section)=>/*#__PURE__*/ jsx(FormSection, {
|
|
310
|
+
section: section,
|
|
311
|
+
context: context,
|
|
312
|
+
customComponents: customComponents,
|
|
313
|
+
disabled: disabled,
|
|
314
|
+
sectionVariant: sectionVariant
|
|
315
|
+
}, section.id))
|
|
316
|
+
})
|
|
317
|
+
}, step.id);
|
|
318
|
+
})
|
|
262
319
|
]
|
|
263
320
|
}),
|
|
264
321
|
/*#__PURE__*/ jsx(FormActions, {
|
|
@@ -269,9 +326,13 @@ function TabbedStepForm({ schema, context, customComponents, disabled, onReset }
|
|
|
269
326
|
]
|
|
270
327
|
});
|
|
271
328
|
}
|
|
272
|
-
function FormSection({ section, context, customComponents, disabled }) {
|
|
329
|
+
function FormSection({ section, context, customComponents, disabled, sectionVariant = 'card' }) {
|
|
273
330
|
const gridColumns = context.schema.layout?.columns || 1;
|
|
274
331
|
const gap = context.schema.layout?.gap || 4;
|
|
332
|
+
const isPlain = 'plain' === sectionVariant;
|
|
333
|
+
const dividerClassName = 'border-t first:border-t-0';
|
|
334
|
+
const wrapperClassName = isPlain ? 'border-b-0' : 'border rounded-lg px-3';
|
|
335
|
+
const triggerClassName = isPlain ? 'justify-start gap-2 py-4 text-sm font-semibold hover:no-underline' : 'text-sm font-medium';
|
|
275
336
|
const fieldsGrid = /*#__PURE__*/ jsx("div", {
|
|
276
337
|
className: "grid",
|
|
277
338
|
style: {
|
|
@@ -285,7 +346,10 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
285
346
|
disabled: disabled
|
|
286
347
|
}, field.name))
|
|
287
348
|
});
|
|
288
|
-
if (!section.title) return
|
|
349
|
+
if (!section.title) return isPlain ? /*#__PURE__*/ jsx("div", {
|
|
350
|
+
className: `${dividerClassName} pb-4 pt-4`,
|
|
351
|
+
children: fieldsGrid
|
|
352
|
+
}) : fieldsGrid;
|
|
289
353
|
const innerContent = /*#__PURE__*/ jsxs("div", {
|
|
290
354
|
className: "flex flex-col gap-4",
|
|
291
355
|
children: [
|
|
@@ -303,12 +367,13 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
303
367
|
return /*#__PURE__*/ jsx(Accordion, {
|
|
304
368
|
type: "multiple",
|
|
305
369
|
defaultValue: defaultValue,
|
|
370
|
+
className: isPlain ? dividerClassName : void 0,
|
|
306
371
|
children: /*#__PURE__*/ jsxs(AccordionItem, {
|
|
307
372
|
value: section.id,
|
|
308
|
-
className:
|
|
373
|
+
className: wrapperClassName,
|
|
309
374
|
children: [
|
|
310
375
|
/*#__PURE__*/ jsx(AccordionTrigger, {
|
|
311
|
-
className:
|
|
376
|
+
className: triggerClassName,
|
|
312
377
|
children: section.title
|
|
313
378
|
}),
|
|
314
379
|
/*#__PURE__*/ jsx(AccordionContent, {
|
|
@@ -319,12 +384,12 @@ function FormSection({ section, context, customComponents, disabled }) {
|
|
|
319
384
|
});
|
|
320
385
|
}
|
|
321
386
|
return /*#__PURE__*/ jsxs("div", {
|
|
322
|
-
className:
|
|
387
|
+
className: isPlain ? dividerClassName : wrapperClassName,
|
|
323
388
|
children: [
|
|
324
389
|
/*#__PURE__*/ jsx("div", {
|
|
325
390
|
className: "flex",
|
|
326
391
|
children: /*#__PURE__*/ jsx("div", {
|
|
327
|
-
className:
|
|
392
|
+
className: isPlain ? 'flex flex-1 items-center justify-start gap-2 py-4 text-sm font-semibold' : 'flex flex-1 items-center justify-between py-4 text-sm font-medium',
|
|
328
393
|
children: section.title
|
|
329
394
|
})
|
|
330
395
|
}),
|
|
@@ -45,6 +45,7 @@ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
|
45
45
|
const react_dropdown_menu_namespaceObject = require("@radix-ui/react-dropdown-menu");
|
|
46
46
|
const external_lucide_react_namespaceObject = require("lucide-react");
|
|
47
47
|
const external_react_namespaceObject = require("react");
|
|
48
|
+
const external_portal_container_cjs_namespaceObject = require("./portal-container.cjs");
|
|
48
49
|
const index_cjs_namespaceObject = require("../../lib/index.cjs");
|
|
49
50
|
const DropdownMenu = react_dropdown_menu_namespaceObject.Root;
|
|
50
51
|
const DropdownMenuTrigger = react_dropdown_menu_namespaceObject.Trigger;
|
|
@@ -70,14 +71,18 @@ const DropdownMenuSubContent = /*#__PURE__*/ external_react_namespaceObject.forw
|
|
|
70
71
|
...props
|
|
71
72
|
}));
|
|
72
73
|
DropdownMenuSubContent.displayName = react_dropdown_menu_namespaceObject.SubContent.displayName;
|
|
73
|
-
const DropdownMenuContent = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ className, sideOffset = 4, ...props }, ref)
|
|
74
|
+
const DropdownMenuContent = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ className, sideOffset = 4, container, ...props }, ref)=>{
|
|
75
|
+
const resolvedContainer = (0, external_portal_container_cjs_namespaceObject.useResolvedPortalContainer)(container);
|
|
76
|
+
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(react_dropdown_menu_namespaceObject.Portal, {
|
|
77
|
+
container: resolvedContainer,
|
|
74
78
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(react_dropdown_menu_namespaceObject.Content, {
|
|
75
79
|
ref: ref,
|
|
76
80
|
sideOffset: sideOffset,
|
|
77
81
|
className: (0, index_cjs_namespaceObject.cn)('z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md future:rounded-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]', className),
|
|
78
82
|
...props
|
|
79
83
|
})
|
|
80
|
-
})
|
|
84
|
+
});
|
|
85
|
+
});
|
|
81
86
|
DropdownMenuContent.displayName = react_dropdown_menu_namespaceObject.Content.displayName;
|
|
82
87
|
const DropdownMenuItem = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ className, inset, ...props }, ref)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(react_dropdown_menu_namespaceObject.Item, {
|
|
83
88
|
ref: ref,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { type PortalContainerOverride } from './portal-container';
|
|
3
4
|
declare const DropdownMenu: React.FC<DropdownMenuPrimitive.DropdownMenuProps>;
|
|
4
5
|
declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
5
6
|
declare const DropdownMenuGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -10,7 +11,9 @@ declare const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<Omit<Dropd
|
|
|
10
11
|
inset?: boolean;
|
|
11
12
|
} & React.RefAttributes<HTMLDivElement>>;
|
|
12
13
|
declare const DropdownMenuSubContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
13
|
-
declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> &
|
|
14
|
+
declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
15
|
+
container?: PortalContainerOverride;
|
|
16
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
14
17
|
declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
15
18
|
inset?: boolean;
|
|
16
19
|
} & React.RefAttributes<HTMLDivElement>>;
|