@page-speed/forms 0.4.9 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.js CHANGED
@@ -1,9 +1,11 @@
1
- import * as React3 from 'react';
1
+ import * as React4 from 'react';
2
2
  import { useRef, useCallback, useContext } from 'react';
3
3
  import { useObservable, useSelector } from '@legendapp/state/react';
4
4
  import { useMap } from '@opensite/hooks/useMap';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
+ import { cva } from 'class-variance-authority';
8
+ import { Label as Label$1, Slot } from 'radix-ui';
7
9
 
8
10
  // src/core/useForm.ts
9
11
  function useForm(options) {
@@ -249,7 +251,7 @@ function useForm(options) {
249
251
  getFieldMeta
250
252
  };
251
253
  }
252
- var FormContext = React3.createContext(null);
254
+ var FormContext = React4.createContext(null);
253
255
  FormContext.displayName = "FormContext";
254
256
 
255
257
  // src/core/useField.ts
@@ -317,7 +319,7 @@ function cn(...inputs) {
317
319
  // src/core/form-feedback.tsx
318
320
  function renderMessage(message, fallbackClassName, className) {
319
321
  if (typeof message === "string") {
320
- return /* @__PURE__ */ React3.createElement(
322
+ return /* @__PURE__ */ React4.createElement(
321
323
  "p",
322
324
  {
323
325
  className: cn(
@@ -328,7 +330,7 @@ function renderMessage(message, fallbackClassName, className) {
328
330
  message
329
331
  );
330
332
  }
331
- return /* @__PURE__ */ React3.createElement("div", { className: cn(fallbackClassName, className) }, message);
333
+ return /* @__PURE__ */ React4.createElement("div", { className: cn(fallbackClassName, className) }, message);
332
334
  }
333
335
  function FormFeedback({
334
336
  successMessage,
@@ -339,7 +341,7 @@ function FormFeedback({
339
341
  if (!successMessage && !submissionError) {
340
342
  return null;
341
343
  }
342
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, successMessage ? /* @__PURE__ */ React3.createElement(
344
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, successMessage ? /* @__PURE__ */ React4.createElement(
343
345
  "div",
344
346
  {
345
347
  className: cn(
@@ -354,7 +356,7 @@ function FormFeedback({
354
356
  "text-primary-foreground",
355
357
  "text-primary-foreground"
356
358
  )
357
- ) : null, submissionError ? /* @__PURE__ */ React3.createElement(
359
+ ) : null, submissionError ? /* @__PURE__ */ React4.createElement(
358
360
  "div",
359
361
  {
360
362
  className: cn(
@@ -372,6 +374,54 @@ function FormFeedback({
372
374
  ) : null);
373
375
  }
374
376
  FormFeedback.displayName = "FormFeedback";
377
+ var buttonVariants = cva(
378
+ "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",
379
+ {
380
+ variants: {
381
+ variant: {
382
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
383
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20",
384
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
385
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
386
+ ghost: "hover:bg-accent hover:text-accent-foreground",
387
+ link: "text-primary underline-offset-4 hover:underline"
388
+ },
389
+ size: {
390
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
391
+ xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
392
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
393
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
394
+ icon: "size-9",
395
+ "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
396
+ "icon-sm": "size-8",
397
+ "icon-lg": "size-10"
398
+ }
399
+ },
400
+ defaultVariants: {
401
+ variant: "default",
402
+ size: "default"
403
+ }
404
+ }
405
+ );
406
+ function Button({
407
+ className,
408
+ variant = "default",
409
+ size = "default",
410
+ asChild = false,
411
+ ...props
412
+ }) {
413
+ const Comp = asChild ? Slot.Root : "button";
414
+ return /* @__PURE__ */ React4.createElement(
415
+ Comp,
416
+ {
417
+ "data-slot": "button",
418
+ "data-variant": variant,
419
+ "data-size": size,
420
+ className: cn(buttonVariants({ variant, size, className })),
421
+ ...props
422
+ }
423
+ );
424
+ }
375
425
 
376
426
  // src/core/Form.tsx
377
427
  function Form({
@@ -389,7 +439,7 @@ function Form({
389
439
  onNewSubmission,
390
440
  ...props
391
441
  }) {
392
- const handleFormSubmit = React3.useCallback(
442
+ const handleFormSubmit = React4.useCallback(
393
443
  async (e) => {
394
444
  try {
395
445
  await form.handleSubmit(e);
@@ -408,11 +458,11 @@ function Form({
408
458
  const newSubmissionAction = submissionConfig?.newFormSubmissionAction;
409
459
  const showNewSubmissionAction = isSubmissionSuccessful && (typeof newSubmissionAction?.enable === "boolean" ? newSubmissionAction.enable : Boolean(newSubmissionAction?.label));
410
460
  const newSubmissionLabel = newSubmissionAction?.label ?? "Submit another response";
411
- const handleNewSubmission = React3.useCallback(() => {
461
+ const handleNewSubmission = React4.useCallback(() => {
412
462
  form.resetForm();
413
463
  onNewSubmission?.();
414
464
  }, [form, onNewSubmission]);
415
- return /* @__PURE__ */ React3.createElement(FormContext.Provider, { value: form }, /* @__PURE__ */ React3.createElement(
465
+ return /* @__PURE__ */ React4.createElement(FormContext.Provider, { value: form }, /* @__PURE__ */ React4.createElement(
416
466
  "form",
417
467
  {
418
468
  onSubmit: handleFormSubmit,
@@ -422,24 +472,21 @@ function Form({
422
472
  className,
423
473
  ...props
424
474
  },
425
- isSubmissionSuccessful ? /* @__PURE__ */ React3.createElement("div", { className: "space-y-4" }, shouldRenderCustomComponent ? submissionConfig?.customComponent : /* @__PURE__ */ React3.createElement(
475
+ isSubmissionSuccessful ? /* @__PURE__ */ React4.createElement("div", { className: "space-y-4" }, shouldRenderCustomComponent ? submissionConfig?.customComponent : /* @__PURE__ */ React4.createElement(
426
476
  FormFeedback,
427
477
  {
428
478
  successMessage: resolvedSuccessMessage,
429
479
  successMessageClassName
430
480
  }
431
- ), showNewSubmissionAction ? /* @__PURE__ */ React3.createElement(
432
- "button",
481
+ ), showNewSubmissionAction ? /* @__PURE__ */ React4.createElement(
482
+ Button,
433
483
  {
434
484
  type: "button",
435
- onClick: handleNewSubmission,
436
- className: cn(
437
- "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",
438
- "hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
439
- )
485
+ variant: "outline",
486
+ onClick: handleNewSubmission
440
487
  },
441
488
  newSubmissionLabel
442
- ) : null) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, children, submissionError ? /* @__PURE__ */ React3.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React3.createElement(
489
+ ) : null) : /* @__PURE__ */ React4.createElement(React4.Fragment, null, children, submissionError ? /* @__PURE__ */ React4.createElement("div", { className: "mt-4" }, /* @__PURE__ */ React4.createElement(
443
490
  FormFeedback,
444
491
  {
445
492
  submissionError,
@@ -449,6 +496,102 @@ function Form({
449
496
  ));
450
497
  }
451
498
  Form.displayName = "Form";
499
+ function Label({
500
+ className,
501
+ ...props
502
+ }) {
503
+ return /* @__PURE__ */ React4.createElement(
504
+ Label$1.Root,
505
+ {
506
+ "data-slot": "label",
507
+ className: cn(
508
+ "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",
509
+ className
510
+ ),
511
+ ...props
512
+ }
513
+ );
514
+ }
515
+
516
+ // src/components/ui/field.tsx
517
+ var Field = React4.forwardRef(
518
+ ({ className, orientation = "vertical", invalid = false, ...props }, ref) => {
519
+ return /* @__PURE__ */ React4.createElement(
520
+ "div",
521
+ {
522
+ ref,
523
+ "data-slot": "field",
524
+ "data-orientation": orientation,
525
+ "data-invalid": invalid || void 0,
526
+ className: cn(
527
+ "flex",
528
+ orientation === "horizontal" ? "items-center gap-2" : "flex-col gap-1.5",
529
+ className
530
+ ),
531
+ ...props
532
+ }
533
+ );
534
+ }
535
+ );
536
+ Field.displayName = "Field";
537
+ var FieldGroup = React4.forwardRef(({ className, ...props }, ref) => {
538
+ return /* @__PURE__ */ React4.createElement(
539
+ "div",
540
+ {
541
+ ref,
542
+ "data-slot": "field-group",
543
+ className: cn("flex flex-col gap-4", className),
544
+ ...props
545
+ }
546
+ );
547
+ });
548
+ FieldGroup.displayName = "FieldGroup";
549
+ var FieldLabel = React4.forwardRef(({ className, required, children, ...props }, ref) => {
550
+ return /* @__PURE__ */ React4.createElement(
551
+ Label,
552
+ {
553
+ ref,
554
+ "data-slot": "field-label",
555
+ className: cn(
556
+ "text-sm font-medium leading-none select-none",
557
+ "peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
558
+ className
559
+ ),
560
+ ...props
561
+ },
562
+ children,
563
+ required && /* @__PURE__ */ React4.createElement("span", { className: "text-destructive ml-1" }, "*")
564
+ );
565
+ });
566
+ FieldLabel.displayName = "FieldLabel";
567
+ var FieldDescription = React4.forwardRef(({ className, ...props }, ref) => {
568
+ return /* @__PURE__ */ React4.createElement(
569
+ "p",
570
+ {
571
+ ref,
572
+ "data-slot": "field-description",
573
+ className: cn("text-sm opacity-70", className),
574
+ ...props
575
+ }
576
+ );
577
+ });
578
+ FieldDescription.displayName = "FieldDescription";
579
+ var FieldError = React4.forwardRef(({ className, ...props }, ref) => {
580
+ return /* @__PURE__ */ React4.createElement(
581
+ "p",
582
+ {
583
+ ref,
584
+ "data-slot": "field-error",
585
+ role: "alert",
586
+ "aria-live": "polite",
587
+ className: cn("text-sm text-destructive", className),
588
+ ...props
589
+ }
590
+ );
591
+ });
592
+ FieldError.displayName = "FieldError";
593
+
594
+ // src/core/field-feedback.tsx
452
595
  var FieldFeedback = ({
453
596
  errorId,
454
597
  errorClassName,
@@ -457,22 +600,7 @@ var FieldFeedback = ({
457
600
  }) => {
458
601
  const errorText = Array.isArray(error) ? error.join(", ") : error;
459
602
  if (!errorText || !shouldRenderError) return null;
460
- return /* @__PURE__ */ React3.createElement(
461
- "div",
462
- {
463
- id: errorId,
464
- className: cn(
465
- "text-xs px-3 py-2 font-medium",
466
- "rounded-md shadow-md mt-2",
467
- "text-destructive-foreground bg-destructive",
468
- "border border-destructive",
469
- errorClassName
470
- ),
471
- role: "alert",
472
- "aria-live": "polite"
473
- },
474
- errorText
475
- );
603
+ return /* @__PURE__ */ React4.createElement(FieldError, { id: errorId, className: errorClassName }, errorText);
476
604
  };
477
605
  var LabelGroup = ({
478
606
  labelHtmlFor,
@@ -489,44 +617,42 @@ var LabelGroup = ({
489
617
  variant === "legend" ? "mb-1.5" : "mb-1 block",
490
618
  primaryClassName
491
619
  );
492
- const requiredIndicator = required ? /* @__PURE__ */ React3.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
620
+ const requiredIndicator = required && variant !== "label" ? /* @__PURE__ */ React4.createElement("span", { className: "text-destructive pl-0.5", "aria-label": "required" }, "*") : null;
493
621
  let primaryElement = null;
494
622
  if (primary) {
495
623
  if (variant === "label") {
496
- primaryElement = /* @__PURE__ */ React3.createElement(
497
- "label",
624
+ primaryElement = /* @__PURE__ */ React4.createElement(
625
+ FieldLabel,
498
626
  {
499
627
  htmlFor: labelHtmlFor,
500
- "data-slot": "field-label",
628
+ required,
501
629
  className: primaryClasses
502
630
  },
503
- primary,
504
- requiredIndicator
631
+ primary
505
632
  );
506
633
  } else if (variant === "legend") {
507
- primaryElement = /* @__PURE__ */ React3.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
634
+ primaryElement = /* @__PURE__ */ React4.createElement("legend", { "data-slot": "field-legend", className: primaryClasses }, primary, requiredIndicator);
508
635
  } else {
509
- primaryElement = /* @__PURE__ */ React3.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
636
+ primaryElement = /* @__PURE__ */ React4.createElement("div", { "data-slot": "field-label", className: primaryClasses }, primary, requiredIndicator);
510
637
  }
511
638
  }
512
- const secondaryElement = secondary ? /* @__PURE__ */ React3.createElement(
513
- "p",
639
+ const secondaryElement = secondary ? /* @__PURE__ */ React4.createElement(
640
+ FieldDescription,
514
641
  {
515
- "data-slot": "field-description",
516
642
  id: secondaryId,
517
- className: cn("text-sm leading-normal font-normal", secondaryClassName)
643
+ className: cn("leading-normal font-normal", secondaryClassName)
518
644
  },
519
645
  secondary
520
646
  ) : null;
521
647
  if (!primaryElement && !secondaryElement) return null;
522
648
  if (variant === "legend") {
523
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, primaryElement, secondaryElement);
649
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, primaryElement, secondaryElement);
524
650
  }
525
- return /* @__PURE__ */ React3.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
651
+ return /* @__PURE__ */ React4.createElement("div", { className: "flex flex-1 flex-col gap-0.5" }, primaryElement, secondaryElement);
526
652
  };
527
653
 
528
654
  // src/core/Field.tsx
529
- function Field({
655
+ function Field2({
530
656
  name,
531
657
  label,
532
658
  description,
@@ -539,33 +665,43 @@ function Field({
539
665
  }) {
540
666
  const fieldState = useField({ name, validate });
541
667
  const { meta } = fieldState;
542
- const hasError = React3.useMemo(() => {
668
+ const hasError = React4.useMemo(() => {
543
669
  return showError && meta.touched && meta.error ? true : false;
544
670
  }, [meta?.touched, meta?.error, showError]);
545
671
  const errorId = `${name}-error`;
546
672
  const descriptionId = `${name}-description`;
547
- return /* @__PURE__ */ React3.createElement("div", { className, "data-field": name }, /* @__PURE__ */ React3.createElement(
548
- LabelGroup,
549
- {
550
- labelHtmlFor: name,
551
- required,
552
- variant: "label",
553
- secondaryId: descriptionId,
554
- secondary: description,
555
- primary: label
556
- }
557
- ), /* @__PURE__ */ React3.createElement("div", null, typeof children === "function" ? children(fieldState) : children), /* @__PURE__ */ React3.createElement(
558
- FieldFeedback,
673
+ return /* @__PURE__ */ React4.createElement(
674
+ Field,
559
675
  {
560
- errorId,
561
- errorClassName,
562
- shouldRenderError: hasError,
563
- error: meta.error
564
- }
565
- ));
676
+ className,
677
+ "data-field": name,
678
+ invalid: hasError
679
+ },
680
+ /* @__PURE__ */ React4.createElement(
681
+ LabelGroup,
682
+ {
683
+ labelHtmlFor: name,
684
+ required,
685
+ variant: "label",
686
+ secondaryId: descriptionId,
687
+ secondary: description,
688
+ primary: label
689
+ }
690
+ ),
691
+ /* @__PURE__ */ React4.createElement("div", { "data-slot": "field-control" }, typeof children === "function" ? children(fieldState) : children),
692
+ /* @__PURE__ */ React4.createElement(
693
+ FieldFeedback,
694
+ {
695
+ errorId,
696
+ errorClassName,
697
+ shouldRenderError: hasError,
698
+ error: meta.error
699
+ }
700
+ )
701
+ );
566
702
  }
567
- Field.displayName = "Field";
703
+ Field2.displayName = "Field";
568
704
 
569
- export { Field, Form, FormContext, FormFeedback, useField, useForm };
705
+ export { Field2 as Field, Form, FormContext, FormFeedback, useField, useForm };
570
706
  //# sourceMappingURL=core.js.map
571
707
  //# sourceMappingURL=core.js.map