@nextlyhq/plugin-form-builder 0.0.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/LICENSE +22 -0
- package/README.md +122 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js +121 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js.map +1 -0
- package/dist/DateFieldEditor-JFJFAVOH.js +187 -0
- package/dist/DateFieldEditor-JFJFAVOH.js.map +1 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js +138 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js.map +1 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js +175 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js.map +1 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js +165 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js.map +1 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js +213 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js.map +1 -0
- package/dist/TextFieldEditor-5EU64EA5.js +187 -0
- package/dist/TextFieldEditor-5EU64EA5.js.map +1 -0
- package/dist/TextareaFieldEditor-773G3LNM.js +190 -0
- package/dist/TextareaFieldEditor-773G3LNM.js.map +1 -0
- package/dist/admin/index.css +934 -0
- package/dist/admin/index.css.map +1 -0
- package/dist/admin/index.d.ts +547 -0
- package/dist/admin/index.js +4030 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/chunk-ABNZFTQK.js +586 -0
- package/dist/chunk-ABNZFTQK.js.map +1 -0
- package/dist/chunk-XTCEPJ7B.js +256 -0
- package/dist/chunk-XTCEPJ7B.js.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index-C0kBvYjm.d.ts +1012 -0
- package/dist/index.d.ts +1663 -0
- package/dist/index.js +2470 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/form-builder.css +1150 -0
- package/dist/styles/submissions-filter.css +75 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/admin/fields/SelectFieldEditor.tsx"],"sourcesContent":["/**\n * Select Field Editor\n *\n * Editor component for configuring select (dropdown) field properties.\n * Includes general settings, options management with drag-and-drop,\n * allow multiple toggle, default value selection, and validation.\n *\n * @module admin/fields/SelectFieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input } from \"@nextlyhq/ui\";\n\nimport type { SelectFormField } from \"../../types\";\n\nimport { OptionsEditor } from \"./OptionsEditor\";\n\nimport type { FieldEditorProps } from \"./index\";\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * SelectFieldEditor - Configure select (dropdown) field properties\n *\n * Provides configuration options for:\n * - Label: Display text shown above the field\n * - Field Name: Key used in submission data (auto-formatted)\n * - Placeholder: Hint text shown when no option selected\n * - Help Text: Additional guidance shown below the field\n * - Required: Whether the field must be filled\n * - Options: List of label/value pairs with drag-and-drop reordering\n * - Allow Multiple: Enable multi-select functionality\n * - Default Value: Pre-selected option(s)\n * - Validation: Custom error message\n *\n * @example\n * ```tsx\n * <SelectFieldEditor\n * field={selectField}\n * allFields={formFields}\n * onUpdate={(updates) => handleUpdate(updates)}\n * />\n * ```\n */\nexport function SelectFieldEditor({\n field,\n onUpdate,\n}: FieldEditorProps<SelectFormField>) {\n // Helper to update validation properties\n const updateValidation = (key: string, value: unknown) => {\n onUpdate({\n validation: {\n ...field.validation,\n [key]: value,\n },\n });\n };\n\n // Get available options for default value dropdown\n const availableOptions = field.options || [];\n\n return (\n <div className=\"select-field-editor\">\n {/* General Settings Section */}\n <div className=\"select-field-editor__section\">\n <h4 className=\"select-field-editor__section-title\">General</h4>\n\n {/* Label */}\n <div className=\"select-field-editor__field\">\n <label className=\"select-field-editor__label\" htmlFor=\"field-label\">\n Label\n </label>\n <Input\n id=\"field-label\"\n type=\"text\"\n value={field.label || \"\"}\n onChange={e => onUpdate({ label: e.target.value })}\n placeholder=\"Enter field label\"\n />\n </div>\n\n {/* Field Name */}\n <div className=\"select-field-editor__field\">\n <label className=\"select-field-editor__label\" htmlFor=\"field-name\">\n Field Name\n </label>\n <Input\n id=\"field-name\"\n type=\"text\"\n value={field.name || \"\"}\n onChange={e =>\n onUpdate({\n name: e.target.value\n .replace(/\\s+/g, \"_\")\n .replace(/[^a-zA-Z0-9_]/g, \"\")\n .toLowerCase(),\n })\n }\n placeholder=\"field_name\"\n className=\"select-field-editor__input--mono\"\n />\n <p className=\"select-field-editor__hint\">\n Used as the key in submission data. Only letters, numbers, and\n underscores.\n </p>\n </div>\n\n {/* Placeholder */}\n <div className=\"select-field-editor__field\">\n <label\n className=\"select-field-editor__label\"\n htmlFor=\"field-placeholder\"\n >\n Placeholder\n </label>\n <Input\n id=\"field-placeholder\"\n type=\"text\"\n value={field.placeholder || \"\"}\n onChange={e => onUpdate({ placeholder: e.target.value })}\n placeholder=\"Choose an option...\"\n />\n </div>\n\n {/* Help Text */}\n <div className=\"select-field-editor__field\">\n <label className=\"select-field-editor__label\" htmlFor=\"field-help\">\n Help Text\n </label>\n <Input\n id=\"field-help\"\n type=\"text\"\n value={field.helpText || \"\"}\n onChange={e => onUpdate({ helpText: e.target.value })}\n placeholder=\"Additional guidance for users\"\n />\n <p className=\"select-field-editor__hint\">Displayed below the field</p>\n </div>\n\n {/* Required */}\n <div className=\"select-field-editor__field select-field-editor__field--inline\">\n <label className=\"select-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.required || false}\n onChange={e => onUpdate({ required: e.target.checked })}\n className=\"select-field-editor__checkbox\"\n />\n <span>Required field</span>\n </label>\n </div>\n </div>\n\n {/* Options Section */}\n <div className=\"select-field-editor__section\">\n <h4 className=\"select-field-editor__section-title\">Options</h4>\n\n <OptionsEditor\n options={field.options || []}\n onOptionsChange={options => onUpdate({ options })}\n />\n </div>\n\n {/* Settings Section */}\n <div className=\"select-field-editor__section\">\n <h4 className=\"select-field-editor__section-title\">Settings</h4>\n\n {/* Allow Multiple */}\n <div className=\"select-field-editor__field select-field-editor__field--inline\">\n <label className=\"select-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.allowMultiple || false}\n onChange={e => onUpdate({ allowMultiple: e.target.checked })}\n className=\"select-field-editor__checkbox\"\n />\n <span>Allow multiple selections</span>\n </label>\n <p className=\"select-field-editor__hint\">\n Users can select more than one option\n </p>\n </div>\n\n {/* Default Value */}\n <div className=\"select-field-editor__field\">\n <label\n className=\"select-field-editor__label\"\n htmlFor=\"field-default-value\"\n >\n Default Value\n </label>\n {field.allowMultiple ? (\n /* Multi-select: Checkboxes for default values */\n <div className=\"select-field-editor__default-multi\">\n {availableOptions.length > 0 ? (\n availableOptions.map(opt => {\n const currentDefaults = Array.isArray(field.defaultValue)\n ? field.defaultValue\n : [];\n const isSelected = currentDefaults.includes(opt.value);\n\n return (\n <label\n key={opt.value}\n className=\"select-field-editor__default-option\"\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={e => {\n const newDefaults = e.target.checked\n ? [...currentDefaults, opt.value]\n : currentDefaults.filter(v => v !== opt.value);\n onUpdate({\n defaultValue:\n newDefaults.length > 0 ? newDefaults : undefined,\n });\n }}\n className=\"select-field-editor__checkbox\"\n />\n <span>{opt.label}</span>\n </label>\n );\n })\n ) : (\n <p className=\"select-field-editor__hint\">\n Add options above to set default values\n </p>\n )}\n </div>\n ) : (\n /* Single-select: Dropdown for default value */\n <select\n id=\"field-default-value\"\n value={field.defaultValue || \"\"}\n onChange={e =>\n onUpdate({\n defaultValue: e.target.value || undefined,\n })\n }\n className=\"select-field-editor__select\"\n >\n <option value=\"\">No default</option>\n {availableOptions.map(opt => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n )}\n <p className=\"select-field-editor__hint\">\n Pre-selected when the form loads\n </p>\n </div>\n </div>\n\n {/* Validation Section */}\n <div className=\"select-field-editor__section\">\n <h4 className=\"select-field-editor__section-title\">Validation</h4>\n\n {/* Error Message */}\n <div className=\"select-field-editor__field\">\n <label className=\"select-field-editor__label\" htmlFor=\"field-error\">\n Error Message\n </label>\n <Input\n id=\"field-error\"\n type=\"text\"\n value={field.validation?.errorMessage || \"\"}\n onChange={e =>\n updateValidation(\"errorMessage\", e.target.value || undefined)\n }\n placeholder=\"Please select an option\"\n />\n <p className=\"select-field-editor__hint\">\n Custom message shown when validation fails\n </p>\n </div>\n </div>\n </div>\n );\n}\n\nexport default SelectFieldEditor;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/admin/fields/TextFieldEditor.tsx
|
|
4
|
+
import { Input } from "@nextlyhq/ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function TextFieldEditor({
|
|
7
|
+
field,
|
|
8
|
+
onUpdate
|
|
9
|
+
}) {
|
|
10
|
+
const updateValidation = (key, value) => {
|
|
11
|
+
onUpdate({
|
|
12
|
+
validation: {
|
|
13
|
+
...field.validation,
|
|
14
|
+
[key]: value
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", { className: "text-field-editor", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__section", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h4", { className: "text-field-editor__section-title", children: "General" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("label", { className: "text-field-editor__label", htmlFor: "field-label", children: "Label" }),
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
Input,
|
|
25
|
+
{
|
|
26
|
+
id: "field-label",
|
|
27
|
+
type: "text",
|
|
28
|
+
value: field.label || "",
|
|
29
|
+
onChange: (e) => onUpdate({ label: e.target.value }),
|
|
30
|
+
placeholder: "Enter field label"
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] }),
|
|
34
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("label", { className: "text-field-editor__label", htmlFor: "field-name", children: "Field Name" }),
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
Input,
|
|
38
|
+
{
|
|
39
|
+
id: "field-name",
|
|
40
|
+
type: "text",
|
|
41
|
+
value: field.name || "",
|
|
42
|
+
onChange: (e) => onUpdate({
|
|
43
|
+
name: e.target.value.replace(/\s+/g, "_").replace(/[^a-zA-Z0-9_]/g, "").toLowerCase()
|
|
44
|
+
}),
|
|
45
|
+
placeholder: "field_name",
|
|
46
|
+
className: "text-field-editor__input--mono"
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx("p", { className: "text-field-editor__hint", children: "Used as the key in submission data. Only letters, numbers, and underscores." })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"label",
|
|
54
|
+
{
|
|
55
|
+
className: "text-field-editor__label",
|
|
56
|
+
htmlFor: "field-placeholder",
|
|
57
|
+
children: "Placeholder"
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
Input,
|
|
62
|
+
{
|
|
63
|
+
id: "field-placeholder",
|
|
64
|
+
type: "text",
|
|
65
|
+
value: field.placeholder || "",
|
|
66
|
+
onChange: (e) => onUpdate({ placeholder: e.target.value }),
|
|
67
|
+
placeholder: "Enter placeholder text"
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
72
|
+
/* @__PURE__ */ jsx("label", { className: "text-field-editor__label", htmlFor: "field-help", children: "Help Text" }),
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
Input,
|
|
75
|
+
{
|
|
76
|
+
id: "field-help",
|
|
77
|
+
type: "text",
|
|
78
|
+
value: field.helpText || "",
|
|
79
|
+
onChange: (e) => onUpdate({ helpText: e.target.value }),
|
|
80
|
+
placeholder: "Additional guidance for users"
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsx("p", { className: "text-field-editor__hint", children: "Displayed below the field" })
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsx("div", { className: "text-field-editor__field text-field-editor__field--inline", children: /* @__PURE__ */ jsxs("label", { className: "text-field-editor__checkbox-label", children: [
|
|
86
|
+
/* @__PURE__ */ jsx(
|
|
87
|
+
"input",
|
|
88
|
+
{
|
|
89
|
+
type: "checkbox",
|
|
90
|
+
checked: field.required || false,
|
|
91
|
+
onChange: (e) => onUpdate({ required: e.target.checked }),
|
|
92
|
+
className: "text-field-editor__checkbox"
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { children: "Required field" })
|
|
96
|
+
] }) })
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__section", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("h4", { className: "text-field-editor__section-title", children: "Validation" }),
|
|
100
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field-row", children: [
|
|
101
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field text-field-editor__field--half", children: [
|
|
102
|
+
/* @__PURE__ */ jsx(
|
|
103
|
+
"label",
|
|
104
|
+
{
|
|
105
|
+
className: "text-field-editor__label",
|
|
106
|
+
htmlFor: "field-minlength",
|
|
107
|
+
children: "Min Length"
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsx(
|
|
111
|
+
Input,
|
|
112
|
+
{
|
|
113
|
+
id: "field-minlength",
|
|
114
|
+
type: "number",
|
|
115
|
+
min: 0,
|
|
116
|
+
value: field.validation?.minLength ?? "",
|
|
117
|
+
onChange: (e) => updateValidation(
|
|
118
|
+
"minLength",
|
|
119
|
+
e.target.value ? parseInt(e.target.value, 10) : void 0
|
|
120
|
+
),
|
|
121
|
+
placeholder: "0"
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
] }),
|
|
125
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field text-field-editor__field--half", children: [
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
"label",
|
|
128
|
+
{
|
|
129
|
+
className: "text-field-editor__label",
|
|
130
|
+
htmlFor: "field-maxlength",
|
|
131
|
+
children: "Max Length"
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
Input,
|
|
136
|
+
{
|
|
137
|
+
id: "field-maxlength",
|
|
138
|
+
type: "number",
|
|
139
|
+
min: 0,
|
|
140
|
+
value: field.validation?.maxLength ?? "",
|
|
141
|
+
onChange: (e) => updateValidation(
|
|
142
|
+
"maxLength",
|
|
143
|
+
e.target.value ? parseInt(e.target.value, 10) : void 0
|
|
144
|
+
),
|
|
145
|
+
placeholder: "No limit"
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
] })
|
|
149
|
+
] }),
|
|
150
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
151
|
+
/* @__PURE__ */ jsx("label", { className: "text-field-editor__label", htmlFor: "field-pattern", children: "Pattern (Regex)" }),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
Input,
|
|
154
|
+
{
|
|
155
|
+
id: "field-pattern",
|
|
156
|
+
type: "text",
|
|
157
|
+
value: field.validation?.pattern || "",
|
|
158
|
+
onChange: (e) => updateValidation("pattern", e.target.value || void 0),
|
|
159
|
+
placeholder: "^[A-Za-z]+$",
|
|
160
|
+
className: "text-field-editor__input--mono"
|
|
161
|
+
}
|
|
162
|
+
),
|
|
163
|
+
/* @__PURE__ */ jsx("p", { className: "text-field-editor__hint", children: "Regular expression for custom validation" })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "text-field-editor__field", children: [
|
|
166
|
+
/* @__PURE__ */ jsx("label", { className: "text-field-editor__label", htmlFor: "field-error", children: "Error Message" }),
|
|
167
|
+
/* @__PURE__ */ jsx(
|
|
168
|
+
Input,
|
|
169
|
+
{
|
|
170
|
+
id: "field-error",
|
|
171
|
+
type: "text",
|
|
172
|
+
value: field.validation?.errorMessage || "",
|
|
173
|
+
onChange: (e) => updateValidation("errorMessage", e.target.value || void 0),
|
|
174
|
+
placeholder: "Please enter a valid value"
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
/* @__PURE__ */ jsx("p", { className: "text-field-editor__hint", children: "Custom message shown when validation fails" })
|
|
178
|
+
] })
|
|
179
|
+
] })
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
var TextFieldEditor_default = TextFieldEditor;
|
|
183
|
+
export {
|
|
184
|
+
TextFieldEditor,
|
|
185
|
+
TextFieldEditor_default as default
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=TextFieldEditor-5EU64EA5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/admin/fields/TextFieldEditor.tsx"],"sourcesContent":["/**\n * Text Field Editor\n *\n * Editor component for configuring text field properties.\n * Includes general settings (label, name, placeholder, required) and\n * validation options (minLength, maxLength, pattern).\n *\n * @module admin/fields/TextFieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input } from \"@nextlyhq/ui\";\n\nimport type { TextFormField } from \"../../types\";\n\nimport type { FieldEditorProps } from \"./index\";\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * TextFieldEditor - Configure text field properties\n *\n * Provides configuration options for:\n * - Label: Display text shown above the field\n * - Field Name: Key used in submission data (auto-formatted)\n * - Placeholder: Hint text shown when field is empty\n * - Help Text: Additional guidance shown below the field\n * - Required: Whether the field must be filled\n * - Validation: minLength, maxLength, pattern (regex), error message\n *\n * @example\n * ```tsx\n * <TextFieldEditor\n * field={textField}\n * allFields={formFields}\n * onUpdate={(updates) => handleUpdate(updates)}\n * />\n * ```\n */\nexport function TextFieldEditor({\n field,\n onUpdate,\n}: FieldEditorProps<TextFormField>) {\n // Helper to update validation properties\n const updateValidation = (key: string, value: unknown) => {\n onUpdate({\n validation: {\n ...field.validation,\n [key]: value,\n },\n });\n };\n\n return (\n <div className=\"text-field-editor\">\n {/* General Settings Section */}\n <div className=\"text-field-editor__section\">\n <h4 className=\"text-field-editor__section-title\">General</h4>\n\n {/* Label */}\n <div className=\"text-field-editor__field\">\n <label className=\"text-field-editor__label\" htmlFor=\"field-label\">\n Label\n </label>\n <Input\n id=\"field-label\"\n type=\"text\"\n value={field.label || \"\"}\n onChange={e => onUpdate({ label: e.target.value })}\n placeholder=\"Enter field label\"\n />\n </div>\n\n {/* Field Name */}\n <div className=\"text-field-editor__field\">\n <label className=\"text-field-editor__label\" htmlFor=\"field-name\">\n Field Name\n </label>\n <Input\n id=\"field-name\"\n type=\"text\"\n value={field.name || \"\"}\n onChange={e =>\n onUpdate({\n name: e.target.value\n .replace(/\\s+/g, \"_\")\n .replace(/[^a-zA-Z0-9_]/g, \"\")\n .toLowerCase(),\n })\n }\n placeholder=\"field_name\"\n className=\"text-field-editor__input--mono\"\n />\n <p className=\"text-field-editor__hint\">\n Used as the key in submission data. Only letters, numbers, and\n underscores.\n </p>\n </div>\n\n {/* Placeholder */}\n <div className=\"text-field-editor__field\">\n <label\n className=\"text-field-editor__label\"\n htmlFor=\"field-placeholder\"\n >\n Placeholder\n </label>\n <Input\n id=\"field-placeholder\"\n type=\"text\"\n value={field.placeholder || \"\"}\n onChange={e => onUpdate({ placeholder: e.target.value })}\n placeholder=\"Enter placeholder text\"\n />\n </div>\n\n {/* Help Text */}\n <div className=\"text-field-editor__field\">\n <label className=\"text-field-editor__label\" htmlFor=\"field-help\">\n Help Text\n </label>\n <Input\n id=\"field-help\"\n type=\"text\"\n value={field.helpText || \"\"}\n onChange={e => onUpdate({ helpText: e.target.value })}\n placeholder=\"Additional guidance for users\"\n />\n <p className=\"text-field-editor__hint\">Displayed below the field</p>\n </div>\n\n {/* Required */}\n <div className=\"text-field-editor__field text-field-editor__field--inline\">\n <label className=\"text-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.required || false}\n onChange={e => onUpdate({ required: e.target.checked })}\n className=\"text-field-editor__checkbox\"\n />\n <span>Required field</span>\n </label>\n </div>\n </div>\n\n {/* Validation Section */}\n <div className=\"text-field-editor__section\">\n <h4 className=\"text-field-editor__section-title\">Validation</h4>\n\n {/* Min/Max Length */}\n <div className=\"text-field-editor__field-row\">\n <div className=\"text-field-editor__field text-field-editor__field--half\">\n <label\n className=\"text-field-editor__label\"\n htmlFor=\"field-minlength\"\n >\n Min Length\n </label>\n <Input\n id=\"field-minlength\"\n type=\"number\"\n min={0}\n value={field.validation?.minLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"minLength\",\n e.target.value ? parseInt(e.target.value, 10) : undefined\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"text-field-editor__field text-field-editor__field--half\">\n <label\n className=\"text-field-editor__label\"\n htmlFor=\"field-maxlength\"\n >\n Max Length\n </label>\n <Input\n id=\"field-maxlength\"\n type=\"number\"\n min={0}\n value={field.validation?.maxLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"maxLength\",\n e.target.value ? parseInt(e.target.value, 10) : undefined\n )\n }\n placeholder=\"No limit\"\n />\n </div>\n </div>\n\n {/* Pattern */}\n <div className=\"text-field-editor__field\">\n <label className=\"text-field-editor__label\" htmlFor=\"field-pattern\">\n Pattern (Regex)\n </label>\n <Input\n id=\"field-pattern\"\n type=\"text\"\n value={field.validation?.pattern || \"\"}\n onChange={e =>\n updateValidation(\"pattern\", e.target.value || undefined)\n }\n placeholder=\"^[A-Za-z]+$\"\n className=\"text-field-editor__input--mono\"\n />\n <p className=\"text-field-editor__hint\">\n Regular expression for custom validation\n </p>\n </div>\n\n {/* Error Message */}\n <div className=\"text-field-editor__field\">\n <label className=\"text-field-editor__label\" htmlFor=\"field-error\">\n Error Message\n </label>\n <Input\n id=\"field-error\"\n type=\"text\"\n value={field.validation?.errorMessage || \"\"}\n onChange={e =>\n updateValidation(\"errorMessage\", e.target.value || undefined)\n }\n placeholder=\"Please enter a valid value\"\n />\n <p className=\"text-field-editor__hint\">\n Custom message shown when validation fails\n </p>\n </div>\n </div>\n </div>\n );\n}\n\nexport default TextFieldEditor;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/admin/fields/TextareaFieldEditor.tsx
|
|
4
|
+
import { Input } from "@nextlyhq/ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function TextareaFieldEditor({
|
|
7
|
+
field,
|
|
8
|
+
onUpdate
|
|
9
|
+
}) {
|
|
10
|
+
const updateValidation = (key, value) => {
|
|
11
|
+
onUpdate({
|
|
12
|
+
validation: {
|
|
13
|
+
...field.validation,
|
|
14
|
+
[key]: value
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", { className: "textarea-field-editor", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__section", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h4", { className: "textarea-field-editor__section-title", children: "General" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("label", { className: "textarea-field-editor__label", htmlFor: "field-label", children: "Label" }),
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
Input,
|
|
25
|
+
{
|
|
26
|
+
id: "field-label",
|
|
27
|
+
type: "text",
|
|
28
|
+
value: field.label || "",
|
|
29
|
+
onChange: (e) => onUpdate({ label: e.target.value }),
|
|
30
|
+
placeholder: "Enter field label"
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
] }),
|
|
34
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("label", { className: "textarea-field-editor__label", htmlFor: "field-name", children: "Field Name" }),
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
Input,
|
|
38
|
+
{
|
|
39
|
+
id: "field-name",
|
|
40
|
+
type: "text",
|
|
41
|
+
value: field.name || "",
|
|
42
|
+
onChange: (e) => onUpdate({
|
|
43
|
+
name: e.target.value.replace(/\s+/g, "_").replace(/[^a-zA-Z0-9_]/g, "").toLowerCase()
|
|
44
|
+
}),
|
|
45
|
+
placeholder: "field_name",
|
|
46
|
+
className: "textarea-field-editor__input--mono"
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx("p", { className: "textarea-field-editor__hint", children: "Used as the key in submission data. Only letters, numbers, and underscores." })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"label",
|
|
54
|
+
{
|
|
55
|
+
className: "textarea-field-editor__label",
|
|
56
|
+
htmlFor: "field-placeholder",
|
|
57
|
+
children: "Placeholder"
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
Input,
|
|
62
|
+
{
|
|
63
|
+
id: "field-placeholder",
|
|
64
|
+
type: "text",
|
|
65
|
+
value: field.placeholder || "",
|
|
66
|
+
onChange: (e) => onUpdate({ placeholder: e.target.value }),
|
|
67
|
+
placeholder: "Enter placeholder text"
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
72
|
+
/* @__PURE__ */ jsx("label", { className: "textarea-field-editor__label", htmlFor: "field-help", children: "Help Text" }),
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
Input,
|
|
75
|
+
{
|
|
76
|
+
id: "field-help",
|
|
77
|
+
type: "text",
|
|
78
|
+
value: field.helpText || "",
|
|
79
|
+
onChange: (e) => onUpdate({ helpText: e.target.value }),
|
|
80
|
+
placeholder: "Additional guidance for users"
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsx("p", { className: "textarea-field-editor__hint", children: "Displayed below the field" })
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
86
|
+
/* @__PURE__ */ jsx("label", { className: "textarea-field-editor__label", htmlFor: "field-rows", children: "Rows" }),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
Input,
|
|
89
|
+
{
|
|
90
|
+
id: "field-rows",
|
|
91
|
+
type: "number",
|
|
92
|
+
min: 2,
|
|
93
|
+
max: 20,
|
|
94
|
+
value: field.rows ?? 4,
|
|
95
|
+
onChange: (e) => onUpdate({
|
|
96
|
+
rows: e.target.value ? parseInt(e.target.value, 10) : 4
|
|
97
|
+
}),
|
|
98
|
+
placeholder: "4"
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
/* @__PURE__ */ jsx("p", { className: "textarea-field-editor__hint", children: "Number of visible text rows (2-20)" })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsx("div", { className: "textarea-field-editor__field textarea-field-editor__field--inline", children: /* @__PURE__ */ jsxs("label", { className: "textarea-field-editor__checkbox-label", children: [
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
"input",
|
|
106
|
+
{
|
|
107
|
+
type: "checkbox",
|
|
108
|
+
checked: field.required || false,
|
|
109
|
+
onChange: (e) => onUpdate({ required: e.target.checked }),
|
|
110
|
+
className: "textarea-field-editor__checkbox"
|
|
111
|
+
}
|
|
112
|
+
),
|
|
113
|
+
/* @__PURE__ */ jsx("span", { children: "Required field" })
|
|
114
|
+
] }) })
|
|
115
|
+
] }),
|
|
116
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__section", children: [
|
|
117
|
+
/* @__PURE__ */ jsx("h4", { className: "textarea-field-editor__section-title", children: "Validation" }),
|
|
118
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field-row", children: [
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field textarea-field-editor__field--half", children: [
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
"label",
|
|
122
|
+
{
|
|
123
|
+
className: "textarea-field-editor__label",
|
|
124
|
+
htmlFor: "field-minlength",
|
|
125
|
+
children: "Min Length"
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx(
|
|
129
|
+
Input,
|
|
130
|
+
{
|
|
131
|
+
id: "field-minlength",
|
|
132
|
+
type: "number",
|
|
133
|
+
min: 0,
|
|
134
|
+
value: field.validation?.minLength ?? "",
|
|
135
|
+
onChange: (e) => updateValidation(
|
|
136
|
+
"minLength",
|
|
137
|
+
e.target.value ? parseInt(e.target.value, 10) : void 0
|
|
138
|
+
),
|
|
139
|
+
placeholder: "0"
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field textarea-field-editor__field--half", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(
|
|
145
|
+
"label",
|
|
146
|
+
{
|
|
147
|
+
className: "textarea-field-editor__label",
|
|
148
|
+
htmlFor: "field-maxlength",
|
|
149
|
+
children: "Max Length"
|
|
150
|
+
}
|
|
151
|
+
),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
Input,
|
|
154
|
+
{
|
|
155
|
+
id: "field-maxlength",
|
|
156
|
+
type: "number",
|
|
157
|
+
min: 0,
|
|
158
|
+
value: field.validation?.maxLength ?? "",
|
|
159
|
+
onChange: (e) => updateValidation(
|
|
160
|
+
"maxLength",
|
|
161
|
+
e.target.value ? parseInt(e.target.value, 10) : void 0
|
|
162
|
+
),
|
|
163
|
+
placeholder: "No limit"
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
] })
|
|
167
|
+
] }),
|
|
168
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea-field-editor__field", children: [
|
|
169
|
+
/* @__PURE__ */ jsx("label", { className: "textarea-field-editor__label", htmlFor: "field-error", children: "Error Message" }),
|
|
170
|
+
/* @__PURE__ */ jsx(
|
|
171
|
+
Input,
|
|
172
|
+
{
|
|
173
|
+
id: "field-error",
|
|
174
|
+
type: "text",
|
|
175
|
+
value: field.validation?.errorMessage || "",
|
|
176
|
+
onChange: (e) => updateValidation("errorMessage", e.target.value || void 0),
|
|
177
|
+
placeholder: "Please enter a valid value"
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
/* @__PURE__ */ jsx("p", { className: "textarea-field-editor__hint", children: "Custom message shown when validation fails" })
|
|
181
|
+
] })
|
|
182
|
+
] })
|
|
183
|
+
] });
|
|
184
|
+
}
|
|
185
|
+
var TextareaFieldEditor_default = TextareaFieldEditor;
|
|
186
|
+
export {
|
|
187
|
+
TextareaFieldEditor,
|
|
188
|
+
TextareaFieldEditor_default as default
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=TextareaFieldEditor-773G3LNM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/admin/fields/TextareaFieldEditor.tsx"],"sourcesContent":["/**\n * Textarea Field Editor\n *\n * Editor component for configuring textarea field properties.\n * Includes general settings (label, name, placeholder, rows, required) and\n * validation options (minLength, maxLength).\n *\n * @module admin/fields/TextareaFieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input } from \"@nextlyhq/ui\";\n\nimport type { TextareaFormField } from \"../../types\";\n\nimport type { FieldEditorProps } from \"./index\";\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * TextareaFieldEditor - Configure textarea field properties\n *\n * Provides configuration options for:\n * - Label: Display text shown above the field\n * - Field Name: Key used in submission data (auto-formatted)\n * - Placeholder: Hint text shown when field is empty\n * - Help Text: Additional guidance shown below the field\n * - Rows: Number of visible text rows (height)\n * - Required: Whether the field must be filled\n * - Validation: minLength, maxLength, error message\n *\n * @example\n * ```tsx\n * <TextareaFieldEditor\n * field={textareaField}\n * allFields={formFields}\n * onUpdate={(updates) => handleUpdate(updates)}\n * />\n * ```\n */\nexport function TextareaFieldEditor({\n field,\n onUpdate,\n}: FieldEditorProps<TextareaFormField>) {\n // Helper to update validation properties\n const updateValidation = (key: string, value: unknown) => {\n onUpdate({\n validation: {\n ...field.validation,\n [key]: value,\n },\n });\n };\n\n return (\n <div className=\"textarea-field-editor\">\n {/* General Settings Section */}\n <div className=\"textarea-field-editor__section\">\n <h4 className=\"textarea-field-editor__section-title\">General</h4>\n\n {/* Label */}\n <div className=\"textarea-field-editor__field\">\n <label className=\"textarea-field-editor__label\" htmlFor=\"field-label\">\n Label\n </label>\n <Input\n id=\"field-label\"\n type=\"text\"\n value={field.label || \"\"}\n onChange={e => onUpdate({ label: e.target.value })}\n placeholder=\"Enter field label\"\n />\n </div>\n\n {/* Field Name */}\n <div className=\"textarea-field-editor__field\">\n <label className=\"textarea-field-editor__label\" htmlFor=\"field-name\">\n Field Name\n </label>\n <Input\n id=\"field-name\"\n type=\"text\"\n value={field.name || \"\"}\n onChange={e =>\n onUpdate({\n name: e.target.value\n .replace(/\\s+/g, \"_\")\n .replace(/[^a-zA-Z0-9_]/g, \"\")\n .toLowerCase(),\n })\n }\n placeholder=\"field_name\"\n className=\"textarea-field-editor__input--mono\"\n />\n <p className=\"textarea-field-editor__hint\">\n Used as the key in submission data. Only letters, numbers, and\n underscores.\n </p>\n </div>\n\n {/* Placeholder */}\n <div className=\"textarea-field-editor__field\">\n <label\n className=\"textarea-field-editor__label\"\n htmlFor=\"field-placeholder\"\n >\n Placeholder\n </label>\n <Input\n id=\"field-placeholder\"\n type=\"text\"\n value={field.placeholder || \"\"}\n onChange={e => onUpdate({ placeholder: e.target.value })}\n placeholder=\"Enter placeholder text\"\n />\n </div>\n\n {/* Help Text */}\n <div className=\"textarea-field-editor__field\">\n <label className=\"textarea-field-editor__label\" htmlFor=\"field-help\">\n Help Text\n </label>\n <Input\n id=\"field-help\"\n type=\"text\"\n value={field.helpText || \"\"}\n onChange={e => onUpdate({ helpText: e.target.value })}\n placeholder=\"Additional guidance for users\"\n />\n <p className=\"textarea-field-editor__hint\">\n Displayed below the field\n </p>\n </div>\n\n {/* Rows */}\n <div className=\"textarea-field-editor__field\">\n <label className=\"textarea-field-editor__label\" htmlFor=\"field-rows\">\n Rows\n </label>\n <Input\n id=\"field-rows\"\n type=\"number\"\n min={2}\n max={20}\n value={field.rows ?? 4}\n onChange={e =>\n onUpdate({\n rows: e.target.value ? parseInt(e.target.value, 10) : 4,\n })\n }\n placeholder=\"4\"\n />\n <p className=\"textarea-field-editor__hint\">\n Number of visible text rows (2-20)\n </p>\n </div>\n\n {/* Required */}\n <div className=\"textarea-field-editor__field textarea-field-editor__field--inline\">\n <label className=\"textarea-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.required || false}\n onChange={e => onUpdate({ required: e.target.checked })}\n className=\"textarea-field-editor__checkbox\"\n />\n <span>Required field</span>\n </label>\n </div>\n </div>\n\n {/* Validation Section */}\n <div className=\"textarea-field-editor__section\">\n <h4 className=\"textarea-field-editor__section-title\">Validation</h4>\n\n {/* Min/Max Length */}\n <div className=\"textarea-field-editor__field-row\">\n <div className=\"textarea-field-editor__field textarea-field-editor__field--half\">\n <label\n className=\"textarea-field-editor__label\"\n htmlFor=\"field-minlength\"\n >\n Min Length\n </label>\n <Input\n id=\"field-minlength\"\n type=\"number\"\n min={0}\n value={field.validation?.minLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"minLength\",\n e.target.value ? parseInt(e.target.value, 10) : undefined\n )\n }\n placeholder=\"0\"\n />\n </div>\n <div className=\"textarea-field-editor__field textarea-field-editor__field--half\">\n <label\n className=\"textarea-field-editor__label\"\n htmlFor=\"field-maxlength\"\n >\n Max Length\n </label>\n <Input\n id=\"field-maxlength\"\n type=\"number\"\n min={0}\n value={field.validation?.maxLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"maxLength\",\n e.target.value ? parseInt(e.target.value, 10) : undefined\n )\n }\n placeholder=\"No limit\"\n />\n </div>\n </div>\n\n {/* Error Message */}\n <div className=\"textarea-field-editor__field\">\n <label className=\"textarea-field-editor__label\" htmlFor=\"field-error\">\n Error Message\n </label>\n <Input\n id=\"field-error\"\n type=\"text\"\n value={field.validation?.errorMessage || \"\"}\n onChange={e =>\n updateValidation(\"errorMessage\", e.target.value || undefined)\n }\n placeholder=\"Please enter a valid value\"\n />\n <p className=\"textarea-field-editor__hint\">\n Custom message shown when validation fails\n </p>\n </div>\n </div>\n </div>\n );\n}\n\nexport default TextareaFieldEditor;\n"],"mappings":"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","names":[]}
|