authfyio-react 0.3.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.
Files changed (68) hide show
  1. package/README.md +83 -0
  2. package/dist/client.d.ts +128 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +227 -0
  5. package/dist/components.d.ts +79 -0
  6. package/dist/components.d.ts.map +1 -0
  7. package/dist/components.js +111 -0
  8. package/dist/hooks-flow.d.ts +59 -0
  9. package/dist/hooks-flow.d.ts.map +1 -0
  10. package/dist/hooks-flow.js +133 -0
  11. package/dist/hooks.d.ts +113 -0
  12. package/dist/hooks.d.ts.map +1 -0
  13. package/dist/hooks.js +212 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +15 -0
  17. package/dist/jwt.d.ts +20 -0
  18. package/dist/jwt.d.ts.map +1 -0
  19. package/dist/jwt.js +30 -0
  20. package/dist/provider.d.ts +50 -0
  21. package/dist/provider.d.ts.map +1 -0
  22. package/dist/provider.js +91 -0
  23. package/dist/ui/CheckoutButton.d.ts +14 -0
  24. package/dist/ui/CheckoutButton.d.ts.map +1 -0
  25. package/dist/ui/CheckoutButton.js +28 -0
  26. package/dist/ui/Control.d.ts +17 -0
  27. package/dist/ui/Control.d.ts.map +1 -0
  28. package/dist/ui/Control.js +33 -0
  29. package/dist/ui/CreateOrganization.d.ts +19 -0
  30. package/dist/ui/CreateOrganization.d.ts.map +1 -0
  31. package/dist/ui/CreateOrganization.js +75 -0
  32. package/dist/ui/OrganizationList.d.ts +13 -0
  33. package/dist/ui/OrganizationList.d.ts.map +1 -0
  34. package/dist/ui/OrganizationList.js +47 -0
  35. package/dist/ui/OrganizationProfile.d.ts +12 -0
  36. package/dist/ui/OrganizationProfile.d.ts.map +1 -0
  37. package/dist/ui/OrganizationProfile.js +116 -0
  38. package/dist/ui/OrganizationSwitcher.d.ts +17 -0
  39. package/dist/ui/OrganizationSwitcher.d.ts.map +1 -0
  40. package/dist/ui/OrganizationSwitcher.js +59 -0
  41. package/dist/ui/PricingTable.d.ts +15 -0
  42. package/dist/ui/PricingTable.d.ts.map +1 -0
  43. package/dist/ui/PricingTable.js +74 -0
  44. package/dist/ui/SignIn.d.ts +23 -0
  45. package/dist/ui/SignIn.d.ts.map +1 -0
  46. package/dist/ui/SignIn.js +489 -0
  47. package/dist/ui/SignUp.d.ts +18 -0
  48. package/dist/ui/SignUp.d.ts.map +1 -0
  49. package/dist/ui/SignUp.js +153 -0
  50. package/dist/ui/UnstyledButtons.d.ts +24 -0
  51. package/dist/ui/UnstyledButtons.d.ts.map +1 -0
  52. package/dist/ui/UnstyledButtons.js +42 -0
  53. package/dist/ui/UserAvatar.d.ts +14 -0
  54. package/dist/ui/UserAvatar.d.ts.map +1 -0
  55. package/dist/ui/UserAvatar.js +52 -0
  56. package/dist/ui/UserButton.d.ts +15 -0
  57. package/dist/ui/UserButton.d.ts.map +1 -0
  58. package/dist/ui/UserButton.js +82 -0
  59. package/dist/ui/UserProfile.d.ts +19 -0
  60. package/dist/ui/UserProfile.d.ts.map +1 -0
  61. package/dist/ui/UserProfile.js +199 -0
  62. package/dist/ui/index.d.ts +14 -0
  63. package/dist/ui/index.d.ts.map +1 -0
  64. package/dist/ui/index.js +13 -0
  65. package/dist/ui/styles.d.ts +10 -0
  66. package/dist/ui/styles.d.ts.map +1 -0
  67. package/dist/ui/styles.js +291 -0
  68. package/package.json +46 -0
@@ -0,0 +1,14 @@
1
+ export * from './SignIn.js';
2
+ export * from './SignUp.js';
3
+ export * from './UserButton.js';
4
+ export * from './UserProfile.js';
5
+ export * from './UserAvatar.js';
6
+ export * from './OrganizationSwitcher.js';
7
+ export * from './CreateOrganization.js';
8
+ export * from './OrganizationList.js';
9
+ export * from './OrganizationProfile.js';
10
+ export * from './PricingTable.js';
11
+ export * from './CheckoutButton.js';
12
+ export * from './Control.js';
13
+ export * from './UnstyledButtons.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,13 @@
1
+ export * from './SignIn.js';
2
+ export * from './SignUp.js';
3
+ export * from './UserButton.js';
4
+ export * from './UserProfile.js';
5
+ export * from './UserAvatar.js';
6
+ export * from './OrganizationSwitcher.js';
7
+ export * from './CreateOrganization.js';
8
+ export * from './OrganizationList.js';
9
+ export * from './OrganizationProfile.js';
10
+ export * from './PricingTable.js';
11
+ export * from './CheckoutButton.js';
12
+ export * from './Control.js';
13
+ export * from './UnstyledButtons.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hand-authored CSS for the prebuilt auth components. We inject a single
3
+ * `<style>` tag on first render so the components look consistent without
4
+ * assuming Tailwind / any host framework. Variables make it trivial to
5
+ * override branding from the host — see `<AuthfyioProvider appearance>`.
6
+ */
7
+ export declare const AF_STYLE_ID = "af-auth-ui-styles";
8
+ export declare const COMPONENT_CSS = "\n.af-card {\n box-sizing: border-box;\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n padding: 32px 32px 28px;\n background: #ffffff;\n border: 1px solid rgba(17, 24, 39, 0.08);\n border-radius: 16px;\n box-shadow: 0 8px 32px -8px rgba(17, 24, 39, 0.08), 0 2px 6px -1px rgba(17, 24, 39, 0.04);\n font-family: var(--af-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n color: #111827;\n}\n.af-card * { box-sizing: border-box; }\n\n.af-brand {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 18px;\n}\n.af-brand-mark {\n width: 26px;\n height: 26px;\n border-radius: 8px;\n background: var(--af-primary-grad, linear-gradient(135deg, #4f3df0 0%, #5b5bd6 100%));\n}\n.af-brand-text { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }\n\n.af-title { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 4px; }\n.af-subtitle { font-size: 13px; color: #6b7280; margin: 0 0 22px; line-height: 1.45; }\n\n.af-label { display: block; font-size: 12px; font-weight: 500; color: #6b7280; margin-bottom: 6px; }\n.af-input {\n width: 100%;\n height: 40px;\n padding: 0 12px;\n font-size: 14px;\n background: #ffffff;\n border: 1px solid rgba(17, 24, 39, 0.14);\n border-radius: 10px;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n color: #111827;\n font-family: inherit;\n}\n.af-input:focus {\n border-color: var(--af-primary, #4f3df0);\n box-shadow: 0 0 0 3px rgba(79, 61, 240, 0.15);\n}\n.af-input::placeholder { color: #9ca3af; }\n\n.af-field + .af-field { margin-top: 14px; }\n\n.af-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n height: 40px;\n padding: 0 16px;\n font-size: 13.5px;\n font-weight: 500;\n font-family: inherit;\n border-radius: 10px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: filter 0.12s, background-color 0.12s, border-color 0.12s;\n text-decoration: none;\n}\n.af-btn:disabled { opacity: 0.55; cursor: not-allowed; }\n.af-btn-primary {\n width: 100%;\n background: var(--af-primary, #4f3df0);\n color: #ffffff;\n box-shadow: 0 1px 2px rgba(17, 24, 39, 0.1);\n}\n.af-btn-primary:hover:not(:disabled) { filter: brightness(1.08); }\n.af-btn-ghost {\n background: #ffffff;\n color: #111827;\n border-color: rgba(17, 24, 39, 0.12);\n}\n.af-btn-ghost:hover:not(:disabled) { background: rgba(17, 24, 39, 0.03); }\n.af-btn-danger {\n background: #ffffff;\n color: #b91c1c;\n border-color: rgba(185, 28, 28, 0.4);\n}\n.af-btn-danger:hover:not(:disabled) { background: rgba(185, 28, 28, 0.05); }\n\n.af-primary-row { margin-top: 18px; }\n\n.af-divider { display: flex; align-items: center; gap: 12px; margin: 18px 0; color: #9ca3af; font-size: 11px; font-weight: 500; }\n.af-divider::before, .af-divider::after { content: ''; flex: 1; height: 1px; background: rgba(17, 24, 39, 0.08); }\n\n.af-social-grid { display: grid; gap: 8px; }\n.af-social-btn {\n display: flex;\n align-items: center;\n gap: 10px;\n justify-content: center;\n height: 40px;\n font-size: 13.5px;\n border: 1px solid rgba(17, 24, 39, 0.12);\n border-radius: 10px;\n background: #ffffff;\n color: #111827;\n cursor: pointer;\n text-decoration: none;\n font-weight: 500;\n transition: background 0.12s;\n font-family: inherit;\n}\n.af-social-btn:hover { background: rgba(17, 24, 39, 0.03); }\n.af-social-icon { width: 16px; height: 16px; display: inline-block; }\n\n.af-link { background: none; border: 0; padding: 4px 0; font: inherit; font-size: 13px; color: var(--af-primary, #4f3df0); cursor: pointer; text-decoration: none; }\n.af-link:hover { text-decoration: underline; }\n.af-footer { margin-top: 22px; text-align: center; font-size: 12.5px; color: #6b7280; }\n.af-footer a { color: var(--af-primary, #4f3df0); text-decoration: none; font-weight: 500; }\n.af-footer a:hover { text-decoration: underline; }\n\n.af-legal { margin-top: 18px; text-align: center; font-size: 11.5px; color: #9ca3af; line-height: 1.5; }\n.af-legal a { color: #6b7280; text-decoration: underline; text-underline-offset: 2px; }\n.af-legal a:hover { color: var(--af-primary, #4f3df0); }\n\n.af-powered { margin-top: 18px; padding-top: 14px; border-top: 1px solid rgba(17,24,39,0.05); text-align: center; font-size: 10.5px; color: #9ca3af; }\n.af-powered a { color: #6b7280; text-decoration: none; font-weight: 500; }\n.af-powered a:hover { text-decoration: underline; }\n\n.af-label-hint { color: #9ca3af; font-weight: 400; }\n\n.af-error {\n margin-top: 12px;\n padding: 10px 12px;\n font-size: 12.5px;\n background: rgba(225, 29, 72, 0.06);\n border: 1px solid rgba(225, 29, 72, 0.2);\n border-radius: 8px;\n color: #b91c1c;\n line-height: 1.45;\n}\n.af-notice {\n margin-top: 12px;\n padding: 10px 12px;\n font-size: 12.5px;\n background: rgba(16, 185, 129, 0.08);\n border: 1px solid rgba(16, 185, 129, 0.28);\n border-radius: 8px;\n color: #047857;\n line-height: 1.45;\n}\n\n/* UserButton */\n.af-user-btn {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 10px 4px 4px;\n font-family: inherit;\n font-size: 12.5px;\n font-weight: 500;\n color: #111827;\n background: #ffffff;\n border: 1px solid rgba(17, 24, 39, 0.1);\n border-radius: 999px;\n cursor: pointer;\n box-shadow: 0 1px 2px rgba(17, 24, 39, 0.04);\n}\n.af-user-btn:hover { background: rgba(17, 24, 39, 0.03); }\n.af-avatar {\n width: 28px; height: 28px;\n border-radius: 999px;\n background: rgba(17, 24, 39, 0.06);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 10.5px;\n font-weight: 600;\n color: #4b5563;\n overflow: hidden;\n position: relative;\n}\n.af-avatar img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }\n.af-avatar-sm { width: 22px; height: 22px; font-size: 9px; }\n.af-avatar-lg { width: 56px; height: 56px; font-size: 14px; }\n\n.af-menu {\n position: absolute;\n right: 0;\n top: calc(100% + 6px);\n min-width: 240px;\n background: #ffffff;\n border: 1px solid rgba(17, 24, 39, 0.08);\n border-radius: 12px;\n box-shadow: 0 12px 32px -4px rgba(17, 24, 39, 0.14);\n padding: 6px;\n z-index: 30;\n}\n.af-menu-head {\n display: flex; align-items: center; gap: 10px;\n padding: 10px 10px 12px;\n border-bottom: 1px solid rgba(17, 24, 39, 0.06);\n margin-bottom: 4px;\n}\n.af-menu-head-name { font-size: 13px; font-weight: 500; color: #111827; line-height: 1.3; }\n.af-menu-head-email { font-size: 11.5px; color: #6b7280; }\n.af-menu-item {\n display: block;\n width: 100%;\n padding: 8px 10px;\n font-size: 12.5px;\n color: #111827;\n background: transparent;\n border: 0;\n border-radius: 7px;\n text-align: left;\n cursor: pointer;\n text-decoration: none;\n font-family: inherit;\n}\n.af-menu-item:hover { background: rgba(17, 24, 39, 0.04); }\n.af-menu-item-danger { color: #b91c1c; }\n.af-menu-item-danger:hover { background: rgba(225, 29, 72, 0.06); }\n.af-menu-sep { height: 1px; background: rgba(17, 24, 39, 0.06); margin: 4px 6px; }\n\n/* Sign-in tabs */\n.af-tabs { display: inline-flex; gap: 4px; padding: 3px; background: rgba(17,24,39,0.04); border-radius: 10px; margin-bottom: 18px; width: 100%; }\n.af-tab {\n font-family: inherit;\n flex: 1;\n padding: 7px 10px;\n font-size: 11.5px;\n font-weight: 500;\n color: #6b7280;\n background: transparent;\n border: 0;\n border-radius: 7px;\n cursor: pointer;\n transition: background 0.12s, color 0.12s;\n}\n.af-tab:hover { color: #111827; }\n.af-tab.is-active { background: #ffffff; color: #111827; box-shadow: 0 1px 2px rgba(17,24,39,0.06); }\n\n/* UserProfile */\n.af-profile { display: grid; grid-template-columns: 200px 1fr; gap: 36px; }\n@media (max-width: 640px) { .af-profile { grid-template-columns: 1fr; } }\n.af-profile-nav { display: flex; flex-direction: column; gap: 2px; }\n.af-profile-nav-item {\n text-align: left;\n padding: 8px 10px;\n border-radius: 8px;\n font-size: 13px;\n color: #6b7280;\n background: transparent;\n border: 0;\n cursor: pointer;\n font-family: inherit;\n}\n.af-profile-nav-item.is-active { background: rgba(17, 24, 39, 0.05); color: #111827; font-weight: 500; }\n.af-profile-panel h3 { margin: 0 0 4px; font-size: 17px; font-weight: 600; letter-spacing: -0.02em; }\n.af-profile-panel p.af-sub { margin: 0 0 18px; font-size: 13px; color: #6b7280; }\n.af-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-top: 1px solid rgba(17, 24, 39, 0.06); }\n.af-row:first-child { border-top: 0; padding-top: 0; }\n.af-row-key { font-size: 12.5px; color: #6b7280; }\n.af-row-val { font-size: 13px; color: #111827; }\n.af-pill { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 500; }\n.af-pill-primary { color: #4f3df0; background: rgba(79, 61, 240, 0.1); }\n.af-pill-success { color: #047857; background: rgba(16, 185, 129, 0.1); }\n.af-pill-muted { color: #6b7280; background: rgba(17, 24, 39, 0.05); }\n";
9
+ export declare function ensureStylesInjected(): void;
10
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAE/C,eAAO,MAAM,aAAa,m5RAiRzB,CAAC;AAEF,wBAAgB,oBAAoB,SAOnC"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Hand-authored CSS for the prebuilt auth components. We inject a single
3
+ * `<style>` tag on first render so the components look consistent without
4
+ * assuming Tailwind / any host framework. Variables make it trivial to
5
+ * override branding from the host — see `<AuthfyioProvider appearance>`.
6
+ */
7
+ export const AF_STYLE_ID = 'af-auth-ui-styles';
8
+ export const COMPONENT_CSS = `
9
+ .af-card {
10
+ box-sizing: border-box;
11
+ width: 100%;
12
+ max-width: 400px;
13
+ margin: 0 auto;
14
+ padding: 32px 32px 28px;
15
+ background: #ffffff;
16
+ border: 1px solid rgba(17, 24, 39, 0.08);
17
+ border-radius: 16px;
18
+ box-shadow: 0 8px 32px -8px rgba(17, 24, 39, 0.08), 0 2px 6px -1px rgba(17, 24, 39, 0.04);
19
+ font-family: var(--af-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
20
+ color: #111827;
21
+ }
22
+ .af-card * { box-sizing: border-box; }
23
+
24
+ .af-brand {
25
+ display: flex;
26
+ align-items: center;
27
+ gap: 8px;
28
+ margin-bottom: 18px;
29
+ }
30
+ .af-brand-mark {
31
+ width: 26px;
32
+ height: 26px;
33
+ border-radius: 8px;
34
+ background: var(--af-primary-grad, linear-gradient(135deg, #4f3df0 0%, #5b5bd6 100%));
35
+ }
36
+ .af-brand-text { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
37
+
38
+ .af-title { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 4px; }
39
+ .af-subtitle { font-size: 13px; color: #6b7280; margin: 0 0 22px; line-height: 1.45; }
40
+
41
+ .af-label { display: block; font-size: 12px; font-weight: 500; color: #6b7280; margin-bottom: 6px; }
42
+ .af-input {
43
+ width: 100%;
44
+ height: 40px;
45
+ padding: 0 12px;
46
+ font-size: 14px;
47
+ background: #ffffff;
48
+ border: 1px solid rgba(17, 24, 39, 0.14);
49
+ border-radius: 10px;
50
+ outline: none;
51
+ transition: border-color 0.15s, box-shadow 0.15s;
52
+ color: #111827;
53
+ font-family: inherit;
54
+ }
55
+ .af-input:focus {
56
+ border-color: var(--af-primary, #4f3df0);
57
+ box-shadow: 0 0 0 3px rgba(79, 61, 240, 0.15);
58
+ }
59
+ .af-input::placeholder { color: #9ca3af; }
60
+
61
+ .af-field + .af-field { margin-top: 14px; }
62
+
63
+ .af-btn {
64
+ display: inline-flex;
65
+ align-items: center;
66
+ justify-content: center;
67
+ gap: 8px;
68
+ height: 40px;
69
+ padding: 0 16px;
70
+ font-size: 13.5px;
71
+ font-weight: 500;
72
+ font-family: inherit;
73
+ border-radius: 10px;
74
+ border: 1px solid transparent;
75
+ cursor: pointer;
76
+ transition: filter 0.12s, background-color 0.12s, border-color 0.12s;
77
+ text-decoration: none;
78
+ }
79
+ .af-btn:disabled { opacity: 0.55; cursor: not-allowed; }
80
+ .af-btn-primary {
81
+ width: 100%;
82
+ background: var(--af-primary, #4f3df0);
83
+ color: #ffffff;
84
+ box-shadow: 0 1px 2px rgba(17, 24, 39, 0.1);
85
+ }
86
+ .af-btn-primary:hover:not(:disabled) { filter: brightness(1.08); }
87
+ .af-btn-ghost {
88
+ background: #ffffff;
89
+ color: #111827;
90
+ border-color: rgba(17, 24, 39, 0.12);
91
+ }
92
+ .af-btn-ghost:hover:not(:disabled) { background: rgba(17, 24, 39, 0.03); }
93
+ .af-btn-danger {
94
+ background: #ffffff;
95
+ color: #b91c1c;
96
+ border-color: rgba(185, 28, 28, 0.4);
97
+ }
98
+ .af-btn-danger:hover:not(:disabled) { background: rgba(185, 28, 28, 0.05); }
99
+
100
+ .af-primary-row { margin-top: 18px; }
101
+
102
+ .af-divider { display: flex; align-items: center; gap: 12px; margin: 18px 0; color: #9ca3af; font-size: 11px; font-weight: 500; }
103
+ .af-divider::before, .af-divider::after { content: ''; flex: 1; height: 1px; background: rgba(17, 24, 39, 0.08); }
104
+
105
+ .af-social-grid { display: grid; gap: 8px; }
106
+ .af-social-btn {
107
+ display: flex;
108
+ align-items: center;
109
+ gap: 10px;
110
+ justify-content: center;
111
+ height: 40px;
112
+ font-size: 13.5px;
113
+ border: 1px solid rgba(17, 24, 39, 0.12);
114
+ border-radius: 10px;
115
+ background: #ffffff;
116
+ color: #111827;
117
+ cursor: pointer;
118
+ text-decoration: none;
119
+ font-weight: 500;
120
+ transition: background 0.12s;
121
+ font-family: inherit;
122
+ }
123
+ .af-social-btn:hover { background: rgba(17, 24, 39, 0.03); }
124
+ .af-social-icon { width: 16px; height: 16px; display: inline-block; }
125
+
126
+ .af-link { background: none; border: 0; padding: 4px 0; font: inherit; font-size: 13px; color: var(--af-primary, #4f3df0); cursor: pointer; text-decoration: none; }
127
+ .af-link:hover { text-decoration: underline; }
128
+ .af-footer { margin-top: 22px; text-align: center; font-size: 12.5px; color: #6b7280; }
129
+ .af-footer a { color: var(--af-primary, #4f3df0); text-decoration: none; font-weight: 500; }
130
+ .af-footer a:hover { text-decoration: underline; }
131
+
132
+ .af-legal { margin-top: 18px; text-align: center; font-size: 11.5px; color: #9ca3af; line-height: 1.5; }
133
+ .af-legal a { color: #6b7280; text-decoration: underline; text-underline-offset: 2px; }
134
+ .af-legal a:hover { color: var(--af-primary, #4f3df0); }
135
+
136
+ .af-powered { margin-top: 18px; padding-top: 14px; border-top: 1px solid rgba(17,24,39,0.05); text-align: center; font-size: 10.5px; color: #9ca3af; }
137
+ .af-powered a { color: #6b7280; text-decoration: none; font-weight: 500; }
138
+ .af-powered a:hover { text-decoration: underline; }
139
+
140
+ .af-label-hint { color: #9ca3af; font-weight: 400; }
141
+
142
+ .af-error {
143
+ margin-top: 12px;
144
+ padding: 10px 12px;
145
+ font-size: 12.5px;
146
+ background: rgba(225, 29, 72, 0.06);
147
+ border: 1px solid rgba(225, 29, 72, 0.2);
148
+ border-radius: 8px;
149
+ color: #b91c1c;
150
+ line-height: 1.45;
151
+ }
152
+ .af-notice {
153
+ margin-top: 12px;
154
+ padding: 10px 12px;
155
+ font-size: 12.5px;
156
+ background: rgba(16, 185, 129, 0.08);
157
+ border: 1px solid rgba(16, 185, 129, 0.28);
158
+ border-radius: 8px;
159
+ color: #047857;
160
+ line-height: 1.45;
161
+ }
162
+
163
+ /* UserButton */
164
+ .af-user-btn {
165
+ position: relative;
166
+ display: inline-flex;
167
+ align-items: center;
168
+ gap: 8px;
169
+ padding: 4px 10px 4px 4px;
170
+ font-family: inherit;
171
+ font-size: 12.5px;
172
+ font-weight: 500;
173
+ color: #111827;
174
+ background: #ffffff;
175
+ border: 1px solid rgba(17, 24, 39, 0.1);
176
+ border-radius: 999px;
177
+ cursor: pointer;
178
+ box-shadow: 0 1px 2px rgba(17, 24, 39, 0.04);
179
+ }
180
+ .af-user-btn:hover { background: rgba(17, 24, 39, 0.03); }
181
+ .af-avatar {
182
+ width: 28px; height: 28px;
183
+ border-radius: 999px;
184
+ background: rgba(17, 24, 39, 0.06);
185
+ display: inline-flex;
186
+ align-items: center;
187
+ justify-content: center;
188
+ font-size: 10.5px;
189
+ font-weight: 600;
190
+ color: #4b5563;
191
+ overflow: hidden;
192
+ position: relative;
193
+ }
194
+ .af-avatar img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
195
+ .af-avatar-sm { width: 22px; height: 22px; font-size: 9px; }
196
+ .af-avatar-lg { width: 56px; height: 56px; font-size: 14px; }
197
+
198
+ .af-menu {
199
+ position: absolute;
200
+ right: 0;
201
+ top: calc(100% + 6px);
202
+ min-width: 240px;
203
+ background: #ffffff;
204
+ border: 1px solid rgba(17, 24, 39, 0.08);
205
+ border-radius: 12px;
206
+ box-shadow: 0 12px 32px -4px rgba(17, 24, 39, 0.14);
207
+ padding: 6px;
208
+ z-index: 30;
209
+ }
210
+ .af-menu-head {
211
+ display: flex; align-items: center; gap: 10px;
212
+ padding: 10px 10px 12px;
213
+ border-bottom: 1px solid rgba(17, 24, 39, 0.06);
214
+ margin-bottom: 4px;
215
+ }
216
+ .af-menu-head-name { font-size: 13px; font-weight: 500; color: #111827; line-height: 1.3; }
217
+ .af-menu-head-email { font-size: 11.5px; color: #6b7280; }
218
+ .af-menu-item {
219
+ display: block;
220
+ width: 100%;
221
+ padding: 8px 10px;
222
+ font-size: 12.5px;
223
+ color: #111827;
224
+ background: transparent;
225
+ border: 0;
226
+ border-radius: 7px;
227
+ text-align: left;
228
+ cursor: pointer;
229
+ text-decoration: none;
230
+ font-family: inherit;
231
+ }
232
+ .af-menu-item:hover { background: rgba(17, 24, 39, 0.04); }
233
+ .af-menu-item-danger { color: #b91c1c; }
234
+ .af-menu-item-danger:hover { background: rgba(225, 29, 72, 0.06); }
235
+ .af-menu-sep { height: 1px; background: rgba(17, 24, 39, 0.06); margin: 4px 6px; }
236
+
237
+ /* Sign-in tabs */
238
+ .af-tabs { display: inline-flex; gap: 4px; padding: 3px; background: rgba(17,24,39,0.04); border-radius: 10px; margin-bottom: 18px; width: 100%; }
239
+ .af-tab {
240
+ font-family: inherit;
241
+ flex: 1;
242
+ padding: 7px 10px;
243
+ font-size: 11.5px;
244
+ font-weight: 500;
245
+ color: #6b7280;
246
+ background: transparent;
247
+ border: 0;
248
+ border-radius: 7px;
249
+ cursor: pointer;
250
+ transition: background 0.12s, color 0.12s;
251
+ }
252
+ .af-tab:hover { color: #111827; }
253
+ .af-tab.is-active { background: #ffffff; color: #111827; box-shadow: 0 1px 2px rgba(17,24,39,0.06); }
254
+
255
+ /* UserProfile */
256
+ .af-profile { display: grid; grid-template-columns: 200px 1fr; gap: 36px; }
257
+ @media (max-width: 640px) { .af-profile { grid-template-columns: 1fr; } }
258
+ .af-profile-nav { display: flex; flex-direction: column; gap: 2px; }
259
+ .af-profile-nav-item {
260
+ text-align: left;
261
+ padding: 8px 10px;
262
+ border-radius: 8px;
263
+ font-size: 13px;
264
+ color: #6b7280;
265
+ background: transparent;
266
+ border: 0;
267
+ cursor: pointer;
268
+ font-family: inherit;
269
+ }
270
+ .af-profile-nav-item.is-active { background: rgba(17, 24, 39, 0.05); color: #111827; font-weight: 500; }
271
+ .af-profile-panel h3 { margin: 0 0 4px; font-size: 17px; font-weight: 600; letter-spacing: -0.02em; }
272
+ .af-profile-panel p.af-sub { margin: 0 0 18px; font-size: 13px; color: #6b7280; }
273
+ .af-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-top: 1px solid rgba(17, 24, 39, 0.06); }
274
+ .af-row:first-child { border-top: 0; padding-top: 0; }
275
+ .af-row-key { font-size: 12.5px; color: #6b7280; }
276
+ .af-row-val { font-size: 13px; color: #111827; }
277
+ .af-pill { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 500; }
278
+ .af-pill-primary { color: #4f3df0; background: rgba(79, 61, 240, 0.1); }
279
+ .af-pill-success { color: #047857; background: rgba(16, 185, 129, 0.1); }
280
+ .af-pill-muted { color: #6b7280; background: rgba(17, 24, 39, 0.05); }
281
+ `;
282
+ export function ensureStylesInjected() {
283
+ if (typeof document === 'undefined')
284
+ return;
285
+ if (document.getElementById(AF_STYLE_ID))
286
+ return;
287
+ const style = document.createElement('style');
288
+ style.id = AF_STYLE_ID;
289
+ style.textContent = COMPONENT_CSS;
290
+ document.head.appendChild(style);
291
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "authfyio-react",
3
+ "version": "0.3.9",
4
+ "description": "React provider, hooks, and components for Authfyio. Includes <SignedIn>, <SignedOut>, <Protect>, useAuth, useUser, useOrganization, and more.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "typecheck": "tsc -p tsconfig.build.json --noEmit",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18"
26
+ },
27
+ "devDependencies": {
28
+ "@types/react": "latest"
29
+ },
30
+ "keywords": [
31
+ "authfyio",
32
+ "auth",
33
+ "authentication",
34
+ "react",
35
+ "hooks",
36
+ "provider"
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "homepage": "https://authfyio.com/docs",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/authfyio/authfyio.git"
45
+ }
46
+ }