@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 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 muted highlight styles
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 React3 = require('react');
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 React3__namespace = /*#__PURE__*/_interopNamespace(React3);
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 = React3.useRef(/* @__PURE__ */ new Set());
52
+ const validationInProgress = React4.useRef(/* @__PURE__ */ new Set());
51
53
  const [, fieldMetadataActions] = useMap.useMap();
52
- const validateField = React3.useCallback(
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 = React3.useCallback(async () => {
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 = React3.useCallback(
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 = React3.useCallback(
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 = React3.useCallback(() => {
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 = React3.useCallback(
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 = React3.useCallback(
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 = React3.useCallback(
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 = React3__namespace.createContext(null);
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 = React3.useContext(FormContext);
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: React3.useCallback(
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: React3.useCallback(
317
+ setTouched: React4.useCallback(
316
318
  (touched) => {
317
319
  form.setFieldTouched(name, touched);
318
320
  },
319
321
  [name, form]
320
322
  ),
321
- setError: React3.useCallback(
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__ */ React3__namespace.createElement(
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__ */ React3__namespace.createElement("div", { className: cn(fallbackClassName, className) }, message);
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__ */ React3__namespace.createElement(React3__namespace.Fragment, null, successMessage ? /* @__PURE__ */ React3__namespace.createElement(
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__ */ React3__namespace.createElement(
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 = "post",
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 = React3__namespace.useCallback(
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 behavior = submissionConfig?.behavior || "showConfirmation";
423
- const shouldManageSubmissionUi = submissionConfig !== void 0 || successMessage !== void 0 || successMessageClassName !== void 0 || errorMessageClassName !== void 0 || submissionError != null || onNewSubmission !== void 0;
424
- const hasSubmissionError = Boolean(submissionError);
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 resolvedSuccessMessage = successMessage ?? defaultSuccessMessage;
428
- const shouldRenderCustomComponent = isSubmissionSuccessful && behavior === "renderCustomComponent" && Boolean(submissionConfig?.customComponent);
429
- const newSubmissionAction = submissionConfig?.newFormSubmissionAction;
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 = React3__namespace.useCallback(() => {
493
+ const handleNewSubmission = React4__namespace.useCallback(() => {
433
494
  form.resetForm();
434
495
  onNewSubmission?.();
435
496
  }, [form, onNewSubmission]);
436
- return /* @__PURE__ */ React3__namespace.createElement(FormContext.Provider, { value: form }, /* @__PURE__ */ React3__namespace.createElement(
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__ */ React3__namespace.createElement("div", { className: "space-y-4" }, shouldRenderCustomComponent ? submissionConfig?.customComponent : /* @__PURE__ */ React3__namespace.createElement(
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: resolvedSuccessMessage,
450
- successMessageClassName
510
+ successMessage: finalSuccessMessage,
511
+ successMessageClassName: resolvedSuccessMessageClassName
451
512
  }
452
- ), showNewSubmissionAction ? /* @__PURE__ */ React3__namespace.createElement(
453
- "button",
513
+ ), showNewSubmissionAction ? /* @__PURE__ */ React4__namespace.createElement(
514
+ Button,
454
515
  {
455
516
  type: "button",
456
- onClick: handleNewSubmission,
457
- className: cn(
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__ */ React3__namespace.createElement(React3__namespace.Fragment, null, children, submissionError ? /* @__PURE__ */ React3__namespace.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React3__namespace.createElement(
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
- var Field = React3__namespace.forwardRef(({ className, ...props }, ref) => {
474
- return /* @__PURE__ */ React3__namespace.createElement(
475
- "div",
531
+ function Label({
532
+ className,
533
+ ...props
534
+ }) {
535
+ return /* @__PURE__ */ React4__namespace.createElement(
536
+ radixUi.Label.Root,
476
537
  {
477
- ref,
478
- "data-slot": "field",
479
- className: cn("flex flex-col gap-1.5", className),
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 = React3__namespace.forwardRef(({ className, ...props }, ref) => {
486
- return /* @__PURE__ */ React3__namespace.createElement(
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 = React3__namespace.forwardRef(({ className, required, children, ...props }, ref) => {
498
- return /* @__PURE__ */ React3__namespace.createElement(
499
- "label",
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__ */ React3__namespace.createElement("span", { className: "text-destructive ml-1" }, "*")
595
+ required && /* @__PURE__ */ React4__namespace.createElement("span", { className: "text-destructive ml-1" }, "*")
512
596
  );
513
597
  });
514
598
  FieldLabel.displayName = "FieldLabel";
515
- var FieldDescription = React3__namespace.forwardRef(({ className, ...props }, ref) => {
516
- return /* @__PURE__ */ React3__namespace.createElement(
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 = React3__namespace.forwardRef(({ className, ...props }, ref) => {
528
- return /* @__PURE__ */ React3__namespace.createElement(
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__ */ React3__namespace.createElement(FieldError, { id: errorId, className: errorClassName }, errorText);
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__ */ React3__namespace.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
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__ */ React3__namespace.createElement(
573
- "label",
656
+ primaryElement = /* @__PURE__ */ React4__namespace.createElement(
657
+ FieldLabel,
574
658
  {
575
659
  htmlFor: labelHtmlFor,
576
- "data-slot": "field-label",
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__ */ React3__namespace.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
666
+ primaryElement = /* @__PURE__ */ React4__namespace.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
584
667
  } else {
585
- primaryElement = /* @__PURE__ */ React3__namespace.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
668
+ primaryElement = /* @__PURE__ */ React4__namespace.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
586
669
  }
587
670
  }
588
- const secondaryElement = secondary ? /* @__PURE__ */ React3__namespace.createElement(
589
- "p",
671
+ const secondaryElement = secondary ? /* @__PURE__ */ React4__namespace.createElement(
672
+ FieldDescription,
590
673
  {
591
- "data-slot": "field-description",
592
674
  id: secondaryId,
593
- className: cn("text-sm leading-normal font-normal", secondaryClassName)
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__ */ React3__namespace.createElement(React3__namespace.Fragment, null, primaryElement, secondaryElement);
681
+ return /* @__PURE__ */ React4__namespace.createElement(React4__namespace.Fragment, null, primaryElement, secondaryElement);
600
682
  }
601
- return /* @__PURE__ */ React3__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
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 = React3__namespace.useMemo(() => {
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__ */ React3__namespace.createElement("div", { className, "data-field": name }, /* @__PURE__ */ React3__namespace.createElement(
624
- LabelGroup,
705
+ return /* @__PURE__ */ React4__namespace.createElement(
706
+ Field,
625
707
  {
626
- labelHtmlFor: name,
627
- required,
628
- variant: "label",
629
- secondaryId: descriptionId,
630
- secondary: description,
631
- primary: label
632
- }
633
- ), /* @__PURE__ */ React3__namespace.createElement("div", null, typeof children === "function" ? children(fieldState) : children), /* @__PURE__ */ React3__namespace.createElement(
634
- FieldFeedback,
635
- {
636
- errorId,
637
- errorClassName,
638
- shouldRenderError: hasError,
639
- error: meta.error
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