@authon/js 0.1.4 → 0.1.6
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.js +54 -18
- package/dist/index.mjs +54 -18
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -60,6 +60,7 @@ var DEFAULT_BRANDING = {
|
|
|
60
60
|
borderRadius: 12,
|
|
61
61
|
showEmailPassword: true,
|
|
62
62
|
showDivider: true,
|
|
63
|
+
showSecuredBy: true,
|
|
63
64
|
locale: "en"
|
|
64
65
|
};
|
|
65
66
|
|
|
@@ -93,6 +94,7 @@ var ModalRenderer = class {
|
|
|
93
94
|
hostElement = null;
|
|
94
95
|
containerElement = null;
|
|
95
96
|
mode;
|
|
97
|
+
theme;
|
|
96
98
|
branding;
|
|
97
99
|
enabledProviders = [];
|
|
98
100
|
onProviderClick;
|
|
@@ -100,6 +102,7 @@ var ModalRenderer = class {
|
|
|
100
102
|
onClose;
|
|
101
103
|
constructor(options) {
|
|
102
104
|
this.mode = options.mode;
|
|
105
|
+
this.theme = options.theme || "auto";
|
|
103
106
|
this.branding = { ...DEFAULT_BRANDING, ...options.branding };
|
|
104
107
|
this.onProviderClick = options.onProviderClick;
|
|
105
108
|
this.onEmailSubmit = options.onEmailSubmit;
|
|
@@ -147,9 +150,13 @@ var ModalRenderer = class {
|
|
|
147
150
|
const title = isSignUp ? "Create your account" : "Welcome back";
|
|
148
151
|
const subtitle = isSignUp ? "Already have an account?" : "Don't have an account?";
|
|
149
152
|
const subtitleLink = isSignUp ? "Sign in" : "Sign up";
|
|
153
|
+
const dark = this.isDark();
|
|
150
154
|
const providerButtons = this.enabledProviders.filter((p) => !b.hiddenProviders?.includes(p)).map((p) => {
|
|
151
155
|
const config = getProviderButtonConfig(p);
|
|
152
|
-
|
|
156
|
+
const isWhiteBg = config.bgColor === "#ffffff";
|
|
157
|
+
const btnBg = dark && isWhiteBg ? "#f8fafc" : config.bgColor;
|
|
158
|
+
const btnBorder = isWhiteBg ? dark ? "#475569" : "#e5e7eb" : config.bgColor;
|
|
159
|
+
return `<button class="provider-btn" data-provider="${p}" style="background:${btnBg};color:${config.textColor};border:1px solid ${btnBorder}">
|
|
153
160
|
<span class="provider-icon">${config.iconSvg}</span>
|
|
154
161
|
<span>${config.label}</span>
|
|
155
162
|
</button>`;
|
|
@@ -178,41 +185,60 @@ var ModalRenderer = class {
|
|
|
178
185
|
${emailForm}
|
|
179
186
|
<p class="switch-view">${subtitle} <a href="#" id="switch-link">${subtitleLink}</a></p>
|
|
180
187
|
${footer}
|
|
188
|
+
${b.showSecuredBy !== false ? `<div class="secured-by">Secured by <span class="secured-brand">Authon</span></div>` : ""}
|
|
181
189
|
</div>
|
|
182
190
|
`;
|
|
183
191
|
}
|
|
192
|
+
isDark() {
|
|
193
|
+
if (this.theme === "dark") return true;
|
|
194
|
+
if (this.theme === "light") return false;
|
|
195
|
+
return typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
196
|
+
}
|
|
184
197
|
buildCSS() {
|
|
185
198
|
const b = this.branding;
|
|
199
|
+
const dark = this.isDark();
|
|
200
|
+
const bg = dark ? b.darkBg || "#0f172a" : b.lightBg || "#ffffff";
|
|
201
|
+
const text = dark ? b.darkText || "#f1f5f9" : b.lightText || "#111827";
|
|
202
|
+
const mutedText = dark ? "#94a3b8" : "#6b7280";
|
|
203
|
+
const dimText = dark ? "#64748b" : "#9ca3af";
|
|
204
|
+
const borderColor = dark ? "#334155" : "#d1d5db";
|
|
205
|
+
const dividerColor = dark ? "#334155" : "#e5e7eb";
|
|
206
|
+
const inputBg = dark ? "#1e293b" : "#ffffff";
|
|
186
207
|
return `
|
|
187
208
|
:host {
|
|
188
209
|
--authon-primary-start: ${b.primaryColorStart || "#7c3aed"};
|
|
189
210
|
--authon-primary-end: ${b.primaryColorEnd || "#4f46e5"};
|
|
190
|
-
--authon-
|
|
191
|
-
--authon-
|
|
192
|
-
--authon-
|
|
193
|
-
--authon-
|
|
211
|
+
--authon-bg: ${bg};
|
|
212
|
+
--authon-text: ${text};
|
|
213
|
+
--authon-muted: ${mutedText};
|
|
214
|
+
--authon-dim: ${dimText};
|
|
215
|
+
--authon-border: ${borderColor};
|
|
216
|
+
--authon-divider: ${dividerColor};
|
|
217
|
+
--authon-input-bg: ${inputBg};
|
|
194
218
|
--authon-radius: ${b.borderRadius ?? 12}px;
|
|
195
219
|
--authon-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
196
220
|
font-family: var(--authon-font);
|
|
197
|
-
color: var(--authon-
|
|
221
|
+
color: var(--authon-text);
|
|
198
222
|
}
|
|
199
223
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
200
224
|
.backdrop {
|
|
201
225
|
position: fixed; inset: 0; z-index: 99998;
|
|
202
|
-
background: rgba(0,0,0
|
|
226
|
+
background: rgba(0,0,0,${dark ? "0.7" : "0.5"}); backdrop-filter: blur(4px);
|
|
203
227
|
animation: fadeIn 0.2s ease;
|
|
204
228
|
}
|
|
205
229
|
.modal-container {
|
|
206
230
|
${this.mode === "popup" ? "position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; max-height: 90vh; overflow-y: auto;" : ""}
|
|
207
|
-
background: var(--authon-
|
|
231
|
+
background: var(--authon-bg);
|
|
232
|
+
color: var(--authon-text);
|
|
233
|
+
border: 1px solid var(--authon-border);
|
|
208
234
|
border-radius: var(--authon-radius);
|
|
209
235
|
padding: 32px;
|
|
210
236
|
width: 400px; max-width: 100%;
|
|
211
|
-
${this.mode === "popup" ?
|
|
237
|
+
${this.mode === "popup" ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? "0.5" : "0.25"}); animation: slideIn 0.3s ease;` : ""}
|
|
212
238
|
}
|
|
213
239
|
.logo { display: block; margin: 0 auto 16px; max-height: 48px; }
|
|
214
|
-
.title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; }
|
|
215
|
-
.brand-name { text-align: center; font-size: 14px; color:
|
|
240
|
+
.title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; color: var(--authon-text); }
|
|
241
|
+
.brand-name { text-align: center; font-size: 14px; color: var(--authon-muted); margin-bottom: 24px; }
|
|
216
242
|
.providers { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
|
|
217
243
|
.provider-btn {
|
|
218
244
|
display: flex; align-items: center; gap: 12px;
|
|
@@ -226,19 +252,22 @@ var ModalRenderer = class {
|
|
|
226
252
|
.provider-icon { display: flex; align-items: center; flex-shrink: 0; }
|
|
227
253
|
.divider {
|
|
228
254
|
display: flex; align-items: center; gap: 12px;
|
|
229
|
-
margin: 16px 0; color:
|
|
255
|
+
margin: 16px 0; color: var(--authon-dim); font-size: 13px;
|
|
230
256
|
}
|
|
231
257
|
.divider::before, .divider::after {
|
|
232
|
-
content: ''; flex: 1; height: 1px; background:
|
|
258
|
+
content: ''; flex: 1; height: 1px; background: var(--authon-divider);
|
|
233
259
|
}
|
|
234
260
|
.email-form { display: flex; flex-direction: column; gap: 10px; }
|
|
235
261
|
.input {
|
|
236
262
|
width: 100%; padding: 10px 14px;
|
|
237
|
-
|
|
263
|
+
background: var(--authon-input-bg);
|
|
264
|
+
color: var(--authon-text);
|
|
265
|
+
border: 1px solid var(--authon-border); border-radius: calc(var(--authon-radius) * 0.5);
|
|
238
266
|
font-size: 14px; font-family: var(--authon-font);
|
|
239
267
|
outline: none; transition: border-color 0.15s;
|
|
240
268
|
}
|
|
241
|
-
.input
|
|
269
|
+
.input::placeholder { color: var(--authon-dim); }
|
|
270
|
+
.input:focus { border-color: var(--authon-primary-start); box-shadow: 0 0 0 3px rgba(124,58,237,0.15); }
|
|
242
271
|
.submit-btn {
|
|
243
272
|
width: 100%; padding: 10px;
|
|
244
273
|
background: linear-gradient(135deg, var(--authon-primary-start), var(--authon-primary-end));
|
|
@@ -247,12 +276,18 @@ var ModalRenderer = class {
|
|
|
247
276
|
font-family: var(--authon-font); transition: opacity 0.15s;
|
|
248
277
|
}
|
|
249
278
|
.submit-btn:hover { opacity: 0.9; }
|
|
250
|
-
.switch-view { text-align: center; margin-top: 16px; font-size: 13px; color:
|
|
279
|
+
.switch-view { text-align: center; margin-top: 16px; font-size: 13px; color: var(--authon-muted); }
|
|
251
280
|
.switch-view a { color: var(--authon-primary-start); text-decoration: none; font-weight: 500; }
|
|
252
281
|
.switch-view a:hover { text-decoration: underline; }
|
|
253
|
-
.footer { text-align: center; margin-top: 16px; font-size: 12px; color:
|
|
254
|
-
.footer a { color:
|
|
282
|
+
.footer { text-align: center; margin-top: 16px; font-size: 12px; color: var(--authon-dim); }
|
|
283
|
+
.footer a { color: var(--authon-dim); text-decoration: none; }
|
|
255
284
|
.footer a:hover { text-decoration: underline; }
|
|
285
|
+
.secured-by {
|
|
286
|
+
text-align: center; margin-top: 20px; padding-top: 16px;
|
|
287
|
+
border-top: 1px solid var(--authon-divider);
|
|
288
|
+
font-size: 11px; color: var(--authon-dim);
|
|
289
|
+
}
|
|
290
|
+
.secured-brand { font-weight: 600; color: var(--authon-muted); }
|
|
256
291
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
257
292
|
@keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }
|
|
258
293
|
${b.customCss || ""}
|
|
@@ -473,6 +508,7 @@ var Authon = class {
|
|
|
473
508
|
if (!this.modal) {
|
|
474
509
|
this.modal = new ModalRenderer({
|
|
475
510
|
mode: this.config.mode,
|
|
511
|
+
theme: this.config.theme,
|
|
476
512
|
containerId: this.config.containerId,
|
|
477
513
|
branding: this.branding || void 0,
|
|
478
514
|
onProviderClick: (provider) => this.startOAuthFlow(provider),
|
package/dist/index.mjs
CHANGED
|
@@ -33,6 +33,7 @@ var DEFAULT_BRANDING = {
|
|
|
33
33
|
borderRadius: 12,
|
|
34
34
|
showEmailPassword: true,
|
|
35
35
|
showDivider: true,
|
|
36
|
+
showSecuredBy: true,
|
|
36
37
|
locale: "en"
|
|
37
38
|
};
|
|
38
39
|
|
|
@@ -66,6 +67,7 @@ var ModalRenderer = class {
|
|
|
66
67
|
hostElement = null;
|
|
67
68
|
containerElement = null;
|
|
68
69
|
mode;
|
|
70
|
+
theme;
|
|
69
71
|
branding;
|
|
70
72
|
enabledProviders = [];
|
|
71
73
|
onProviderClick;
|
|
@@ -73,6 +75,7 @@ var ModalRenderer = class {
|
|
|
73
75
|
onClose;
|
|
74
76
|
constructor(options) {
|
|
75
77
|
this.mode = options.mode;
|
|
78
|
+
this.theme = options.theme || "auto";
|
|
76
79
|
this.branding = { ...DEFAULT_BRANDING, ...options.branding };
|
|
77
80
|
this.onProviderClick = options.onProviderClick;
|
|
78
81
|
this.onEmailSubmit = options.onEmailSubmit;
|
|
@@ -120,9 +123,13 @@ var ModalRenderer = class {
|
|
|
120
123
|
const title = isSignUp ? "Create your account" : "Welcome back";
|
|
121
124
|
const subtitle = isSignUp ? "Already have an account?" : "Don't have an account?";
|
|
122
125
|
const subtitleLink = isSignUp ? "Sign in" : "Sign up";
|
|
126
|
+
const dark = this.isDark();
|
|
123
127
|
const providerButtons = this.enabledProviders.filter((p) => !b.hiddenProviders?.includes(p)).map((p) => {
|
|
124
128
|
const config = getProviderButtonConfig(p);
|
|
125
|
-
|
|
129
|
+
const isWhiteBg = config.bgColor === "#ffffff";
|
|
130
|
+
const btnBg = dark && isWhiteBg ? "#f8fafc" : config.bgColor;
|
|
131
|
+
const btnBorder = isWhiteBg ? dark ? "#475569" : "#e5e7eb" : config.bgColor;
|
|
132
|
+
return `<button class="provider-btn" data-provider="${p}" style="background:${btnBg};color:${config.textColor};border:1px solid ${btnBorder}">
|
|
126
133
|
<span class="provider-icon">${config.iconSvg}</span>
|
|
127
134
|
<span>${config.label}</span>
|
|
128
135
|
</button>`;
|
|
@@ -151,41 +158,60 @@ var ModalRenderer = class {
|
|
|
151
158
|
${emailForm}
|
|
152
159
|
<p class="switch-view">${subtitle} <a href="#" id="switch-link">${subtitleLink}</a></p>
|
|
153
160
|
${footer}
|
|
161
|
+
${b.showSecuredBy !== false ? `<div class="secured-by">Secured by <span class="secured-brand">Authon</span></div>` : ""}
|
|
154
162
|
</div>
|
|
155
163
|
`;
|
|
156
164
|
}
|
|
165
|
+
isDark() {
|
|
166
|
+
if (this.theme === "dark") return true;
|
|
167
|
+
if (this.theme === "light") return false;
|
|
168
|
+
return typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
169
|
+
}
|
|
157
170
|
buildCSS() {
|
|
158
171
|
const b = this.branding;
|
|
172
|
+
const dark = this.isDark();
|
|
173
|
+
const bg = dark ? b.darkBg || "#0f172a" : b.lightBg || "#ffffff";
|
|
174
|
+
const text = dark ? b.darkText || "#f1f5f9" : b.lightText || "#111827";
|
|
175
|
+
const mutedText = dark ? "#94a3b8" : "#6b7280";
|
|
176
|
+
const dimText = dark ? "#64748b" : "#9ca3af";
|
|
177
|
+
const borderColor = dark ? "#334155" : "#d1d5db";
|
|
178
|
+
const dividerColor = dark ? "#334155" : "#e5e7eb";
|
|
179
|
+
const inputBg = dark ? "#1e293b" : "#ffffff";
|
|
159
180
|
return `
|
|
160
181
|
:host {
|
|
161
182
|
--authon-primary-start: ${b.primaryColorStart || "#7c3aed"};
|
|
162
183
|
--authon-primary-end: ${b.primaryColorEnd || "#4f46e5"};
|
|
163
|
-
--authon-
|
|
164
|
-
--authon-
|
|
165
|
-
--authon-
|
|
166
|
-
--authon-
|
|
184
|
+
--authon-bg: ${bg};
|
|
185
|
+
--authon-text: ${text};
|
|
186
|
+
--authon-muted: ${mutedText};
|
|
187
|
+
--authon-dim: ${dimText};
|
|
188
|
+
--authon-border: ${borderColor};
|
|
189
|
+
--authon-divider: ${dividerColor};
|
|
190
|
+
--authon-input-bg: ${inputBg};
|
|
167
191
|
--authon-radius: ${b.borderRadius ?? 12}px;
|
|
168
192
|
--authon-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
169
193
|
font-family: var(--authon-font);
|
|
170
|
-
color: var(--authon-
|
|
194
|
+
color: var(--authon-text);
|
|
171
195
|
}
|
|
172
196
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
173
197
|
.backdrop {
|
|
174
198
|
position: fixed; inset: 0; z-index: 99998;
|
|
175
|
-
background: rgba(0,0,0
|
|
199
|
+
background: rgba(0,0,0,${dark ? "0.7" : "0.5"}); backdrop-filter: blur(4px);
|
|
176
200
|
animation: fadeIn 0.2s ease;
|
|
177
201
|
}
|
|
178
202
|
.modal-container {
|
|
179
203
|
${this.mode === "popup" ? "position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 99999; max-height: 90vh; overflow-y: auto;" : ""}
|
|
180
|
-
background: var(--authon-
|
|
204
|
+
background: var(--authon-bg);
|
|
205
|
+
color: var(--authon-text);
|
|
206
|
+
border: 1px solid var(--authon-border);
|
|
181
207
|
border-radius: var(--authon-radius);
|
|
182
208
|
padding: 32px;
|
|
183
209
|
width: 400px; max-width: 100%;
|
|
184
|
-
${this.mode === "popup" ?
|
|
210
|
+
${this.mode === "popup" ? `box-shadow: 0 25px 50px -12px rgba(0,0,0,${dark ? "0.5" : "0.25"}); animation: slideIn 0.3s ease;` : ""}
|
|
185
211
|
}
|
|
186
212
|
.logo { display: block; margin: 0 auto 16px; max-height: 48px; }
|
|
187
|
-
.title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; }
|
|
188
|
-
.brand-name { text-align: center; font-size: 14px; color:
|
|
213
|
+
.title { text-align: center; font-size: 24px; font-weight: 700; margin-bottom: 8px; color: var(--authon-text); }
|
|
214
|
+
.brand-name { text-align: center; font-size: 14px; color: var(--authon-muted); margin-bottom: 24px; }
|
|
189
215
|
.providers { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
|
|
190
216
|
.provider-btn {
|
|
191
217
|
display: flex; align-items: center; gap: 12px;
|
|
@@ -199,19 +225,22 @@ var ModalRenderer = class {
|
|
|
199
225
|
.provider-icon { display: flex; align-items: center; flex-shrink: 0; }
|
|
200
226
|
.divider {
|
|
201
227
|
display: flex; align-items: center; gap: 12px;
|
|
202
|
-
margin: 16px 0; color:
|
|
228
|
+
margin: 16px 0; color: var(--authon-dim); font-size: 13px;
|
|
203
229
|
}
|
|
204
230
|
.divider::before, .divider::after {
|
|
205
|
-
content: ''; flex: 1; height: 1px; background:
|
|
231
|
+
content: ''; flex: 1; height: 1px; background: var(--authon-divider);
|
|
206
232
|
}
|
|
207
233
|
.email-form { display: flex; flex-direction: column; gap: 10px; }
|
|
208
234
|
.input {
|
|
209
235
|
width: 100%; padding: 10px 14px;
|
|
210
|
-
|
|
236
|
+
background: var(--authon-input-bg);
|
|
237
|
+
color: var(--authon-text);
|
|
238
|
+
border: 1px solid var(--authon-border); border-radius: calc(var(--authon-radius) * 0.5);
|
|
211
239
|
font-size: 14px; font-family: var(--authon-font);
|
|
212
240
|
outline: none; transition: border-color 0.15s;
|
|
213
241
|
}
|
|
214
|
-
.input
|
|
242
|
+
.input::placeholder { color: var(--authon-dim); }
|
|
243
|
+
.input:focus { border-color: var(--authon-primary-start); box-shadow: 0 0 0 3px rgba(124,58,237,0.15); }
|
|
215
244
|
.submit-btn {
|
|
216
245
|
width: 100%; padding: 10px;
|
|
217
246
|
background: linear-gradient(135deg, var(--authon-primary-start), var(--authon-primary-end));
|
|
@@ -220,12 +249,18 @@ var ModalRenderer = class {
|
|
|
220
249
|
font-family: var(--authon-font); transition: opacity 0.15s;
|
|
221
250
|
}
|
|
222
251
|
.submit-btn:hover { opacity: 0.9; }
|
|
223
|
-
.switch-view { text-align: center; margin-top: 16px; font-size: 13px; color:
|
|
252
|
+
.switch-view { text-align: center; margin-top: 16px; font-size: 13px; color: var(--authon-muted); }
|
|
224
253
|
.switch-view a { color: var(--authon-primary-start); text-decoration: none; font-weight: 500; }
|
|
225
254
|
.switch-view a:hover { text-decoration: underline; }
|
|
226
|
-
.footer { text-align: center; margin-top: 16px; font-size: 12px; color:
|
|
227
|
-
.footer a { color:
|
|
255
|
+
.footer { text-align: center; margin-top: 16px; font-size: 12px; color: var(--authon-dim); }
|
|
256
|
+
.footer a { color: var(--authon-dim); text-decoration: none; }
|
|
228
257
|
.footer a:hover { text-decoration: underline; }
|
|
258
|
+
.secured-by {
|
|
259
|
+
text-align: center; margin-top: 20px; padding-top: 16px;
|
|
260
|
+
border-top: 1px solid var(--authon-divider);
|
|
261
|
+
font-size: 11px; color: var(--authon-dim);
|
|
262
|
+
}
|
|
263
|
+
.secured-brand { font-weight: 600; color: var(--authon-muted); }
|
|
229
264
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
230
265
|
@keyframes slideIn { from { opacity: 0; transform: translate(-50%, -48%); } to { opacity: 1; transform: translate(-50%, -50%); } }
|
|
231
266
|
${b.customCss || ""}
|
|
@@ -446,6 +481,7 @@ var Authon = class {
|
|
|
446
481
|
if (!this.modal) {
|
|
447
482
|
this.modal = new ModalRenderer({
|
|
448
483
|
mode: this.config.mode,
|
|
484
|
+
theme: this.config.theme,
|
|
449
485
|
containerId: this.config.containerId,
|
|
450
486
|
branding: this.branding || void 0,
|
|
451
487
|
onProviderClick: (provider) => this.startOAuthFlow(provider),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authon/js",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Authon core SDK — ShadowDOM login modal for any app",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"tsup": "^8.4.0",
|
|
22
22
|
"typescript": "^5.7.0"
|
|
23
23
|
},
|
|
24
|
-
"files": [
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
25
27
|
"license": "MIT"
|
|
26
28
|
}
|