@rqdhw3n/react-auth-flow 1.0.3 → 1.0.5

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/index.es.js CHANGED
@@ -1,6 +1,14 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import React, { createContext, useReducer, useCallback, useEffect, useContext, useState } from "react";
3
3
  import { Navigate } from "react-router-dom";
4
+ const authStyles = ".rq-auth-container,\n.rq-auth-container * {\n box-sizing: border-box;\n}\n\n.rq-auth-container {\n --rq-auth-primary: #2563eb;\n --rq-auth-primary-hover: #1d4ed8;\n --rq-auth-primary-soft: rgba(37, 99, 235, 0.16);\n --rq-auth-border: #dbe4f0;\n --rq-auth-border-strong: #c7d4e5;\n --rq-auth-text: #0f172a;\n --rq-auth-muted: #64748b;\n --rq-auth-surface: #ffffff;\n --rq-auth-surface-alt: #f8fbff;\n --rq-auth-disabled: #eef2f7;\n --rq-auth-error: #b91c1c;\n --rq-auth-error-border: #fecaca;\n --rq-auth-error-bg: #fef2f2;\n --rq-auth-success: #047857;\n --rq-auth-success-border: #a7f3d0;\n --rq-auth-success-bg: #ecfdf5;\n width: min(100%, 28rem);\n margin: 0 auto;\n padding: clamp(1.25rem, 3vw, 2rem);\n border: 1px solid var(--rq-auth-border);\n border-radius: 1.5rem;\n background:\n radial-gradient(circle at top, rgba(96, 165, 250, 0.14), transparent 34%),\n linear-gradient(180deg, var(--rq-auth-surface) 0%, var(--rq-auth-surface-alt) 100%);\n box-shadow:\n 0 24px 48px rgba(15, 23, 42, 0.08),\n 0 8px 20px rgba(15, 23, 42, 0.05);\n color: var(--rq-auth-text);\n}\n\n.rq-auth-header {\n margin-bottom: 1.5rem;\n}\n\n.rq-auth-title {\n margin: 0;\n font-size: clamp(1.625rem, 4vw, 2rem);\n font-weight: 700;\n line-height: 1.15;\n letter-spacing: -0.02em;\n color: var(--rq-auth-text);\n}\n\n.rq-auth-subtitle {\n margin: 0.5rem 0 0;\n font-size: 0.95rem;\n line-height: 1.6;\n color: var(--rq-auth-muted);\n}\n\n.rq-auth-form {\n display: grid;\n gap: 1rem;\n}\n\n.rq-auth-field {\n display: grid;\n gap: 0.5rem;\n}\n\n.rq-auth-label {\n font-size: 0.94rem;\n font-weight: 600;\n line-height: 1.4;\n color: var(--rq-auth-text);\n}\n\n.rq-auth-input {\n width: 100%;\n min-width: 0;\n padding: 0.9rem 1rem;\n border: 1px solid var(--rq-auth-border);\n border-radius: 0.95rem;\n background: rgba(255, 255, 255, 0.92);\n color: var(--rq-auth-text);\n font: inherit;\n line-height: 1.5;\n outline: none;\n transition:\n border-color 0.2s ease,\n box-shadow 0.2s ease,\n background-color 0.2s ease,\n transform 0.2s ease;\n box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.03);\n}\n\n.rq-auth-input::placeholder {\n color: #94a3b8;\n}\n\n.rq-auth-input:hover {\n border-color: var(--rq-auth-border-strong);\n}\n\n.rq-auth-input:focus {\n border-color: var(--rq-auth-primary);\n box-shadow:\n 0 0 0 4px var(--rq-auth-primary-soft),\n inset 0 1px 2px rgba(15, 23, 42, 0.03);\n}\n\n.rq-auth-input:disabled {\n cursor: not-allowed;\n background: var(--rq-auth-disabled);\n color: #94a3b8;\n}\n\n.rq-auth-checkbox {\n display: flex;\n align-items: flex-start;\n gap: 0.75rem;\n font-size: 0.94rem;\n line-height: 1.5;\n color: var(--rq-auth-muted);\n}\n\n.rq-auth-checkbox-input {\n width: 1.05rem;\n height: 1.05rem;\n margin: 0.2rem 0 0;\n border-radius: 0.35rem;\n accent-color: var(--rq-auth-primary);\n flex: 0 0 auto;\n}\n\n.rq-auth-checkbox-input:disabled {\n cursor: not-allowed;\n}\n\n.rq-auth-checkbox-label {\n color: var(--rq-auth-muted);\n}\n\n.rq-auth-button {\n width: 100%;\n border: 0;\n border-radius: 0.95rem;\n padding: 0.95rem 1.15rem;\n background: linear-gradient(180deg, #3b82f6 0%, var(--rq-auth-primary) 100%);\n color: #ffffff;\n font: inherit;\n font-size: 0.98rem;\n font-weight: 600;\n line-height: 1.2;\n cursor: pointer;\n transition:\n background 0.2s ease,\n box-shadow 0.2s ease,\n transform 0.2s ease,\n opacity 0.2s ease;\n box-shadow:\n 0 14px 28px rgba(37, 99, 235, 0.22),\n inset 0 1px 0 rgba(255, 255, 255, 0.18);\n}\n\n.rq-auth-button:hover:not(:disabled) {\n background: linear-gradient(180deg, #2563eb 0%, var(--rq-auth-primary-hover) 100%);\n transform: translateY(-1px);\n}\n\n.rq-auth-button:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 4px var(--rq-auth-primary-soft),\n 0 14px 28px rgba(37, 99, 235, 0.22);\n}\n\n.rq-auth-button:disabled {\n cursor: not-allowed;\n opacity: 0.68;\n transform: none;\n box-shadow: none;\n}\n\n.rq-auth-button-content {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n}\n\n.rq-auth-button-spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid rgba(255, 255, 255, 0.4);\n border-top-color: #ffffff;\n border-radius: 999px;\n animation: rq-auth-spin 0.75s linear infinite;\n}\n\n.rq-auth-error,\n.rq-auth-success,\n.auth-loading,\n.auth-forbidden {\n padding: 0.95rem 1rem;\n border-radius: 1rem;\n border: 1px solid transparent;\n font-size: 0.94rem;\n line-height: 1.55;\n}\n\n.rq-auth-error {\n border-color: var(--rq-auth-error-border);\n background: var(--rq-auth-error-bg);\n color: var(--rq-auth-error);\n}\n\n.rq-auth-success {\n border-color: var(--rq-auth-success-border);\n background: var(--rq-auth-success-bg);\n color: var(--rq-auth-success);\n}\n\n.auth-loading {\n border-color: var(--rq-auth-border);\n background: var(--rq-auth-surface-alt);\n color: var(--rq-auth-muted);\n}\n\n.auth-forbidden {\n border-color: var(--rq-auth-error-border);\n background: var(--rq-auth-error-bg);\n color: var(--rq-auth-error);\n}\n\n@keyframes rq-auth-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (max-width: 640px) {\n .rq-auth-container {\n width: 100%;\n padding: 1.125rem;\n border-radius: 1.25rem;\n }\n\n .rq-auth-form {\n gap: 0.9rem;\n }\n\n .rq-auth-input,\n .rq-auth-button {\n padding-inline: 0.95rem;\n }\n}\n";
5
+ const STYLE_ELEMENT_ID = "rq-auth-flow-styles";
6
+ if (typeof document !== "undefined" && !document.getElementById(STYLE_ELEMENT_ID)) {
7
+ const styleElement = document.createElement("style");
8
+ styleElement.id = STYLE_ELEMENT_ID;
9
+ styleElement.textContent = authStyles;
10
+ document.head.appendChild(styleElement);
11
+ }
4
12
  const AuthContext = createContext(
5
13
  void 0
6
14
  );
@@ -403,11 +411,44 @@ function useAuth() {
403
411
  }
404
412
  return context;
405
413
  }
414
+ function cn(...classes) {
415
+ return classes.filter(Boolean).join(" ");
416
+ }
417
+ const AUTH_FORM_CLASSES = {
418
+ container: "rq-auth-container",
419
+ header: "rq-auth-header",
420
+ form: "rq-auth-form",
421
+ field: "rq-auth-field",
422
+ label: "rq-auth-label",
423
+ input: "rq-auth-input",
424
+ button: "rq-auth-button",
425
+ buttonContent: "rq-auth-button-content",
426
+ buttonSpinner: "rq-auth-button-spinner",
427
+ error: "rq-auth-error",
428
+ success: "rq-auth-success",
429
+ title: "rq-auth-title",
430
+ subtitle: "rq-auth-subtitle",
431
+ checkbox: "rq-auth-checkbox",
432
+ checkboxInput: "rq-auth-checkbox-input",
433
+ checkboxLabel: "rq-auth-checkbox-label"
434
+ };
406
435
  const LoginForm = ({
407
- className = "",
436
+ className,
437
+ formClassName,
438
+ fieldClassName,
439
+ labelClassName,
440
+ inputClassName,
441
+ buttonClassName,
442
+ errorClassName,
443
+ titleClassName,
444
+ subtitleClassName,
408
445
  labels = {},
409
446
  placeholders = {},
410
447
  submitButtonText = "Login",
448
+ loadingText = "Signing in...",
449
+ title,
450
+ subtitle,
451
+ showTitle = !!title,
411
452
  onSuccess,
412
453
  onError
413
454
  }) => {
@@ -437,71 +478,110 @@ const LoginForm = ({
437
478
  });
438
479
  }
439
480
  };
440
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, children: [
441
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
442
- /* @__PURE__ */ jsx("label", { htmlFor: "email", className: "auth-form-label", children: labels.email || "Email" }),
443
- /* @__PURE__ */ jsx(
444
- "input",
445
- {
446
- id: "email",
447
- type: "email",
448
- value: email,
449
- onChange: (e) => setEmail(e.target.value),
450
- placeholder: placeholders.email || "your@email.com",
451
- disabled: isLoading,
452
- className: "auth-form-input",
453
- required: true
454
- }
455
- )
456
- ] }),
457
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
458
- /* @__PURE__ */ jsx("label", { htmlFor: "password", className: "auth-form-label", children: labels.password || "Password" }),
459
- /* @__PURE__ */ jsx(
460
- "input",
461
- {
462
- id: "password",
463
- type: "password",
464
- value: password,
465
- onChange: (e) => setPassword(e.target.value),
466
- placeholder: placeholders.password || "••••••••",
467
- disabled: isLoading,
468
- className: "auth-form-input",
469
- required: true
470
- }
471
- )
472
- ] }),
473
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group auth-form-checkbox", children: [
474
- /* @__PURE__ */ jsx(
475
- "input",
476
- {
477
- id: "rememberMe",
478
- type: "checkbox",
479
- checked: rememberMe,
480
- onChange: (e) => setRememberMe(e.target.checked),
481
- disabled: isLoading,
482
- className: "auth-form-input"
483
- }
484
- ),
485
- /* @__PURE__ */ jsx("label", { htmlFor: "rememberMe", className: "auth-form-label", children: labels.rememberMe || "Remember me" })
481
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
482
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
483
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
484
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
486
485
  ] }),
487
- error && /* @__PURE__ */ jsx("div", { className: "auth-form-error", children: error }),
488
- /* @__PURE__ */ jsx(
489
- "button",
486
+ /* @__PURE__ */ jsxs(
487
+ "form",
490
488
  {
491
- type: "submit",
492
- disabled: isLoading,
493
- className: "auth-form-button auth-form-button-primary",
494
- children: isLoading ? "Loading..." : submitButtonText
489
+ onSubmit: handleSubmit,
490
+ className: cn(AUTH_FORM_CLASSES.form, formClassName),
491
+ "aria-busy": isLoading,
492
+ children: [
493
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
494
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.email || "Email" }),
495
+ /* @__PURE__ */ jsx(
496
+ "input",
497
+ {
498
+ id: "email",
499
+ type: "email",
500
+ value: email,
501
+ onChange: (e) => setEmail(e.target.value),
502
+ placeholder: placeholders.email || "your@email.com",
503
+ disabled: isLoading,
504
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
505
+ autoComplete: "username",
506
+ required: true
507
+ }
508
+ )
509
+ ] }),
510
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
511
+ /* @__PURE__ */ jsx(
512
+ "label",
513
+ {
514
+ htmlFor: "password",
515
+ className: cn(AUTH_FORM_CLASSES.label, labelClassName),
516
+ children: labels.password || "Password"
517
+ }
518
+ ),
519
+ /* @__PURE__ */ jsx(
520
+ "input",
521
+ {
522
+ id: "password",
523
+ type: "password",
524
+ value: password,
525
+ onChange: (e) => setPassword(e.target.value),
526
+ placeholder: placeholders.password || "Enter your password",
527
+ disabled: isLoading,
528
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
529
+ autoComplete: "current-password",
530
+ required: true
531
+ }
532
+ )
533
+ ] }),
534
+ /* @__PURE__ */ jsxs("label", { htmlFor: "rememberMe", className: AUTH_FORM_CLASSES.checkbox, children: [
535
+ /* @__PURE__ */ jsx(
536
+ "input",
537
+ {
538
+ id: "rememberMe",
539
+ type: "checkbox",
540
+ checked: rememberMe,
541
+ onChange: (e) => setRememberMe(e.target.checked),
542
+ disabled: isLoading,
543
+ className: AUTH_FORM_CLASSES.checkboxInput
544
+ }
545
+ ),
546
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.checkboxLabel, children: labels.rememberMe || "Remember me" })
547
+ ] }),
548
+ error && /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.error, errorClassName), role: "alert", children: error }),
549
+ /* @__PURE__ */ jsx(
550
+ "button",
551
+ {
552
+ type: "submit",
553
+ disabled: isLoading,
554
+ className: cn(AUTH_FORM_CLASSES.button, buttonClassName),
555
+ "aria-busy": isLoading,
556
+ children: isLoading ? /* @__PURE__ */ jsxs("span", { className: AUTH_FORM_CLASSES.buttonContent, children: [
557
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.buttonSpinner, "aria-hidden": "true" }),
558
+ loadingText
559
+ ] }) : submitButtonText
560
+ }
561
+ )
562
+ ]
495
563
  }
496
564
  )
497
565
  ] });
498
566
  };
499
567
  LoginForm.displayName = "LoginForm";
500
568
  const RegisterForm = ({
501
- className = "",
569
+ className,
570
+ formClassName,
571
+ fieldClassName,
572
+ labelClassName,
573
+ inputClassName,
574
+ buttonClassName,
575
+ errorClassName,
576
+ titleClassName,
577
+ subtitleClassName,
502
578
  labels = {},
503
579
  placeholders = {},
504
580
  submitButtonText = "Register",
581
+ loadingText = "Creating account...",
582
+ title,
583
+ subtitle,
584
+ showTitle = !!title,
505
585
  onSuccess,
506
586
  onError
507
587
  }) => {
@@ -545,89 +625,138 @@ const RegisterForm = ({
545
625
  });
546
626
  }
547
627
  };
548
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, children: [
549
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
550
- /* @__PURE__ */ jsx("label", { htmlFor: "name", className: "auth-form-label", children: labels.name || "Full Name" }),
551
- /* @__PURE__ */ jsx(
552
- "input",
553
- {
554
- id: "name",
555
- type: "text",
556
- value: name,
557
- onChange: (e) => setName(e.target.value),
558
- placeholder: placeholders.name || "John Doe",
559
- disabled: isLoading,
560
- className: "auth-form-input",
561
- required: true
562
- }
563
- )
628
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
629
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
630
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
631
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
564
632
  ] }),
565
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
566
- /* @__PURE__ */ jsx("label", { htmlFor: "email", className: "auth-form-label", children: labels.email || "Email" }),
567
- /* @__PURE__ */ jsx(
568
- "input",
569
- {
570
- id: "email",
571
- type: "email",
572
- value: email,
573
- onChange: (e) => setEmail(e.target.value),
574
- placeholder: placeholders.email || "your@email.com",
575
- disabled: isLoading,
576
- className: "auth-form-input",
577
- required: true
578
- }
579
- )
580
- ] }),
581
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
582
- /* @__PURE__ */ jsx("label", { htmlFor: "password", className: "auth-form-label", children: labels.password || "Password" }),
583
- /* @__PURE__ */ jsx(
584
- "input",
585
- {
586
- id: "password",
587
- type: "password",
588
- value: password,
589
- onChange: (e) => setPassword(e.target.value),
590
- placeholder: placeholders.password || "••••••••",
591
- disabled: isLoading,
592
- className: "auth-form-input",
593
- required: true
594
- }
595
- )
596
- ] }),
597
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
598
- /* @__PURE__ */ jsx("label", { htmlFor: "confirmPassword", className: "auth-form-label", children: labels.confirmPassword || "Confirm Password" }),
599
- /* @__PURE__ */ jsx(
600
- "input",
601
- {
602
- id: "confirmPassword",
603
- type: "password",
604
- value: confirmPassword,
605
- onChange: (e) => setConfirmPassword(e.target.value),
606
- placeholder: placeholders.confirmPassword || "••••••••",
607
- disabled: isLoading,
608
- className: "auth-form-input",
609
- required: true
610
- }
611
- )
612
- ] }),
613
- error && /* @__PURE__ */ jsx("div", { className: "auth-form-error", children: error }),
614
- /* @__PURE__ */ jsx(
615
- "button",
633
+ /* @__PURE__ */ jsxs(
634
+ "form",
616
635
  {
617
- type: "submit",
618
- disabled: isLoading,
619
- className: "auth-form-button auth-form-button-primary",
620
- children: isLoading ? "Loading..." : submitButtonText
636
+ onSubmit: handleSubmit,
637
+ className: cn(AUTH_FORM_CLASSES.form, formClassName),
638
+ "aria-busy": isLoading,
639
+ children: [
640
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
641
+ /* @__PURE__ */ jsx("label", { htmlFor: "name", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.name || "Full Name" }),
642
+ /* @__PURE__ */ jsx(
643
+ "input",
644
+ {
645
+ id: "name",
646
+ type: "text",
647
+ value: name,
648
+ onChange: (e) => setName(e.target.value),
649
+ placeholder: placeholders.name || "John Doe",
650
+ disabled: isLoading,
651
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
652
+ autoComplete: "name",
653
+ required: true
654
+ }
655
+ )
656
+ ] }),
657
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
658
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.email || "Email" }),
659
+ /* @__PURE__ */ jsx(
660
+ "input",
661
+ {
662
+ id: "email",
663
+ type: "email",
664
+ value: email,
665
+ onChange: (e) => setEmail(e.target.value),
666
+ placeholder: placeholders.email || "your@email.com",
667
+ disabled: isLoading,
668
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
669
+ autoComplete: "email",
670
+ required: true
671
+ }
672
+ )
673
+ ] }),
674
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
675
+ /* @__PURE__ */ jsx(
676
+ "label",
677
+ {
678
+ htmlFor: "password",
679
+ className: cn(AUTH_FORM_CLASSES.label, labelClassName),
680
+ children: labels.password || "Password"
681
+ }
682
+ ),
683
+ /* @__PURE__ */ jsx(
684
+ "input",
685
+ {
686
+ id: "password",
687
+ type: "password",
688
+ value: password,
689
+ onChange: (e) => setPassword(e.target.value),
690
+ placeholder: placeholders.password || "Create a password",
691
+ disabled: isLoading,
692
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
693
+ autoComplete: "new-password",
694
+ required: true
695
+ }
696
+ )
697
+ ] }),
698
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
699
+ /* @__PURE__ */ jsx(
700
+ "label",
701
+ {
702
+ htmlFor: "confirmPassword",
703
+ className: cn(AUTH_FORM_CLASSES.label, labelClassName),
704
+ children: labels.confirmPassword || "Confirm Password"
705
+ }
706
+ ),
707
+ /* @__PURE__ */ jsx(
708
+ "input",
709
+ {
710
+ id: "confirmPassword",
711
+ type: "password",
712
+ value: confirmPassword,
713
+ onChange: (e) => setConfirmPassword(e.target.value),
714
+ placeholder: placeholders.confirmPassword || "Confirm your password",
715
+ disabled: isLoading,
716
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
717
+ autoComplete: "new-password",
718
+ required: true
719
+ }
720
+ )
721
+ ] }),
722
+ error && /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.error, errorClassName), role: "alert", children: error }),
723
+ /* @__PURE__ */ jsx(
724
+ "button",
725
+ {
726
+ type: "submit",
727
+ disabled: isLoading,
728
+ className: cn(AUTH_FORM_CLASSES.button, buttonClassName),
729
+ "aria-busy": isLoading,
730
+ children: isLoading ? /* @__PURE__ */ jsxs("span", { className: AUTH_FORM_CLASSES.buttonContent, children: [
731
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.buttonSpinner, "aria-hidden": "true" }),
732
+ loadingText
733
+ ] }) : submitButtonText
734
+ }
735
+ )
736
+ ]
621
737
  }
622
738
  )
623
739
  ] });
624
740
  };
625
741
  RegisterForm.displayName = "RegisterForm";
626
742
  const ForgotPasswordForm = ({
627
- className = "",
743
+ className,
744
+ formClassName,
745
+ fieldClassName,
746
+ labelClassName,
747
+ inputClassName,
748
+ buttonClassName,
749
+ errorClassName,
750
+ successClassName,
751
+ titleClassName,
752
+ subtitleClassName,
628
753
  labels = {},
629
754
  placeholders = {},
630
755
  submitButtonText = "Send Reset Link",
756
+ loadingText = "Sending...",
757
+ title,
758
+ subtitle,
759
+ showTitle = !!title,
631
760
  onSuccess,
632
761
  onError
633
762
  }) => {
@@ -664,33 +793,58 @@ const ForgotPasswordForm = ({
664
793
  }
665
794
  };
666
795
  if (successMessage) {
667
- return /* @__PURE__ */ jsx("div", { className: `auth-form-success ${className}`, children: /* @__PURE__ */ jsx("p", { className: "auth-form-success-message", children: successMessage }) });
796
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
797
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
798
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
799
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
800
+ ] }),
801
+ /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.success, successClassName), role: "status", children: /* @__PURE__ */ jsx("p", { children: successMessage }) })
802
+ ] });
668
803
  }
669
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, children: [
670
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
671
- /* @__PURE__ */ jsx("label", { htmlFor: "email", className: "auth-form-label", children: labels.email || "Email" }),
672
- /* @__PURE__ */ jsx(
673
- "input",
674
- {
675
- id: "email",
676
- type: "email",
677
- value: email,
678
- onChange: (e) => setEmail(e.target.value),
679
- placeholder: placeholders.email || "your@email.com",
680
- disabled: isLoading,
681
- className: "auth-form-input",
682
- required: true
683
- }
684
- )
804
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
805
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
806
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
807
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
685
808
  ] }),
686
- error && /* @__PURE__ */ jsx("div", { className: "auth-form-error", children: error }),
687
- /* @__PURE__ */ jsx(
688
- "button",
809
+ /* @__PURE__ */ jsxs(
810
+ "form",
689
811
  {
690
- type: "submit",
691
- disabled: isLoading,
692
- className: "auth-form-button auth-form-button-primary",
693
- children: isLoading ? "Loading..." : submitButtonText
812
+ onSubmit: handleSubmit,
813
+ className: cn(AUTH_FORM_CLASSES.form, formClassName),
814
+ "aria-busy": isLoading,
815
+ children: [
816
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
817
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.email || "Email" }),
818
+ /* @__PURE__ */ jsx(
819
+ "input",
820
+ {
821
+ id: "email",
822
+ type: "email",
823
+ value: email,
824
+ onChange: (e) => setEmail(e.target.value),
825
+ placeholder: placeholders.email || "your@email.com",
826
+ disabled: isLoading,
827
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
828
+ autoComplete: "email",
829
+ required: true
830
+ }
831
+ )
832
+ ] }),
833
+ error && /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.error, errorClassName), role: "alert", children: error }),
834
+ /* @__PURE__ */ jsx(
835
+ "button",
836
+ {
837
+ type: "submit",
838
+ disabled: isLoading,
839
+ className: cn(AUTH_FORM_CLASSES.button, buttonClassName),
840
+ "aria-busy": isLoading,
841
+ children: isLoading ? /* @__PURE__ */ jsxs("span", { className: AUTH_FORM_CLASSES.buttonContent, children: [
842
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.buttonSpinner, "aria-hidden": "true" }),
843
+ loadingText
844
+ ] }) : submitButtonText
845
+ }
846
+ )
847
+ ]
694
848
  }
695
849
  )
696
850
  ] });
@@ -698,10 +852,23 @@ const ForgotPasswordForm = ({
698
852
  ForgotPasswordForm.displayName = "ForgotPasswordForm";
699
853
  const ResetPasswordForm = ({
700
854
  token,
701
- className = "",
855
+ className,
856
+ formClassName,
857
+ fieldClassName,
858
+ labelClassName,
859
+ inputClassName,
860
+ buttonClassName,
861
+ errorClassName,
862
+ successClassName,
863
+ titleClassName,
864
+ subtitleClassName,
702
865
  labels = {},
703
866
  placeholders = {},
704
867
  submitButtonText = "Reset Password",
868
+ loadingText = "Updating...",
869
+ title,
870
+ subtitle,
871
+ showTitle = !!title,
705
872
  onSuccess,
706
873
  onError
707
874
  }) => {
@@ -748,49 +915,89 @@ const ResetPasswordForm = ({
748
915
  }
749
916
  };
750
917
  if (successMessage) {
751
- return /* @__PURE__ */ jsx("div", { className: `auth-form-success ${className}`, children: /* @__PURE__ */ jsx("p", { className: "auth-form-success-message", children: successMessage }) });
918
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
919
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
920
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
921
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
922
+ ] }),
923
+ /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.success, successClassName), role: "status", children: /* @__PURE__ */ jsx("p", { children: successMessage }) })
924
+ ] });
752
925
  }
753
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, children: [
754
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
755
- /* @__PURE__ */ jsx("label", { htmlFor: "password", className: "auth-form-label", children: labels.password || "New Password" }),
756
- /* @__PURE__ */ jsx(
757
- "input",
758
- {
759
- id: "password",
760
- type: "password",
761
- value: password,
762
- onChange: (e) => setPassword(e.target.value),
763
- placeholder: placeholders.password || "••••••••",
764
- disabled: isLoading,
765
- className: "auth-form-input",
766
- required: true
767
- }
768
- )
769
- ] }),
770
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
771
- /* @__PURE__ */ jsx("label", { htmlFor: "confirmPassword", className: "auth-form-label", children: labels.confirmPassword || "Confirm Password" }),
772
- /* @__PURE__ */ jsx(
773
- "input",
774
- {
775
- id: "confirmPassword",
776
- type: "password",
777
- value: confirmPassword,
778
- onChange: (e) => setConfirmPassword(e.target.value),
779
- placeholder: placeholders.confirmPassword || "••••••••",
780
- disabled: isLoading,
781
- className: "auth-form-input",
782
- required: true
783
- }
784
- )
926
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
927
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
928
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
929
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
785
930
  ] }),
786
- error && /* @__PURE__ */ jsx("div", { className: "auth-form-error", children: error }),
787
- /* @__PURE__ */ jsx(
788
- "button",
931
+ /* @__PURE__ */ jsxs(
932
+ "form",
789
933
  {
790
- type: "submit",
791
- disabled: isLoading,
792
- className: "auth-form-button auth-form-button-primary",
793
- children: isLoading ? "Loading..." : submitButtonText
934
+ onSubmit: handleSubmit,
935
+ className: cn(AUTH_FORM_CLASSES.form, formClassName),
936
+ "aria-busy": isLoading,
937
+ children: [
938
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
939
+ /* @__PURE__ */ jsx(
940
+ "label",
941
+ {
942
+ htmlFor: "password",
943
+ className: cn(AUTH_FORM_CLASSES.label, labelClassName),
944
+ children: labels.password || "New Password"
945
+ }
946
+ ),
947
+ /* @__PURE__ */ jsx(
948
+ "input",
949
+ {
950
+ id: "password",
951
+ type: "password",
952
+ value: password,
953
+ onChange: (e) => setPassword(e.target.value),
954
+ placeholder: placeholders.password || "Enter a new password",
955
+ disabled: isLoading,
956
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
957
+ autoComplete: "new-password",
958
+ required: true
959
+ }
960
+ )
961
+ ] }),
962
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
963
+ /* @__PURE__ */ jsx(
964
+ "label",
965
+ {
966
+ htmlFor: "confirmPassword",
967
+ className: cn(AUTH_FORM_CLASSES.label, labelClassName),
968
+ children: labels.confirmPassword || "Confirm Password"
969
+ }
970
+ ),
971
+ /* @__PURE__ */ jsx(
972
+ "input",
973
+ {
974
+ id: "confirmPassword",
975
+ type: "password",
976
+ value: confirmPassword,
977
+ onChange: (e) => setConfirmPassword(e.target.value),
978
+ placeholder: placeholders.confirmPassword || "Confirm your new password",
979
+ disabled: isLoading,
980
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
981
+ autoComplete: "new-password",
982
+ required: true
983
+ }
984
+ )
985
+ ] }),
986
+ error && /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.error, errorClassName), role: "alert", children: error }),
987
+ /* @__PURE__ */ jsx(
988
+ "button",
989
+ {
990
+ type: "submit",
991
+ disabled: isLoading,
992
+ className: cn(AUTH_FORM_CLASSES.button, buttonClassName),
993
+ "aria-busy": isLoading,
994
+ children: isLoading ? /* @__PURE__ */ jsxs("span", { className: AUTH_FORM_CLASSES.buttonContent, children: [
995
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.buttonSpinner, "aria-hidden": "true" }),
996
+ loadingText
997
+ ] }) : submitButtonText
998
+ }
999
+ )
1000
+ ]
794
1001
  }
795
1002
  )
796
1003
  ] });
@@ -799,10 +1006,23 @@ ResetPasswordForm.displayName = "ResetPasswordForm";
799
1006
  const VerifyEmailForm = ({
800
1007
  token: initialToken,
801
1008
  email: initialEmail,
802
- className = "",
1009
+ className,
1010
+ formClassName,
1011
+ fieldClassName,
1012
+ labelClassName,
1013
+ inputClassName,
1014
+ buttonClassName,
1015
+ errorClassName,
1016
+ successClassName,
1017
+ titleClassName,
1018
+ subtitleClassName,
803
1019
  labels = {},
804
1020
  placeholders = {},
805
1021
  submitButtonText = "Verify Email",
1022
+ loadingText = "Verifying...",
1023
+ title,
1024
+ subtitle,
1025
+ showTitle = !!title,
806
1026
  onSuccess,
807
1027
  onError
808
1028
  }) => {
@@ -817,12 +1037,6 @@ const VerifyEmailForm = ({
817
1037
  const [successMessage, setSuccessMessage] = useState("");
818
1038
  const isLoading = authLoading;
819
1039
  const error = formError || authError?.message;
820
- useEffect(() => {
821
- if (token && email && !successMessage && !error) {
822
- handleSubmit({ preventDefault: () => {
823
- } });
824
- }
825
- }, [token, email]);
826
1040
  const handleSubmit = async (e) => {
827
1041
  e.preventDefault();
828
1042
  setFormError("");
@@ -848,50 +1062,82 @@ const VerifyEmailForm = ({
848
1062
  });
849
1063
  }
850
1064
  };
1065
+ useEffect(() => {
1066
+ if (token && email && !successMessage && !error) {
1067
+ void handleSubmit({ preventDefault: () => {
1068
+ } });
1069
+ }
1070
+ }, [token, email]);
851
1071
  if (successMessage) {
852
- return /* @__PURE__ */ jsx("div", { className: `auth-form-success ${className}`, children: /* @__PURE__ */ jsx("p", { className: "auth-form-success-message", children: successMessage }) });
1072
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
1073
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
1074
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
1075
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
1076
+ ] }),
1077
+ /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.success, successClassName), role: "status", children: /* @__PURE__ */ jsx("p", { children: successMessage }) })
1078
+ ] });
853
1079
  }
854
- return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className, children: [
855
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
856
- /* @__PURE__ */ jsx("label", { htmlFor: "email", className: "auth-form-label", children: labels.email || "Email" }),
857
- /* @__PURE__ */ jsx(
858
- "input",
859
- {
860
- id: "email",
861
- type: "email",
862
- value: email,
863
- onChange: (e) => setEmail(e.target.value),
864
- placeholder: placeholders.email || "your@email.com",
865
- disabled: isLoading,
866
- className: "auth-form-input",
867
- required: true
868
- }
869
- )
870
- ] }),
871
- /* @__PURE__ */ jsxs("div", { className: "auth-form-group", children: [
872
- /* @__PURE__ */ jsx("label", { htmlFor: "token", className: "auth-form-label", children: labels.token || "Verification Code" }),
873
- /* @__PURE__ */ jsx(
874
- "input",
875
- {
876
- id: "token",
877
- type: "text",
878
- value: token,
879
- onChange: (e) => setToken(e.target.value),
880
- placeholder: placeholders.token || "Enter verification code",
881
- disabled: isLoading,
882
- className: "auth-form-input",
883
- required: true
884
- }
885
- )
1080
+ return /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.container, className), children: [
1081
+ showTitle && title && /* @__PURE__ */ jsxs("div", { className: AUTH_FORM_CLASSES.header, children: [
1082
+ /* @__PURE__ */ jsx("h1", { className: cn(AUTH_FORM_CLASSES.title, titleClassName), children: title }),
1083
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn(AUTH_FORM_CLASSES.subtitle, subtitleClassName), children: subtitle })
886
1084
  ] }),
887
- error && /* @__PURE__ */ jsx("div", { className: "auth-form-error", children: error }),
888
- /* @__PURE__ */ jsx(
889
- "button",
1085
+ /* @__PURE__ */ jsxs(
1086
+ "form",
890
1087
  {
891
- type: "submit",
892
- disabled: isLoading,
893
- className: "auth-form-button auth-form-button-primary",
894
- children: isLoading ? "Loading..." : submitButtonText
1088
+ onSubmit: handleSubmit,
1089
+ className: cn(AUTH_FORM_CLASSES.form, formClassName),
1090
+ "aria-busy": isLoading,
1091
+ children: [
1092
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
1093
+ /* @__PURE__ */ jsx("label", { htmlFor: "email", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.email || "Email" }),
1094
+ /* @__PURE__ */ jsx(
1095
+ "input",
1096
+ {
1097
+ id: "email",
1098
+ type: "email",
1099
+ value: email,
1100
+ onChange: (e) => setEmail(e.target.value),
1101
+ placeholder: placeholders.email || "your@email.com",
1102
+ disabled: isLoading,
1103
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
1104
+ autoComplete: "email",
1105
+ required: true
1106
+ }
1107
+ )
1108
+ ] }),
1109
+ /* @__PURE__ */ jsxs("div", { className: cn(AUTH_FORM_CLASSES.field, fieldClassName), children: [
1110
+ /* @__PURE__ */ jsx("label", { htmlFor: "token", className: cn(AUTH_FORM_CLASSES.label, labelClassName), children: labels.token || "Verification Code" }),
1111
+ /* @__PURE__ */ jsx(
1112
+ "input",
1113
+ {
1114
+ id: "token",
1115
+ type: "text",
1116
+ value: token,
1117
+ onChange: (e) => setToken(e.target.value),
1118
+ placeholder: placeholders.token || "Enter verification code",
1119
+ disabled: isLoading,
1120
+ className: cn(AUTH_FORM_CLASSES.input, inputClassName),
1121
+ autoComplete: "one-time-code",
1122
+ required: true
1123
+ }
1124
+ )
1125
+ ] }),
1126
+ error && /* @__PURE__ */ jsx("div", { className: cn(AUTH_FORM_CLASSES.error, errorClassName), role: "alert", children: error }),
1127
+ /* @__PURE__ */ jsx(
1128
+ "button",
1129
+ {
1130
+ type: "submit",
1131
+ disabled: isLoading,
1132
+ className: cn(AUTH_FORM_CLASSES.button, buttonClassName),
1133
+ "aria-busy": isLoading,
1134
+ children: isLoading ? /* @__PURE__ */ jsxs("span", { className: AUTH_FORM_CLASSES.buttonContent, children: [
1135
+ /* @__PURE__ */ jsx("span", { className: AUTH_FORM_CLASSES.buttonSpinner, "aria-hidden": "true" }),
1136
+ loadingText
1137
+ ] }) : submitButtonText
1138
+ }
1139
+ )
1140
+ ]
895
1141
  }
896
1142
  )
897
1143
  ] });
@@ -937,6 +1183,7 @@ export {
937
1183
  RegisterForm,
938
1184
  ResetPasswordForm,
939
1185
  VerifyEmailForm,
1186
+ cn,
940
1187
  createAuthClient,
941
1188
  normalizeError,
942
1189
  useAuth