@squaredr/fieldcraft-pro 1.8.0 → 1.9.1
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/{chunk-IW654Z3M.mjs → chunk-5QXKDYWY.mjs} +92 -5
- package/dist/{chunk-MLP5EDWP.mjs → chunk-7GPX3YIB.mjs} +35 -61
- package/dist/{chunk-GXKQCXIB.mjs → chunk-DWRLPGX5.mjs} +395 -86
- package/dist/{chunk-CYXJGOQH.mjs → chunk-KTIU7VCP.mjs} +68 -9
- package/dist/default-schema-BGxf9Jrg.d.ts +174 -0
- package/dist/default-schema-Bwq8FATF.d.mts +174 -0
- package/dist/form-builder/index.d.mts +14 -170
- package/dist/form-builder/index.d.ts +14 -170
- package/dist/form-builder/index.js +396 -85
- package/dist/form-builder/index.mjs +1 -1
- package/dist/index.d.mts +109 -8
- package/dist/index.d.ts +109 -8
- package/dist/index.js +1697 -217
- package/dist/index.mjs +1106 -11
- package/dist/response-viewer/index.js +36 -61
- package/dist/response-viewer/index.mjs +1 -1
- package/dist/styles.css +2 -2
- package/dist/templates/index.d.mts +1 -1
- package/dist/templates/index.d.ts +1 -1
- package/dist/templates/index.js +92 -5
- package/dist/templates/index.mjs +1 -1
- package/dist/theme-editor/index.d.mts +1 -2
- package/dist/theme-editor/index.d.ts +1 -2
- package/dist/theme-editor/index.js +68 -9
- package/dist/theme-editor/index.mjs +1 -1
- package/dist/{types-bFHsZT1n.d.mts → types-BQOeI3LX.d.mts} +1 -1
- package/dist/{types-bFHsZT1n.d.ts → types-BQOeI3LX.d.ts} +1 -1
- package/package.json +20 -20
- package/theme-editor/styles.css +29 -0
|
@@ -419,16 +419,20 @@ function deepMerge(base, partial) {
|
|
|
419
419
|
|
|
420
420
|
// src/theme-editor/palette-generator.ts
|
|
421
421
|
function generatePalette(baseHex) {
|
|
422
|
+
const cleaned = baseHex.replace("#", "");
|
|
423
|
+
if (!/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(cleaned)) {
|
|
424
|
+
return generatePalette("#6B7280");
|
|
425
|
+
}
|
|
422
426
|
const [h, s, l] = hexToHsl(baseHex);
|
|
423
427
|
const secH = (h + 180) % 360;
|
|
424
428
|
const isLightBase = l > 50;
|
|
425
429
|
return {
|
|
426
430
|
// Primary
|
|
427
431
|
primary: hslToHex(h, s, clamp(l, 30, 60)),
|
|
428
|
-
primaryForeground: isLightBase ? "#ffffff" : "#
|
|
432
|
+
primaryForeground: isLightBase ? "#ffffff" : "#000000",
|
|
429
433
|
// Secondary (complementary)
|
|
430
434
|
secondary: hslToHex(secH, Math.max(s - 15, 10), clamp(l, 35, 55)),
|
|
431
|
-
secondaryForeground: "#ffffff",
|
|
435
|
+
secondaryForeground: isLightBase ? "#ffffff" : "#000000",
|
|
432
436
|
// Surfaces
|
|
433
437
|
surface: hslToHex(h, Math.max(s - 35, 3), 97),
|
|
434
438
|
background: "#F4F7F8",
|
|
@@ -1474,6 +1478,12 @@ function resolveThemeFromDOM() {
|
|
|
1474
1478
|
const val = styles.getPropertyValue(prop).trim();
|
|
1475
1479
|
return val || void 0;
|
|
1476
1480
|
};
|
|
1481
|
+
const getNumber = (prop) => {
|
|
1482
|
+
const val = get(prop);
|
|
1483
|
+
if (val == null) return void 0;
|
|
1484
|
+
const num = parseFloat(val);
|
|
1485
|
+
return isNaN(num) ? void 0 : num;
|
|
1486
|
+
};
|
|
1477
1487
|
return {
|
|
1478
1488
|
colors: {
|
|
1479
1489
|
primary: get("--primary"),
|
|
@@ -1506,6 +1516,17 @@ function resolveThemeFromDOM() {
|
|
|
1506
1516
|
inputRadius: get("--fc-radius-input"),
|
|
1507
1517
|
buttonRadius: get("--fc-radius-button"),
|
|
1508
1518
|
cardRadius: get("--fc-radius-card")
|
|
1519
|
+
},
|
|
1520
|
+
spacing: {
|
|
1521
|
+
base: getNumber("--fc-spacing-base"),
|
|
1522
|
+
sectionGap: getNumber("--fc-section-gap"),
|
|
1523
|
+
fieldGap: getNumber("--fc-field-gap"),
|
|
1524
|
+
inputPaddingX: getNumber("--fc-input-padding-x"),
|
|
1525
|
+
inputPaddingY: getNumber("--fc-input-padding-y")
|
|
1526
|
+
},
|
|
1527
|
+
layout: {
|
|
1528
|
+
maxWidth: get("--fc-max-width")
|
|
1529
|
+
// alignment, progressPosition, sectionLayout are enums — not resolvable from CSS
|
|
1509
1530
|
}
|
|
1510
1531
|
};
|
|
1511
1532
|
}
|
|
@@ -1560,6 +1581,9 @@ function detectPresetFamily(theme) {
|
|
|
1560
1581
|
}
|
|
1561
1582
|
return null;
|
|
1562
1583
|
}
|
|
1584
|
+
function isValidHex(value) {
|
|
1585
|
+
return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
|
|
1586
|
+
}
|
|
1563
1587
|
var SECTIONS = [
|
|
1564
1588
|
{
|
|
1565
1589
|
id: "colors",
|
|
@@ -1810,6 +1834,7 @@ function ThemeEditorInner({
|
|
|
1810
1834
|
a.click();
|
|
1811
1835
|
URL.revokeObjectURL(url);
|
|
1812
1836
|
}, [theme]);
|
|
1837
|
+
const [importError, setImportError] = useState(null);
|
|
1813
1838
|
const importJson = useCallback(() => {
|
|
1814
1839
|
const input = document.createElement("input");
|
|
1815
1840
|
input.type = "file";
|
|
@@ -1821,10 +1846,16 @@ function ThemeEditorInner({
|
|
|
1821
1846
|
reader.onload = () => {
|
|
1822
1847
|
try {
|
|
1823
1848
|
const parsed = JSON.parse(reader.result);
|
|
1849
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || !("colors" in parsed || "typography" in parsed || "shape" in parsed || "spacing" in parsed || "layout" in parsed)) {
|
|
1850
|
+
setImportError("Invalid theme file: expected an object with colors, typography, shape, spacing, or layout.");
|
|
1851
|
+
return;
|
|
1852
|
+
}
|
|
1853
|
+
setImportError(null);
|
|
1824
1854
|
setTheme(parsed);
|
|
1825
1855
|
setPresetKey("custom");
|
|
1826
1856
|
onChange?.(parsed, "custom");
|
|
1827
1857
|
} catch {
|
|
1858
|
+
setImportError("Failed to parse JSON file. Please check the file format.");
|
|
1828
1859
|
}
|
|
1829
1860
|
};
|
|
1830
1861
|
reader.readAsText(file);
|
|
@@ -1902,6 +1933,10 @@ function ThemeEditorInner({
|
|
|
1902
1933
|
onSave && /* @__PURE__ */ jsx("button", { onClick: () => onSave(theme, presetKey), className: "fcte-btn fcte-btn--primary", children: "Save" })
|
|
1903
1934
|
] })
|
|
1904
1935
|
] }),
|
|
1936
|
+
importError && /* @__PURE__ */ jsxs("div", { className: "fcte-import-error", role: "alert", children: [
|
|
1937
|
+
/* @__PURE__ */ jsx("span", { children: importError }),
|
|
1938
|
+
/* @__PURE__ */ jsx("button", { onClick: () => setImportError(null), className: "fcte-import-error__close", children: "\xD7" })
|
|
1939
|
+
] }),
|
|
1905
1940
|
showPalette && /* @__PURE__ */ jsx(
|
|
1906
1941
|
PaletteGenerator,
|
|
1907
1942
|
{
|
|
@@ -1935,6 +1970,8 @@ function ThemeEditorInner({
|
|
|
1935
1970
|
/* @__PURE__ */ jsx("div", { className: "fcte-fields", children: currentSection.fields.map((field) => {
|
|
1936
1971
|
const val = sectionValues[field.key];
|
|
1937
1972
|
if (field.kind === "color") {
|
|
1973
|
+
const colorVal = typeof val === "string" ? val : "#000000";
|
|
1974
|
+
const isInvalid = colorVal.length > 0 && !isValidHex(colorVal);
|
|
1938
1975
|
return /* @__PURE__ */ jsxs("div", { className: "fcte-field", children: [
|
|
1939
1976
|
/* @__PURE__ */ jsx("label", { className: "fcte-field__label", children: field.label }),
|
|
1940
1977
|
/* @__PURE__ */ jsxs("div", { className: "fcte-field__color-row", children: [
|
|
@@ -1942,7 +1979,7 @@ function ThemeEditorInner({
|
|
|
1942
1979
|
"input",
|
|
1943
1980
|
{
|
|
1944
1981
|
type: "color",
|
|
1945
|
-
value:
|
|
1982
|
+
value: isValidHex(colorVal) ? colorVal : "#000000",
|
|
1946
1983
|
onChange: (e) => updateField(currentSection.themeKey, field.key, e.target.value),
|
|
1947
1984
|
className: "fcte-field__swatch"
|
|
1948
1985
|
}
|
|
@@ -1951,10 +1988,24 @@ function ThemeEditorInner({
|
|
|
1951
1988
|
"input",
|
|
1952
1989
|
{
|
|
1953
1990
|
type: "text",
|
|
1954
|
-
value:
|
|
1955
|
-
onChange: (e) =>
|
|
1956
|
-
|
|
1957
|
-
|
|
1991
|
+
value: colorVal,
|
|
1992
|
+
onChange: (e) => {
|
|
1993
|
+
const v = e.target.value;
|
|
1994
|
+
if (isValidHex(v)) {
|
|
1995
|
+
updateField(currentSection.themeKey, field.key, v);
|
|
1996
|
+
} else {
|
|
1997
|
+
setTheme((prev) => ({
|
|
1998
|
+
...prev,
|
|
1999
|
+
[currentSection.themeKey]: {
|
|
2000
|
+
...prev[currentSection.themeKey],
|
|
2001
|
+
[field.key]: v
|
|
2002
|
+
}
|
|
2003
|
+
}));
|
|
2004
|
+
}
|
|
2005
|
+
},
|
|
2006
|
+
className: `fcte-field__text${isInvalid ? " fcte-field__text--invalid" : ""}`,
|
|
2007
|
+
spellCheck: false,
|
|
2008
|
+
placeholder: "#RRGGBB"
|
|
1958
2009
|
}
|
|
1959
2010
|
)
|
|
1960
2011
|
] })
|
|
@@ -1983,9 +2034,16 @@ function ThemeEditorInner({
|
|
|
1983
2034
|
{
|
|
1984
2035
|
type: "number",
|
|
1985
2036
|
value: typeof val === "number" ? val : 0,
|
|
1986
|
-
onChange: (e) =>
|
|
2037
|
+
onChange: (e) => {
|
|
2038
|
+
let n = Math.round(Number(e.target.value));
|
|
2039
|
+
if (isNaN(n)) n = 0;
|
|
2040
|
+
if (field.min != null) n = Math.max(field.min, n);
|
|
2041
|
+
if (field.max != null) n = Math.min(field.max, n);
|
|
2042
|
+
updateField(currentSection.themeKey, field.key, n);
|
|
2043
|
+
},
|
|
1987
2044
|
min: field.min,
|
|
1988
2045
|
max: field.max,
|
|
2046
|
+
step: 1,
|
|
1989
2047
|
className: "fcte-field__number"
|
|
1990
2048
|
}
|
|
1991
2049
|
),
|
|
@@ -2003,7 +2061,8 @@ function ThemeEditorInner({
|
|
|
2003
2061
|
onChange: (e) => updateField(currentSection.themeKey, field.key, e.target.value),
|
|
2004
2062
|
placeholder: field.placeholder,
|
|
2005
2063
|
className: "fcte-field__text",
|
|
2006
|
-
spellCheck: false
|
|
2064
|
+
spellCheck: false,
|
|
2065
|
+
maxLength: 200
|
|
2007
2066
|
}
|
|
2008
2067
|
)
|
|
2009
2068
|
] }, field.key);
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { c as FormBuilderProps, F as FormBuilderTheme, e as QuestionTypeInfo, S as SelectedItem, D as DragItem } from './types-BQOeI3LX.js';
|
|
4
|
+
import { FormEngineSchema, Option, Question, Section } from '@squaredr/fieldcraft-core';
|
|
5
|
+
import { ClassValue } from 'clsx';
|
|
6
|
+
import * as _dnd_kit_core from '@dnd-kit/core';
|
|
7
|
+
import { DragStartEvent, DragEndEvent } from '@dnd-kit/core';
|
|
8
|
+
|
|
9
|
+
declare const FormBuilder: react.ComponentType<FormBuilderProps>;
|
|
10
|
+
|
|
11
|
+
declare function useBuilderTheme(): FormBuilderTheme;
|
|
12
|
+
type FormBuilderThemeProviderProps = {
|
|
13
|
+
theme?: FormBuilderTheme;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
};
|
|
16
|
+
declare function FormBuilderThemeProvider({ theme, children }: FormBuilderThemeProviderProps): react.JSX.Element;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Metadata for all question types available in the Pro palette.
|
|
20
|
+
* Icons are lucide-react component names (imported dynamically via ICON_MAP).
|
|
21
|
+
*
|
|
22
|
+
* 44 field types — general-purpose form building.
|
|
23
|
+
* Telehealth-specific fields (15) are in @squaredr/fieldcraft-pro-telehealth.
|
|
24
|
+
*/
|
|
25
|
+
declare const QUESTION_TYPE_INFO: Record<string, QuestionTypeInfo>;
|
|
26
|
+
/**
|
|
27
|
+
* Default palette layout with categories (44 Pro field types).
|
|
28
|
+
* Telehealth fields can be appended via FormBuilder's `palette` prop.
|
|
29
|
+
*/
|
|
30
|
+
declare const DEFAULT_PALETTE: ({
|
|
31
|
+
category: "text";
|
|
32
|
+
label: string;
|
|
33
|
+
types: string[];
|
|
34
|
+
} | {
|
|
35
|
+
category: "numeric";
|
|
36
|
+
label: string;
|
|
37
|
+
types: string[];
|
|
38
|
+
} | {
|
|
39
|
+
category: "selection";
|
|
40
|
+
label: string;
|
|
41
|
+
types: string[];
|
|
42
|
+
} | {
|
|
43
|
+
category: "datetime";
|
|
44
|
+
label: string;
|
|
45
|
+
types: string[];
|
|
46
|
+
} | {
|
|
47
|
+
category: "media";
|
|
48
|
+
label: string;
|
|
49
|
+
types: string[];
|
|
50
|
+
} | {
|
|
51
|
+
category: "content";
|
|
52
|
+
label: string;
|
|
53
|
+
types: string[];
|
|
54
|
+
} | {
|
|
55
|
+
category: "structural";
|
|
56
|
+
label: string;
|
|
57
|
+
types: string[];
|
|
58
|
+
} | {
|
|
59
|
+
category: "advanced";
|
|
60
|
+
label: string;
|
|
61
|
+
types: string[];
|
|
62
|
+
})[];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generate unique IDs for sections, questions, and options.
|
|
66
|
+
* Format: {prefix}_{uuid}
|
|
67
|
+
*/
|
|
68
|
+
declare function generateId(prefix: string): string;
|
|
69
|
+
declare function generateSectionId(): string;
|
|
70
|
+
declare function generateQuestionId(): string;
|
|
71
|
+
declare function generateOptionId(): string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Pure functions for mutating FormEngineSchema.
|
|
75
|
+
* All functions return a new schema object (immutable updates).
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
declare function addSection(schema: FormEngineSchema, section: Section, index: number): FormEngineSchema;
|
|
79
|
+
declare function removeSection(schema: FormEngineSchema, sectionId: string): FormEngineSchema;
|
|
80
|
+
declare function updateSection(schema: FormEngineSchema, sectionId: string, updates: Partial<Section>): FormEngineSchema;
|
|
81
|
+
declare function moveSection(schema: FormEngineSchema, sectionId: string, newIndex: number): FormEngineSchema;
|
|
82
|
+
declare function duplicateSection(schema: FormEngineSchema, sectionId: string): FormEngineSchema;
|
|
83
|
+
declare function addQuestion(schema: FormEngineSchema, sectionId: string, question: Question, index: number): FormEngineSchema;
|
|
84
|
+
declare function removeQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): FormEngineSchema;
|
|
85
|
+
declare function updateQuestion(schema: FormEngineSchema, sectionId: string, questionId: string, updates: Partial<Question>): FormEngineSchema;
|
|
86
|
+
declare function moveQuestion(schema: FormEngineSchema, sectionId: string, questionId: string, targetSectionId: string, newIndex: number): FormEngineSchema;
|
|
87
|
+
declare function duplicateQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): FormEngineSchema;
|
|
88
|
+
declare function addOption(schema: FormEngineSchema, sectionId: string, questionId: string, option: Option, index: number): FormEngineSchema;
|
|
89
|
+
declare function removeOption(schema: FormEngineSchema, sectionId: string, questionId: string, optionIndex: number): FormEngineSchema;
|
|
90
|
+
declare function updateOption(schema: FormEngineSchema, sectionId: string, questionId: string, optionIndex: number, updates: Partial<Option>): FormEngineSchema;
|
|
91
|
+
declare function moveOption(schema: FormEngineSchema, sectionId: string, questionId: string, oldIndex: number, newIndex: number): FormEngineSchema;
|
|
92
|
+
declare function findQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): {
|
|
93
|
+
section: Section;
|
|
94
|
+
question: Question;
|
|
95
|
+
questionIndex: number;
|
|
96
|
+
} | null;
|
|
97
|
+
declare function findSection(schema: FormEngineSchema, sectionId: string): {
|
|
98
|
+
section: Section;
|
|
99
|
+
sectionIndex: number;
|
|
100
|
+
} | null;
|
|
101
|
+
|
|
102
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Master state hook for the FormBuilder.
|
|
106
|
+
* Combines schema state, selection, and undo/redo.
|
|
107
|
+
*
|
|
108
|
+
* All mutation callbacks use a ref to read the latest schema,
|
|
109
|
+
* avoiding stale closures when multiple mutations fire in the
|
|
110
|
+
* same render tick.
|
|
111
|
+
*/
|
|
112
|
+
declare function useBuilderState(initialSchema: FormEngineSchema): {
|
|
113
|
+
schema: FormEngineSchema;
|
|
114
|
+
selectedItem: SelectedItem | null;
|
|
115
|
+
isDirty: boolean;
|
|
116
|
+
updateSchema: (newSchema: FormEngineSchema) => void;
|
|
117
|
+
addSection: (section: Section, index: number) => void;
|
|
118
|
+
removeSection: (sectionId: string) => void;
|
|
119
|
+
updateSection: (sectionId: string, updates: Partial<Section>) => void;
|
|
120
|
+
moveSection: (sectionId: string, newIndex: number) => void;
|
|
121
|
+
duplicateSection: (sectionId: string) => void;
|
|
122
|
+
addQuestion: (sectionId: string, question: Question, index: number) => void;
|
|
123
|
+
removeQuestion: (sectionId: string, questionId: string) => void;
|
|
124
|
+
updateQuestion: (sectionId: string, questionId: string, updates: Partial<Question>) => void;
|
|
125
|
+
moveQuestion: (sectionId: string, questionId: string, targetSectionId: string, newIndex: number) => void;
|
|
126
|
+
duplicateQuestion: (sectionId: string, questionId: string) => void;
|
|
127
|
+
selectQuestion: (sectionId: string, questionId: string) => void;
|
|
128
|
+
selectSection: (sectionId: string) => void;
|
|
129
|
+
clearSelection: () => void;
|
|
130
|
+
canUndo: boolean;
|
|
131
|
+
canRedo: boolean;
|
|
132
|
+
undo: () => void;
|
|
133
|
+
redo: () => void;
|
|
134
|
+
resetSchema: (newSchema: FormEngineSchema) => void;
|
|
135
|
+
markClean: () => void;
|
|
136
|
+
};
|
|
137
|
+
type BuilderStateHook = ReturnType<typeof useBuilderState>;
|
|
138
|
+
|
|
139
|
+
type UndoRedoState = {
|
|
140
|
+
canUndo: boolean;
|
|
141
|
+
canRedo: boolean;
|
|
142
|
+
undo: () => void;
|
|
143
|
+
redo: () => void;
|
|
144
|
+
push: (schema: FormEngineSchema) => void;
|
|
145
|
+
clear: () => void;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Hook for undo/redo functionality.
|
|
149
|
+
* Maintains a history stack of schemas with max 50 entries.
|
|
150
|
+
* Uses state for the index so canUndo/canRedo trigger re-renders.
|
|
151
|
+
* The history array is kept in a ref since its identity doesn't
|
|
152
|
+
* need to cause re-renders — only the index matters.
|
|
153
|
+
*/
|
|
154
|
+
declare function useUndoRedo(currentSchema: FormEngineSchema, setSchema: (schema: FormEngineSchema) => void): UndoRedoState;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Hook to wire up @dnd-kit drag-and-drop.
|
|
158
|
+
* Returns DndContext props and handlers.
|
|
159
|
+
*/
|
|
160
|
+
declare function useDragDrop(builderState: BuilderStateHook): {
|
|
161
|
+
sensors: _dnd_kit_core.SensorDescriptor<_dnd_kit_core.SensorOptions>[];
|
|
162
|
+
handleDragStart: (event: DragStartEvent) => void;
|
|
163
|
+
handleDragEnd: (event: DragEndEvent) => void;
|
|
164
|
+
handleDragCancel: () => void;
|
|
165
|
+
activeDragItem: DragItem | null;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Default empty schema for new forms.
|
|
170
|
+
* Contains one section with one question to get started.
|
|
171
|
+
*/
|
|
172
|
+
declare const DEFAULT_SCHEMA: FormEngineSchema;
|
|
173
|
+
|
|
174
|
+
export { useUndoRedo as A, type BuilderStateHook as B, DEFAULT_PALETTE as D, FormBuilder as F, QUESTION_TYPE_INFO as Q, type UndoRedoState as U, DEFAULT_SCHEMA as a, FormBuilderThemeProvider as b, addOption as c, addQuestion as d, addSection as e, cn as f, duplicateQuestion as g, duplicateSection as h, findQuestion as i, findSection as j, generateId as k, generateOptionId as l, generateQuestionId as m, generateSectionId as n, moveOption as o, moveQuestion as p, moveSection as q, removeOption as r, removeQuestion as s, removeSection as t, updateOption as u, updateQuestion as v, updateSection as w, useBuilderState as x, useBuilderTheme as y, useDragDrop as z };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { c as FormBuilderProps, F as FormBuilderTheme, e as QuestionTypeInfo, S as SelectedItem, D as DragItem } from './types-BQOeI3LX.mjs';
|
|
4
|
+
import { FormEngineSchema, Option, Question, Section } from '@squaredr/fieldcraft-core';
|
|
5
|
+
import { ClassValue } from 'clsx';
|
|
6
|
+
import * as _dnd_kit_core from '@dnd-kit/core';
|
|
7
|
+
import { DragStartEvent, DragEndEvent } from '@dnd-kit/core';
|
|
8
|
+
|
|
9
|
+
declare const FormBuilder: react.ComponentType<FormBuilderProps>;
|
|
10
|
+
|
|
11
|
+
declare function useBuilderTheme(): FormBuilderTheme;
|
|
12
|
+
type FormBuilderThemeProviderProps = {
|
|
13
|
+
theme?: FormBuilderTheme;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
};
|
|
16
|
+
declare function FormBuilderThemeProvider({ theme, children }: FormBuilderThemeProviderProps): react.JSX.Element;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Metadata for all question types available in the Pro palette.
|
|
20
|
+
* Icons are lucide-react component names (imported dynamically via ICON_MAP).
|
|
21
|
+
*
|
|
22
|
+
* 44 field types — general-purpose form building.
|
|
23
|
+
* Telehealth-specific fields (15) are in @squaredr/fieldcraft-pro-telehealth.
|
|
24
|
+
*/
|
|
25
|
+
declare const QUESTION_TYPE_INFO: Record<string, QuestionTypeInfo>;
|
|
26
|
+
/**
|
|
27
|
+
* Default palette layout with categories (44 Pro field types).
|
|
28
|
+
* Telehealth fields can be appended via FormBuilder's `palette` prop.
|
|
29
|
+
*/
|
|
30
|
+
declare const DEFAULT_PALETTE: ({
|
|
31
|
+
category: "text";
|
|
32
|
+
label: string;
|
|
33
|
+
types: string[];
|
|
34
|
+
} | {
|
|
35
|
+
category: "numeric";
|
|
36
|
+
label: string;
|
|
37
|
+
types: string[];
|
|
38
|
+
} | {
|
|
39
|
+
category: "selection";
|
|
40
|
+
label: string;
|
|
41
|
+
types: string[];
|
|
42
|
+
} | {
|
|
43
|
+
category: "datetime";
|
|
44
|
+
label: string;
|
|
45
|
+
types: string[];
|
|
46
|
+
} | {
|
|
47
|
+
category: "media";
|
|
48
|
+
label: string;
|
|
49
|
+
types: string[];
|
|
50
|
+
} | {
|
|
51
|
+
category: "content";
|
|
52
|
+
label: string;
|
|
53
|
+
types: string[];
|
|
54
|
+
} | {
|
|
55
|
+
category: "structural";
|
|
56
|
+
label: string;
|
|
57
|
+
types: string[];
|
|
58
|
+
} | {
|
|
59
|
+
category: "advanced";
|
|
60
|
+
label: string;
|
|
61
|
+
types: string[];
|
|
62
|
+
})[];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generate unique IDs for sections, questions, and options.
|
|
66
|
+
* Format: {prefix}_{uuid}
|
|
67
|
+
*/
|
|
68
|
+
declare function generateId(prefix: string): string;
|
|
69
|
+
declare function generateSectionId(): string;
|
|
70
|
+
declare function generateQuestionId(): string;
|
|
71
|
+
declare function generateOptionId(): string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Pure functions for mutating FormEngineSchema.
|
|
75
|
+
* All functions return a new schema object (immutable updates).
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
declare function addSection(schema: FormEngineSchema, section: Section, index: number): FormEngineSchema;
|
|
79
|
+
declare function removeSection(schema: FormEngineSchema, sectionId: string): FormEngineSchema;
|
|
80
|
+
declare function updateSection(schema: FormEngineSchema, sectionId: string, updates: Partial<Section>): FormEngineSchema;
|
|
81
|
+
declare function moveSection(schema: FormEngineSchema, sectionId: string, newIndex: number): FormEngineSchema;
|
|
82
|
+
declare function duplicateSection(schema: FormEngineSchema, sectionId: string): FormEngineSchema;
|
|
83
|
+
declare function addQuestion(schema: FormEngineSchema, sectionId: string, question: Question, index: number): FormEngineSchema;
|
|
84
|
+
declare function removeQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): FormEngineSchema;
|
|
85
|
+
declare function updateQuestion(schema: FormEngineSchema, sectionId: string, questionId: string, updates: Partial<Question>): FormEngineSchema;
|
|
86
|
+
declare function moveQuestion(schema: FormEngineSchema, sectionId: string, questionId: string, targetSectionId: string, newIndex: number): FormEngineSchema;
|
|
87
|
+
declare function duplicateQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): FormEngineSchema;
|
|
88
|
+
declare function addOption(schema: FormEngineSchema, sectionId: string, questionId: string, option: Option, index: number): FormEngineSchema;
|
|
89
|
+
declare function removeOption(schema: FormEngineSchema, sectionId: string, questionId: string, optionIndex: number): FormEngineSchema;
|
|
90
|
+
declare function updateOption(schema: FormEngineSchema, sectionId: string, questionId: string, optionIndex: number, updates: Partial<Option>): FormEngineSchema;
|
|
91
|
+
declare function moveOption(schema: FormEngineSchema, sectionId: string, questionId: string, oldIndex: number, newIndex: number): FormEngineSchema;
|
|
92
|
+
declare function findQuestion(schema: FormEngineSchema, sectionId: string, questionId: string): {
|
|
93
|
+
section: Section;
|
|
94
|
+
question: Question;
|
|
95
|
+
questionIndex: number;
|
|
96
|
+
} | null;
|
|
97
|
+
declare function findSection(schema: FormEngineSchema, sectionId: string): {
|
|
98
|
+
section: Section;
|
|
99
|
+
sectionIndex: number;
|
|
100
|
+
} | null;
|
|
101
|
+
|
|
102
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Master state hook for the FormBuilder.
|
|
106
|
+
* Combines schema state, selection, and undo/redo.
|
|
107
|
+
*
|
|
108
|
+
* All mutation callbacks use a ref to read the latest schema,
|
|
109
|
+
* avoiding stale closures when multiple mutations fire in the
|
|
110
|
+
* same render tick.
|
|
111
|
+
*/
|
|
112
|
+
declare function useBuilderState(initialSchema: FormEngineSchema): {
|
|
113
|
+
schema: FormEngineSchema;
|
|
114
|
+
selectedItem: SelectedItem | null;
|
|
115
|
+
isDirty: boolean;
|
|
116
|
+
updateSchema: (newSchema: FormEngineSchema) => void;
|
|
117
|
+
addSection: (section: Section, index: number) => void;
|
|
118
|
+
removeSection: (sectionId: string) => void;
|
|
119
|
+
updateSection: (sectionId: string, updates: Partial<Section>) => void;
|
|
120
|
+
moveSection: (sectionId: string, newIndex: number) => void;
|
|
121
|
+
duplicateSection: (sectionId: string) => void;
|
|
122
|
+
addQuestion: (sectionId: string, question: Question, index: number) => void;
|
|
123
|
+
removeQuestion: (sectionId: string, questionId: string) => void;
|
|
124
|
+
updateQuestion: (sectionId: string, questionId: string, updates: Partial<Question>) => void;
|
|
125
|
+
moveQuestion: (sectionId: string, questionId: string, targetSectionId: string, newIndex: number) => void;
|
|
126
|
+
duplicateQuestion: (sectionId: string, questionId: string) => void;
|
|
127
|
+
selectQuestion: (sectionId: string, questionId: string) => void;
|
|
128
|
+
selectSection: (sectionId: string) => void;
|
|
129
|
+
clearSelection: () => void;
|
|
130
|
+
canUndo: boolean;
|
|
131
|
+
canRedo: boolean;
|
|
132
|
+
undo: () => void;
|
|
133
|
+
redo: () => void;
|
|
134
|
+
resetSchema: (newSchema: FormEngineSchema) => void;
|
|
135
|
+
markClean: () => void;
|
|
136
|
+
};
|
|
137
|
+
type BuilderStateHook = ReturnType<typeof useBuilderState>;
|
|
138
|
+
|
|
139
|
+
type UndoRedoState = {
|
|
140
|
+
canUndo: boolean;
|
|
141
|
+
canRedo: boolean;
|
|
142
|
+
undo: () => void;
|
|
143
|
+
redo: () => void;
|
|
144
|
+
push: (schema: FormEngineSchema) => void;
|
|
145
|
+
clear: () => void;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Hook for undo/redo functionality.
|
|
149
|
+
* Maintains a history stack of schemas with max 50 entries.
|
|
150
|
+
* Uses state for the index so canUndo/canRedo trigger re-renders.
|
|
151
|
+
* The history array is kept in a ref since its identity doesn't
|
|
152
|
+
* need to cause re-renders — only the index matters.
|
|
153
|
+
*/
|
|
154
|
+
declare function useUndoRedo(currentSchema: FormEngineSchema, setSchema: (schema: FormEngineSchema) => void): UndoRedoState;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Hook to wire up @dnd-kit drag-and-drop.
|
|
158
|
+
* Returns DndContext props and handlers.
|
|
159
|
+
*/
|
|
160
|
+
declare function useDragDrop(builderState: BuilderStateHook): {
|
|
161
|
+
sensors: _dnd_kit_core.SensorDescriptor<_dnd_kit_core.SensorOptions>[];
|
|
162
|
+
handleDragStart: (event: DragStartEvent) => void;
|
|
163
|
+
handleDragEnd: (event: DragEndEvent) => void;
|
|
164
|
+
handleDragCancel: () => void;
|
|
165
|
+
activeDragItem: DragItem | null;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Default empty schema for new forms.
|
|
170
|
+
* Contains one section with one question to get started.
|
|
171
|
+
*/
|
|
172
|
+
declare const DEFAULT_SCHEMA: FormEngineSchema;
|
|
173
|
+
|
|
174
|
+
export { useUndoRedo as A, type BuilderStateHook as B, DEFAULT_PALETTE as D, FormBuilder as F, QUESTION_TYPE_INFO as Q, type UndoRedoState as U, DEFAULT_SCHEMA as a, FormBuilderThemeProvider as b, addOption as c, addQuestion as d, addSection as e, cn as f, duplicateQuestion as g, duplicateSection as h, findQuestion as i, findSection as j, generateId as k, generateOptionId as l, generateQuestionId as m, generateSectionId as n, moveOption as o, moveQuestion as p, moveSection as q, removeOption as r, removeQuestion as s, removeSection as t, updateOption as u, updateQuestion as v, updateSection as w, useBuilderState as x, useBuilderTheme as y, useDragDrop as z };
|