@poly-x/react 0.1.0-alpha.8 → 0.1.0-alpha.9

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.cjs CHANGED
@@ -360,6 +360,8 @@ const DEFAULT_LABELS$2 = {
360
360
  emailPlaceholder: "you@company.com",
361
361
  passwordLabel: "Password",
362
362
  passwordPlaceholder: "••••••••",
363
+ showPassword: "Show password",
364
+ hidePassword: "Hide password",
363
365
  submit: "Sign in",
364
366
  submitting: "Signing in…",
365
367
  forgotPassword: "Forgot password?",
@@ -380,6 +382,77 @@ const DEFAULT_LABELS$2 = {
380
382
  };
381
383
  /** Mirrors poly-auth's own floor (Joi: min 6). */
382
384
  const MIN_PASSWORD_LENGTH = 6;
385
+ function EyeIcon() {
386
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
387
+ viewBox: "0 0 24 24",
388
+ fill: "none",
389
+ stroke: "currentColor",
390
+ strokeWidth: "2",
391
+ strokeLinecap: "round",
392
+ strokeLinejoin: "round",
393
+ "aria-hidden": "true",
394
+ focusable: "false",
395
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
396
+ cx: "12",
397
+ cy: "12",
398
+ r: "3"
399
+ })]
400
+ });
401
+ }
402
+ function EyeOffIcon() {
403
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
404
+ viewBox: "0 0 24 24",
405
+ fill: "none",
406
+ stroke: "currentColor",
407
+ strokeWidth: "2",
408
+ strokeLinecap: "round",
409
+ strokeLinejoin: "round",
410
+ "aria-hidden": "true",
411
+ focusable: "false",
412
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M9.88 4.24A9.1 9.1 0 0 1 12 4c6.5 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68M6.61 6.61A13.5 13.5 0 0 0 2 12s3.5 7 10 7a9.7 9.7 0 0 0 5.39-1.61" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
413
+ x1: "2",
414
+ y1: "2",
415
+ x2: "22",
416
+ y2: "22"
417
+ })]
418
+ });
419
+ }
420
+ /** A password input with an accessible show/hide reveal toggle (own visibility state). */
421
+ function PasswordField(props) {
422
+ const [visible, setVisible] = (0, react.useState)(false);
423
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
424
+ className: "polyx-signin__field",
425
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
426
+ className: "polyx-signin__label",
427
+ htmlFor: props.id,
428
+ children: props.label
429
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
430
+ className: "polyx-signin__input-wrap",
431
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
432
+ id: props.id,
433
+ className: "polyx-signin__input polyx-signin__input--has-reveal",
434
+ type: visible ? "text" : "password",
435
+ name: props.name,
436
+ autoComplete: props.autoComplete,
437
+ placeholder: props.placeholder,
438
+ required: true,
439
+ minLength: props.minLength,
440
+ value: props.value,
441
+ disabled: props.disabled,
442
+ onChange: (event) => props.onChange(event.target.value)
443
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
444
+ type: "button",
445
+ className: "polyx-signin__reveal",
446
+ "aria-pressed": visible,
447
+ "aria-label": visible ? props.hideLabel : props.showLabel,
448
+ title: visible ? props.hideLabel : props.showLabel,
449
+ disabled: props.disabled,
450
+ onClick: () => setVisible((value) => !value),
451
+ children: visible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EyeOffIcon, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EyeIcon, {})
452
+ })]
453
+ })]
454
+ });
455
+ }
383
456
  /**
384
457
  * The embedded, Clerk-style sign-in form (D2b). Renders email/password inside the
385
458
  * consuming app and POSTs to the SDK's BFF (`@poly-x/next` `authenticate`), which
@@ -405,6 +478,29 @@ function SignIn(props) {
405
478
  const [tenants, setTenants] = (0, react.useState)(null);
406
479
  const [submitting, setSubmitting] = (0, react.useState)(false);
407
480
  const [error, setError] = (0, react.useState)(null);
481
+ const polyx = (0, react.useContext)(PolyXContext);
482
+ const [branding, setBranding] = (0, react.useState)({});
483
+ (0, react.useEffect)(() => {
484
+ if (!polyx) return;
485
+ let active = true;
486
+ polyx.authClient.fetchBranding(props.organizationCode ? { organizationCode: props.organizationCode } : {}).then((tokens) => {
487
+ if (active) setBranding(tokens);
488
+ });
489
+ return () => {
490
+ active = false;
491
+ };
492
+ }, [polyx, props.organizationCode]);
493
+ const brandingStyle = {};
494
+ if (branding.primaryColor) brandingStyle["--polyx-brand"] = branding.primaryColor;
495
+ if (branding.backgroundColor) {
496
+ brandingStyle["--polyx-bg"] = branding.backgroundColor;
497
+ brandingStyle["--polyx-page-bg"] = branding.backgroundColor;
498
+ }
499
+ const brandingLogo = props.logo ?? (branding.logoUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
500
+ className: "polyx-signin__brand-logo",
501
+ src: branding.logoUrl,
502
+ alt: branding.displayName ?? ""
503
+ }) : void 0);
408
504
  /**
409
505
  * One round-trip to the BFF. `tenantId` picks a workspace; `passwords` completes
410
506
  * the temp-password flow (the BFF re-verifies the temporary password, sets the
@@ -474,8 +570,7 @@ function SignIn(props) {
474
570
  } });
475
571
  }
476
572
  const picking = tenants !== null;
477
- const hasPanel = variant === "page";
478
- const showHeaderLogo = Boolean(props.logo) && !hasPanel;
573
+ const showHeaderLogo = Boolean(brandingLogo) && !(variant === "page");
479
574
  const rootClass = [
480
575
  "polyx-signin",
481
576
  `polyx-signin--${variant}`,
@@ -501,7 +596,7 @@ function SignIn(props) {
501
596
  children: [
502
597
  showHeaderLogo ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
503
598
  className: "polyx-signin__logo",
504
- children: props.logo
599
+ children: brandingLogo
505
600
  }) : null,
506
601
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
507
602
  className: "polyx-signin__heading",
@@ -546,41 +641,31 @@ function SignIn(props) {
546
641
  className: "polyx-signin__form",
547
642
  onSubmit: onSetPasswordSubmit,
548
643
  children: [
549
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
550
- className: "polyx-signin__field",
551
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
552
- className: "polyx-signin__label",
553
- children: labels.newPasswordLabel
554
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
555
- className: "polyx-signin__input",
556
- type: "password",
557
- name: "newPassword",
558
- autoComplete: "new-password",
559
- placeholder: labels.passwordPlaceholder,
560
- required: true,
561
- minLength: MIN_PASSWORD_LENGTH,
562
- value: newPassword,
563
- disabled: submitting,
564
- onChange: (event) => setNewPassword(event.target.value)
565
- })]
644
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PasswordField, {
645
+ id: "polyx-signin-new-password",
646
+ label: labels.newPasswordLabel,
647
+ name: "newPassword",
648
+ autoComplete: "new-password",
649
+ placeholder: labels.passwordPlaceholder,
650
+ minLength: MIN_PASSWORD_LENGTH,
651
+ value: newPassword,
652
+ disabled: submitting,
653
+ onChange: setNewPassword,
654
+ showLabel: labels.showPassword,
655
+ hideLabel: labels.hidePassword
566
656
  }),
567
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
568
- className: "polyx-signin__field",
569
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
570
- className: "polyx-signin__label",
571
- children: labels.confirmPasswordLabel
572
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
573
- className: "polyx-signin__input",
574
- type: "password",
575
- name: "confirmPassword",
576
- autoComplete: "new-password",
577
- placeholder: labels.passwordPlaceholder,
578
- required: true,
579
- minLength: MIN_PASSWORD_LENGTH,
580
- value: confirmPassword,
581
- disabled: submitting,
582
- onChange: (event) => setConfirmPassword(event.target.value)
583
- })]
657
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PasswordField, {
658
+ id: "polyx-signin-confirm-password",
659
+ label: labels.confirmPasswordLabel,
660
+ name: "confirmPassword",
661
+ autoComplete: "new-password",
662
+ placeholder: labels.passwordPlaceholder,
663
+ minLength: MIN_PASSWORD_LENGTH,
664
+ value: confirmPassword,
665
+ disabled: submitting,
666
+ onChange: setConfirmPassword,
667
+ showLabel: labels.showPassword,
668
+ hideLabel: labels.hidePassword
584
669
  }),
585
670
  errorNode,
586
671
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -616,22 +701,17 @@ function SignIn(props) {
616
701
  onChange: (event) => setEmail(event.target.value)
617
702
  })]
618
703
  }),
619
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
620
- className: "polyx-signin__field",
621
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
622
- className: "polyx-signin__label",
623
- children: labels.passwordLabel
624
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
625
- className: "polyx-signin__input",
626
- type: "password",
627
- name: "password",
628
- autoComplete: "current-password",
629
- placeholder: labels.passwordPlaceholder,
630
- required: true,
631
- value: password,
632
- disabled: submitting,
633
- onChange: (event) => setPassword(event.target.value)
634
- })]
704
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PasswordField, {
705
+ id: "polyx-signin-password",
706
+ label: labels.passwordLabel,
707
+ name: "password",
708
+ autoComplete: "current-password",
709
+ placeholder: labels.passwordPlaceholder,
710
+ value: password,
711
+ disabled: submitting,
712
+ onChange: setPassword,
713
+ showLabel: labels.showPassword,
714
+ hideLabel: labels.hidePassword
635
715
  }),
636
716
  props.forgotPasswordUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
637
717
  className: "polyx-signin__forgot",
@@ -656,11 +736,12 @@ function SignIn(props) {
656
736
  if (variant === "page") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
657
737
  className: rootClass,
658
738
  "data-polyx-signin": step,
739
+ style: brandingStyle,
659
740
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
660
741
  className: "polyx-signin__panel",
661
- children: props.panel ?? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [props.logo ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
742
+ children: props.panel ?? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [brandingLogo ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
662
743
  className: "polyx-signin__panel-logo",
663
- children: props.logo
744
+ children: brandingLogo
664
745
  }) : null, labels.tagline ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
665
746
  className: "polyx-signin__tagline",
666
747
  children: labels.tagline
@@ -673,6 +754,7 @@ function SignIn(props) {
673
754
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
674
755
  className: rootClass,
675
756
  "data-polyx-signin": step,
757
+ style: brandingStyle,
676
758
  children: card
677
759
  });
678
760
  }
package/dist/index.d.cts CHANGED
@@ -201,6 +201,9 @@ interface SignInLabels {
201
201
  emailPlaceholder: string;
202
202
  passwordLabel: string;
203
203
  passwordPlaceholder: string;
204
+ /** Reveal-toggle a11y labels (aria-label / tooltip on the show-hide button). */
205
+ showPassword: string;
206
+ hidePassword: string;
204
207
  submit: string;
205
208
  submitting: string;
206
209
  forgotPassword: string;
package/dist/index.d.mts CHANGED
@@ -201,6 +201,9 @@ interface SignInLabels {
201
201
  emailPlaceholder: string;
202
202
  passwordLabel: string;
203
203
  passwordPlaceholder: string;
204
+ /** Reveal-toggle a11y labels (aria-label / tooltip on the show-hide button). */
205
+ showPassword: string;
206
+ hidePassword: string;
204
207
  submit: string;
205
208
  submitting: string;
206
209
  forgotPassword: string;
package/dist/index.mjs CHANGED
@@ -359,6 +359,8 @@ const DEFAULT_LABELS$2 = {
359
359
  emailPlaceholder: "you@company.com",
360
360
  passwordLabel: "Password",
361
361
  passwordPlaceholder: "••••••••",
362
+ showPassword: "Show password",
363
+ hidePassword: "Hide password",
362
364
  submit: "Sign in",
363
365
  submitting: "Signing in…",
364
366
  forgotPassword: "Forgot password?",
@@ -379,6 +381,77 @@ const DEFAULT_LABELS$2 = {
379
381
  };
380
382
  /** Mirrors poly-auth's own floor (Joi: min 6). */
381
383
  const MIN_PASSWORD_LENGTH = 6;
384
+ function EyeIcon() {
385
+ return /* @__PURE__ */ jsxs("svg", {
386
+ viewBox: "0 0 24 24",
387
+ fill: "none",
388
+ stroke: "currentColor",
389
+ strokeWidth: "2",
390
+ strokeLinecap: "round",
391
+ strokeLinejoin: "round",
392
+ "aria-hidden": "true",
393
+ focusable: "false",
394
+ children: [/* @__PURE__ */ jsx("path", { d: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z" }), /* @__PURE__ */ jsx("circle", {
395
+ cx: "12",
396
+ cy: "12",
397
+ r: "3"
398
+ })]
399
+ });
400
+ }
401
+ function EyeOffIcon() {
402
+ return /* @__PURE__ */ jsxs("svg", {
403
+ viewBox: "0 0 24 24",
404
+ fill: "none",
405
+ stroke: "currentColor",
406
+ strokeWidth: "2",
407
+ strokeLinecap: "round",
408
+ strokeLinejoin: "round",
409
+ "aria-hidden": "true",
410
+ focusable: "false",
411
+ children: [/* @__PURE__ */ jsx("path", { d: "M9.88 4.24A9.1 9.1 0 0 1 12 4c6.5 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68M6.61 6.61A13.5 13.5 0 0 0 2 12s3.5 7 10 7a9.7 9.7 0 0 0 5.39-1.61" }), /* @__PURE__ */ jsx("line", {
412
+ x1: "2",
413
+ y1: "2",
414
+ x2: "22",
415
+ y2: "22"
416
+ })]
417
+ });
418
+ }
419
+ /** A password input with an accessible show/hide reveal toggle (own visibility state). */
420
+ function PasswordField(props) {
421
+ const [visible, setVisible] = useState(false);
422
+ return /* @__PURE__ */ jsxs("div", {
423
+ className: "polyx-signin__field",
424
+ children: [/* @__PURE__ */ jsx("label", {
425
+ className: "polyx-signin__label",
426
+ htmlFor: props.id,
427
+ children: props.label
428
+ }), /* @__PURE__ */ jsxs("div", {
429
+ className: "polyx-signin__input-wrap",
430
+ children: [/* @__PURE__ */ jsx("input", {
431
+ id: props.id,
432
+ className: "polyx-signin__input polyx-signin__input--has-reveal",
433
+ type: visible ? "text" : "password",
434
+ name: props.name,
435
+ autoComplete: props.autoComplete,
436
+ placeholder: props.placeholder,
437
+ required: true,
438
+ minLength: props.minLength,
439
+ value: props.value,
440
+ disabled: props.disabled,
441
+ onChange: (event) => props.onChange(event.target.value)
442
+ }), /* @__PURE__ */ jsx("button", {
443
+ type: "button",
444
+ className: "polyx-signin__reveal",
445
+ "aria-pressed": visible,
446
+ "aria-label": visible ? props.hideLabel : props.showLabel,
447
+ title: visible ? props.hideLabel : props.showLabel,
448
+ disabled: props.disabled,
449
+ onClick: () => setVisible((value) => !value),
450
+ children: visible ? /* @__PURE__ */ jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsx(EyeIcon, {})
451
+ })]
452
+ })]
453
+ });
454
+ }
382
455
  /**
383
456
  * The embedded, Clerk-style sign-in form (D2b). Renders email/password inside the
384
457
  * consuming app and POSTs to the SDK's BFF (`@poly-x/next` `authenticate`), which
@@ -404,6 +477,29 @@ function SignIn(props) {
404
477
  const [tenants, setTenants] = useState(null);
405
478
  const [submitting, setSubmitting] = useState(false);
406
479
  const [error, setError] = useState(null);
480
+ const polyx = useContext(PolyXContext);
481
+ const [branding, setBranding] = useState({});
482
+ useEffect(() => {
483
+ if (!polyx) return;
484
+ let active = true;
485
+ polyx.authClient.fetchBranding(props.organizationCode ? { organizationCode: props.organizationCode } : {}).then((tokens) => {
486
+ if (active) setBranding(tokens);
487
+ });
488
+ return () => {
489
+ active = false;
490
+ };
491
+ }, [polyx, props.organizationCode]);
492
+ const brandingStyle = {};
493
+ if (branding.primaryColor) brandingStyle["--polyx-brand"] = branding.primaryColor;
494
+ if (branding.backgroundColor) {
495
+ brandingStyle["--polyx-bg"] = branding.backgroundColor;
496
+ brandingStyle["--polyx-page-bg"] = branding.backgroundColor;
497
+ }
498
+ const brandingLogo = props.logo ?? (branding.logoUrl ? /* @__PURE__ */ jsx("img", {
499
+ className: "polyx-signin__brand-logo",
500
+ src: branding.logoUrl,
501
+ alt: branding.displayName ?? ""
502
+ }) : void 0);
407
503
  /**
408
504
  * One round-trip to the BFF. `tenantId` picks a workspace; `passwords` completes
409
505
  * the temp-password flow (the BFF re-verifies the temporary password, sets the
@@ -473,8 +569,7 @@ function SignIn(props) {
473
569
  } });
474
570
  }
475
571
  const picking = tenants !== null;
476
- const hasPanel = variant === "page";
477
- const showHeaderLogo = Boolean(props.logo) && !hasPanel;
572
+ const showHeaderLogo = Boolean(brandingLogo) && !(variant === "page");
478
573
  const rootClass = [
479
574
  "polyx-signin",
480
575
  `polyx-signin--${variant}`,
@@ -500,7 +595,7 @@ function SignIn(props) {
500
595
  children: [
501
596
  showHeaderLogo ? /* @__PURE__ */ jsx("div", {
502
597
  className: "polyx-signin__logo",
503
- children: props.logo
598
+ children: brandingLogo
504
599
  }) : null,
505
600
  /* @__PURE__ */ jsx("h1", {
506
601
  className: "polyx-signin__heading",
@@ -545,41 +640,31 @@ function SignIn(props) {
545
640
  className: "polyx-signin__form",
546
641
  onSubmit: onSetPasswordSubmit,
547
642
  children: [
548
- /* @__PURE__ */ jsxs("label", {
549
- className: "polyx-signin__field",
550
- children: [/* @__PURE__ */ jsx("span", {
551
- className: "polyx-signin__label",
552
- children: labels.newPasswordLabel
553
- }), /* @__PURE__ */ jsx("input", {
554
- className: "polyx-signin__input",
555
- type: "password",
556
- name: "newPassword",
557
- autoComplete: "new-password",
558
- placeholder: labels.passwordPlaceholder,
559
- required: true,
560
- minLength: MIN_PASSWORD_LENGTH,
561
- value: newPassword,
562
- disabled: submitting,
563
- onChange: (event) => setNewPassword(event.target.value)
564
- })]
643
+ /* @__PURE__ */ jsx(PasswordField, {
644
+ id: "polyx-signin-new-password",
645
+ label: labels.newPasswordLabel,
646
+ name: "newPassword",
647
+ autoComplete: "new-password",
648
+ placeholder: labels.passwordPlaceholder,
649
+ minLength: MIN_PASSWORD_LENGTH,
650
+ value: newPassword,
651
+ disabled: submitting,
652
+ onChange: setNewPassword,
653
+ showLabel: labels.showPassword,
654
+ hideLabel: labels.hidePassword
565
655
  }),
566
- /* @__PURE__ */ jsxs("label", {
567
- className: "polyx-signin__field",
568
- children: [/* @__PURE__ */ jsx("span", {
569
- className: "polyx-signin__label",
570
- children: labels.confirmPasswordLabel
571
- }), /* @__PURE__ */ jsx("input", {
572
- className: "polyx-signin__input",
573
- type: "password",
574
- name: "confirmPassword",
575
- autoComplete: "new-password",
576
- placeholder: labels.passwordPlaceholder,
577
- required: true,
578
- minLength: MIN_PASSWORD_LENGTH,
579
- value: confirmPassword,
580
- disabled: submitting,
581
- onChange: (event) => setConfirmPassword(event.target.value)
582
- })]
656
+ /* @__PURE__ */ jsx(PasswordField, {
657
+ id: "polyx-signin-confirm-password",
658
+ label: labels.confirmPasswordLabel,
659
+ name: "confirmPassword",
660
+ autoComplete: "new-password",
661
+ placeholder: labels.passwordPlaceholder,
662
+ minLength: MIN_PASSWORD_LENGTH,
663
+ value: confirmPassword,
664
+ disabled: submitting,
665
+ onChange: setConfirmPassword,
666
+ showLabel: labels.showPassword,
667
+ hideLabel: labels.hidePassword
583
668
  }),
584
669
  errorNode,
585
670
  /* @__PURE__ */ jsx("button", {
@@ -615,22 +700,17 @@ function SignIn(props) {
615
700
  onChange: (event) => setEmail(event.target.value)
616
701
  })]
617
702
  }),
618
- /* @__PURE__ */ jsxs("label", {
619
- className: "polyx-signin__field",
620
- children: [/* @__PURE__ */ jsx("span", {
621
- className: "polyx-signin__label",
622
- children: labels.passwordLabel
623
- }), /* @__PURE__ */ jsx("input", {
624
- className: "polyx-signin__input",
625
- type: "password",
626
- name: "password",
627
- autoComplete: "current-password",
628
- placeholder: labels.passwordPlaceholder,
629
- required: true,
630
- value: password,
631
- disabled: submitting,
632
- onChange: (event) => setPassword(event.target.value)
633
- })]
703
+ /* @__PURE__ */ jsx(PasswordField, {
704
+ id: "polyx-signin-password",
705
+ label: labels.passwordLabel,
706
+ name: "password",
707
+ autoComplete: "current-password",
708
+ placeholder: labels.passwordPlaceholder,
709
+ value: password,
710
+ disabled: submitting,
711
+ onChange: setPassword,
712
+ showLabel: labels.showPassword,
713
+ hideLabel: labels.hidePassword
634
714
  }),
635
715
  props.forgotPasswordUrl ? /* @__PURE__ */ jsx("div", {
636
716
  className: "polyx-signin__forgot",
@@ -655,11 +735,12 @@ function SignIn(props) {
655
735
  if (variant === "page") return /* @__PURE__ */ jsxs("div", {
656
736
  className: rootClass,
657
737
  "data-polyx-signin": step,
738
+ style: brandingStyle,
658
739
  children: [/* @__PURE__ */ jsx("aside", {
659
740
  className: "polyx-signin__panel",
660
- children: props.panel ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [props.logo ? /* @__PURE__ */ jsx("div", {
741
+ children: props.panel ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [brandingLogo ? /* @__PURE__ */ jsx("div", {
661
742
  className: "polyx-signin__panel-logo",
662
- children: props.logo
743
+ children: brandingLogo
663
744
  }) : null, labels.tagline ? /* @__PURE__ */ jsx("p", {
664
745
  className: "polyx-signin__tagline",
665
746
  children: labels.tagline
@@ -672,6 +753,7 @@ function SignIn(props) {
672
753
  return /* @__PURE__ */ jsx("div", {
673
754
  className: rootClass,
674
755
  "data-polyx-signin": step,
756
+ style: brandingStyle,
675
757
  children: card
676
758
  });
677
759
  }
package/dist/styles.css CHANGED
@@ -208,6 +208,13 @@
208
208
  margin-bottom: 0.75rem;
209
209
  }
210
210
 
211
+ /* Branding logo fetched from the app's tokens (FR-BRND). */
212
+ .polyx-signin__brand-logo {
213
+ max-height: 2.25rem;
214
+ width: auto;
215
+ object-fit: contain;
216
+ }
217
+
211
218
  .polyx-signin__heading {
212
219
  margin: 0;
213
220
  font-size: 1.375rem;
@@ -270,6 +277,56 @@
270
277
  cursor: not-allowed;
271
278
  }
272
279
 
280
+ /* --- Password reveal toggle --------------------------------------------- */
281
+
282
+ .polyx-signin__input-wrap {
283
+ position: relative;
284
+ display: flex;
285
+ align-items: center;
286
+ }
287
+
288
+ /* Leave room for the reveal button so masked text never slides under it. */
289
+ .polyx-signin__input--has-reveal {
290
+ padding-right: 2.75rem;
291
+ }
292
+
293
+ .polyx-signin__reveal {
294
+ position: absolute;
295
+ right: 0.25rem;
296
+ display: inline-flex;
297
+ align-items: center;
298
+ justify-content: center;
299
+ width: 2rem;
300
+ height: 2rem;
301
+ padding: 0;
302
+ color: var(--polyx-muted-fg);
303
+ background: transparent;
304
+ border: none;
305
+ border-radius: var(--polyx-radius-sm);
306
+ cursor: pointer;
307
+ transition: color 0.15s ease, box-shadow 0.15s ease;
308
+ }
309
+
310
+ .polyx-signin__reveal:hover:not(:disabled) {
311
+ color: var(--polyx-fg);
312
+ }
313
+
314
+ .polyx-signin__reveal:focus-visible {
315
+ outline: none;
316
+ color: var(--polyx-fg);
317
+ box-shadow: 0 0 0 3px var(--polyx-ring);
318
+ }
319
+
320
+ .polyx-signin__reveal:disabled {
321
+ cursor: not-allowed;
322
+ opacity: 0.6;
323
+ }
324
+
325
+ .polyx-signin__reveal svg {
326
+ width: 1.125rem;
327
+ height: 1.125rem;
328
+ }
329
+
273
330
  /* --- Buttons ------------------------------------------------------------- */
274
331
 
275
332
  .polyx-signin__submit,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poly-x/react",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "PolyX SDK for React SPAs - provider, hooks, drop-in auth UI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,7 +27,7 @@
27
27
  "module": "./dist/index.mjs",
28
28
  "types": "./dist/index.d.cts",
29
29
  "dependencies": {
30
- "@poly-x/core": "0.1.0-alpha.8"
30
+ "@poly-x/core": "0.1.0-alpha.9"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "react": ">=18",