@page-speed/forms 0.5.0 → 0.5.2
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/README.md +30 -2
- package/dist/core.cjs +189 -97
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +3 -3
- package/dist/core.d.ts +3 -3
- package/dist/core.js +175 -83
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +189 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +175 -83
- package/dist/index.js.map +1 -1
- package/dist/inputs.cjs +2720 -1371
- package/dist/inputs.cjs.map +1 -1
- package/dist/inputs.d.cts +10 -259
- package/dist/inputs.d.ts +10 -259
- package/dist/inputs.js +2721 -1371
- package/dist/inputs.js.map +1 -1
- package/dist/integration.cjs +5168 -9
- package/dist/integration.cjs.map +1 -1
- package/dist/integration.d.cts +298 -1
- package/dist/integration.d.ts +298 -1
- package/dist/integration.js +5160 -9
- package/dist/integration.js.map +1 -1
- package/dist/{types-DuX3q6A4.d.cts → types-CnOCn7b3.d.cts} +51 -1
- package/dist/{types-DuX3q6A4.d.ts → types-CnOCn7b3.d.ts} +51 -1
- package/dist/validation-rules.d.cts +1 -1
- package/dist/validation-rules.d.ts +1 -1
- package/dist/validation-utils.d.cts +1 -1
- package/dist/validation-utils.d.ts +1 -1
- package/dist/validation-valibot.d.cts +1 -1
- package/dist/validation-valibot.d.ts +1 -1
- package/dist/validation.d.cts +1 -1
- package/dist/validation.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,35 @@ export function ContactForm() {
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
### Grouped Form Configuration
|
|
104
|
+
|
|
105
|
+
`Form` supports both classic props and grouped config objects for cleaner callsites.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import * as React from "react";
|
|
109
|
+
import { Form } from "@page-speed/forms";
|
|
110
|
+
|
|
111
|
+
<Form
|
|
112
|
+
form={form}
|
|
113
|
+
notificationConfig={{
|
|
114
|
+
successMessage: "Thanks, submission received.",
|
|
115
|
+
submissionError,
|
|
116
|
+
}}
|
|
117
|
+
styleConfig={{
|
|
118
|
+
formClassName: "space-y-6",
|
|
119
|
+
successMessageClassName: "bg-emerald-600 text-white",
|
|
120
|
+
errorMessageClassName: "bg-red-600 text-white",
|
|
121
|
+
}}
|
|
122
|
+
formConfig={{
|
|
123
|
+
endpoint: "/api/contact",
|
|
124
|
+
method: "post",
|
|
125
|
+
submissionConfig: {
|
|
126
|
+
behavior: "showConfirmation",
|
|
127
|
+
},
|
|
128
|
+
}}
|
|
129
|
+
/>;
|
|
130
|
+
```
|
|
131
|
+
|
|
103
132
|
## Package Entry Points
|
|
104
133
|
|
|
105
134
|
### Main
|
|
@@ -123,7 +152,6 @@ Exports:
|
|
|
123
152
|
- `DatePicker`
|
|
124
153
|
- `DateRangePicker`
|
|
125
154
|
- `TimePicker`
|
|
126
|
-
- `RichTextEditor`
|
|
127
155
|
- `FileInput`
|
|
128
156
|
|
|
129
157
|
### Validation
|
|
@@ -154,7 +182,7 @@ Exports:
|
|
|
154
182
|
- Close on outside click
|
|
155
183
|
- Search support
|
|
156
184
|
- Option groups
|
|
157
|
-
- Selected options inside the menu use
|
|
185
|
+
- Selected options inside the menu use accent highlight styles
|
|
158
186
|
|
|
159
187
|
## Styling (Tailwind 4 + Semantic Tokens)
|
|
160
188
|
|
package/dist/core.cjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React4 = require('react');
|
|
4
4
|
var react = require('@legendapp/state/react');
|
|
5
5
|
var useMap = require('@opensite/hooks/useMap');
|
|
6
6
|
var clsx = require('clsx');
|
|
7
7
|
var tailwindMerge = require('tailwind-merge');
|
|
8
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
9
|
+
var radixUi = require('radix-ui');
|
|
8
10
|
|
|
9
11
|
function _interopNamespace(e) {
|
|
10
12
|
if (e && e.__esModule) return e;
|
|
@@ -24,7 +26,7 @@ function _interopNamespace(e) {
|
|
|
24
26
|
return Object.freeze(n);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
var
|
|
29
|
+
var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
|
|
28
30
|
|
|
29
31
|
// src/core/useForm.ts
|
|
30
32
|
function useForm(options) {
|
|
@@ -47,9 +49,9 @@ function useForm(options) {
|
|
|
47
49
|
// Create a copy to prevent reference sharing
|
|
48
50
|
hasValidated: {}
|
|
49
51
|
});
|
|
50
|
-
const validationInProgress =
|
|
52
|
+
const validationInProgress = React4.useRef(/* @__PURE__ */ new Set());
|
|
51
53
|
const [, fieldMetadataActions] = useMap.useMap();
|
|
52
|
-
const validateField =
|
|
54
|
+
const validateField = React4.useCallback(
|
|
53
55
|
async (field) => {
|
|
54
56
|
const validators = validationSchema?.[field];
|
|
55
57
|
if (!validators) return void 0;
|
|
@@ -86,7 +88,7 @@ function useForm(options) {
|
|
|
86
88
|
},
|
|
87
89
|
[validationSchema, state$, fieldMetadataActions]
|
|
88
90
|
);
|
|
89
|
-
const validateForm =
|
|
91
|
+
const validateForm = React4.useCallback(async () => {
|
|
90
92
|
if (!validationSchema) return {};
|
|
91
93
|
const fields = Object.keys(validationSchema);
|
|
92
94
|
const errors2 = {};
|
|
@@ -101,7 +103,7 @@ function useForm(options) {
|
|
|
101
103
|
state$.errors.set(errors2);
|
|
102
104
|
return errors2;
|
|
103
105
|
}, [validationSchema, validateField, state$]);
|
|
104
|
-
const setFieldValue =
|
|
106
|
+
const setFieldValue = React4.useCallback(
|
|
105
107
|
(field, value) => {
|
|
106
108
|
state$.values[field].set(value);
|
|
107
109
|
const shouldRevalidate = revalidateOn === "onChange" && state$.hasValidated[String(field)].get();
|
|
@@ -114,7 +116,7 @@ function useForm(options) {
|
|
|
114
116
|
},
|
|
115
117
|
[state$, revalidateOn, validationSchema, validateField, debug]
|
|
116
118
|
);
|
|
117
|
-
const setFieldTouched =
|
|
119
|
+
const setFieldTouched = React4.useCallback(
|
|
118
120
|
(field, touched2) => {
|
|
119
121
|
state$.touched[field].set(touched2);
|
|
120
122
|
if (touched2 && validateOn === "onBlur" && validationSchema?.[field]) {
|
|
@@ -127,7 +129,7 @@ function useForm(options) {
|
|
|
127
129
|
},
|
|
128
130
|
[state$, validateOn, validationSchema, validateField, debug]
|
|
129
131
|
);
|
|
130
|
-
const resetForm =
|
|
132
|
+
const resetForm = React4.useCallback(() => {
|
|
131
133
|
state$.values.set(state$.initialValues.get());
|
|
132
134
|
state$.errors.set({});
|
|
133
135
|
state$.touched.set({});
|
|
@@ -139,7 +141,7 @@ function useForm(options) {
|
|
|
139
141
|
console.log("[useForm] Form reset");
|
|
140
142
|
}
|
|
141
143
|
}, [state$, fieldMetadataActions, debug]);
|
|
142
|
-
const handleSubmit =
|
|
144
|
+
const handleSubmit = React4.useCallback(
|
|
143
145
|
async (e) => {
|
|
144
146
|
e?.preventDefault();
|
|
145
147
|
if (debug) {
|
|
@@ -200,7 +202,7 @@ function useForm(options) {
|
|
|
200
202
|
debug
|
|
201
203
|
]
|
|
202
204
|
);
|
|
203
|
-
const getFieldProps =
|
|
205
|
+
const getFieldProps = React4.useCallback(
|
|
204
206
|
(field) => {
|
|
205
207
|
return {
|
|
206
208
|
name: String(field),
|
|
@@ -211,7 +213,7 @@ function useForm(options) {
|
|
|
211
213
|
},
|
|
212
214
|
[state$, setFieldValue, setFieldTouched]
|
|
213
215
|
);
|
|
214
|
-
const getFieldMeta =
|
|
216
|
+
const getFieldMeta = React4.useCallback(
|
|
215
217
|
(field) => {
|
|
216
218
|
const fieldKey = String(field);
|
|
217
219
|
const metadata = fieldMetadataActions.get(fieldKey);
|
|
@@ -270,13 +272,13 @@ function useForm(options) {
|
|
|
270
272
|
getFieldMeta
|
|
271
273
|
};
|
|
272
274
|
}
|
|
273
|
-
var FormContext =
|
|
275
|
+
var FormContext = React4__namespace.createContext(null);
|
|
274
276
|
FormContext.displayName = "FormContext";
|
|
275
277
|
|
|
276
278
|
// src/core/useField.ts
|
|
277
279
|
function useField(options) {
|
|
278
280
|
const { name, validate, transform } = options;
|
|
279
|
-
const form =
|
|
281
|
+
const form = React4.useContext(FormContext);
|
|
280
282
|
if (!form) {
|
|
281
283
|
throw new Error(
|
|
282
284
|
"useField must be used within a FormContext. Wrap your component with <Form> or use useForm's getFieldProps instead."
|
|
@@ -305,20 +307,20 @@ function useField(options) {
|
|
|
305
307
|
};
|
|
306
308
|
const meta = form.getFieldMeta(name);
|
|
307
309
|
const helpers = {
|
|
308
|
-
setValue:
|
|
310
|
+
setValue: React4.useCallback(
|
|
309
311
|
(value) => {
|
|
310
312
|
const transformedValue = transform ? transform(value) : value;
|
|
311
313
|
form.setFieldValue(name, transformedValue);
|
|
312
314
|
},
|
|
313
315
|
[name, transform, form]
|
|
314
316
|
),
|
|
315
|
-
setTouched:
|
|
317
|
+
setTouched: React4.useCallback(
|
|
316
318
|
(touched) => {
|
|
317
319
|
form.setFieldTouched(name, touched);
|
|
318
320
|
},
|
|
319
321
|
[name, form]
|
|
320
322
|
),
|
|
321
|
-
setError:
|
|
323
|
+
setError: React4.useCallback(
|
|
322
324
|
(error) => {
|
|
323
325
|
form.setFieldError(name, error);
|
|
324
326
|
},
|
|
@@ -338,7 +340,7 @@ function cn(...inputs) {
|
|
|
338
340
|
// src/core/form-feedback.tsx
|
|
339
341
|
function renderMessage(message, fallbackClassName, className) {
|
|
340
342
|
if (typeof message === "string") {
|
|
341
|
-
return /* @__PURE__ */
|
|
343
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
342
344
|
"p",
|
|
343
345
|
{
|
|
344
346
|
className: cn(
|
|
@@ -349,7 +351,7 @@ function renderMessage(message, fallbackClassName, className) {
|
|
|
349
351
|
message
|
|
350
352
|
);
|
|
351
353
|
}
|
|
352
|
-
return /* @__PURE__ */
|
|
354
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { className: cn(fallbackClassName, className) }, message);
|
|
353
355
|
}
|
|
354
356
|
function FormFeedback({
|
|
355
357
|
successMessage,
|
|
@@ -360,7 +362,7 @@ function FormFeedback({
|
|
|
360
362
|
if (!successMessage && !submissionError) {
|
|
361
363
|
return null;
|
|
362
364
|
}
|
|
363
|
-
return /* @__PURE__ */
|
|
365
|
+
return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, successMessage ? /* @__PURE__ */ React4__namespace.createElement(
|
|
364
366
|
"div",
|
|
365
367
|
{
|
|
366
368
|
className: cn(
|
|
@@ -375,7 +377,7 @@ function FormFeedback({
|
|
|
375
377
|
"text-primary-foreground",
|
|
376
378
|
"text-primary-foreground"
|
|
377
379
|
)
|
|
378
|
-
) : null, submissionError ? /* @__PURE__ */
|
|
380
|
+
) : null, submissionError ? /* @__PURE__ */ React4__namespace.createElement(
|
|
379
381
|
"div",
|
|
380
382
|
{
|
|
381
383
|
className: cn(
|
|
@@ -393,6 +395,54 @@ function FormFeedback({
|
|
|
393
395
|
) : null);
|
|
394
396
|
}
|
|
395
397
|
FormFeedback.displayName = "FormFeedback";
|
|
398
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
399
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 aria-invalid:border-destructive",
|
|
400
|
+
{
|
|
401
|
+
variants: {
|
|
402
|
+
variant: {
|
|
403
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
404
|
+
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20",
|
|
405
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
406
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
407
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
408
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
409
|
+
},
|
|
410
|
+
size: {
|
|
411
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
412
|
+
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
413
|
+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
414
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
415
|
+
icon: "size-9",
|
|
416
|
+
"icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
417
|
+
"icon-sm": "size-8",
|
|
418
|
+
"icon-lg": "size-10"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
defaultVariants: {
|
|
422
|
+
variant: "default",
|
|
423
|
+
size: "default"
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
function Button({
|
|
428
|
+
className,
|
|
429
|
+
variant = "default",
|
|
430
|
+
size = "default",
|
|
431
|
+
asChild = false,
|
|
432
|
+
...props
|
|
433
|
+
}) {
|
|
434
|
+
const Comp = asChild ? radixUi.Slot.Root : "button";
|
|
435
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
436
|
+
Comp,
|
|
437
|
+
{
|
|
438
|
+
"data-slot": "button",
|
|
439
|
+
"data-variant": variant,
|
|
440
|
+
"data-size": size,
|
|
441
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
442
|
+
...props
|
|
443
|
+
}
|
|
444
|
+
);
|
|
445
|
+
}
|
|
396
446
|
|
|
397
447
|
// src/core/Form.tsx
|
|
398
448
|
function Form({
|
|
@@ -400,7 +450,7 @@ function Form({
|
|
|
400
450
|
children,
|
|
401
451
|
className,
|
|
402
452
|
action,
|
|
403
|
-
method
|
|
453
|
+
method,
|
|
404
454
|
noValidate = true,
|
|
405
455
|
submissionConfig,
|
|
406
456
|
successMessage,
|
|
@@ -408,9 +458,12 @@ function Form({
|
|
|
408
458
|
successMessageClassName,
|
|
409
459
|
errorMessageClassName,
|
|
410
460
|
onNewSubmission,
|
|
461
|
+
notificationConfig,
|
|
462
|
+
styleConfig,
|
|
463
|
+
formConfig,
|
|
411
464
|
...props
|
|
412
465
|
}) {
|
|
413
|
-
const handleFormSubmit =
|
|
466
|
+
const handleFormSubmit = React4__namespace.useCallback(
|
|
414
467
|
async (e) => {
|
|
415
468
|
try {
|
|
416
469
|
await form.handleSubmit(e);
|
|
@@ -419,71 +472,102 @@ function Form({
|
|
|
419
472
|
},
|
|
420
473
|
[form]
|
|
421
474
|
);
|
|
422
|
-
const
|
|
423
|
-
const
|
|
424
|
-
const
|
|
475
|
+
const resolvedClassName = className ?? styleConfig?.formClassName;
|
|
476
|
+
const resolvedAction = action ?? formConfig?.endpoint;
|
|
477
|
+
const resolvedMethod = method ?? formConfig?.method ?? "post";
|
|
478
|
+
const resolvedSubmissionConfig = submissionConfig ?? formConfig?.submissionConfig;
|
|
479
|
+
const resolvedSuccessMessage = successMessage ?? notificationConfig?.successMessage;
|
|
480
|
+
const resolvedSubmissionError = submissionError ?? notificationConfig?.submissionError;
|
|
481
|
+
const resolvedSuccessMessageClassName = successMessageClassName ?? styleConfig?.successMessageClassName;
|
|
482
|
+
const resolvedErrorMessageClassName = errorMessageClassName ?? styleConfig?.errorMessageClassName;
|
|
483
|
+
const behavior = resolvedSubmissionConfig?.behavior || "showConfirmation";
|
|
484
|
+
const shouldManageSubmissionUi = resolvedSubmissionConfig !== void 0 || resolvedSuccessMessage !== void 0 || resolvedSuccessMessageClassName !== void 0 || resolvedErrorMessageClassName !== void 0 || resolvedSubmissionError != null || onNewSubmission !== void 0;
|
|
485
|
+
const hasSubmissionError = Boolean(resolvedSubmissionError);
|
|
425
486
|
const isSubmissionSuccessful = shouldManageSubmissionUi && form.status === "success" && !hasSubmissionError;
|
|
426
487
|
const defaultSuccessMessage = behavior === "redirect" ? "Form submitted successfully. Redirecting..." : "Thank you. Your form has been submitted successfully.";
|
|
427
|
-
const
|
|
428
|
-
const shouldRenderCustomComponent = isSubmissionSuccessful && behavior === "renderCustomComponent" && Boolean(
|
|
429
|
-
const newSubmissionAction =
|
|
488
|
+
const finalSuccessMessage = resolvedSuccessMessage ?? defaultSuccessMessage;
|
|
489
|
+
const shouldRenderCustomComponent = isSubmissionSuccessful && behavior === "renderCustomComponent" && Boolean(resolvedSubmissionConfig?.customComponent);
|
|
490
|
+
const newSubmissionAction = resolvedSubmissionConfig?.newFormSubmissionAction;
|
|
430
491
|
const showNewSubmissionAction = isSubmissionSuccessful && (typeof newSubmissionAction?.enable === "boolean" ? newSubmissionAction.enable : Boolean(newSubmissionAction?.label));
|
|
431
492
|
const newSubmissionLabel = newSubmissionAction?.label ?? "Submit another response";
|
|
432
|
-
const handleNewSubmission =
|
|
493
|
+
const handleNewSubmission = React4__namespace.useCallback(() => {
|
|
433
494
|
form.resetForm();
|
|
434
495
|
onNewSubmission?.();
|
|
435
496
|
}, [form, onNewSubmission]);
|
|
436
|
-
return /* @__PURE__ */
|
|
497
|
+
return /* @__PURE__ */ React4__namespace.createElement(FormContext.Provider, { value: form }, /* @__PURE__ */ React4__namespace.createElement(
|
|
437
498
|
"form",
|
|
438
499
|
{
|
|
439
500
|
onSubmit: handleFormSubmit,
|
|
440
|
-
action,
|
|
441
|
-
method,
|
|
501
|
+
action: resolvedAction,
|
|
502
|
+
method: resolvedMethod,
|
|
442
503
|
noValidate,
|
|
443
|
-
className,
|
|
504
|
+
className: resolvedClassName,
|
|
444
505
|
...props
|
|
445
506
|
},
|
|
446
|
-
isSubmissionSuccessful ? /* @__PURE__ */
|
|
507
|
+
isSubmissionSuccessful ? /* @__PURE__ */ React4__namespace.createElement("div", { className: "space-y-4" }, shouldRenderCustomComponent ? resolvedSubmissionConfig?.customComponent : /* @__PURE__ */ React4__namespace.createElement(
|
|
447
508
|
FormFeedback,
|
|
448
509
|
{
|
|
449
|
-
successMessage:
|
|
450
|
-
successMessageClassName
|
|
510
|
+
successMessage: finalSuccessMessage,
|
|
511
|
+
successMessageClassName: resolvedSuccessMessageClassName
|
|
451
512
|
}
|
|
452
|
-
), showNewSubmissionAction ? /* @__PURE__ */
|
|
453
|
-
|
|
513
|
+
), showNewSubmissionAction ? /* @__PURE__ */ React4__namespace.createElement(
|
|
514
|
+
Button,
|
|
454
515
|
{
|
|
455
516
|
type: "button",
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md border border-input bg-transparent px-4 py-2 text-sm font-medium shadow-sm transition-colors",
|
|
459
|
-
"hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
460
|
-
)
|
|
517
|
+
variant: "outline",
|
|
518
|
+
onClick: handleNewSubmission
|
|
461
519
|
},
|
|
462
520
|
newSubmissionLabel
|
|
463
|
-
) : null) : /* @__PURE__ */
|
|
521
|
+
) : null) : /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, children, resolvedSubmissionError ? /* @__PURE__ */ React4__namespace.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React4__namespace.createElement(
|
|
464
522
|
FormFeedback,
|
|
465
523
|
{
|
|
466
|
-
submissionError,
|
|
467
|
-
errorMessageClassName
|
|
524
|
+
submissionError: resolvedSubmissionError,
|
|
525
|
+
errorMessageClassName: resolvedErrorMessageClassName
|
|
468
526
|
}
|
|
469
527
|
)) : null)
|
|
470
528
|
));
|
|
471
529
|
}
|
|
472
530
|
Form.displayName = "Form";
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
531
|
+
function Label({
|
|
532
|
+
className,
|
|
533
|
+
...props
|
|
534
|
+
}) {
|
|
535
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
536
|
+
radixUi.Label.Root,
|
|
476
537
|
{
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
538
|
+
"data-slot": "label",
|
|
539
|
+
className: cn(
|
|
540
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
541
|
+
className
|
|
542
|
+
),
|
|
480
543
|
...props
|
|
481
544
|
}
|
|
482
545
|
);
|
|
483
|
-
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/components/ui/field.tsx
|
|
549
|
+
var Field = React4__namespace.forwardRef(
|
|
550
|
+
({ className, orientation = "vertical", invalid = false, ...props }, ref) => {
|
|
551
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
552
|
+
"div",
|
|
553
|
+
{
|
|
554
|
+
ref,
|
|
555
|
+
"data-slot": "field",
|
|
556
|
+
"data-orientation": orientation,
|
|
557
|
+
"data-invalid": invalid || void 0,
|
|
558
|
+
className: cn(
|
|
559
|
+
"flex",
|
|
560
|
+
orientation === "horizontal" ? "items-center gap-2" : "flex-col gap-1.5",
|
|
561
|
+
className
|
|
562
|
+
),
|
|
563
|
+
...props
|
|
564
|
+
}
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
);
|
|
484
568
|
Field.displayName = "Field";
|
|
485
|
-
var FieldGroup =
|
|
486
|
-
return /* @__PURE__ */
|
|
569
|
+
var FieldGroup = React4__namespace.forwardRef(({ className, ...props }, ref) => {
|
|
570
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
487
571
|
"div",
|
|
488
572
|
{
|
|
489
573
|
ref,
|
|
@@ -494,9 +578,9 @@ var FieldGroup = React3__namespace.forwardRef(({ className, ...props }, ref) =>
|
|
|
494
578
|
);
|
|
495
579
|
});
|
|
496
580
|
FieldGroup.displayName = "FieldGroup";
|
|
497
|
-
var FieldLabel =
|
|
498
|
-
return /* @__PURE__ */
|
|
499
|
-
|
|
581
|
+
var FieldLabel = React4__namespace.forwardRef(({ className, required, children, ...props }, ref) => {
|
|
582
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
583
|
+
Label,
|
|
500
584
|
{
|
|
501
585
|
ref,
|
|
502
586
|
"data-slot": "field-label",
|
|
@@ -508,12 +592,12 @@ var FieldLabel = React3__namespace.forwardRef(({ className, required, children,
|
|
|
508
592
|
...props
|
|
509
593
|
},
|
|
510
594
|
children,
|
|
511
|
-
required && /* @__PURE__ */
|
|
595
|
+
required && /* @__PURE__ */ React4__namespace.createElement("span", { className: "text-destructive ml-1" }, "*")
|
|
512
596
|
);
|
|
513
597
|
});
|
|
514
598
|
FieldLabel.displayName = "FieldLabel";
|
|
515
|
-
var FieldDescription =
|
|
516
|
-
return /* @__PURE__ */
|
|
599
|
+
var FieldDescription = React4__namespace.forwardRef(({ className, ...props }, ref) => {
|
|
600
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
517
601
|
"p",
|
|
518
602
|
{
|
|
519
603
|
ref,
|
|
@@ -524,8 +608,8 @@ var FieldDescription = React3__namespace.forwardRef(({ className, ...props }, re
|
|
|
524
608
|
);
|
|
525
609
|
});
|
|
526
610
|
FieldDescription.displayName = "FieldDescription";
|
|
527
|
-
var FieldError =
|
|
528
|
-
return /* @__PURE__ */
|
|
611
|
+
var FieldError = React4__namespace.forwardRef(({ className, ...props }, ref) => {
|
|
612
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
529
613
|
"p",
|
|
530
614
|
{
|
|
531
615
|
ref,
|
|
@@ -548,7 +632,7 @@ var FieldFeedback = ({
|
|
|
548
632
|
}) => {
|
|
549
633
|
const errorText = Array.isArray(error) ? error.join(", ") : error;
|
|
550
634
|
if (!errorText || !shouldRenderError) return null;
|
|
551
|
-
return /* @__PURE__ */
|
|
635
|
+
return /* @__PURE__ */ React4__namespace.createElement(FieldError, { id: errorId, className: errorClassName }, errorText);
|
|
552
636
|
};
|
|
553
637
|
var LabelGroup = ({
|
|
554
638
|
labelHtmlFor,
|
|
@@ -565,40 +649,38 @@ var LabelGroup = ({
|
|
|
565
649
|
variant === "legend" ? "mb-1.5" : "mb-1 block",
|
|
566
650
|
primaryClassName
|
|
567
651
|
);
|
|
568
|
-
const requiredIndicator = required ? /* @__PURE__ */
|
|
652
|
+
const requiredIndicator = required && variant !== "label" ? /* @__PURE__ */ React4__namespace.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
|
|
569
653
|
let primaryElement = null;
|
|
570
654
|
if (primary) {
|
|
571
655
|
if (variant === "label") {
|
|
572
|
-
primaryElement = /* @__PURE__ */
|
|
573
|
-
|
|
656
|
+
primaryElement = /* @__PURE__ */ React4__namespace.createElement(
|
|
657
|
+
FieldLabel,
|
|
574
658
|
{
|
|
575
659
|
htmlFor: labelHtmlFor,
|
|
576
|
-
|
|
660
|
+
required,
|
|
577
661
|
className: primaryClasses
|
|
578
662
|
},
|
|
579
|
-
primary
|
|
580
|
-
requiredIndicator
|
|
663
|
+
primary
|
|
581
664
|
);
|
|
582
665
|
} else if (variant === "legend") {
|
|
583
|
-
primaryElement = /* @__PURE__ */
|
|
666
|
+
primaryElement = /* @__PURE__ */ React4__namespace.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
|
|
584
667
|
} else {
|
|
585
|
-
primaryElement = /* @__PURE__ */
|
|
668
|
+
primaryElement = /* @__PURE__ */ React4__namespace.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
|
|
586
669
|
}
|
|
587
670
|
}
|
|
588
|
-
const secondaryElement = secondary ? /* @__PURE__ */
|
|
589
|
-
|
|
671
|
+
const secondaryElement = secondary ? /* @__PURE__ */ React4__namespace.createElement(
|
|
672
|
+
FieldDescription,
|
|
590
673
|
{
|
|
591
|
-
"data-slot": "field-description",
|
|
592
674
|
id: secondaryId,
|
|
593
|
-
className: cn("
|
|
675
|
+
className: cn("leading-normal font-normal", secondaryClassName)
|
|
594
676
|
},
|
|
595
677
|
secondary
|
|
596
678
|
) : null;
|
|
597
679
|
if (!primaryElement && !secondaryElement) return null;
|
|
598
680
|
if (variant === "legend") {
|
|
599
|
-
return /* @__PURE__ */
|
|
681
|
+
return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, primaryElement, secondaryElement);
|
|
600
682
|
}
|
|
601
|
-
return /* @__PURE__ */
|
|
683
|
+
return /* @__PURE__ */ React4__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
|
|
602
684
|
};
|
|
603
685
|
|
|
604
686
|
// src/core/Field.tsx
|
|
@@ -615,30 +697,40 @@ function Field2({
|
|
|
615
697
|
}) {
|
|
616
698
|
const fieldState = useField({ name, validate });
|
|
617
699
|
const { meta } = fieldState;
|
|
618
|
-
const hasError =
|
|
700
|
+
const hasError = React4__namespace.useMemo(() => {
|
|
619
701
|
return showError && meta.touched && meta.error ? true : false;
|
|
620
702
|
}, [meta?.touched, meta?.error, showError]);
|
|
621
703
|
const errorId = `${name}-error`;
|
|
622
704
|
const descriptionId = `${name}-description`;
|
|
623
|
-
return /* @__PURE__ */
|
|
624
|
-
|
|
705
|
+
return /* @__PURE__ */ React4__namespace.createElement(
|
|
706
|
+
Field,
|
|
625
707
|
{
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
708
|
+
className,
|
|
709
|
+
"data-field": name,
|
|
710
|
+
invalid: hasError
|
|
711
|
+
},
|
|
712
|
+
/* @__PURE__ */ React4__namespace.createElement(
|
|
713
|
+
LabelGroup,
|
|
714
|
+
{
|
|
715
|
+
labelHtmlFor: name,
|
|
716
|
+
required,
|
|
717
|
+
variant: "label",
|
|
718
|
+
secondaryId: descriptionId,
|
|
719
|
+
secondary: description,
|
|
720
|
+
primary: label
|
|
721
|
+
}
|
|
722
|
+
),
|
|
723
|
+
/* @__PURE__ */ React4__namespace.createElement("div", { "data-slot": "field-control" }, typeof children === "function" ? children(fieldState) : children),
|
|
724
|
+
/* @__PURE__ */ React4__namespace.createElement(
|
|
725
|
+
FieldFeedback,
|
|
726
|
+
{
|
|
727
|
+
errorId,
|
|
728
|
+
errorClassName,
|
|
729
|
+
shouldRenderError: hasError,
|
|
730
|
+
error: meta.error
|
|
731
|
+
}
|
|
732
|
+
)
|
|
733
|
+
);
|
|
642
734
|
}
|
|
643
735
|
Field2.displayName = "Field";
|
|
644
736
|
|