@zitadel/components 1.0.0-alpha.21 → 1.0.0-alpha.22

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.
@@ -681,7 +681,7 @@ const e$5 = (e, t, c) => (c.configurable = !0, c.enumerable = !0, Reflect.decora
681
681
  }
682
682
  //#endregion
683
683
  //#region src/atoms/zl-alert.css?inline
684
- var zl_alert_default = ":host {\n display: block;\n}\n\n.zr-alert {\n align-items: flex-start;\n gap: var(--zl-spacing-2);\n padding-block: var(--zl-spacing-3);\n padding-inline: var(--zl-spacing-4);\n background: var(--zl-muted);\n color: var(--zl-foreground);\n border: 1px solid var(--zl-border);\n border-radius: var(--zl-radius-lg);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n display: flex;\n}\n\n.zr-alert__icon {\n color: currentColor;\n flex-shrink: 0;\n padding-block-start: var(--zl-spacing-0-5);\n}\n\n.zr-alert__body {\n gap: var(--zl-spacing-0-5);\n flex-direction: column;\n flex: auto;\n min-width: 0;\n display: flex;\n}\n\n.zr-alert__title {\n font-family: var(--zl-font-family-heading);\n color: var(--zl-foreground);\n}\n\n.zr-alert__message {\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zr-alert:not(:has(.zr-alert__title)) .zr-alert__message {\n color: var(--zl-foreground);\n}\n\n.zr-alert--error, .zr-alert--error .zr-alert__title {\n color: var(--zl-destructive);\n}\n\n.zr-alert--success .zr-alert__icon {\n color: var(--zl-success);\n}\n\n.zr-alert--warning .zr-alert__icon, .zr-alert--info .zr-alert__icon {\n color: var(--zl-muted-foreground);\n}\n\n.zr-alert__close {\n all: unset;\n width: var(--zl-spacing-6);\n height: var(--zl-spacing-6);\n border-radius: var(--zl-radius-md);\n color: var(--zl-muted-foreground);\n cursor: pointer;\n transition: background-color var(--zl-duration-fast) var(--zl-easing-standard);\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n display: inline-flex;\n}\n\n.zr-alert__close .zr-icon {\n --zl-icon-size: var(--zl-spacing-4);\n width: var(--zl-spacing-4);\n height: var(--zl-spacing-4);\n}\n\n.zr-alert__close:hover {\n background: var(--zl-accent);\n color: var(--zl-accent-foreground);\n}\n\n.zr-alert__close:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n";
684
+ var zl_alert_default = ":host {\n display: block;\n}\n\n.zr-alert {\n align-items: flex-start;\n gap: var(--zl-spacing-2);\n padding-block: var(--zl-spacing-3);\n padding-inline: var(--zl-spacing-4);\n background: var(--zl-muted);\n color: var(--zl-foreground);\n border: 1px solid var(--zl-border);\n border-radius: var(--zl-radius-lg);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n display: flex;\n}\n\n.zr-alert__icon {\n height: var(--zl-text-sm-leading);\n color: currentColor;\n flex-shrink: 0;\n align-items: center;\n display: inline-flex;\n}\n\n.zr-alert__body {\n gap: var(--zl-spacing-0-5);\n flex-direction: column;\n flex: auto;\n min-width: 0;\n display: flex;\n}\n\n.zr-alert__title {\n font-family: var(--zl-font-family-heading);\n color: var(--zl-foreground);\n}\n\n.zr-alert__message {\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zr-alert:not(:has(.zr-alert__title)) .zr-alert__message {\n color: var(--zl-foreground);\n}\n\n.zr-alert--error {\n color: var(--zl-destructive);\n}\n\n.zr-alert--success .zr-alert__icon {\n color: var(--zl-success);\n}\n\n.zr-alert--warning .zr-alert__icon, .zr-alert--info .zr-alert__icon {\n color: var(--zl-muted-foreground);\n}\n\n.zr-alert__close {\n all: unset;\n width: var(--zl-spacing-6);\n height: var(--zl-spacing-6);\n border-radius: var(--zl-radius-md);\n color: var(--zl-muted-foreground);\n cursor: pointer;\n transition: background-color var(--zl-duration-fast) var(--zl-easing-standard);\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n display: inline-flex;\n}\n\n.zr-alert__close zl-icon {\n flex-shrink: 0;\n display: inline-flex;\n}\n\n.zr-alert__close:hover {\n background: var(--zl-accent);\n color: var(--zl-accent-foreground);\n}\n\n.zr-alert__close:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n";
685
685
  //#endregion
686
686
  //#region src/internal/emit.ts
687
687
  /**
@@ -9039,7 +9039,7 @@ const en = {
9039
9039
  "password.action.register.lead": "Don't have an account? ",
9040
9040
  "password.action.register.link": "Sign up",
9041
9041
  "register.title": "Create your account",
9042
- "register.description": "",
9042
+ "register.description": "Enter your details to get started",
9043
9043
  "register.field.email": "Email",
9044
9044
  "register.field.email.placeholder": "you@example.com",
9045
9045
  "register.field.password": "Password",
@@ -9156,7 +9156,7 @@ const de = {
9156
9156
  "password.action.register.lead": "Noch kein Konto? ",
9157
9157
  "password.action.register.link": "Registrieren",
9158
9158
  "register.title": "Konto erstellen",
9159
- "register.description": "",
9159
+ "register.description": "Gib deine Daten ein, um loszulegen",
9160
9160
  "register.field.email": "E-Mail",
9161
9161
  "register.field.email.placeholder": "du@beispiel.de",
9162
9162
  "register.field.password": "Passwort",
@@ -9272,7 +9272,7 @@ const it = {
9272
9272
  "password.action.register.lead": "Non hai un account? ",
9273
9273
  "password.action.register.link": "Registrati",
9274
9274
  "register.title": "Crea il tuo account",
9275
- "register.description": "",
9275
+ "register.description": "Inserisci i tuoi dati per iniziare",
9276
9276
  "register.field.email": "E-mail",
9277
9277
  "register.field.email.placeholder": "tu@esempio.com",
9278
9278
  "register.field.password": "Password",
@@ -9426,6 +9426,7 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
9426
9426
  getBeginUserPasskeyRegistrationUrl: () => getBeginUserPasskeyRegistrationUrl,
9427
9427
  getBrandingById: () => getBrandingById,
9428
9428
  getClaimStatus: () => getClaimStatus,
9429
+ getClaimWindow: () => getClaimWindow,
9429
9430
  getCompleteClaimUrl: () => getCompleteClaimUrl,
9430
9431
  getCreateAuthAttemptUrl: () => getCreateAuthAttemptUrl,
9431
9432
  getCreateBrandingUrl: () => getCreateBrandingUrl,
@@ -9452,6 +9453,7 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
9452
9453
  getGetAuthAttemptUrl: () => getGetAuthAttemptUrl,
9453
9454
  getGetBrandingByIdUrl: () => getGetBrandingByIdUrl,
9454
9455
  getGetClaimStatusUrl: () => getGetClaimStatusUrl,
9456
+ getGetClaimWindowUrl: () => getGetClaimWindowUrl,
9455
9457
  getGetEnvironmentByNameUrl: () => getGetEnvironmentByNameUrl,
9456
9458
  getGetEventUrl: () => getGetEventUrl,
9457
9459
  getGetFlowDefinitionUrl: () => getGetFlowDefinitionUrl,
@@ -9485,6 +9487,7 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
9485
9487
  getMyUser: () => getMyUser,
9486
9488
  getPatchProjectUrl: () => getPatchProjectUrl,
9487
9489
  getProject: () => getProject,
9490
+ getQueryGrantsUrl: () => getQueryGrantsUrl,
9488
9491
  getQueryProjectsUrl: () => getQueryProjectsUrl,
9489
9492
  getQuerySessionsUrl: () => getQuerySessionsUrl,
9490
9493
  getQueryTeamsUrl: () => getQueryTeamsUrl,
@@ -9513,6 +9516,7 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
9513
9516
  listUserPasskeys: () => listUserPasskeys,
9514
9517
  listUserTeams: () => listUserTeams,
9515
9518
  patchProject: () => patchProject,
9519
+ queryGrants: () => queryGrants,
9516
9520
  queryProjects: () => queryProjects,
9517
9521
  querySessions: () => querySessions,
9518
9522
  queryTeams: () => queryTeams,
@@ -10062,7 +10066,11 @@ const getGetClaimStatusUrl = (projectId, params) => {
10062
10066
  * Polled by the CLI while a browser completes the claim. Authorized by the
10063
10067
  project secret that initiated the challenge. Returns `pending`, or
10064
10068
  `completed` with the owning team, the claim timestamp, and the dashboard
10065
- URL once the browser leg has finished.
10069
+ URL once the project is claimed. The claim grant, not the polled
10070
+ challenge, is the source of truth: a project claimed through another
10071
+ concurrent challenge also reports `completed`, and a completed claim
10072
+ keeps reporting `completed` past this challenge's expiry and past the
10073
+ project's claim window.
10066
10074
 
10067
10075
  * @summary Get claim status
10068
10076
  */
@@ -10094,6 +10102,30 @@ const completeClaim = async (projectId, completeClaimBody, options) => {
10094
10102
  body: JSON.stringify(completeClaimBody)
10095
10103
  });
10096
10104
  };
10105
+ const getGetClaimWindowUrl = (projectId, params) => {
10106
+ const normalizedParams = new URLSearchParams();
10107
+ Object.entries(params || {}).forEach(([key, value]) => {
10108
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
10109
+ });
10110
+ const stringifiedParams = normalizedParams.toString();
10111
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/projects/${projectId}/claim/window?${stringifiedParams}` : `${getProxyPath()}/projects/${projectId}/claim/window`;
10112
+ };
10113
+ /**
10114
+ * Read by the claim page in the browser to show how long is left to claim the
10115
+ project. Unauthenticated by design: the claim page runs this before the
10116
+ developer has signed in, and holding the `challenge_id` from the claim URL
10117
+ is the authorization — the same capability `claim/complete` accepts. It
10118
+ reveals only the window, never the project itself, and unlike
10119
+ `claim/complete` it spends nothing, so a reload is free.
10120
+
10121
+ * @summary Get the claim window for a project
10122
+ */
10123
+ const getClaimWindow = async (projectId, params, options) => {
10124
+ return customFetch(getGetClaimWindowUrl(projectId, params), {
10125
+ ...options,
10126
+ method: "GET"
10127
+ });
10128
+ };
10097
10129
  const getCreateSessionUrl = () => {
10098
10130
  return `${getProxyPath()}/sessions`;
10099
10131
  };
@@ -10355,12 +10387,17 @@ const getCreateFlowDefinitionUrl = () => {
10355
10387
  return `${getProxyPath()}/flow_definitions`;
10356
10388
  };
10357
10389
  /**
10358
- * Creates a new flow definition.
10390
+ * Publishes a new flow definition revision.
10359
10391
  Flow definitions are templates that define the sequence of steps (capabilities)
10360
10392
  for a particular user journey (e.g., registration, login, password reset).
10361
10393
 
10362
10394
  Flow definitions are created based on the flow definition schema, which includes the flow's purpose, audience, and the steps involved.
10363
10395
 
10396
+ Every call allocates a new opaque id. Revisions of one flow share its
10397
+ `name`; posting a definition under an existing `name` publishes a new
10398
+ revision of that flow, it is not a conflict. List with `name` to see a
10399
+ flow's revisions, newest by creation time first.
10400
+
10364
10401
  * @summary Create a new flow definition
10365
10402
  */
10366
10403
  const createFlowDefinition = async (createFlowDefinitionBody, options) => {
@@ -10383,8 +10420,9 @@ const getListFlowDefinitionsUrl = (params) => {
10383
10420
  return stringifiedParams.length > 0 ? `${getProxyPath()}/flow_definitions?${stringifiedParams}` : `${getProxyPath()}/flow_definitions`;
10384
10421
  };
10385
10422
  /**
10386
- * Retrieves a list of all flow definitions.
10423
+ * Retrieves a list of all flow definitions, newest by creation time first.
10387
10424
  This endpoint can be used to view existing flow definitions and their configurations.
10425
+ Filter by `name` to list the revisions of one flow.
10388
10426
 
10389
10427
  * @summary List flow definitions
10390
10428
  */
@@ -10769,6 +10807,39 @@ const createGrant = async (createGrantBody, params, options) => {
10769
10807
  body: JSON.stringify(createGrantBody)
10770
10808
  });
10771
10809
  };
10810
+ const getQueryGrantsUrl = (params) => {
10811
+ const normalizedParams = new URLSearchParams();
10812
+ Object.entries(params || {}).forEach(([key, value]) => {
10813
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
10814
+ });
10815
+ const stringifiedParams = normalizedParams.toString();
10816
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/grants/query?${stringifiedParams}` : `${getProxyPath()}/grants/query`;
10817
+ };
10818
+ /**
10819
+ * Returns the collaboration grants of a project, paginated with a cursor.
10820
+ Only unrevoked grants this API manages are listed (user or team bound to
10821
+ viewer, editor, or admin), including expired grants so a client can
10822
+ DELETE before re-granting. Project-secret setup (`sk_proj`) and
10823
+ owning-team (`relation=team`) rows are not returned. Grants are not in
10824
+ `resource_scope_index`; project scope is required on the query (same as
10825
+ get). Requires `project.read`. `expand: ["principal"]` additionally
10826
+ requires `user.read` and `team.read` (documented on the expand enum;
10827
+ those scopes cannot be ANDed onto this security block because they are
10828
+ body-conditional).
10829
+
10830
+ * @summary Query grants
10831
+ */
10832
+ const queryGrants = async (queryGrantsBody, params, options) => {
10833
+ return customFetch(getQueryGrantsUrl(params), {
10834
+ ...options,
10835
+ method: "POST",
10836
+ headers: {
10837
+ "Content-Type": "application/json",
10838
+ ...options?.headers
10839
+ },
10840
+ body: JSON.stringify(queryGrantsBody)
10841
+ });
10842
+ };
10772
10843
  const getGetGrantUrl = (id, params) => {
10773
10844
  const normalizedParams = new URLSearchParams();
10774
10845
  Object.entries(params || {}).forEach(([key, value]) => {
@@ -13884,7 +13955,7 @@ const TEMPLATE_NAMES = {
13884
13955
  };
13885
13956
  //#endregion
13886
13957
  //#region src/orchestrator/templates/layout-chrome.css?inline
13887
- var layout_chrome_default = ":host {\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n background: none;\n display: block;\n}\n\n:host([variant=\"page\"]) {\n background: var(--zl-background);\n min-height: 100%;\n}\n\nimg[data-zl-asset-broken] {\n display: none;\n}\n\n.zl-mount {\n min-height: var(--zl-page-min-height, auto);\n background: inherit;\n color: inherit;\n flex-direction: column;\n display: flex;\n container-type: inline-size;\n}\n\n:host([variant=\"page\"]) .zl-mount {\n min-height: var(--zl-page-min-height, 100vh);\n}\n\n.zl-mount > zl-page-shell, .zl-mount > [data-zl-template-root] {\n flex: auto;\n}\n\n.zl-attribution {\n background: none;\n justify-content: center;\n align-items: center;\n display: flex;\n}\n\n.zl-attribution[hidden] {\n display: none;\n}\n\n.zl-trustmark {\n gap: var(--zl-spacing-2-5);\n flex-wrap: wrap;\n}\n\n.zl-trustmark__mark {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n color: var(--zl-foreground);\n text-decoration: none;\n display: inline-flex;\n}\n\n.zl-trustmark__mark:hover {\n text-underline-offset: 4px;\n text-decoration: underline;\n}\n\n.zl-trustmark__mark:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n border-radius: var(--zl-radius-sm);\n}\n\n.zl-trustmark__logotype {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n line-height: 0;\n display: block;\n}\n\n.zl-trustmark__logotype-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zl-card-logo {\n width: auto;\n max-width: min(12rem, 60%);\n max-height: var(--zl-card-logo-max-height, 2.5rem);\n object-fit: contain;\n}\n\n.zl-card-title {\n font-family: var(--zl-font-family-heading);\n font-size: var(--zl-text-xl-size);\n font-weight: var(--zl-font-weight-medium);\n color: var(--zl-card-foreground);\n text-align: left;\n margin: 0;\n line-height: 1;\n}\n\n.zl-card-subtitle {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zl-field-group {\n gap: var(--zl-spacing-7);\n flex-direction: column;\n display: flex;\n}\n\n.zl-field-group:not(:has(*)) {\n display: none;\n}\n\n.zl-card-actions {\n gap: var(--zl-spacing-3);\n flex-direction: column;\n display: flex;\n}\n\n[data-suppress-header] .zl-card-title, [data-suppress-header] .zl-card-subtitle {\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n}\n\n.zl-card-nav {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n text-align: center;\n margin: 0;\n}\n\n.zl-card-nav__link {\n font: inherit;\n line-height: inherit;\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: underline;\n display: inline;\n}\n\n.zl-card-nav__link:hover {\n color: var(--zl-foreground);\n}\n\n.zl-card-nav__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-card-forgot {\n text-align: right;\n margin: 0;\n}\n\n.zl-card-forgot__link {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n display: inline;\n}\n\n.zl-card-forgot__link:hover {\n text-decoration: underline;\n}\n\n.zl-card-forgot__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-split {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n align-items: var(--zl-split-align, center);\n gap: var(--zl-spacing-8);\n width: 100%;\n min-height: 100%;\n display: grid;\n}\n\n.zl-split__brand {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n padding: var(--zl-spacing-8) var(--zl-spacing-4);\n flex-direction: column;\n display: flex;\n}\n\n.zl-split__logo {\n max-width: min(16rem, 60%);\n max-height: var(--zl-split-logo-max-height, 16rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) {\n max-height: var(--zl-split-logo-max-height, 8rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) + .zl-split__hero {\n max-height: min(var(--zl-split-hero-max-height, 22.5rem),\n max(6rem,\n calc(100vh - 104px - var(--zl-spacing-8) - var(--zl-spacing-8) -\n 2.5rem - var(--zl-spacing-6) - var(--zl-spacing-6) -\n var(--zl-split-logo-max-height, 8rem))));\n}\n\n.zl-split__hero {\n width: 100%;\n max-height: var(--zl-split-hero-max-height, min(22.5rem, 60vh));\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n}\n\n.zl-split__placeholder {\n aspect-ratio: 4 / 5;\n border-radius: var(--zl-radius-lg);\n background: radial-gradient(120% 120% at 18% 12%,\n var(--zl-gradient-lavender-start) 0%,\n transparent 60%),\n radial-gradient(130% 130% at 85% 92%,\n var(--zl-gradient-rose-start) 0%,\n transparent 60%),\n var(--zl-card);\n width: min(18rem, 85%);\n}\n\n.zl-split__form {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n flex-direction: column;\n padding: 16px;\n display: flex;\n}\n\n.zl-split__compact {\n max-width: min(12rem, 60%);\n display: none;\n}\n\nimg.zl-split__compact {\n max-height: 2.5rem;\n}\n\nimg.zl-split__compact--hero {\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n width: 100%;\n max-width: 100%;\n max-height: 6rem;\n}\n\n.zl-split--right .zl-split__brand {\n order: 2;\n}\n\n.zl-split--right .zl-split__form {\n order: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n gap: var(--zl-spacing-8);\n width: 100%;\n display: grid;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution > * {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n}\n\n@container (width <= 48rem) {\n .zl-split {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .zl-split__brand {\n display: var(--zl-split-brand-mobile, none);\n }\n\n .zl-split__compact {\n display: block;\n }\n\n zl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: minmax(0, 1fr);\n }\n\n zl-page-shell:has(.zl-split) .zl-attribution > *, zl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n }\n}\n\n.zl-hero {\n text-align: left;\n width: 100%;\n max-width: 34rem;\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n flex-direction: column;\n display: flex;\n}\n\n.zl-hero__nav {\n margin-bottom: var(--zl-spacing-8);\n justify-content: space-between;\n align-items: center;\n display: flex;\n}\n\n.zl-hero__brand {\n align-items: center;\n gap: var(--zl-spacing-2);\n letter-spacing: -.01em;\n font-size: 1.125rem;\n font-weight: 700;\n display: inline-flex;\n}\n\n.zl-hero__brand-logo {\n max-height: 1.75rem;\n}\n\n.zl-hero__brand-mark {\n border-radius: var(--zl-radius-md);\n background: linear-gradient(135deg,\n var(--zl-gradient-lavender-start),\n var(--zl-gradient-rose-start));\n width: 1.75rem;\n height: 1.75rem;\n display: inline-flex;\n}\n\n.zl-hero__compact-brand {\n overflow-wrap: anywhere;\n letter-spacing: -.01em;\n max-width: 100%;\n color: var(--zl-foreground);\n margin: 0;\n font-size: 1.125rem;\n font-weight: 700;\n}\n\n.zl-hero__nav-links {\n gap: var(--zl-spacing-6);\n color: var(--zl-muted-foreground);\n font-size: .9375rem;\n display: flex;\n}\n\n.zl-hero__nav-links a {\n color: inherit;\n text-decoration: none;\n}\n\n.zl-hero__nav-links a:hover {\n text-decoration: underline;\n}\n\n.zl-hero__eyebrow {\n margin: 0 0 var(--zl-spacing-4);\n letter-spacing: .08em;\n text-transform: uppercase;\n color: var(--zl-muted-foreground);\n font-size: .8125rem;\n font-weight: 600;\n}\n\n.zl-hero__headline {\n margin: 0 0 var(--zl-spacing-4);\n font-family: var(--zl-font-family-heading);\n letter-spacing: -.02em;\n font-size: 2.75rem;\n font-weight: 700;\n line-height: 1.1;\n}\n\n.zl-hero__sub {\n margin: 0 0 var(--zl-spacing-8);\n max-width: 30rem;\n color: var(--zl-muted-foreground);\n font-size: 1.0625rem;\n line-height: 1.6;\n}\n\n.zl-hero__bullets {\n gap: var(--zl-spacing-2);\n margin: 0 0 var(--zl-spacing-8);\n flex-direction: column;\n padding: 0;\n list-style: none;\n display: flex;\n}\n\n.zl-hero__bullets li {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-size: 1rem;\n display: flex;\n}\n\n.zl-hero__bullets li:before {\n content: \"✓\";\n color: var(--zl-success);\n font-weight: 700;\n}\n\n.zl-hero__footnote {\n padding-top: var(--zl-spacing-6);\n border-top: 1px solid var(--zl-border);\n color: var(--zl-muted-foreground);\n margin: 0;\n font-size: .8125rem;\n}\n\n.zl-hero__footnote strong {\n color: var(--zl-muted-foreground);\n font-weight: 600;\n}\n\n.zl-minimal {\n gap: var(--zl-spacing-6);\n flex-direction: column;\n width: min(24rem, 100%);\n margin-inline: auto;\n display: flex;\n}\n\n:host([variant=\"page\"]) .zl-minimal {\n padding: 52px 16px;\n}\n";
13958
+ var layout_chrome_default = ":host {\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n background: none;\n display: block;\n}\n\n:host([variant=\"page\"]) {\n background: var(--zl-background);\n min-height: 100%;\n}\n\nimg[data-zl-asset-broken] {\n display: none;\n}\n\n.zl-mount {\n min-height: var(--zl-page-min-height, auto);\n background: inherit;\n color: inherit;\n flex-direction: column;\n display: flex;\n container-type: inline-size;\n}\n\n:host([variant=\"page\"]) .zl-mount {\n min-height: var(--zl-page-min-height, 100vh);\n}\n\n.zl-mount > zl-page-shell, .zl-mount > [data-zl-template-root] {\n flex: auto;\n}\n\n.zl-attribution {\n background: none;\n justify-content: center;\n align-items: center;\n display: flex;\n}\n\n.zl-attribution[hidden] {\n display: none;\n}\n\n.zl-trustmark {\n gap: var(--zl-spacing-2-5);\n flex-wrap: wrap;\n}\n\n.zl-trustmark__mark {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n color: var(--zl-foreground);\n text-decoration: none;\n display: inline-flex;\n}\n\n.zl-trustmark__mark:hover {\n text-underline-offset: 4px;\n text-decoration: underline;\n}\n\n.zl-trustmark__mark:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n border-radius: var(--zl-radius-sm);\n}\n\n.zl-trustmark__logotype {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n line-height: 0;\n display: block;\n}\n\n.zl-trustmark__logotype-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zl-card-logo {\n width: auto;\n max-width: min(12rem, 60%);\n max-height: var(--zl-card-logo-max-height, 2.5rem);\n object-fit: contain;\n}\n\n.zl-card-title {\n font-family: var(--zl-font-family-heading);\n font-size: var(--zl-text-xl-size);\n font-weight: var(--zl-font-weight-medium);\n color: var(--zl-card-foreground);\n text-align: left;\n margin: 0;\n line-height: 1;\n}\n\n.zl-card-subtitle {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zl-field-group {\n gap: var(--zl-spacing-7);\n flex-direction: column;\n display: flex;\n}\n\n.zl-field-group:not(:has(*)) {\n display: none;\n}\n\n.zl-card-actions {\n gap: var(--zl-spacing-3);\n flex-direction: column;\n display: flex;\n}\n\n[data-suppress-header] .zl-card-title, [data-suppress-header] .zl-card-subtitle {\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n}\n\n.zl-card-nav {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n text-align: center;\n margin: 0;\n}\n\n.zl-card-nav__link {\n font: inherit;\n line-height: inherit;\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: underline;\n display: inline;\n}\n\n.zl-card-nav__link:hover {\n color: var(--zl-foreground);\n}\n\n.zl-card-nav__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-card-forgot {\n text-align: right;\n margin: 0;\n}\n\n.zl-card-forgot__link {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n display: inline;\n}\n\n.zl-card-forgot__link:hover {\n text-decoration: underline;\n}\n\n.zl-card-forgot__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-split {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n align-items: var(--zl-split-align, center);\n gap: var(--zl-spacing-8);\n width: 100%;\n min-height: 100%;\n display: grid;\n}\n\n.zl-split__brand {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n padding: var(--zl-spacing-8) var(--zl-spacing-4);\n flex-direction: column;\n display: flex;\n}\n\n.zl-split__logo {\n max-width: min(16rem, 60%);\n max-height: var(--zl-split-logo-max-height, 16rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) {\n max-height: var(--zl-split-logo-max-height, 8rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) + .zl-split__hero {\n max-height: min(var(--zl-split-hero-max-height, 22.5rem),\n max(6rem,\n calc(100vh - 104px - var(--zl-spacing-8) - var(--zl-spacing-8) -\n 2.5rem - var(--zl-spacing-6) - var(--zl-spacing-6) -\n var(--zl-split-logo-max-height, 8rem))));\n}\n\n.zl-split__hero {\n width: 100%;\n max-height: var(--zl-split-hero-max-height, min(22.5rem, 60vh));\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n}\n\n.zl-split__placeholder {\n aspect-ratio: 4 / 5;\n border-radius: var(--zl-radius-lg);\n background: radial-gradient(120% 120% at 18% 12%,\n var(--zl-gradient-lavender-start) 0%,\n transparent 60%),\n radial-gradient(130% 130% at 85% 92%,\n var(--zl-gradient-rose-start) 0%,\n transparent 60%),\n var(--zl-card);\n width: min(18rem, 85%);\n}\n\n.zl-split__form {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n flex-direction: column;\n padding: 16px;\n display: flex;\n}\n\n.zl-split__compact {\n max-width: min(12rem, 60%);\n display: none;\n}\n\nimg.zl-split__compact {\n max-height: 2.5rem;\n}\n\nimg.zl-split__compact--hero {\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n width: 100%;\n max-width: 100%;\n max-height: 6rem;\n}\n\n.zl-split--right .zl-split__brand {\n order: 2;\n}\n\n.zl-split--right .zl-split__form {\n order: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n gap: var(--zl-spacing-8);\n width: 100%;\n display: grid;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution > * {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 1;\n}\n\n@container (width <= 48rem) {\n .zl-split {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .zl-split__brand {\n display: var(--zl-split-brand-mobile, none);\n }\n\n .zl-split__compact {\n display: block;\n }\n\n zl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: minmax(0, 1fr);\n }\n\n zl-page-shell:has(.zl-split) .zl-attribution > *, zl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n }\n}\n\n.zl-hero {\n text-align: left;\n width: 100%;\n max-width: 34rem;\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n flex-direction: column;\n display: flex;\n}\n\n.zl-hero__nav {\n margin-bottom: var(--zl-spacing-8);\n justify-content: space-between;\n align-items: center;\n display: flex;\n}\n\n.zl-hero__brand {\n align-items: center;\n gap: var(--zl-spacing-2);\n letter-spacing: -.01em;\n font-size: 1.125rem;\n font-weight: 700;\n display: inline-flex;\n}\n\n.zl-hero__brand-logo {\n max-height: 1.75rem;\n}\n\n.zl-hero__brand-mark {\n border-radius: var(--zl-radius-md);\n background: linear-gradient(135deg,\n var(--zl-gradient-lavender-start),\n var(--zl-gradient-rose-start));\n width: 1.75rem;\n height: 1.75rem;\n display: inline-flex;\n}\n\n.zl-hero__compact-brand {\n overflow-wrap: anywhere;\n letter-spacing: -.01em;\n max-width: 100%;\n color: var(--zl-foreground);\n margin: 0;\n font-size: 1.125rem;\n font-weight: 700;\n}\n\n.zl-hero__nav-links {\n gap: var(--zl-spacing-6);\n color: var(--zl-muted-foreground);\n font-size: .9375rem;\n display: flex;\n}\n\n.zl-hero__nav-links a {\n color: inherit;\n text-decoration: none;\n}\n\n.zl-hero__nav-links a:hover {\n text-decoration: underline;\n}\n\n.zl-hero__eyebrow {\n margin: 0 0 var(--zl-spacing-4);\n letter-spacing: .08em;\n text-transform: uppercase;\n color: var(--zl-muted-foreground);\n font-size: .8125rem;\n font-weight: 600;\n}\n\n.zl-hero__headline {\n margin: 0 0 var(--zl-spacing-4);\n font-family: var(--zl-font-family-heading);\n letter-spacing: -.02em;\n font-size: 2.75rem;\n font-weight: 700;\n line-height: 1.1;\n}\n\n.zl-hero__sub {\n margin: 0 0 var(--zl-spacing-8);\n max-width: 30rem;\n color: var(--zl-muted-foreground);\n font-size: 1.0625rem;\n line-height: 1.6;\n}\n\n.zl-hero__bullets {\n gap: var(--zl-spacing-2);\n margin: 0 0 var(--zl-spacing-8);\n flex-direction: column;\n padding: 0;\n list-style: none;\n display: flex;\n}\n\n.zl-hero__bullets li {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-size: 1rem;\n display: flex;\n}\n\n.zl-hero__bullets li:before {\n content: \"✓\";\n color: var(--zl-success);\n font-weight: 700;\n}\n\n.zl-hero__footnote {\n padding-top: var(--zl-spacing-6);\n border-top: 1px solid var(--zl-border);\n color: var(--zl-muted-foreground);\n margin: 0;\n font-size: .8125rem;\n}\n\n.zl-hero__footnote strong {\n color: var(--zl-muted-foreground);\n font-weight: 600;\n}\n\n.zl-minimal {\n gap: var(--zl-spacing-6);\n flex-direction: column;\n width: min(24rem, 100%);\n margin-inline: auto;\n display: flex;\n}\n\n:host([variant=\"page\"]) .zl-minimal {\n padding: 52px 16px;\n}\n";
13888
13959
  //#endregion
13889
13960
  //#region src/orchestrator/zitadel-login.ts
13890
13961
  /** Narrow a rendered named element to the `formValue` field-atom contract. */
@@ -13993,6 +14064,13 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
13993
14064
  set loading(value) {
13994
14065
  this.#_loading_accessor_storage = value;
13995
14066
  }
14067
+ #_completing_accessor_storage = false;
14068
+ get completing() {
14069
+ return this.#_completing_accessor_storage;
14070
+ }
14071
+ set completing(value) {
14072
+ this.#_completing_accessor_storage = value;
14073
+ }
13996
14074
  #_startupError_accessor_storage = null;
13997
14075
  get startupError() {
13998
14076
  return this.#_startupError_accessor_storage;
@@ -14137,7 +14215,7 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
14137
14215
  </zl-card>
14138
14216
  </zl-page-shell>
14139
14217
  </form>`;
14140
- if (!this.response || !this.engine) return b`<slot name="loader"></slot>`;
14218
+ if (!this.response || !this.engine || this.completing) return b`<slot name="loader"></slot>`;
14141
14219
  const rendered = this.injectAttribution(this.renderStep(this.response.step, this.engine));
14142
14220
  return b`<form
14143
14221
  class="zl-mount"
@@ -14181,7 +14259,7 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
14181
14259
  const custom = attribution?.custom_link;
14182
14260
  if (!show && !custom) return "";
14183
14261
  const mark = custom ? `<a class="zl-trustmark__mark" part="attribution-mark" href="${escapeHtml(String(custom.href))}">${escapeHtml(String(custom.label))}</a>` : `<a class="zl-trustmark__mark" part="attribution-mark" href="https://zitadel.com" aria-label="Secured with Zitadel">${zitadelTrustmarkInnerHtml()}</a>`;
14184
- return `<div${placement === "footer" ? ` slot="footer"` : ""} part="attribution" class="zl-attribution zl-trustmark">${mark}</div>`;
14262
+ return `<div${placement === "footer" ? ` slot="footer"` : ""} part="attribution" class="zl-attribution zl-trustmark">${mark}<slot name="attribution-trailing"></slot></div>`;
14185
14263
  }
14186
14264
  /** Declarative config read from this element's attributes. */
14187
14265
  get projectAttrs() {
@@ -14229,6 +14307,7 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
14229
14307
  }
14230
14308
  applyResponse(wire) {
14231
14309
  this.stepErrorDismissed = false;
14310
+ this.completing = navigatesOnComplete(wire, this.postSignInUrl);
14232
14311
  this.response = wire;
14233
14312
  const { branding, issues } = validateBranding(wire.branding, { renderingOrigin: this.ownerDocument.location.origin });
14234
14313
  this.branding = branding;
@@ -14700,6 +14779,7 @@ __decorate([n$1({ attribute: false })], ZitadelLogin.prototype, "locales", null)
14700
14779
  __decorate([r$1()], ZitadelLogin.prototype, "response", null);
14701
14780
  __decorate([r$1()], ZitadelLogin.prototype, "branding", null);
14702
14781
  __decorate([r$1()], ZitadelLogin.prototype, "loading", null);
14782
+ __decorate([r$1()], ZitadelLogin.prototype, "completing", null);
14703
14783
  __decorate([r$1()], ZitadelLogin.prototype, "startupError", null);
14704
14784
  __decorate([r$1()], ZitadelLogin.prototype, "formValues", null);
14705
14785
  ZitadelLogin = __decorate([t$4("zitadel-login")], ZitadelLogin);
@@ -14713,6 +14793,19 @@ ZitadelLogin = __decorate([t$4("zitadel-login")], ZitadelLogin);
14713
14793
  function isAllowedSelectValue(field, value) {
14714
14794
  return field.validation?.enum?.includes(value) ?? false;
14715
14795
  }
14796
+ /**
14797
+ * Whether a terminal step ends in a navigation rather than a screen: a
14798
+ * `redirect` with a URI, or a `show` whose handoff the widget exchanges before
14799
+ * sending the browser to `post-sign-in-url`. A `show` without a
14800
+ * `post-sign-in-url` is the host handling the handoff itself, and that screen
14801
+ * is the flow's own last word — it still renders.
14802
+ */
14803
+ function navigatesOnComplete(wire, postSignInUrl) {
14804
+ const behavior = wire.step.complete;
14805
+ if (behavior === "redirect") return Boolean(wire.redirect_uri);
14806
+ if (behavior === "show") return Boolean(wire.handoff_token && postSignInUrl);
14807
+ return false;
14808
+ }
14716
14809
  function collectInitialValues(step) {
14717
14810
  const values = {};
14718
14811
  if (!step.fields) return values;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zitadel/components",
3
- "version": "1.0.0-alpha.21",
3
+ "version": "1.0.0-alpha.22",
4
4
  "description": "Lit-based atomic web components and the <zitadel-login> orchestrator for the Zitadel auth UI.",
5
5
  "homepage": "https://github.com/zitadel/nextgen/tree/main/packages/components#readme",
6
6
  "bugs": {
@@ -60,7 +60,7 @@
60
60
  "liquidjs": "^10.27.2",
61
61
  "lit": "^3.3.2",
62
62
  "lucide": "^1.16.0",
63
- "@zitadel/config": "1.0.0-alpha.21"
63
+ "@zitadel/config": "1.0.0-alpha.22"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@tsdown/css": "^0.21.10",
@@ -74,9 +74,9 @@
74
74
  "lightningcss": "^1.30.1",
75
75
  "tsdown": "^0.21.10",
76
76
  "tslib": "^2.8.1",
77
- "@zitadel/design-tokens": "0.1.0-alpha.1",
78
77
  "@zitadel/api-mock": "0.0.0",
79
- "@zitadel/api": "1.0.0-alpha.21"
78
+ "@zitadel/api": "1.0.0-alpha.22",
79
+ "@zitadel/design-tokens": "0.1.0-alpha.1"
80
80
  },
81
81
  "scripts": {
82
82
  "build": "tsdown",