@zitadel/components 0.1.0-alpha.17 → 0.1.0-alpha.19

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 (36) hide show
  1. package/README.md +99 -26
  2. package/dist/atoms/index.d.mts +1 -1
  3. package/dist/atoms/index.mjs +1 -1
  4. package/dist/{atoms-KC7OJWXZ.mjs → atoms-B6QmUAzo.mjs} +264 -189
  5. package/dist/atoms-B6QmUAzo.mjs.map +1 -0
  6. package/dist/default-Bnjy2dJB.mjs +6 -0
  7. package/dist/default-Bnjy2dJB.mjs.map +1 -0
  8. package/dist/{index-DSZnfOJH.d.mts → index-CAi5gsHK.d.mts} +4789 -2181
  9. package/dist/index-CAi5gsHK.d.mts.map +1 -0
  10. package/dist/{index-DjYJwejg.d.mts → index-Ce_81oFH.d.mts} +505 -230
  11. package/dist/index-Ce_81oFH.d.mts.map +1 -0
  12. package/dist/{index-BniwXaIC.d.mts → index-Dgc94IMN.d.mts} +113 -1
  13. package/dist/index-Dgc94IMN.d.mts.map +1 -0
  14. package/dist/index.d.mts +5 -5
  15. package/dist/index.mjs +5 -5
  16. package/dist/jsx.d.ts +67 -0
  17. package/dist/manifests.mjs +1 -1
  18. package/dist/orchestrator/index.d.mts +3 -3
  19. package/dist/orchestrator/index.mjs +3 -3
  20. package/dist/{orchestrator-BWqJw4Yl.mjs → orchestrator-CsHP57zo.mjs} +2847 -2272
  21. package/dist/orchestrator-CsHP57zo.mjs.map +1 -0
  22. package/dist/standalone.mjs +8340 -6946
  23. package/dist/tokens/index.d.mts +1 -1
  24. package/dist/tokens/index.mjs +1 -1
  25. package/dist/tokens-DSnSf1mf.mjs +358 -0
  26. package/dist/tokens-DSnSf1mf.mjs.map +1 -0
  27. package/package.json +14 -10
  28. package/dist/atoms-KC7OJWXZ.mjs.map +0 -1
  29. package/dist/default-CfF7GoLv.mjs +0 -6
  30. package/dist/default-CfF7GoLv.mjs.map +0 -1
  31. package/dist/index-BniwXaIC.d.mts.map +0 -1
  32. package/dist/index-DSZnfOJH.d.mts.map +0 -1
  33. package/dist/index-DjYJwejg.d.mts.map +0 -1
  34. package/dist/orchestrator-BWqJw4Yl.mjs.map +0 -1
  35. package/dist/tokens-CbH2s1jV.mjs +0 -246
  36. package/dist/tokens-CbH2s1jV.mjs.map +0 -1
package/README.md CHANGED
@@ -6,12 +6,16 @@ Zitadel auth UI.
6
6
  The package exports:
7
7
 
8
8
  - **Atoms** — `<zl-field>`, `<zl-button>`, `<zl-alert>`, `<zl-icon>`,
9
- `<zl-pill>`, `<zl-card>`, `<zl-page-shell>`. Form-associated, accessible,
9
+ `<zl-pill>`, `<zl-card>`, `<zl-checkbox>`, `<zl-select>`,
10
+ `<zl-page-shell>`, and `<zl-passkey>` (an invisible WebAuthn ceremony
11
+ handler — no rendered surface). Form-associated, accessible,
10
12
  branding-aware Lit elements that map 1:1 to the flow API
11
13
  field/action/error primitives and the Figma design system.
12
- - **Orchestrator** — `<zitadel-login>`. A single drop-in element that calls
14
+ - **Orchestrators** — `<zitadel-login>`, a single drop-in element that calls
13
15
  the flow API, renders each step through a Liquid template, manages focus
14
- and form submission, and applies branding/theme/locale.
16
+ and form submission, and applies branding/theme/locale; `<zitadel-logout>`
17
+ for sign-out; and `<zitadel-session>`, the post-sign-in "signed in" card
18
+ (session read + sign-out in one element).
15
19
  - **Tokens & manifests** — design tokens (`--zl-*` CSS custom properties), a
16
20
  Liquid template registry, and per-atom manifests describing allowed
17
21
  attributes/parts/events for sanitiser allowlists.
@@ -56,7 +60,9 @@ language. `<zitadel-login>` reads the global project handle from
56
60
  el.lang = 'en'; // optional; defaults to <html lang> / navigator.language
57
61
  </script>
58
62
 
59
- <zitadel-login id="login" purpose="login"></zitadel-login>
63
+ <!-- variant="page" = a dedicated login route that owns the viewport.
64
+ Omit it to embed a content-sized widget inside your own layout. -->
65
+ <zitadel-login id="login" variant="page" purpose="login"></zitadel-login>
60
66
  ```
61
67
 
62
68
  What `<zitadel-login>` handles for you:
@@ -65,9 +71,13 @@ What `<zitadel-login>` handles for you:
65
71
  `redirect` / `show` honoured automatically.
66
72
  - Native `<form>` semantics: Enter submits, password managers see the inputs,
67
73
  `<button type="submit">` works, browser autofill works.
68
- - Focus moved to the first field on every step change.
74
+ - Focus moved to the first field on every step change (and on load in
75
+ `variant="page"`; an embedded widget deliberately leaves initial focus alone
76
+ so it can't scroll-jump the page it sits on).
69
77
  - Branding tokens mapped to CSS variables on the shadow root.
70
- - Light/dark theme via `prefers-color-scheme`, hot-swappable.
78
+ - Light and dark theme, hot-swappable: the `theme` property, else the tenant's
79
+ `branding.theme.mode`, else the variant default (`page` dark, `widget`
80
+ follows `prefers-color-scheme`).
71
81
  - Mandatory gates (terms, captcha) enforced before submit.
72
82
  - Output sanitised with DOMPurify against a per-atom allowlist before injection.
73
83
  - Stateless server: the `_zflow` HttpOnly cookie is the source of truth
@@ -122,8 +132,9 @@ fixtures:
122
132
  `applyBranding(...)` injects a tenant branding overlay merged into every
123
133
  response (presets include `font_url` for Inter).
124
134
  - **Framework demos (TCP server)** — `moon run api-mock:start`
125
- serves the same handlers on port 4000 with `defaultDevBranding` (Arimo
126
- `font_url`) applied at boot. See [`apps/demo-next`](../../apps/demo-next/README.md)
135
+ serves the same handlers on port 8080 (set `PORT` to override) with
136
+ `defaultDevBranding` (Arimo `font_url`) applied at boot. See
137
+ [`apps/demo-next`](../../apps/demo-next/README.md)
127
138
  and [`apps/demo-nuxt`](../../apps/demo-nuxt/README.md).
128
139
 
129
140
  ### Preview surfaces
@@ -131,8 +142,8 @@ fixtures:
131
142
  | Surface | Moon command | What it gives you |
132
143
  | --- | --- | --- |
133
144
  | **Storybook** | `moon run storybook:dev` ([:6006](http://localhost:6006)) | The workbench for both the Lit atoms and the paired React components, plus the `<zitadel-login>` orchestrator (MSW via `msw-storybook-addon`, flow/branding as controls). |
134
- | **demo-next** | `moon run api-mock:start` + `ZITADEL_URL=http://localhost:4000 moon run demo-next:dev` | Next.js SDK, middleware, cookies, built `dist/` ([:3002/login](http://localhost:3002/login)). See [`apps/demo-next`](../../apps/demo-next/README.md). |
135
- | **demo-nuxt** | mock on `:4000`, then `ZITADEL_URL=http://localhost:4000 moon run demo-nuxt:dev` | Nuxt SDK, middleware, cookies, built `dist/` ([:3001/login](http://localhost:3001/login)). See [`apps/demo-nuxt`](../../apps/demo-nuxt/README.md). |
145
+ | **demo-next** | `moon run api-mock:start` + `moon run demo-next:dev` | Next.js SDK, middleware, cookies, built `dist/` ([:3002/login](http://localhost:3002/login)). See [`apps/demo-next`](../../apps/demo-next/README.md). |
146
+ | **demo-nuxt** | mock on `:8080`, then `moon run demo-nuxt:dev` | Nuxt SDK, middleware, cookies, built `dist/` ([:3001/login](http://localhost:3001/login)). See [`apps/demo-nuxt`](../../apps/demo-nuxt/README.md). |
136
147
 
137
148
  Storybook consumes the built `@zitadel/components` / `@zitadel/ui-react`
138
149
  artifacts, so rebuild after source changes (`moon run components:build`) or
@@ -157,21 +168,78 @@ form-associated inputs.
157
168
  | Tier | Surface | Use when |
158
169
  | --- | --- | --- |
159
170
  | SDK config | `configureZitadel({ projectId, proxyPath })` from `@zitadel/api/config` | every consumer — sets the project + proxy path the element reads |
160
- | Tokens | branding payload returned from the server | tenant colour / logo / font |
161
- | CSS hooks | `zitadel-login::part(form)`, `zl-field::part(input)` | targeted overrides from the host page |
171
+ | Tokens (server) | branding payload returned from the server | tenant colour / logo / font, managed centrally |
172
+ | Tokens (host page) | `zitadel-login { --zl-color-…: … }` in your own stylesheet | matching the widget to the app you embedded it in |
173
+ | Layout / placement | host CSS on `zitadel-login { ... }`, `variant`, `--zl-page-min-height` | sizing and positioning inside your layout |
174
+ | CSS hooks | `zitadel-login::part(form)`, `zitadel-login::part(field-input)` | targeted overrides of atom internals |
162
175
  | Locale | `el.lang = 'de'` / `el.locales = { ... }` | i18n / custom copy |
163
176
  | MSW mocks | `setupWorker` / `setupServer` from `msw` | offline / staging / fixtures |
164
- | Custom template | (planned) | tenant-supplied Liquid layouts |
177
+ | Custom template | `zitadel branding eject` → edit Liquid → `zitadel apply`, or `branding.liquid_template` on the payload | tenant-supplied layouts |
165
178
  | Atoms-only | hand-built form | non-standard flow shells |
166
179
 
167
180
  For styling, start with the generated `--zl-*` variables from
168
181
  `@zitadel/design-tokens`, then use host CSS on `zitadel-login { ... }` for page
169
182
  placement and `::part(...)` hooks for targeted internals such as the form or
170
183
  field input. The design-token package README is the canonical token catalogue;
171
- the branding design notes explain the broader override ladder. The current
172
- orchestrator is page-oriented: the host element can be constrained, but the
173
- inner `.zl-mount` still claims `100vh`, so embedding it as a small inline card is
174
- limited until the component follow-up relaxes that layout.
184
+ the branding design notes explain the broader override ladder.
185
+
186
+ **Your stylesheet is the strongest styling authority.** A plain rule in the
187
+ embedding app wins:
188
+
189
+ ```css
190
+ zitadel-login {
191
+ --zl-color-text-primary-white: #101828;
192
+ --zl-color-surface-default-primary-gray: #ffffff;
193
+ --zl-radius-m: 0.25rem;
194
+ }
195
+ ```
196
+
197
+ Those values reach the atoms' own shadow roots — custom properties inherit
198
+ across shadow boundaries — and they outrank both the design-system defaults
199
+ and the tenant's server-side branding, because the CSS cascade gives normal
200
+ declarations from the outer tree precedence over the `:host` rules the
201
+ orchestrator adopts internally. That ordering is deliberate: an app embedding
202
+ its own login should be able to match its design system without a server
203
+ round-trip. Leave the tokens alone and centrally-managed tenant branding
204
+ applies as before. `customization.browser.spec.ts` pins this.
205
+
206
+ **Sizing is a two-mode contract.** The default is `variant="widget"`:
207
+ content-sized, transparent through every layer, no fonts injected into your
208
+ document, no focus grab on load — drop it into a section, sidebar, or modal
209
+ and your app keeps owning the page. Dedicated login routes opt into the
210
+ full-page chrome:
211
+
212
+ ```html
213
+ <zitadel-login variant="page"></zitadel-login>
214
+ <!-- claims the viewport, paints the surface background from tokens,
215
+ loads the brand font, focuses the first field -->
216
+ ```
217
+
218
+ Width-responsive chrome (the split designs' two-column collapse, the compact
219
+ brand header) keys off the **widget's own width** via container queries, so a
220
+ narrow embed on a desktop viewport lays out like a phone. Fine-grained height
221
+ control in either mode: `--zl-page-min-height` (inherits across the shadow
222
+ boundaries, releasing the orchestrator mount and the `zl-page-shell` atom in
223
+ one setting). `embedding.browser.spec.ts` pins this whole contract.
224
+
225
+ **Colour mode** ships light and dark. A `page` renders dark (the design
226
+ system's primary surface); a `widget` follows the visitor's
227
+ `prefers-color-scheme` so it doesn't force a dark card onto a light page.
228
+ Pin it when your app's surface is fixed:
229
+
230
+ ```html
231
+ <zitadel-login theme="light"></zitadel-login>
232
+ ```
233
+
234
+ Resolution runs strongest-first: this `theme` property → the tenant's
235
+ `branding.theme.mode` → the variant default. The resolved mode lands on
236
+ `data-theme` on the element, and every `--zl-*` token repaints with it.
237
+
238
+ Atom internals forward through the orchestrator as `<atom>-<part>` names —
239
+ `zitadel-login::part(field-input)`, `zitadel-login::part(button-root)` — for
240
+ every part an atom's manifest declares; bare names (`zl-field::part(input)`)
241
+ apply when composing atoms directly without the orchestrator
242
+ (`exportparts.browser.spec.ts` pins the forwarding).
175
243
 
176
244
  Automation can use the stable host and native shadow-root hooks that the default
177
245
  template emits. Host atoms expose hooks such as `zitadel-field-email`,
@@ -193,6 +261,8 @@ renders the bundled `default.liquid`. Tracked as a follow-up.
193
261
 
194
262
  | Property | Type | Notes |
195
263
  | --- | --- | --- |
264
+ | `variant` | `'widget' \| 'page'` | Sizing/chrome mode. `widget` (default): content-sized, transparent, no font injection, no initial focus grab. `page`: full-page chrome for dedicated login routes |
265
+ | `theme` | `'light' \| 'dark' \| 'auto'` | Colour mode. Unset defers to `branding.theme.mode`, then to the variant default (`dark` for `page`, `auto` for `widget`). Resolved value lands on `data-theme` |
196
266
  | `purpose` | `'login' \| 'register' \| 'reset_password' \| string` | Which flow purpose to drive |
197
267
  | `flowName` / `flow-name` | `string` | Run the flow definition with this `name` instead of the project default |
198
268
  | `project` | `ZitadelProject` | SDK handle from `configureZitadel()`. Object property (not an attribute). When unset, the element falls back to the global handle from `getZitadelConfig()` |
@@ -202,9 +272,11 @@ renders the bundled `default.liquid`. Tracked as a follow-up.
202
272
  | `resumeFlowId` / `resume-flow-id` | `string` | Resume an existing flow handle instead of starting fresh |
203
273
 
204
274
  Events: `zitadel-flow-input`, `zitadel-flow-step`, `zitadel-flow-complete`,
205
- `zitadel-flow-error`. The orchestrator exposes `::part(form)` for tenant-side
206
- CSS hooks. Adopts design tokens and `branding.font_url` into its shadow root
207
- on each update.
275
+ `zitadel-flow-error`. `zitadel-flow-step` fires for every applied step
276
+ including the first, so a host app can drive its own chrome (progress,
277
+ headings, analytics) from mount onwards rather than from the first submit.
278
+ The orchestrator exposes `::part(form)` for tenant-side CSS hooks. Adopts
279
+ design tokens and `branding.font_url` into its shadow root on each update.
208
280
 
209
281
  ### `<zitadel-logout>`
210
282
 
@@ -218,7 +290,6 @@ the SDK handle, and clears the session. Uses the same token adoption as
218
290
  | --- | --- | --- |
219
291
  | `project` | `ZitadelProject` | SDK handle from `configureZitadel()`. Object property; falls back to the global handle from `getZitadelConfig()` |
220
292
  | `postSignOutUrl` / `post-sign-out-url` | `string` | Navigate here after sign-out |
221
- | `clientId` / `client-id` | `string` | Optional OIDC client id forwarded to `getEndSessionUrl()` |
222
293
 
223
294
  Supports a light-DOM `<template>` slot for a fully custom menu; default UI is
224
295
  the avatar trigger + dropdown.
@@ -278,8 +349,10 @@ See [`src/atoms/`](src/atoms) for full TypeScript types and JSDoc.
278
349
  packages/components/
279
350
  ├── src/
280
351
  │ ├── atoms/ zl-field, zl-button, zl-alert, zl-icon, zl-pill,
281
- │ │ zl-card, zl-page-shell + tests
282
- ├── orchestrator/ <zitadel-login>, <zitadel-logout>, api-client, liquid, branding
352
+ │ │ zl-card, zl-checkbox, zl-select, zl-page-shell,
353
+ │ zl-passkey + tests
354
+ │ ├── orchestrator/ <zitadel-login>, <zitadel-logout>, <zitadel-session>,
355
+ │ │ api-client, liquid, branding
283
356
  │ │ ├── locales/ bundled English fallback
284
357
  │ │ └── templates/ default.liquid (all steps) + layout-chrome.css
285
358
  │ ├── tokens/ re-export of @zitadel/design-tokens
@@ -311,9 +384,9 @@ moon run storybook:dev
311
384
  # → http://localhost:6006
312
385
 
313
386
  # Framework demos (TCP mock + SDK) — see apps/demo-*/README.md
314
- # moon run api-mock:start # → http://localhost:4000
315
- # ZITADEL_URL=http://localhost:4000 moon run demo-next:dev # → :3002
316
- # ZITADEL_URL=http://localhost:4000 moon run demo-nuxt:dev # → :3001
387
+ # moon run api-mock:start # → http://localhost:8080
388
+ # moon run demo-next:dev # → :3002 (ZITADEL_URL defaults to :8080)
389
+ # moon run demo-nuxt:dev # → :3001 (ZITADEL_URL defaults to :8080)
317
390
 
318
391
  # --- Package checks ---
319
392
 
@@ -1,2 +1,2 @@
1
- import { $t as ZlCheckbox, a as ZlPill, an as zlButtonManifest, c as ZlPasskeyErrorDetail, cn as IconName, d as ZlPageShell, en as ZlCheckboxChangeDetail, f as zlPageShellManifest, h as zlFieldManifest, i as zlSelectManifest, in as ZlButton, l as ZlPasskeyResultDetail, ln as ZlIcon, m as ZlFieldType, n as ZlSelectChangeDetail, nn as ZlCard, o as zlPillManifest, on as ZlAlert, p as ZlField, r as ZlSelectOption, rn as zlCardManifest, s as ZlPasskey, sn as zlAlertManifest, t as ZlSelect, tn as zlCheckboxManifest, u as zlPasskeyManifest, un as zlIconManifest } from "../index-DSZnfOJH.mjs";
1
+ import { a as ZlPill, an as zlCardManifest, c as ZlPasskeyErrorDetail, cn as ZlAlert, d as ZlPageShell, dn as ZlIcon, f as zlPageShellManifest, fn as zlIconManifest, h as zlFieldManifest, i as zlSelectManifest, in as ZlCard, l as ZlPasskeyResultDetail, ln as zlAlertManifest, m as ZlFieldType, n as ZlSelectChangeDetail, nn as ZlCheckboxChangeDetail, o as zlPillManifest, on as ZlButton, p as ZlField, r as ZlSelectOption, rn as zlCheckboxManifest, s as ZlPasskey, sn as zlButtonManifest, t as ZlSelect, tn as ZlCheckbox, u as zlPasskeyManifest, un as IconName } from "../index-CAi5gsHK.mjs";
2
2
  export { IconName, ZlAlert, ZlButton, ZlCard, ZlCheckbox, ZlCheckboxChangeDetail, ZlField, ZlFieldType, ZlIcon, ZlPageShell, ZlPasskey, ZlPasskeyErrorDetail, ZlPasskeyResultDetail, ZlPill, ZlSelect, ZlSelectChangeDetail, ZlSelectOption, zlAlertManifest, zlButtonManifest, zlCardManifest, zlCheckboxManifest, zlFieldManifest, zlIconManifest, zlPageShellManifest, zlPasskeyManifest, zlPillManifest, zlSelectManifest };
@@ -1,2 +1,2 @@
1
- import { _ as zlButtonManifest, a as ZlPasskey, b as ZlIcon, c as zlPageShellManifest, f as ZlCheckbox, g as ZlButton, h as zlCardManifest, i as zlPillManifest, l as ZlField, m as ZlCard, n as zlSelectManifest, o as zlPasskeyManifest, p as zlCheckboxManifest, r as ZlPill, s as ZlPageShell, t as ZlSelect, u as zlFieldManifest, v as ZlAlert, x as zlIconManifest, y as zlAlertManifest } from "../atoms-KC7OJWXZ.mjs";
1
+ import { _ as zlButtonManifest, a as ZlPasskey, b as ZlIcon, c as zlPageShellManifest, f as ZlCheckbox, g as ZlButton, h as zlCardManifest, i as zlPillManifest, l as ZlField, m as ZlCard, n as zlSelectManifest, o as zlPasskeyManifest, p as zlCheckboxManifest, r as ZlPill, s as ZlPageShell, t as ZlSelect, u as zlFieldManifest, v as ZlAlert, x as zlIconManifest, y as zlAlertManifest } from "../atoms-B6QmUAzo.mjs";
2
2
  export { ZlAlert, ZlButton, ZlCard, ZlCheckbox, ZlField, ZlIcon, ZlPageShell, ZlPasskey, ZlPill, ZlSelect, zlAlertManifest, zlButtonManifest, zlCardManifest, zlCheckboxManifest, zlFieldManifest, zlIconManifest, zlPageShellManifest, zlPasskeyManifest, zlPillManifest, zlSelectManifest };