@draftlab/auth 0.0.3 → 0.1.0

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 (78) hide show
  1. package/dist/allow.d.ts +58 -1
  2. package/dist/allow.js +61 -2
  3. package/dist/client.d.ts +2 -3
  4. package/dist/client.js +2 -2
  5. package/dist/core.d.ts +128 -8
  6. package/dist/core.js +496 -12
  7. package/dist/error.d.ts +242 -1
  8. package/dist/error.js +235 -1
  9. package/dist/index.d.ts +1 -8
  10. package/dist/index.js +1 -12
  11. package/dist/keys.d.ts +1 -1
  12. package/dist/keys.js +138 -3
  13. package/dist/pkce.js +160 -1
  14. package/dist/provider/code.d.ts +227 -3
  15. package/dist/provider/code.js +27 -14
  16. package/dist/provider/facebook.d.ts +2 -3
  17. package/dist/provider/facebook.js +1 -5
  18. package/dist/provider/github.d.ts +2 -3
  19. package/dist/provider/github.js +1 -5
  20. package/dist/provider/google.d.ts +2 -3
  21. package/dist/provider/google.js +1 -5
  22. package/dist/provider/oauth2.d.ts +175 -3
  23. package/dist/provider/oauth2.js +153 -5
  24. package/dist/provider/password.d.ts +384 -3
  25. package/dist/provider/password.js +4 -4
  26. package/dist/provider/provider.d.ts +226 -2
  27. package/dist/random.js +85 -1
  28. package/dist/storage/memory.d.ts +2 -2
  29. package/dist/storage/memory.js +1 -1
  30. package/dist/storage/storage.d.ts +161 -1
  31. package/dist/storage/storage.js +60 -1
  32. package/dist/storage/turso.d.ts +1 -1
  33. package/dist/storage/turso.js +1 -1
  34. package/dist/storage/unstorage.d.ts +2 -2
  35. package/dist/storage/unstorage.js +2 -2
  36. package/dist/subject.d.ts +61 -2
  37. package/dist/themes/theme.d.ts +208 -1
  38. package/dist/themes/theme.js +118 -1
  39. package/dist/ui/base.d.ts +22 -35
  40. package/dist/ui/base.js +388 -3
  41. package/dist/ui/code.d.ts +22 -137
  42. package/dist/ui/code.js +199 -161
  43. package/dist/ui/form.d.ts +8 -6
  44. package/dist/ui/form.js +57 -1
  45. package/dist/ui/icon.d.ts +7 -84
  46. package/dist/ui/icon.js +69 -2
  47. package/dist/ui/password.d.ts +30 -37
  48. package/dist/ui/password.js +340 -237
  49. package/dist/ui/select.d.ts +19 -218
  50. package/dist/ui/select.js +91 -4
  51. package/dist/util.d.ts +71 -1
  52. package/dist/util.js +106 -1
  53. package/package.json +5 -3
  54. package/dist/allow-CixonwTW.d.ts +0 -59
  55. package/dist/allow-DX5cehSc.js +0 -63
  56. package/dist/base-DRutbxgL.js +0 -422
  57. package/dist/code-DJxdFR7p.d.ts +0 -212
  58. package/dist/core-BZHEAefX.d.ts +0 -129
  59. package/dist/core-CDM5o4rs.js +0 -498
  60. package/dist/error-CWAdNAzm.d.ts +0 -243
  61. package/dist/error-DgAKK7b2.js +0 -237
  62. package/dist/form-6XKM_cOk.js +0 -61
  63. package/dist/icon-Ci5uqGB_.js +0 -192
  64. package/dist/keys-EEfxEGfO.js +0 -140
  65. package/dist/oauth2-B7-6Z7Lc.js +0 -155
  66. package/dist/oauth2-CXHukHf2.d.ts +0 -176
  67. package/dist/password-C4KLmO0O.d.ts +0 -385
  68. package/dist/pkce-276Za_rZ.js +0 -162
  69. package/dist/provider-tndlqCzp.d.ts +0 -227
  70. package/dist/random-SXMYlaVr.js +0 -87
  71. package/dist/select-BjySLL8I.js +0 -280
  72. package/dist/storage-BEaqEPNQ.js +0 -62
  73. package/dist/storage-CxKerLlc.d.ts +0 -162
  74. package/dist/subject-DMIMVtaT.d.ts +0 -62
  75. package/dist/theme-C9by7VXf.d.ts +0 -209
  76. package/dist/theme-CswaLtbW.js +0 -120
  77. package/dist/util-CSdHUFOo.js +0 -108
  78. package/dist/util-DbSKG1Xm.d.ts +0 -72
@@ -1,3 +1,120 @@
1
- import { THEME_DRAFTAUTH, THEME_SST, THEME_SUPABASE, THEME_TERMINAL, THEME_VERCEL, getTheme, setTheme } from "../theme-CswaLtbW.js";
1
+ //#region src/themes/theme.ts
2
+ /**
3
+ * Built-in default Draft Auth theme.
4
+ */
5
+ const THEME_DRAFTAUTH = {
6
+ title: "Draft Auth",
7
+ radius: "none",
8
+ background: {
9
+ dark: "black",
10
+ light: "white"
11
+ },
12
+ primary: {
13
+ dark: "white",
14
+ light: "black"
15
+ },
16
+ font: { family: "IBM Plex Sans, sans-serif" },
17
+ css: `
18
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@100;200;300;400;500;600;700&display=swap');
19
+ `
20
+ };
21
+ /**
22
+ * Built-in theme based on [Terminal](https://terminal.shop).
23
+ */
24
+ const THEME_TERMINAL = {
25
+ title: "terminal",
26
+ radius: "none",
27
+ favicon: "https://www.terminal.shop/favicon.svg",
28
+ logo: {
29
+ dark: "https://www.terminal.shop/images/logo-white.svg",
30
+ light: "https://www.terminal.shop/images/logo-black.svg"
31
+ },
32
+ primary: "#ff5e00",
33
+ background: {
34
+ dark: "rgb(0, 0, 0)",
35
+ light: "rgb(255, 255, 255)"
36
+ },
37
+ font: { family: "Geist Mono, monospace" },
38
+ css: `
39
+ @import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100;200;300;400;500;600;700;800;900&display=swap');
40
+ `
41
+ };
42
+ /**
43
+ * Built-in theme based on [SST](https://sst.dev).
44
+ */
45
+ const THEME_SST = {
46
+ title: "SST",
47
+ favicon: "https://sst.dev/favicon.svg",
48
+ logo: {
49
+ dark: "https://sst.dev/favicon.svg",
50
+ light: "https://sst.dev/favicon.svg"
51
+ },
52
+ background: {
53
+ dark: "#1a1a2d",
54
+ light: "rgb(255, 255, 255)"
55
+ },
56
+ primary: "#f3663f",
57
+ font: { family: "Rubik, sans-serif" },
58
+ css: `
59
+ @import url('https://fonts.googleapis.com/css2?family=Rubik:wght@100;200;300;400;500;600;700;800;900&display=swap');
60
+ `
61
+ };
62
+ /**
63
+ * Built-in theme based on [Supabase](https://supabase.com).
64
+ */
65
+ const THEME_SUPABASE = {
66
+ title: "Supabase",
67
+ logo: {
68
+ dark: "https://supabase.com/dashboard/_next/image?url=%2Fdashboard%2Fimg%2Fsupabase-dark.svg&w=128&q=75",
69
+ light: "https://supabase.com/dashboard/_next/image?url=%2Fdashboard%2Fimg%2Fsupabase-light.svg&w=128&q=75"
70
+ },
71
+ background: {
72
+ dark: "#171717",
73
+ light: "#f8f8f8"
74
+ },
75
+ primary: {
76
+ dark: "#006239",
77
+ light: "#72e3ad"
78
+ },
79
+ font: { family: "Varela Round, sans-serif" },
80
+ css: `
81
+ @import url('https://fonts.googleapis.com/css2?family=Varela+Round:wght@100;200;300;400;500;600;700;800;900&display=swap');
82
+ `
83
+ };
84
+ /**
85
+ * Built-in theme based on [Vercel](https://vercel.com).
86
+ */
87
+ const THEME_VERCEL = {
88
+ title: "Vercel",
89
+ logo: {
90
+ dark: "https://vercel.com/mktng/_next/static/media/vercel-logotype-dark.e8c0a742.svg",
91
+ light: "https://vercel.com/mktng/_next/static/media/vercel-logotype-light.700a8d26.svg"
92
+ },
93
+ background: {
94
+ dark: "black",
95
+ light: "white"
96
+ },
97
+ primary: {
98
+ dark: "white",
99
+ light: "black"
100
+ },
101
+ font: { family: "Geist, sans-serif" },
102
+ css: `
103
+ @import url('https://fonts.googleapis.com/css2?family=Geist:wght@100;200;300;400;500;600;700;800;900&display=swap');
104
+ `
105
+ };
106
+ /**
107
+ * @internal
108
+ */
109
+ const setTheme = (value) => {
110
+ globalThis.DRAFTAUTH_THEME = value;
111
+ };
112
+ /**
113
+ * @internal
114
+ */
115
+ const getTheme = () => {
116
+ return globalThis.DRAFTAUTH_THEME || THEME_DRAFTAUTH;
117
+ };
2
118
 
119
+ //#endregion
3
120
  export { THEME_DRAFTAUTH, THEME_SST, THEME_SUPABASE, THEME_TERMINAL, THEME_VERCEL, getTheme, setTheme };
package/dist/ui/base.d.ts CHANGED
@@ -1,43 +1,30 @@
1
+ import { Theme } from "../themes/theme.js";
2
+ import * as preact4 from "preact";
3
+ import { ComponentChildren } from "preact";
4
+
1
5
  //#region src/ui/base.d.ts
2
- type PropsWithChildren<P = {}> = P & {
3
- children?: string;
4
- };
6
+
5
7
  /**
6
- * Base layout component for Draft Auth UI.
7
- * Provides theming, responsive design, and consistent styling across all auth screens.
8
- *
9
- * ## Features
10
- *
11
- * - **Theme Support**: Light/dark mode with custom colors and fonts
12
- * - **Responsive Design**: Adapts to different screen sizes
13
- * - **Custom Branding**: Support for custom logos and styling
14
- * - **CSS Variables**: Uses CSS custom properties for theming
15
- *
16
- * @example
17
- * ```tsx
18
- * <Layout size="small">
19
- *   <div>Your auth form content</div>
20
- * </Layout>
21
- * ```
22
- */
23
- /**
24
- * Props for the Layout component.
8
+ * Props for the Layout component
25
9
  */
26
10
  interface LayoutProps {
27
- /**
28
- * Optional size variant for the layout container.
29
- *
30
- * @default undefined (normal size)
31
- */
32
- readonly size?: "small";
11
+ children: ComponentChildren;
12
+ theme?: Theme;
13
+ title?: string;
14
+ size?: "small";
33
15
  }
34
16
  /**
35
- * Main layout component that wraps all authentication UI screens.
36
- * Handles theming, logo display, and provides consistent styling.
37
- *
38
- * @param props - Layout props including children and optional size
39
- * @returns Complete HTML document as a string with theming and branding applied
17
+ * Base Layout component that provides the foundational structure for all auth UIs
18
+ */
19
+ declare const Layout: ({
20
+ children,
21
+ theme,
22
+ title,
23
+ size
24
+ }: LayoutProps) => preact4.JSX.Element;
25
+ /**
26
+ * Helper function to render a Preact component to HTML string
40
27
  */
41
- declare const Layout: (props: PropsWithChildren<LayoutProps>) => string;
28
+ declare const renderToHTML: (component: ComponentChildren) => string;
42
29
  //#endregion
43
- export { Layout, LayoutProps };
30
+ export { Layout, LayoutProps, renderToHTML };
package/dist/ui/base.js CHANGED
@@ -1,4 +1,389 @@
1
- import "../theme-CswaLtbW.js";
2
- import { Layout } from "../base-DRutbxgL.js";
1
+ import { getTheme } from "../themes/theme.js";
2
+ import { render } from "preact-render-to-string";
3
+ import { jsx, jsxs } from "preact/jsx-runtime";
3
4
 
4
- export { Layout };
5
+ //#region src/ui/base.tsx
6
+ const css = `@import url("https://unpkg.com/tailwindcss@3.4.15/src/css/preflight.css");
7
+
8
+ :root {
9
+ --color-background-dark: #0e0e11;
10
+ --color-background-light: #ffffff;
11
+ --color-primary-dark: #6772e5;
12
+ --color-primary-light: #6772e5;
13
+
14
+ --color-background-success-dark: oklch(0.3 0.04 172);
15
+ --color-background-success-light: oklch(
16
+ from var(--color-background-success-dark) 0.83 c h
17
+ );
18
+ --color-success-dark: oklch(
19
+ from var(--color-background-success-dark) 0.92 c h
20
+ );
21
+ --color-success-light: oklch(
22
+ from var(--color-background-success-dark) 0.25 c h
23
+ );
24
+
25
+ --color-background-error-dark: oklch(0.32 0.07 15);
26
+ --color-background-error-light: oklch(
27
+ from var(--color-background-error-dark) 0.92 c h
28
+ );
29
+ --color-error-dark: oklch(from var(--color-background-error-dark) 0.92 c h);
30
+ --color-error-light: oklch(from var(--color-background-error-dark) 0.25 c h);
31
+
32
+ --border-radius: 0;
33
+
34
+ --color-background: var(--color-background-dark);
35
+ --color-primary: var(--color-primary-dark);
36
+
37
+ --color-background-success: var(--color-background-success-dark);
38
+ --color-success: var(--color-success-dark);
39
+ --color-background-error: var(--color-background-error-dark);
40
+ --color-error: var(--color-error-dark);
41
+
42
+ @media (prefers-color-scheme: light) {
43
+ --color-background: var(--color-background-light);
44
+ --color-primary: var(--color-primary-light);
45
+
46
+ --color-background-success: var(--color-background-success-light);
47
+ --color-success: var(--color-success-light);
48
+ --color-background-error: var(--color-background-error-light);
49
+ --color-error: var(--color-error-light);
50
+ }
51
+
52
+ --color-high: oklch(
53
+ from var(--color-background) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
54
+ );
55
+ --color-low: oklch(
56
+ from var(--color-background) clamp(0, calc((l - 0.714) * 1000), 1) 0 0
57
+ );
58
+ --lightness-high: color-mix(
59
+ in oklch,
60
+ var(--color-high) 0%,
61
+ oklch(var(--color-high) 0 0)
62
+ );
63
+ --lightness-low: color-mix(
64
+ in oklch,
65
+ var(--color-low) 0%,
66
+ oklch(var(--color-low) 0 0)
67
+ );
68
+ --font-family:
69
+ ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
70
+ "Segoe UI Symbol", "Noto Color Emoji";
71
+ --font-scale: 1;
72
+
73
+ --font-size-xs: calc(0.75rem * var(--font-scale));
74
+ --font-size-sm: calc(0.875rem * var(--font-scale));
75
+ --font-size-md: calc(1rem * var(--font-scale));
76
+ --font-size-lg: calc(1.125rem * var(--font-scale));
77
+ --font-size-xl: calc(1.25rem * var(--font-scale));
78
+ --font-size-2xl: calc(1.5rem * var(--font-scale));
79
+ }
80
+
81
+ [data-component="root"] {
82
+ font-family: var(--font-family);
83
+ background-color: var(--color-background);
84
+ padding: 1rem;
85
+ color: white;
86
+ position: absolute;
87
+ inset: 0;
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ flex-direction: column;
92
+ user-select: none;
93
+ color: var(--color-high);
94
+ }
95
+
96
+ [data-component="center"] {
97
+ width: 380px;
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 1.5rem;
101
+ }
102
+
103
+ [data-component="center"][data-size="small"] {
104
+ width: 300px;
105
+ }
106
+
107
+ [data-component="button"] {
108
+ height: 2.5rem;
109
+ cursor: pointer;
110
+ border: 0;
111
+ font-weight: 500;
112
+ font-size: var(--font-size-sm);
113
+ border-radius: calc(var(--border-radius) * 0.25rem);
114
+ display: flex;
115
+ gap: 0.75rem;
116
+ align-items: center;
117
+ justify-content: center;
118
+ background: var(--color-primary);
119
+ color: oklch(
120
+ from var(--color-primary) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
121
+ );
122
+ }
123
+
124
+ [data-component="button"][data-color="ghost"] {
125
+ background: transparent;
126
+ color: var(--color-high);
127
+ border: 1px solid
128
+ oklch(
129
+ from var(--color-background)
130
+ calc(
131
+ clamp(
132
+ 0.22,
133
+ l +
134
+ (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
135
+ 0.88
136
+ )
137
+ )
138
+ c h
139
+ );
140
+ }
141
+
142
+ [data-component="button"] [data-slot="icon"] {
143
+ width: 16px;
144
+ height: 16px;
145
+ }
146
+
147
+ [data-component="button"] [data-slot="icon"] svg {
148
+ width: 100%;
149
+ height: 100%;
150
+ }
151
+
152
+ [data-component="form"] {
153
+ max-width: 100%;
154
+ display: flex;
155
+ flex-direction: column;
156
+ gap: 1rem;
157
+ margin: 0;
158
+ }
159
+
160
+ [data-component="input"] {
161
+ height: 2.5rem;
162
+ border: 1px solid
163
+ oklch(
164
+ from var(--color-background)
165
+ calc(
166
+ clamp(
167
+ 0.22,
168
+ l +
169
+ (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
170
+ 0.88
171
+ )
172
+ )
173
+ c h
174
+ );
175
+ border-radius: calc(var(--border-radius) * 0.25rem);
176
+ background: var(--color-background);
177
+ color: var(--color-high);
178
+ padding: 0 0.75rem;
179
+ font-size: var(--font-size-sm);
180
+ font-family: var(--font-family);
181
+ }
182
+
183
+ [data-component="input"]:focus {
184
+ outline: none;
185
+ border-color: var(--color-primary);
186
+ }
187
+
188
+ [data-component="input"]::placeholder {
189
+ color: oklch(
190
+ from var(--color-high)
191
+ l
192
+ c
193
+ h /
194
+ 0.6
195
+ );
196
+ }
197
+
198
+ [data-component="form-alert"] {
199
+ padding: 0.75rem;
200
+ border-radius: calc(var(--border-radius) * 0.25rem);
201
+ display: flex;
202
+ align-items: center;
203
+ gap: 0.75rem;
204
+ font-size: var(--font-size-sm);
205
+ }
206
+
207
+ [data-component="form-alert"][data-color="danger"] {
208
+ background: var(--color-background-error);
209
+ color: var(--color-error);
210
+ border: 1px solid var(--color-error);
211
+ }
212
+
213
+ [data-component="form-alert"][data-color="success"] {
214
+ background: var(--color-background-success);
215
+ color: var(--color-success);
216
+ border: 1px solid var(--color-success);
217
+ }
218
+
219
+ [data-component="form-alert"] [data-slot="icon-success"] {
220
+ display: none;
221
+ }
222
+
223
+ [data-component="form-alert"] [data-slot="icon-danger"] {
224
+ display: none;
225
+ }
226
+
227
+ [data-component="form-alert"][data-color="success"] [data-slot="icon-success"] {
228
+ display: block;
229
+ width: 16px;
230
+ height: 16px;
231
+ }
232
+
233
+ [data-component="form-alert"][data-color="danger"] [data-slot="icon-danger"] {
234
+ display: block;
235
+ width: 16px;
236
+ height: 16px;
237
+ }
238
+
239
+ [data-component="link"] {
240
+ color: var(--color-primary);
241
+ text-decoration: none;
242
+ font-size: var(--font-size-sm);
243
+ }
244
+
245
+ [data-component="link"]:hover {
246
+ text-decoration: underline;
247
+ }
248
+
249
+ [data-component="form-footer"] {
250
+ display: flex;
251
+ gap: 1rem;
252
+ font-size: 0.75rem;
253
+ align-items: center;
254
+ justify-content: center;
255
+ }
256
+
257
+ [data-component="form-footer"]:has(> :nth-child(2)) {
258
+ justify-content: space-between;
259
+ }
260
+
261
+ [data-component="logo-default"] {
262
+ margin: 0 auto;
263
+ height: 2.5rem;
264
+ width: auto;
265
+ }
266
+
267
+ @media (prefers-color-scheme: light) {
268
+ [data-component="logo-default"] {
269
+ color: var(--color-high);
270
+ }
271
+ }
272
+
273
+ @media (prefers-color-scheme: dark) {
274
+ [data-component="logo-default"] {
275
+ color: var(--color-high);
276
+ }
277
+ }
278
+ `;
279
+ /**
280
+ * Base Layout component that provides the foundational structure for all auth UIs
281
+ */
282
+ const Layout = ({ children, theme, title, size }) => {
283
+ const currentTheme = theme || getTheme();
284
+ /**
285
+ * Gets a theme value for a specific key and color mode.
286
+ */
287
+ const getThemeValue = (key, mode) => {
288
+ if (!currentTheme?.[key]) return;
289
+ if (typeof currentTheme[key] === "string") return currentTheme[key];
290
+ return currentTheme[key][mode];
291
+ };
292
+ /**
293
+ * Calculates border radius value based on theme configuration.
294
+ */
295
+ const getBorderRadius = () => {
296
+ switch (currentTheme?.radius) {
297
+ case "none": return "0";
298
+ case "sm": return "1";
299
+ case "md": return "1.25";
300
+ case "lg": return "1.5";
301
+ case "full": return "1000000000001";
302
+ default: return "1";
303
+ }
304
+ };
305
+ /**
306
+ * Checks if both light and dark logo variants are available.
307
+ */
308
+ const hasCustomLogo = Boolean(getThemeValue("logo", "light") && getThemeValue("logo", "dark"));
309
+ /**
310
+ * CSS custom properties for theming.
311
+ */
312
+ const themeStyles = [
313
+ `--color-background-light: ${getThemeValue("background", "light") || ""}`,
314
+ `--color-background-dark: ${getThemeValue("background", "dark") || ""}`,
315
+ `--color-primary-light: ${getThemeValue("primary", "light") || ""}`,
316
+ `--color-primary-dark: ${getThemeValue("primary", "dark") || ""}`,
317
+ `--font-family: ${currentTheme?.font?.family || ""}`,
318
+ `--font-scale: ${currentTheme?.font?.scale || ""}`,
319
+ `--border-radius: ${getBorderRadius()}`
320
+ ].join("; ");
321
+ const faviconHtml = currentTheme?.favicon ? `<link href="${currentTheme.favicon}" rel="icon" />` : `
322
+ <link href="https://openauth.js.org/favicon.ico" rel="icon" sizes="48x48" />
323
+ <link href="https://openauth.js.org/favicon.svg" media="(prefers-color-scheme: light)" rel="icon" />
324
+ <link href="https://openauth.js.org/favicon-dark.svg" media="(prefers-color-scheme: dark)" rel="icon" />
325
+ <link href="https://openauth.js.org/favicon.svg" rel="shortcut icon" type="image/svg+xml" />
326
+ `;
327
+ const logoHtml = hasCustomLogo ? `
328
+ <img
329
+ alt="Logo Light"
330
+ data-component="logo"
331
+ data-mode="light"
332
+ src="${getThemeValue("logo", "light") || ""}"
333
+ />
334
+ <img
335
+ alt="Logo Dark"
336
+ data-component="logo"
337
+ data-mode="dark"
338
+ src="${getThemeValue("logo", "dark") || ""}"
339
+ />
340
+ ` : `
341
+ <svg
342
+ aria-label="Draft Auth Logo"
343
+ data-component="logo-default"
344
+ fill="none"
345
+ height="51"
346
+ viewBox="0 0 51 51"
347
+ width="51"
348
+ xmlns="http://www.w3.org/2000/svg"
349
+ >
350
+ <title>Draft Auth Logo</title>
351
+ <path
352
+ d="M0 50.2303V0.12854H50.1017V50.2303H0ZM3.08002 11.8326H11.7041V3.20856H3.08002V11.8326ZM14.8526 11.8326H23.4766V3.20856H14.8526V11.8326ZM26.5566 11.8326H35.1807V3.20856H26.5566V11.8326ZM38.3292 11.8326H47.0217V3.20856H38.3292V11.8326ZM3.08002 23.6052H11.7041V14.9811H3.08002V23.6052ZM14.8526 23.6052H23.4766V14.9811H14.8526V23.6052ZM26.5566 23.6052H35.1807V14.9811H26.5566V23.6052ZM38.3292 23.6052H47.0217V14.9811H38.3292V23.6052ZM3.08002 35.3092H11.7041V26.6852H3.08002V35.3092ZM14.8526 35.3092H23.4766V26.6852H14.8526V35.3092ZM26.5566 35.3092H35.1807V26.6852H26.5566V35.3092ZM38.3292 35.3092H47.0217V26.6852H38.3292V35.3092ZM3.08002 47.1502H11.7041V38.3893H3.08002V47.1502ZM14.8526 47.1502H23.4766V38.3893H14.8526V47.1502ZM26.5566 47.1502H35.1807V38.3893H26.5566V47.1502ZM38.3292 47.1502H47.0217V38.3893H38.3292V47.1502Z"
353
+ fill="currentColor"
354
+ />
355
+ </svg>
356
+ `;
357
+ return /* @__PURE__ */ jsxs("html", {
358
+ lang: "en",
359
+ style: themeStyles,
360
+ children: [/* @__PURE__ */ jsxs("head", { children: [
361
+ /* @__PURE__ */ jsx("title", { children: title || currentTheme?.title || "Draft Auth" }),
362
+ /* @__PURE__ */ jsx("meta", { charset: "utf-8" }),
363
+ /* @__PURE__ */ jsx("meta", {
364
+ content: "width=device-width, initial-scale=1",
365
+ name: "viewport"
366
+ }),
367
+ /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: faviconHtml } }),
368
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: css } }),
369
+ currentTheme?.css && /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: currentTheme.css } })
370
+ ] }), /* @__PURE__ */ jsx("body", { children: /* @__PURE__ */ jsx("div", {
371
+ "data-component": "root",
372
+ children: /* @__PURE__ */ jsxs("div", {
373
+ "data-component": "center",
374
+ "data-size": size || "",
375
+ children: [/* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: logoHtml } }), children]
376
+ })
377
+ }) })]
378
+ });
379
+ };
380
+ /**
381
+ * Helper function to render a Preact component to HTML string
382
+ */
383
+ const renderToHTML = (component) => {
384
+ if (!component) return "";
385
+ return render(component);
386
+ };
387
+
388
+ //#endregion
389
+ export { Layout, renderToHTML };