@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
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NextlyHQ <info@nextlyhq.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# @nextlyhq/plugin-form-builder
|
|
2
|
+
|
|
3
|
+
Drag-and-drop form builder plugin for Nextly. Build forms visually, collect submissions, and filter them by form. _Coming soon in beta._
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@nextlyhq/plugin-form-builder"><img alt="npm" src="https://img.shields.io/npm/v/@nextlyhq/plugin-form-builder?style=flat-square&label=npm&color=cb3837" /></a>
|
|
7
|
+
<a href="https://github.com/nextlyhq/nextly/blob/main/LICENSE.md"><img alt="License" src="https://img.shields.io/github/license/nextlyhq/nextly?style=flat-square&color=blue" /></a>
|
|
8
|
+
<a href="https://nextlyhq.com/docs"><img alt="Status" src="https://img.shields.io/badge/status-alpha-orange?style=flat-square" /></a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
> [!WARNING]
|
|
12
|
+
> **Coming soon in beta. Plugins are not ready for use yet.** Public plugin support, including stable APIs, the official plugin gallery, and documentation guarantees, lands at the Nextly **beta** release. This package is published for early exploration only. Surfaces, names, and behaviour will change without notice. Do not rely on plugins for production or serious development work. Wait for the beta release announcement before integrating plugins into your project.
|
|
13
|
+
|
|
14
|
+
> [!IMPORTANT]
|
|
15
|
+
> Nextly is in alpha. APIs may change before 1.0. Pin exact versions in production.
|
|
16
|
+
|
|
17
|
+
## What it is
|
|
18
|
+
|
|
19
|
+
A first-party Nextly plugin that adds a visual form builder to the admin panel and a `form-submissions` collection for capturing entries. Users design forms by dragging fields onto a canvas; submissions are stored in your database and browsable in the admin.
|
|
20
|
+
|
|
21
|
+
Install this whenever you want admin-managed forms (contact, signup, newsletter, surveys) without writing a backend.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @nextlyhq/plugin-form-builder
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick usage
|
|
30
|
+
|
|
31
|
+
Register the plugin in `nextly.config.ts`:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { defineConfig } from "nextly/config";
|
|
35
|
+
import { formBuilder } from "@nextlyhq/plugin-form-builder";
|
|
36
|
+
|
|
37
|
+
const fb = formBuilder({
|
|
38
|
+
notifications: { defaultFrom: "noreply@example.com" },
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export default defineConfig({
|
|
42
|
+
plugins: [fb.plugin],
|
|
43
|
+
collections: [...fb.collections],
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> A `formBuilderPlugin` default-instance shortcut is also exported for cases where no customization is needed. See [the plugin docs](https://nextlyhq.com/docs/plugins/form-builder) for the full options reference.
|
|
48
|
+
|
|
49
|
+
## Admin styling
|
|
50
|
+
|
|
51
|
+
The plugin's admin UI requires three imports in your admin route page so the builder and submissions filter render correctly:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// app/admin/[[...params]]/page.tsx
|
|
55
|
+
import "@nextlyhq/plugin-form-builder/admin";
|
|
56
|
+
import "@nextlyhq/plugin-form-builder/styles/builder.css";
|
|
57
|
+
import "@nextlyhq/plugin-form-builder/styles/submissions-filter.css";
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## What this plugin adds
|
|
61
|
+
|
|
62
|
+
- **Admin routes:** `/admin/collections/forms` and `/admin/collections/form-submissions`
|
|
63
|
+
- **Collections:** `forms`, `form-submissions`
|
|
64
|
+
- **Form lifecycle states:** Draft, Published, Closed
|
|
65
|
+
- **Optional integrations:** email notifications, webhook delivery on submission, spam protection (honeypot, rate limit, reCAPTCHA v3)
|
|
66
|
+
|
|
67
|
+
## Field types
|
|
68
|
+
|
|
69
|
+
The plugin ships 13 field types. All are enabled by default; disable any by setting it to `false` in the `fields` option.
|
|
70
|
+
|
|
71
|
+
| Type | Description |
|
|
72
|
+
| ---------- | ------------------------------------ |
|
|
73
|
+
| `text` | Single-line text input |
|
|
74
|
+
| `email` | Email address with format validation |
|
|
75
|
+
| `number` | Numeric input |
|
|
76
|
+
| `phone` | Phone number input |
|
|
77
|
+
| `url` | URL with format validation |
|
|
78
|
+
| `textarea` | Multi-line text input |
|
|
79
|
+
| `select` | Dropdown menu |
|
|
80
|
+
| `checkbox` | Single boolean toggle |
|
|
81
|
+
| `radio` | Radio button group |
|
|
82
|
+
| `file` | File upload |
|
|
83
|
+
| `date` | Date picker |
|
|
84
|
+
| `time` | Time picker |
|
|
85
|
+
| `hidden` | Hidden value (not shown to users) |
|
|
86
|
+
|
|
87
|
+
See the [Field types reference](https://nextlyhq.com/docs/plugins/form-builder#field-types) for full options on each type.
|
|
88
|
+
|
|
89
|
+
## Main exports
|
|
90
|
+
|
|
91
|
+
- `formBuilder`: factory for customized plugin instances
|
|
92
|
+
- `formBuilderPlugin`: pre-configured default instance
|
|
93
|
+
- Field helpers: `text`, `email`, `number`, `phone`, `url`, `textarea`, `select`, `checkbox`, `radio`, `file`, `date`, `time`, `hidden`, `option`
|
|
94
|
+
- Server helpers: `submitForm`, `validateSubmission`, `getFormSubmissionStats`, `createFormConfig`, `validateFormConfig`, `assertValidFormConfig`
|
|
95
|
+
- Export utilities: `exportToCSV`, `exportToJSON`, `exportAndDownload`, `downloadFile`, `generateExportFilename`
|
|
96
|
+
- Collections: `formsCollection`, `submissionsCollection`
|
|
97
|
+
- Type exports: `FormDocument`, `SubmissionDocument`, `FormSubmission`, `EmailConfig`, `WebhookConfig`, `WebhookEvent`, `FormFieldOption`, `SubmissionListProps`, `SubmissionDetailProps`
|
|
98
|
+
|
|
99
|
+
## Compatibility
|
|
100
|
+
|
|
101
|
+
| Tool | Version |
|
|
102
|
+
| ----------------- | ------- |
|
|
103
|
+
| Node.js | 20+ |
|
|
104
|
+
| `nextly` | 0.0.x |
|
|
105
|
+
| `@nextlyhq/admin` | 0.0.x |
|
|
106
|
+
|
|
107
|
+
Plugins can break across minor versions during alpha. Pin exact versions of `nextly`, `@nextlyhq/admin`, and this plugin together.
|
|
108
|
+
|
|
109
|
+
## Documentation
|
|
110
|
+
|
|
111
|
+
- [**Form Builder plugin docs**](https://nextlyhq.com/docs/plugins/form-builder): full configuration, field options, server helpers, webhooks, exports
|
|
112
|
+
- [**Plugins overview**](https://nextlyhq.com/docs/plugins): how the plugin system works
|
|
113
|
+
- [**Email configuration**](https://nextlyhq.com/docs/guides/email): set up providers and templates for form notifications
|
|
114
|
+
|
|
115
|
+
## Related packages
|
|
116
|
+
|
|
117
|
+
- [`nextly`](../nextly): the core runtime
|
|
118
|
+
- [`@nextlyhq/admin`](../admin): the admin panel that hosts the builder UI
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
[MIT](../../LICENSE.md)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/admin/fields/CheckboxFieldEditor.tsx
|
|
4
|
+
import { Input } from "@nextlyhq/ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function CheckboxFieldEditor({
|
|
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: "checkbox-field-editor", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__section", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h4", { className: "checkbox-field-editor__section-title", children: "General" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("label", { className: "checkbox-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: "I agree to the terms and conditions"
|
|
31
|
+
}
|
|
32
|
+
),
|
|
33
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "Text displayed next to the checkbox" })
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field", children: [
|
|
36
|
+
/* @__PURE__ */ jsx("label", { className: "checkbox-field-editor__label", htmlFor: "field-name", children: "Field Name" }),
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
Input,
|
|
39
|
+
{
|
|
40
|
+
id: "field-name",
|
|
41
|
+
type: "text",
|
|
42
|
+
value: field.name || "",
|
|
43
|
+
onChange: (e) => onUpdate({
|
|
44
|
+
name: e.target.value.replace(/\s+/g, "_").replace(/[^a-zA-Z0-9_]/g, "").toLowerCase()
|
|
45
|
+
}),
|
|
46
|
+
placeholder: "field_name",
|
|
47
|
+
className: "checkbox-field-editor__input--mono"
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "Used as the key in submission data. Only letters, numbers, and underscores." })
|
|
51
|
+
] }),
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field", children: [
|
|
53
|
+
/* @__PURE__ */ jsx("label", { className: "checkbox-field-editor__label", htmlFor: "field-help", children: "Help Text" }),
|
|
54
|
+
/* @__PURE__ */ jsx(
|
|
55
|
+
Input,
|
|
56
|
+
{
|
|
57
|
+
id: "field-help",
|
|
58
|
+
type: "text",
|
|
59
|
+
value: field.helpText || "",
|
|
60
|
+
onChange: (e) => onUpdate({ helpText: e.target.value }),
|
|
61
|
+
placeholder: "Additional guidance for users"
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "Displayed below the field" })
|
|
65
|
+
] }),
|
|
66
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field checkbox-field-editor__field--inline", children: [
|
|
67
|
+
/* @__PURE__ */ jsxs("label", { className: "checkbox-field-editor__checkbox-label", children: [
|
|
68
|
+
/* @__PURE__ */ jsx(
|
|
69
|
+
"input",
|
|
70
|
+
{
|
|
71
|
+
type: "checkbox",
|
|
72
|
+
checked: field.defaultValue || false,
|
|
73
|
+
onChange: (e) => onUpdate({ defaultValue: e.target.checked }),
|
|
74
|
+
className: "checkbox-field-editor__checkbox"
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsx("span", { children: "Checked by default" })
|
|
78
|
+
] }),
|
|
79
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "Whether the checkbox is pre-checked when the form loads" })
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field checkbox-field-editor__field--inline", children: [
|
|
82
|
+
/* @__PURE__ */ jsxs("label", { className: "checkbox-field-editor__checkbox-label", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"input",
|
|
85
|
+
{
|
|
86
|
+
type: "checkbox",
|
|
87
|
+
checked: field.required || false,
|
|
88
|
+
onChange: (e) => onUpdate({ required: e.target.checked }),
|
|
89
|
+
className: "checkbox-field-editor__checkbox"
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx("span", { children: "Required field" })
|
|
93
|
+
] }),
|
|
94
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "User must check this box to submit the form (useful for terms acceptance)" })
|
|
95
|
+
] })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__section", children: [
|
|
98
|
+
/* @__PURE__ */ jsx("h4", { className: "checkbox-field-editor__section-title", children: "Validation" }),
|
|
99
|
+
/* @__PURE__ */ jsxs("div", { className: "checkbox-field-editor__field", children: [
|
|
100
|
+
/* @__PURE__ */ jsx("label", { className: "checkbox-field-editor__label", htmlFor: "field-error", children: "Error Message" }),
|
|
101
|
+
/* @__PURE__ */ jsx(
|
|
102
|
+
Input,
|
|
103
|
+
{
|
|
104
|
+
id: "field-error",
|
|
105
|
+
type: "text",
|
|
106
|
+
value: field.validation?.errorMessage || "",
|
|
107
|
+
onChange: (e) => updateValidation("errorMessage", e.target.value || void 0),
|
|
108
|
+
placeholder: "You must accept the terms to continue"
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
/* @__PURE__ */ jsx("p", { className: "checkbox-field-editor__hint", children: "Custom message shown when required checkbox is not checked" })
|
|
112
|
+
] })
|
|
113
|
+
] })
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
var CheckboxFieldEditor_default = CheckboxFieldEditor;
|
|
117
|
+
export {
|
|
118
|
+
CheckboxFieldEditor,
|
|
119
|
+
CheckboxFieldEditor_default as default
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=CheckboxFieldEditor-K4T6QX52.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/admin/fields/CheckboxFieldEditor.tsx"],"sourcesContent":["/**\n * Checkbox Field Editor\n *\n * Editor component for configuring checkbox field properties.\n * Includes general settings (label, name, help text, required) and\n * default value configuration.\n *\n * Checkbox fields are typically used for:\n * - Terms and conditions acceptance\n * - Newsletter opt-in\n * - Boolean yes/no questions\n *\n * @module admin/fields/CheckboxFieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input } from \"@nextlyhq/ui\";\n\nimport type { CheckboxFormField } from \"../../types\";\n\nimport type { FieldEditorProps } from \"./index\";\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * CheckboxFieldEditor - Configure checkbox field properties\n *\n * Provides configuration options for:\n * - Label: Text shown next to the checkbox (e.g., \"I agree to the terms\")\n * - Field Name: Key used in submission data (auto-formatted)\n * - Help Text: Additional guidance shown below the field\n * - Required: Whether the checkbox must be checked (for consent forms)\n * - Default Value: Whether the checkbox is checked by default\n * - Validation: error message\n *\n * @example\n * ```tsx\n * <CheckboxFieldEditor\n * field={checkboxField}\n * allFields={formFields}\n * onUpdate={(updates) => handleUpdate(updates)}\n * />\n * ```\n */\nexport function CheckboxFieldEditor({\n field,\n onUpdate,\n}: FieldEditorProps<CheckboxFormField>) {\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=\"checkbox-field-editor\">\n {/* General Settings Section */}\n <div className=\"checkbox-field-editor__section\">\n <h4 className=\"checkbox-field-editor__section-title\">General</h4>\n\n {/* Label */}\n <div className=\"checkbox-field-editor__field\">\n <label className=\"checkbox-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=\"I agree to the terms and conditions\"\n />\n <p className=\"checkbox-field-editor__hint\">\n Text displayed next to the checkbox\n </p>\n </div>\n\n {/* Field Name */}\n <div className=\"checkbox-field-editor__field\">\n <label className=\"checkbox-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=\"checkbox-field-editor__input--mono\"\n />\n <p className=\"checkbox-field-editor__hint\">\n Used as the key in submission data. Only letters, numbers, and\n underscores.\n </p>\n </div>\n\n {/* Help Text */}\n <div className=\"checkbox-field-editor__field\">\n <label className=\"checkbox-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=\"checkbox-field-editor__hint\">\n Displayed below the field\n </p>\n </div>\n\n {/* Default Value */}\n <div className=\"checkbox-field-editor__field checkbox-field-editor__field--inline\">\n <label className=\"checkbox-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.defaultValue || false}\n onChange={e => onUpdate({ defaultValue: e.target.checked })}\n className=\"checkbox-field-editor__checkbox\"\n />\n <span>Checked by default</span>\n </label>\n <p className=\"checkbox-field-editor__hint\">\n Whether the checkbox is pre-checked when the form loads\n </p>\n </div>\n\n {/* Required */}\n <div className=\"checkbox-field-editor__field checkbox-field-editor__field--inline\">\n <label className=\"checkbox-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.required || false}\n onChange={e => onUpdate({ required: e.target.checked })}\n className=\"checkbox-field-editor__checkbox\"\n />\n <span>Required field</span>\n </label>\n <p className=\"checkbox-field-editor__hint\">\n User must check this box to submit the form (useful for terms\n acceptance)\n </p>\n </div>\n </div>\n\n {/* Validation Section */}\n <div className=\"checkbox-field-editor__section\">\n <h4 className=\"checkbox-field-editor__section-title\">Validation</h4>\n\n {/* Error Message */}\n <div className=\"checkbox-field-editor__field\">\n <label className=\"checkbox-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=\"You must accept the terms to continue\"\n />\n <p className=\"checkbox-field-editor__hint\">\n Custom message shown when required checkbox is not checked\n </p>\n </div>\n </div>\n </div>\n );\n}\n\nexport default CheckboxFieldEditor;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/admin/fields/DateFieldEditor.tsx
|
|
4
|
+
import { Input } from "@nextlyhq/ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function DateFieldEditor({
|
|
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: "date-field-editor", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__section", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h4", { className: "date-field-editor__section-title", children: "General" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("label", { className: "date-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: "date-field-editor__field", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("label", { className: "date-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: "date-field-editor__input--mono"
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx("p", { className: "date-field-editor__hint", children: "Used as the key in submission data. Only letters, numbers, and underscores." })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"label",
|
|
54
|
+
{
|
|
55
|
+
className: "date-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: "Select a date..."
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field", children: [
|
|
72
|
+
/* @__PURE__ */ jsx("label", { className: "date-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: "date-field-editor__hint", children: "Displayed below the field" })
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field", children: [
|
|
86
|
+
/* @__PURE__ */ jsx(
|
|
87
|
+
"label",
|
|
88
|
+
{
|
|
89
|
+
className: "date-field-editor__label",
|
|
90
|
+
htmlFor: "field-default-value",
|
|
91
|
+
children: "Default Value"
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
"input",
|
|
96
|
+
{
|
|
97
|
+
id: "field-default-value",
|
|
98
|
+
type: "date",
|
|
99
|
+
value: field.defaultValue || "",
|
|
100
|
+
onChange: (e) => onUpdate({ defaultValue: e.target.value || void 0 }),
|
|
101
|
+
className: "date-field-editor__date-input"
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
/* @__PURE__ */ jsx("p", { className: "date-field-editor__hint", children: "Pre-selected date when the form loads" })
|
|
105
|
+
] }),
|
|
106
|
+
/* @__PURE__ */ jsx("div", { className: "date-field-editor__field date-field-editor__field--inline", children: /* @__PURE__ */ jsxs("label", { className: "date-field-editor__checkbox-label", children: [
|
|
107
|
+
/* @__PURE__ */ jsx(
|
|
108
|
+
"input",
|
|
109
|
+
{
|
|
110
|
+
type: "checkbox",
|
|
111
|
+
checked: field.required || false,
|
|
112
|
+
onChange: (e) => onUpdate({ required: e.target.checked }),
|
|
113
|
+
className: "date-field-editor__checkbox"
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
/* @__PURE__ */ jsx("span", { children: "Required field" })
|
|
117
|
+
] }) })
|
|
118
|
+
] }),
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__section", children: [
|
|
120
|
+
/* @__PURE__ */ jsx("h4", { className: "date-field-editor__section-title", children: "Validation" }),
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field-row", children: [
|
|
122
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field date-field-editor__field--half", children: [
|
|
123
|
+
/* @__PURE__ */ jsx(
|
|
124
|
+
"label",
|
|
125
|
+
{
|
|
126
|
+
className: "date-field-editor__label",
|
|
127
|
+
htmlFor: "field-min-date",
|
|
128
|
+
children: "Min Date"
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
"input",
|
|
133
|
+
{
|
|
134
|
+
id: "field-min-date",
|
|
135
|
+
type: "date",
|
|
136
|
+
value: field.min || "",
|
|
137
|
+
onChange: (e) => onUpdate({ min: e.target.value || void 0 }),
|
|
138
|
+
className: "date-field-editor__date-input"
|
|
139
|
+
}
|
|
140
|
+
),
|
|
141
|
+
/* @__PURE__ */ jsx("p", { className: "date-field-editor__hint", children: "Earliest allowed date" })
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field date-field-editor__field--half", children: [
|
|
144
|
+
/* @__PURE__ */ jsx(
|
|
145
|
+
"label",
|
|
146
|
+
{
|
|
147
|
+
className: "date-field-editor__label",
|
|
148
|
+
htmlFor: "field-max-date",
|
|
149
|
+
children: "Max Date"
|
|
150
|
+
}
|
|
151
|
+
),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"input",
|
|
154
|
+
{
|
|
155
|
+
id: "field-max-date",
|
|
156
|
+
type: "date",
|
|
157
|
+
value: field.max || "",
|
|
158
|
+
onChange: (e) => onUpdate({ max: e.target.value || void 0 }),
|
|
159
|
+
className: "date-field-editor__date-input"
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsx("p", { className: "date-field-editor__hint", children: "Latest allowed date" })
|
|
163
|
+
] })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "date-field-editor__field", children: [
|
|
166
|
+
/* @__PURE__ */ jsx("label", { className: "date-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 select a valid date"
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
/* @__PURE__ */ jsx("p", { className: "date-field-editor__hint", children: "Custom message shown when validation fails" })
|
|
178
|
+
] })
|
|
179
|
+
] })
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
var DateFieldEditor_default = DateFieldEditor;
|
|
183
|
+
export {
|
|
184
|
+
DateFieldEditor,
|
|
185
|
+
DateFieldEditor_default as default
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=DateFieldEditor-JFJFAVOH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/admin/fields/DateFieldEditor.tsx"],"sourcesContent":["/**\n * Date Field Editor\n *\n * Editor component for configuring date picker field properties.\n * Includes general settings (label, name, placeholder, required, default value)\n * and validation options (min date, max date).\n *\n * @module admin/fields/DateFieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input } from \"@nextlyhq/ui\";\n\nimport type { DateFormField } from \"../../types\";\n\nimport type { FieldEditorProps } from \"./index\";\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * DateFieldEditor - Configure date 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 * - Default Value: Pre-selected date when form loads\n * - Validation: min date, max date, error message\n *\n * @example\n * ```tsx\n * <DateFieldEditor\n * field={dateField}\n * allFields={formFields}\n * onUpdate={(updates) => handleUpdate(updates)}\n * />\n * ```\n */\nexport function DateFieldEditor({\n field,\n onUpdate,\n}: FieldEditorProps<DateFormField>) {\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=\"date-field-editor\">\n {/* General Settings Section */}\n <div className=\"date-field-editor__section\">\n <h4 className=\"date-field-editor__section-title\">General</h4>\n\n {/* Label */}\n <div className=\"date-field-editor__field\">\n <label className=\"date-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=\"date-field-editor__field\">\n <label className=\"date-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=\"date-field-editor__input--mono\"\n />\n <p className=\"date-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=\"date-field-editor__field\">\n <label\n className=\"date-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=\"Select a date...\"\n />\n </div>\n\n {/* Help Text */}\n <div className=\"date-field-editor__field\">\n <label className=\"date-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=\"date-field-editor__hint\">Displayed below the field</p>\n </div>\n\n {/* Default Value */}\n <div className=\"date-field-editor__field\">\n <label\n className=\"date-field-editor__label\"\n htmlFor=\"field-default-value\"\n >\n Default Value\n </label>\n <input\n id=\"field-default-value\"\n type=\"date\"\n value={field.defaultValue || \"\"}\n onChange={e =>\n onUpdate({ defaultValue: e.target.value || undefined })\n }\n className=\"date-field-editor__date-input\"\n />\n <p className=\"date-field-editor__hint\">\n Pre-selected date when the form loads\n </p>\n </div>\n\n {/* Required */}\n <div className=\"date-field-editor__field date-field-editor__field--inline\">\n <label className=\"date-field-editor__checkbox-label\">\n <input\n type=\"checkbox\"\n checked={field.required || false}\n onChange={e => onUpdate({ required: e.target.checked })}\n className=\"date-field-editor__checkbox\"\n />\n <span>Required field</span>\n </label>\n </div>\n </div>\n\n {/* Validation Section */}\n <div className=\"date-field-editor__section\">\n <h4 className=\"date-field-editor__section-title\">Validation</h4>\n\n {/* Min/Max Date */}\n <div className=\"date-field-editor__field-row\">\n <div className=\"date-field-editor__field date-field-editor__field--half\">\n <label\n className=\"date-field-editor__label\"\n htmlFor=\"field-min-date\"\n >\n Min Date\n </label>\n <input\n id=\"field-min-date\"\n type=\"date\"\n value={field.min || \"\"}\n onChange={e => onUpdate({ min: e.target.value || undefined })}\n className=\"date-field-editor__date-input\"\n />\n <p className=\"date-field-editor__hint\">Earliest allowed date</p>\n </div>\n <div className=\"date-field-editor__field date-field-editor__field--half\">\n <label\n className=\"date-field-editor__label\"\n htmlFor=\"field-max-date\"\n >\n Max Date\n </label>\n <input\n id=\"field-max-date\"\n type=\"date\"\n value={field.max || \"\"}\n onChange={e => onUpdate({ max: e.target.value || undefined })}\n className=\"date-field-editor__date-input\"\n />\n <p className=\"date-field-editor__hint\">Latest allowed date</p>\n </div>\n </div>\n\n {/* Error Message */}\n <div className=\"date-field-editor__field\">\n <label className=\"date-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 a valid date\"\n />\n <p className=\"date-field-editor__hint\">\n Custom message shown when validation fails\n </p>\n </div>\n </div>\n </div>\n );\n}\n\nexport default DateFieldEditor;\n"],"mappings":";;;AAaA,SAAS,aAAa;AAiDd,cAGA,YAHA;AAlBD,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAAoC;AAElC,QAAM,mBAAmB,CAAC,KAAa,UAAmB;AACxD,aAAS;AAAA,MACP,YAAY;AAAA,QACV,GAAG,MAAM;AAAA,QACT,CAAC,GAAG,GAAG;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SACE,qBAAC,SAAI,WAAU,qBAEb;AAAA,yBAAC,SAAI,WAAU,8BACb;AAAA,0BAAC,QAAG,WAAU,oCAAmC,qBAAO;AAAA,MAGxD,qBAAC,SAAI,WAAU,4BACb;AAAA,4BAAC,WAAM,WAAU,4BAA2B,SAAQ,eAAc,mBAElE;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,SAAS;AAAA,YACtB,UAAU,OAAK,SAAS,EAAE,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,YACjD,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MAGA,qBAAC,SAAI,WAAU,4BACb;AAAA,4BAAC,WAAM,WAAU,4BAA2B,SAAQ,cAAa,wBAEjE;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,QAAQ;AAAA,YACrB,UAAU,OACR,SAAS;AAAA,cACP,MAAM,EAAE,OAAO,MACZ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,kBAAkB,EAAE,EAC5B,YAAY;AAAA,YACjB,CAAC;AAAA,YAEH,aAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,oBAAC,OAAE,WAAU,2BAA0B,yFAGvC;AAAA,SACF;AAAA,MAGA,qBAAC,SAAI,WAAU,4BACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAQ;AAAA,YACT;AAAA;AAAA,QAED;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,eAAe;AAAA,YAC5B,UAAU,OAAK,SAAS,EAAE,aAAa,EAAE,OAAO,MAAM,CAAC;AAAA,YACvD,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MAGA,qBAAC,SAAI,WAAU,4BACb;AAAA,4BAAC,WAAM,WAAU,4BAA2B,SAAQ,cAAa,uBAEjE;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,YAAY;AAAA,YACzB,UAAU,OAAK,SAAS,EAAE,UAAU,EAAE,OAAO,MAAM,CAAC;AAAA,YACpD,aAAY;AAAA;AAAA,QACd;AAAA,QACA,oBAAC,OAAE,WAAU,2BAA0B,uCAAyB;AAAA,SAClE;AAAA,MAGA,qBAAC,SAAI,WAAU,4BACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAQ;AAAA,YACT;AAAA;AAAA,QAED;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,gBAAgB;AAAA,YAC7B,UAAU,OACR,SAAS,EAAE,cAAc,EAAE,OAAO,SAAS,OAAU,CAAC;AAAA,YAExD,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,oBAAC,OAAE,WAAU,2BAA0B,mDAEvC;AAAA,SACF;AAAA,MAGA,oBAAC,SAAI,WAAU,6DACb,+BAAC,WAAM,WAAU,qCACf;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,YAAY;AAAA,YAC3B,UAAU,OAAK,SAAS,EAAE,UAAU,EAAE,OAAO,QAAQ,CAAC;AAAA,YACtD,WAAU;AAAA;AAAA,QACZ;AAAA,QACA,oBAAC,UAAK,4BAAc;AAAA,SACtB,GACF;AAAA,OACF;AAAA,IAGA,qBAAC,SAAI,WAAU,8BACb;AAAA,0BAAC,QAAG,WAAU,oCAAmC,wBAAU;AAAA,MAG3D,qBAAC,SAAI,WAAU,gCACb;AAAA,6BAAC,SAAI,WAAU,2DACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAQ;AAAA,cACT;AAAA;AAAA,UAED;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO,MAAM,OAAO;AAAA,cACpB,UAAU,OAAK,SAAS,EAAE,KAAK,EAAE,OAAO,SAAS,OAAU,CAAC;AAAA,cAC5D,WAAU;AAAA;AAAA,UACZ;AAAA,UACA,oBAAC,OAAE,WAAU,2BAA0B,mCAAqB;AAAA,WAC9D;AAAA,QACA,qBAAC,SAAI,WAAU,2DACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAQ;AAAA,cACT;AAAA;AAAA,UAED;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO,MAAM,OAAO;AAAA,cACpB,UAAU,OAAK,SAAS,EAAE,KAAK,EAAE,OAAO,SAAS,OAAU,CAAC;AAAA,cAC5D,WAAU;AAAA;AAAA,UACZ;AAAA,UACA,oBAAC,OAAE,WAAU,2BAA0B,iCAAmB;AAAA,WAC5D;AAAA,SACF;AAAA,MAGA,qBAAC,SAAI,WAAU,4BACb;AAAA,4BAAC,WAAM,WAAU,4BAA2B,SAAQ,eAAc,2BAElE;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO,MAAM,YAAY,gBAAgB;AAAA,YACzC,UAAU,OACR,iBAAiB,gBAAgB,EAAE,OAAO,SAAS,MAAS;AAAA,YAE9D,aAAY;AAAA;AAAA,QACd;AAAA,QACA,oBAAC,OAAE,WAAU,2BAA0B,wDAEvC;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,IAAO,0BAAQ;","names":[]}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/admin/fields/EmailFieldEditor.tsx
|
|
4
|
+
import { Input } from "@nextlyhq/ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function EmailFieldEditor({
|
|
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: "email-field-editor", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__section", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h4", { className: "email-field-editor__section-title", children: "General" }),
|
|
21
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__field", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("label", { className: "email-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: "email-field-editor__field", children: [
|
|
35
|
+
/* @__PURE__ */ jsx("label", { className: "email-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: "email-field-editor__input--mono"
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx("p", { className: "email-field-editor__hint", children: "Used as the key in submission data. Only letters, numbers, and underscores." })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__field", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"label",
|
|
54
|
+
{
|
|
55
|
+
className: "email-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: "email@example.com"
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__field", children: [
|
|
72
|
+
/* @__PURE__ */ jsx("label", { className: "email-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: "email-field-editor__hint", children: "Displayed below the field" })
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsx("div", { className: "email-field-editor__field email-field-editor__field--inline", children: /* @__PURE__ */ jsxs("label", { className: "email-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: "email-field-editor__checkbox"
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { children: "Required field" })
|
|
96
|
+
] }) })
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__section", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("h4", { className: "email-field-editor__section-title", children: "Validation" }),
|
|
100
|
+
/* @__PURE__ */ jsx("div", { className: "email-field-editor__info", children: /* @__PURE__ */ jsx("p", { className: "email-field-editor__info-text", children: "Email format validation is automatic. Use the pattern field below for additional restrictions (e.g., corporate domains only)." }) }),
|
|
101
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__field", children: [
|
|
102
|
+
/* @__PURE__ */ jsx("label", { className: "email-field-editor__label", htmlFor: "field-pattern", children: "Pattern (Regex)" }),
|
|
103
|
+
/* @__PURE__ */ jsx(
|
|
104
|
+
Input,
|
|
105
|
+
{
|
|
106
|
+
id: "field-pattern",
|
|
107
|
+
type: "text",
|
|
108
|
+
value: field.validation?.pattern || "",
|
|
109
|
+
onChange: (e) => updateValidation("pattern", e.target.value || void 0),
|
|
110
|
+
placeholder: ".*@company\\.com$",
|
|
111
|
+
className: "email-field-editor__input--mono"
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ jsx("p", { className: "email-field-editor__hint", children: "Optional: Additional regex pattern (e.g., restrict to specific domains)" })
|
|
115
|
+
] }),
|
|
116
|
+
/* @__PURE__ */ jsxs("div", { className: "email-field-editor__field", children: [
|
|
117
|
+
/* @__PURE__ */ jsx("label", { className: "email-field-editor__label", htmlFor: "field-error", children: "Error Message" }),
|
|
118
|
+
/* @__PURE__ */ jsx(
|
|
119
|
+
Input,
|
|
120
|
+
{
|
|
121
|
+
id: "field-error",
|
|
122
|
+
type: "text",
|
|
123
|
+
value: field.validation?.errorMessage || "",
|
|
124
|
+
onChange: (e) => updateValidation("errorMessage", e.target.value || void 0),
|
|
125
|
+
placeholder: "Please enter a valid email address"
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx("p", { className: "email-field-editor__hint", children: "Custom message shown when validation fails" })
|
|
129
|
+
] })
|
|
130
|
+
] })
|
|
131
|
+
] });
|
|
132
|
+
}
|
|
133
|
+
var EmailFieldEditor_default = EmailFieldEditor;
|
|
134
|
+
export {
|
|
135
|
+
EmailFieldEditor,
|
|
136
|
+
EmailFieldEditor_default as default
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=EmailFieldEditor-MMOXXL7P.js.map
|