@zitadel/components 0.0.0 → 0.1.0-alpha.2

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 (80) hide show
  1. package/README.md +41 -36
  2. package/dist/atoms/index.d.mts +1 -1
  3. package/dist/atoms/index.mjs +1 -1
  4. package/dist/atoms/zl-alert.d.ts.map +1 -1
  5. package/dist/atoms/zl-button.d.ts +7 -1
  6. package/dist/atoms/zl-button.d.ts.map +1 -1
  7. package/dist/atoms/zl-card.d.ts +7 -0
  8. package/dist/atoms/zl-card.d.ts.map +1 -1
  9. package/dist/atoms/zl-field.d.ts +14 -1
  10. package/dist/atoms/zl-field.d.ts.map +1 -1
  11. package/dist/atoms/zl-icon.d.ts.map +1 -1
  12. package/dist/atoms/zl-page-shell.d.ts +6 -0
  13. package/dist/atoms/zl-page-shell.d.ts.map +1 -1
  14. package/dist/atoms/zl-passkey.d.ts +6 -1
  15. package/dist/atoms/zl-passkey.d.ts.map +1 -1
  16. package/dist/atoms/zl-pill.d.ts +0 -1
  17. package/dist/atoms/zl-pill.d.ts.map +1 -1
  18. package/dist/{atoms-CmOTltTH.mjs → atoms-eOxuoGDq.mjs} +135 -78
  19. package/dist/atoms-eOxuoGDq.mjs.map +1 -0
  20. package/dist/default-DP74t2io.mjs +6 -0
  21. package/dist/default-DP74t2io.mjs.map +1 -0
  22. package/dist/{index-bZEvwHtq.d.mts → index-DjBsBWdg.d.mts} +99 -98
  23. package/dist/index-DjBsBWdg.d.mts.map +1 -0
  24. package/dist/{index-DIUFZjXw.d.mts → index-DmtnqUIY.d.mts} +1237 -574
  25. package/dist/index-DmtnqUIY.d.mts.map +1 -0
  26. package/dist/{index-DaOSCm0T.d.mts → index-EJengPPu.d.mts} +1 -1
  27. package/dist/{index-DaOSCm0T.d.mts.map → index-EJengPPu.d.mts.map} +1 -1
  28. package/dist/index.d.mts +6 -5
  29. package/dist/index.d.mts.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.mjs +4 -3
  33. package/dist/internal/emit.d.ts +12 -0
  34. package/dist/internal/emit.d.ts.map +1 -0
  35. package/dist/internal/escape-html.d.ts +10 -0
  36. package/dist/internal/escape-html.d.ts.map +1 -0
  37. package/dist/{manifest-DCC2FxCE.d.mts → manifest-DN5Al_Ur.d.mts} +1 -1
  38. package/dist/{manifest-DCC2FxCE.d.mts.map → manifest-DN5Al_Ur.d.mts.map} +1 -1
  39. package/dist/manifests.d.mts +1 -1
  40. package/dist/manifests.mjs +1 -1
  41. package/dist/orchestrator/index.d.mts +3 -2
  42. package/dist/orchestrator/index.d.ts +3 -5
  43. package/dist/orchestrator/index.d.ts.map +1 -1
  44. package/dist/orchestrator/index.mjs +3 -2
  45. package/dist/orchestrator/liquid.d.ts +3 -0
  46. package/dist/orchestrator/liquid.d.ts.map +1 -1
  47. package/dist/orchestrator/locales/de.d.ts +7 -0
  48. package/dist/orchestrator/locales/de.d.ts.map +1 -1
  49. package/dist/orchestrator/locales/en.d.ts +6 -0
  50. package/dist/orchestrator/locales/en.d.ts.map +1 -1
  51. package/dist/orchestrator/locales/index.d.ts +1 -0
  52. package/dist/orchestrator/locales/index.d.ts.map +1 -1
  53. package/dist/orchestrator/locales/it.d.ts +14 -0
  54. package/dist/orchestrator/locales/it.d.ts.map +1 -0
  55. package/dist/orchestrator/resolve-api.d.ts +37 -0
  56. package/dist/orchestrator/resolve-api.d.ts.map +1 -0
  57. package/dist/orchestrator/zitadel-login.d.ts +30 -2
  58. package/dist/orchestrator/zitadel-login.d.ts.map +1 -1
  59. package/dist/orchestrator/zitadel-logout.d.ts +33 -5
  60. package/dist/orchestrator/zitadel-logout.d.ts.map +1 -1
  61. package/dist/{orchestrator-CNKo2WQG.mjs → orchestrator-Dds72XrU.mjs} +587 -619
  62. package/dist/orchestrator-Dds72XrU.mjs.map +1 -0
  63. package/dist/standalone.mjs +12002 -0
  64. package/dist/tokens/index.d.mts +1 -1
  65. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  66. package/package.json +9 -3
  67. package/dist/atoms-CmOTltTH.mjs.map +0 -1
  68. package/dist/index-7FDHEpv5.d.mts +0 -996
  69. package/dist/index-7FDHEpv5.d.mts.map +0 -1
  70. package/dist/index-DIUFZjXw.d.mts.map +0 -1
  71. package/dist/index-bZEvwHtq.d.mts.map +0 -1
  72. package/dist/orchestrator/templates/auth-form.liquid.d.ts +0 -14
  73. package/dist/orchestrator/templates/auth-form.liquid.d.ts.map +0 -1
  74. package/dist/orchestrator/templates/default.liquid.d.ts +0 -23
  75. package/dist/orchestrator/templates/default.liquid.d.ts.map +0 -1
  76. package/dist/orchestrator/templates/passkey-upsell.liquid.d.ts +0 -15
  77. package/dist/orchestrator/templates/passkey-upsell.liquid.d.ts.map +0 -1
  78. package/dist/orchestrator/templates/signed-in.liquid.d.ts +0 -20
  79. package/dist/orchestrator/templates/signed-in.liquid.d.ts.map +0 -1
  80. package/dist/orchestrator-CNKo2WQG.mjs.map +0 -1
@@ -1,14 +1,36 @@
1
1
  import { t as cssVars } from "./tokens-TXmurodq.mjs";
2
2
  import { LitElement, css, html, nothing, unsafeCSS } from "lit";
3
- import { customElement, property, state } from "lit/decorators.js";
3
+ import { customElement, property, query, state } from "lit/decorators.js";
4
+ import { classMap } from "lit/directives/class-map.js";
4
5
  import { unsafeSVG } from "lit/directives/unsafe-svg.js";
5
6
  import { ArrowLeft, ArrowRight, Check, CircleAlert, Eye, EyeOff, Info, KeyRound, LoaderCircle, Plus, TriangleAlert, User, X } from "lucide";
7
+ import { ifDefined } from "lit/directives/if-defined.js";
8
+ import { live } from "lit/directives/live.js";
6
9
  //#region ../shared-component-styles/src/lit/alert-host.css?inline
7
10
  var alert_host_default = ":host {\n display: block;\n}\n";
8
11
  //#endregion
9
12
  //#region ../shared-component-styles/src/alert.css?inline
10
13
  var alert_default = ".zr-alert {\n align-items: flex-start;\n gap: var(--zl-spacing-03, 1rem);\n padding: var(--zl-spacing-03, 1rem);\n border-radius: var(--zl-radius-m, .75rem);\n background: var(--zl-color-surface-default-primary-gray, #252528);\n color: var(--zl-color-text-button-invert, #f4f4f6);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n font-size: .875rem;\n font-weight: 400;\n line-height: 1.25rem;\n display: flex;\n box-shadow: 0 1px 2px #1018280d;\n}\n\n.zr-alert__icon {\n color: var(--zl-color-text-error, #ea4f70);\n flex-shrink: 0;\n}\n\n.zr-alert--warning .zr-alert__icon {\n color: var(--zl-color-text-subtitle-orange, #f25543);\n}\n\n.zr-alert--success .zr-alert__icon {\n color: var(--zl-color-text-success, #33a779);\n}\n\n.zr-alert--info .zr-alert__icon {\n color: var(--zl-color-text-subtitle-gray, #bfbfcf);\n}\n\n.zr-alert__body {\n gap: var(--zl-spacing-01, .25rem);\n flex-direction: column;\n flex: auto;\n min-width: 0;\n display: flex;\n}\n\n.zr-alert__title {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n font-weight: 600;\n}\n\n.zr-alert__message {\n color: var(--zl-color-border-default-white, #f4f4f6);\n margin: 0;\n}\n\n.zr-alert:not(:has(.zr-alert__title)) .zr-alert__message {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n\n.zr-alert__close {\n all: unset;\n width: 2.25rem;\n height: 2.25rem;\n padding: var(--zl-spacing-02, .5rem);\n border-radius: var(--zl-radius-s, .5rem);\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n cursor: pointer;\n transition: background-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1));\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: 1.25rem;\n width: 1.25rem;\n height: 1.25rem;\n}\n\n.zr-alert__close:hover {\n background: var(--zl-color-gray-200, #484a57);\n}\n\n.zr-alert__close:focus-visible {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n}\n";
11
14
  //#endregion
15
+ //#region src/internal/emit.ts
16
+ /**
17
+ * Dispatch a custom event with the project-wide defaults (`bubbles` +
18
+ * `composed`) so it crosses the shadow boundary and reaches delegated
19
+ * listeners — whether it's an atom's `zl-*` event or the orchestrator's
20
+ * public `zitadel-*` event.
21
+ *
22
+ * Centralising the dispatch shape keeps every event contract identical and
23
+ * removes the repeated `new CustomEvent(..., { bubbles: true, composed: true,
24
+ * detail })` boilerplate.
25
+ */
26
+ function emit(host, type, detail) {
27
+ return host.dispatchEvent(new CustomEvent(type, {
28
+ bubbles: true,
29
+ composed: true,
30
+ detail
31
+ }));
32
+ }
33
+ //#endregion
12
34
  //#region src/styles/tokens.ts
13
35
  function wrap(node) {
14
36
  if (typeof node === "string") return unsafeCSS(node);
@@ -123,12 +145,12 @@ let ZlIcon = class ZlIcon extends LitElement {
123
145
  const ariaLabel = this.label ?? DEFAULT_LABELS[this.name];
124
146
  const hidden = this.decorative || !ariaLabel;
125
147
  return html`
126
- <span class=${[
127
- "zr-icon",
128
- `zr-icon--${this.size}`,
129
- this.tone !== "default" ? `zr-icon--tone-${this.tone}` : "",
130
- this.spin ? "zr-icon--spin" : ""
131
- ].filter(Boolean).join(" ")}>
148
+ <span class=${classMap({
149
+ "zr-icon": true,
150
+ [`zr-icon--${this.size}`]: true,
151
+ [`zr-icon--tone-${this.tone}`]: this.tone !== "default",
152
+ "zr-icon--spin": this.spin
153
+ })}>
132
154
  <svg
133
155
  viewBox="0 0 24 24"
134
156
  fill="none"
@@ -257,10 +279,7 @@ let ZlAlert = class ZlAlert extends LitElement {
257
279
  `;
258
280
  }
259
281
  handleDismiss = () => {
260
- this.dispatchEvent(new CustomEvent("zl-dismiss", {
261
- bubbles: true,
262
- composed: true
263
- }));
282
+ emit(this, "zl-dismiss");
264
283
  this.remove();
265
284
  };
266
285
  };
@@ -292,7 +311,7 @@ const zlAlertManifest = {
292
311
  "message",
293
312
  "close"
294
313
  ],
295
- slots: [],
314
+ slots: [""],
296
315
  events: ["zl-dismiss"]
297
316
  };
298
317
  //#endregion
@@ -366,6 +385,13 @@ let ZlButton = class ZlButton extends LitElement {
366
385
  set label(value) {
367
386
  this.#_label_accessor_storage = value;
368
387
  }
388
+ #_forcedState_accessor_storage = null;
389
+ get forcedState() {
390
+ return this.#_forcedState_accessor_storage;
391
+ }
392
+ set forcedState(value) {
393
+ this.#_forcedState_accessor_storage = value;
394
+ }
369
395
  internals;
370
396
  constructor() {
371
397
  super();
@@ -374,27 +400,23 @@ let ZlButton = class ZlButton extends LitElement {
374
400
  focus(options) {
375
401
  this.shadowRoot?.querySelector("button")?.focus(options);
376
402
  }
377
- surfaceClasses() {
378
- return [
379
- "root",
380
- "zr-btn",
381
- `zr-btn--${this.hierarchy}`,
382
- `zr-btn--${this.size}`,
383
- this.block ? "zr-btn--block" : ""
384
- ].filter(Boolean).join(" ");
385
- }
386
403
  render() {
387
404
  const blocked = this.disabled || this.loading;
388
- const forcedState = this.getAttribute("data-state");
389
405
  const body = this.label !== void 0 ? html`<span>${this.label}</span>` : html`<slot></slot>`;
390
406
  return html`
391
407
  <button
392
- class=${this.surfaceClasses()}
408
+ class=${classMap({
409
+ root: true,
410
+ "zr-btn": true,
411
+ [`zr-btn--${this.hierarchy}`]: true,
412
+ [`zr-btn--${this.size}`]: true,
413
+ "zr-btn--block": this.block
414
+ })}
393
415
  part="root"
394
416
  type=${this.type}
395
417
  ?disabled=${blocked}
396
418
  aria-busy=${this.loading ? "true" : "false"}
397
- data-state=${forcedState ?? nothing}
419
+ data-state=${this.forcedState ?? nothing}
398
420
  @click=${this.handleClick}
399
421
  >
400
422
  <slot name="leading"></slot>
@@ -417,11 +439,7 @@ let ZlButton = class ZlButton extends LitElement {
417
439
  event.preventDefault();
418
440
  form.reset();
419
441
  }
420
- this.dispatchEvent(new CustomEvent("zl-submit", {
421
- bubbles: true,
422
- composed: true,
423
- detail: { action: this.action ?? null }
424
- }));
442
+ emit(this, "zl-submit", { action: this.action ?? null });
425
443
  };
426
444
  };
427
445
  __decorate([property({ reflect: true })], ZlButton.prototype, "hierarchy", null);
@@ -438,6 +456,7 @@ __decorate([property({
438
456
  reflect: true
439
457
  })], ZlButton.prototype, "block", null);
440
458
  __decorate([property()], ZlButton.prototype, "label", null);
459
+ __decorate([property({ attribute: "data-state" })], ZlButton.prototype, "forcedState", null);
441
460
  ZlButton = __decorate([customElement("zl-button")], ZlButton);
442
461
  const zlButtonManifest = {
443
462
  tag: "zl-button",
@@ -483,20 +502,32 @@ let ZlCard = class ZlCard extends LitElement {
483
502
  render() {
484
503
  const hasHeader = this.lightDomSlotFilled("header");
485
504
  const hasFooter = this.lightDomSlotFilled("footer");
505
+ const cardClass = this.compact ? "zr-card zr-card--compact" : "zr-card";
506
+ const headerClass = hasHeader ? "zr-card__header" : "zr-card__header zr-card__region--empty";
507
+ const footerClass = hasFooter ? "zr-card__footer" : "zr-card__footer zr-card__region--empty";
486
508
  return html`
487
- <section class=${this.compact ? "zr-card zr-card--compact" : "zr-card"} part="card">
488
- <header class=${hasHeader ? "zr-card__header" : "zr-card__header zr-card__region--empty"} part="header">
489
- <slot name="header"></slot>
509
+ <section class=${cardClass} part="card">
510
+ <header class=${headerClass} part="header">
511
+ <slot name="header" @slotchange=${this.onSlotChange}></slot>
490
512
  </header>
491
513
  <div class="zr-card__body" part="body">
492
514
  <slot></slot>
493
515
  </div>
494
- <footer class=${hasFooter ? "zr-card__footer" : "zr-card__footer zr-card__region--empty"} part="footer">
495
- <slot name="footer"></slot>
516
+ <footer class=${footerClass} part="footer">
517
+ <slot name="footer" @slotchange=${this.onSlotChange}></slot>
496
518
  </footer>
497
519
  </section>
498
520
  `;
499
521
  }
522
+ /**
523
+ * `lightDomSlotFilled` is a render-time snapshot, so re-run render whenever a
524
+ * named slot's assignment changes (e.g. a header added after first paint).
525
+ * The initial render still reads children synchronously, avoiding the
526
+ * empty-then-filled flash a slotchange-only approach would introduce.
527
+ */
528
+ onSlotChange = () => {
529
+ this.requestUpdate();
530
+ };
500
531
  /** Slotted nodes are always light-DOM children of the host in our templates. */
501
532
  lightDomSlotFilled(slot) {
502
533
  for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
@@ -557,12 +588,17 @@ let ZlField = class ZlField extends LitElement {
557
588
  delegatesFocus: true
558
589
  };
559
590
  static styles = [baseHostStyles, ...surfaceStyles(text_field_host_default, text_field_default)];
560
- #_name_accessor_storage = "";
591
+ /**
592
+ * Field name — used as the key in form submission and in `zl-input` event
593
+ * detail. For form-associated custom elements the browser owns a native
594
+ * `name` property; using `@property()` would create a conflicting accessor
595
+ * that loses sync with the DOM attribute. We therefore manage it manually.
596
+ */
561
597
  get name() {
562
- return this.#_name_accessor_storage;
598
+ return this.getAttribute("name") ?? "";
563
599
  }
564
600
  set name(value) {
565
- this.#_name_accessor_storage = value;
601
+ this.setAttribute("name", value);
566
602
  }
567
603
  #_label_accessor_storage = "";
568
604
  get label() {
@@ -676,6 +712,13 @@ let ZlField = class ZlField extends LitElement {
676
712
  set hasSuffixSlot(value) {
677
713
  this.#_hasSuffixSlot_accessor_storage = value;
678
714
  }
715
+ #_inputEl_accessor_storage = null;
716
+ get inputEl() {
717
+ return this.#_inputEl_accessor_storage;
718
+ }
719
+ set inputEl(value) {
720
+ this.#_inputEl_accessor_storage = value;
721
+ }
679
722
  inputId = nextUid("zl-field");
680
723
  internals;
681
724
  constructor() {
@@ -696,7 +739,7 @@ let ZlField = class ZlField extends LitElement {
696
739
  this.value = state ?? "";
697
740
  }
698
741
  focus(options) {
699
- this.shadowRoot?.querySelector("input")?.focus(options);
742
+ this.inputEl?.focus(options);
700
743
  }
701
744
  render() {
702
745
  const labelId = `${this.inputId}-label`;
@@ -710,15 +753,18 @@ let ZlField = class ZlField extends LitElement {
710
753
  showSuccess ? successId : null,
711
754
  this.hasHelp ? helpId : null
712
755
  ].filter(Boolean).join(" ");
713
- const rootClass = [
714
- "zr-field",
715
- this.invalid || showError ? "zr-field--invalid" : "",
716
- showSuccess ? "zr-field--success" : "",
717
- this.disabled ? "zr-field--disabled" : ""
718
- ].filter(Boolean).join(" ");
756
+ const rootClass = classMap({
757
+ "zr-field": true,
758
+ "zr-field--invalid": this.invalid || showError,
759
+ "zr-field--success": showSuccess,
760
+ "zr-field--disabled": this.disabled
761
+ });
719
762
  const showDefaultTrailing = this.trailingIcon && !this.hasSuffixSlot && !this.disabled;
720
763
  const trailing = showDefaultTrailing ? this.renderTrailingIcon() : null;
721
- const wrapClass = ["zr-field__wrap", showDefaultTrailing ? "zr-field__wrap--trailing" : ""].filter(Boolean).join(" ");
764
+ const wrapClass = classMap({
765
+ "zr-field__wrap": true,
766
+ "zr-field__wrap--trailing": showDefaultTrailing
767
+ });
722
768
  return html`
723
769
  <div class=${rootClass} part="root">
724
770
  ${this.renderLabelRow(labelId)}
@@ -730,10 +776,10 @@ let ZlField = class ZlField extends LitElement {
730
776
  id=${this.inputId}
731
777
  name=${this.name}
732
778
  type=${this.type}
733
- .value=${this.value}
779
+ .value=${live(this.value)}
734
780
  placeholder=${this.placeholder}
735
- autocomplete=${this.autocomplete ?? ""}
736
- pattern=${this.pattern ?? ""}
781
+ autocomplete=${ifDefined(this.autocomplete)}
782
+ pattern=${ifDefined(this.pattern)}
737
783
  ?required=${this.required}
738
784
  ?disabled=${this.disabled}
739
785
  aria-invalid=${this.invalid || showError ? "true" : "false"}
@@ -829,28 +875,20 @@ let ZlField = class ZlField extends LitElement {
829
875
  };
830
876
  handleClear = () => {
831
877
  this.value = "";
832
- this.dispatchEvent(new CustomEvent("zl-input", {
833
- bubbles: true,
834
- composed: true,
835
- detail: {
836
- name: this.name,
837
- value: this.value
838
- }
839
- }));
878
+ emit(this, "zl-input", {
879
+ name: this.name,
880
+ value: this.value
881
+ });
840
882
  this.syncFormState();
841
- this.shadowRoot?.querySelector(".zr-field__input")?.focus();
883
+ this.inputEl?.focus();
842
884
  };
843
885
  handleInput = (event) => {
844
886
  const input = event.target;
845
887
  this.value = input.value;
846
- this.dispatchEvent(new CustomEvent("zl-input", {
847
- bubbles: true,
848
- composed: true,
849
- detail: {
850
- name: this.name,
851
- value: this.value
852
- }
853
- }));
888
+ emit(this, "zl-input", {
889
+ name: this.name,
890
+ value: this.value
891
+ });
854
892
  };
855
893
  handleChange = (event) => {
856
894
  const input = event.target;
@@ -870,7 +908,6 @@ let ZlField = class ZlField extends LitElement {
870
908
  }
871
909
  };
872
910
  };
873
- __decorate([property()], ZlField.prototype, "name", null);
874
911
  __decorate([property()], ZlField.prototype, "label", null);
875
912
  __decorate([property()], ZlField.prototype, "type", null);
876
913
  __decorate([property()], ZlField.prototype, "value", null);
@@ -896,6 +933,7 @@ __decorate([property({
896
933
  })], ZlField.prototype, "invalid", null);
897
934
  __decorate([state()], ZlField.prototype, "hasHelp", null);
898
935
  __decorate([state()], ZlField.prototype, "hasSuffixSlot", null);
936
+ __decorate([query(".zr-field__input")], ZlField.prototype, "inputEl", null);
899
937
  ZlField = __decorate([customElement("zl-field")], ZlField);
900
938
  const zlFieldManifest = {
901
939
  tag: "zl-field",
@@ -950,20 +988,30 @@ let ZlPageShell = class ZlPageShell extends LitElement {
950
988
  render() {
951
989
  const hasHeader = this.lightDomSlotFilled("header");
952
990
  const hasFooter = this.lightDomSlotFilled("footer");
991
+ const headerClass = hasHeader ? "zr-page-shell__header" : "zr-page-shell__header zr-page-shell__region--empty";
992
+ const footerClass = hasFooter ? "zr-page-shell__footer" : "zr-page-shell__footer zr-page-shell__region--empty";
953
993
  return html`
954
994
  <div class="zr-page-shell" part="shell">
955
- <header class=${hasHeader ? "zr-page-shell__header" : "zr-page-shell__header zr-page-shell__region--empty"} part="header">
956
- <slot name="header"></slot>
995
+ <header class=${headerClass} part="header">
996
+ <slot name="header" @slotchange=${this.onSlotChange}></slot>
957
997
  </header>
958
998
  <main class="zr-page-shell__main" part="main">
959
999
  <slot></slot>
960
1000
  </main>
961
- <footer class=${hasFooter ? "zr-page-shell__footer" : "zr-page-shell__footer zr-page-shell__region--empty"} part="footer">
962
- <slot name="footer"></slot>
1001
+ <footer class=${footerClass} part="footer">
1002
+ <slot name="footer" @slotchange=${this.onSlotChange}></slot>
963
1003
  </footer>
964
1004
  </div>
965
1005
  `;
966
1006
  }
1007
+ /**
1008
+ * Re-render when a named slot's assignment changes so a footer/header added
1009
+ * after first paint updates the empty-region class. The initial render reads
1010
+ * children synchronously (no empty-then-filled flash).
1011
+ */
1012
+ onSlotChange = () => {
1013
+ this.requestUpdate();
1014
+ };
967
1015
  lightDomSlotFilled(slot) {
968
1016
  for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
969
1017
  return false;
@@ -1041,6 +1089,13 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1041
1089
  set options(value) {
1042
1090
  this.#_options_accessor_storage = value;
1043
1091
  }
1092
+ #_method_accessor_storage = "passkey";
1093
+ get method() {
1094
+ return this.#_method_accessor_storage;
1095
+ }
1096
+ set method(value) {
1097
+ this.#_method_accessor_storage = value;
1098
+ }
1044
1099
  #_manual_accessor_storage = false;
1045
1100
  get manual() {
1046
1101
  return this.#_manual_accessor_storage;
@@ -1185,7 +1240,7 @@ let ZlPasskey = class ZlPasskey extends LitElement {
1185
1240
  emitResult(proof) {
1186
1241
  const detail = {
1187
1242
  challenge_id: this.challengeId,
1188
- method: "passkey",
1243
+ method: this.method,
1189
1244
  proof
1190
1245
  };
1191
1246
  this.dispatchEvent(new CustomEvent("zl-passkey-result", {
@@ -1229,6 +1284,7 @@ __decorate([property({
1229
1284
  }
1230
1285
  }
1231
1286
  })], ZlPasskey.prototype, "options", null);
1287
+ __decorate([property({ type: String })], ZlPasskey.prototype, "method", null);
1232
1288
  __decorate([property({ type: Boolean })], ZlPasskey.prototype, "manual", null);
1233
1289
  ZlPasskey = __decorate([customElement("zl-passkey")], ZlPasskey);
1234
1290
  const zlPasskeyManifest = {
@@ -1236,6 +1292,7 @@ const zlPasskeyManifest = {
1236
1292
  consumes: {},
1237
1293
  attrs: [
1238
1294
  "ceremony",
1295
+ "method",
1239
1296
  "challenge-id",
1240
1297
  "options",
1241
1298
  "manual"
@@ -1275,11 +1332,11 @@ let ZlPill = class ZlPill extends LitElement {
1275
1332
  set ariaLabel(value) {
1276
1333
  this.#_ariaLabel_accessor_storage = value;
1277
1334
  }
1278
- surfaceClasses() {
1279
- return ["zr-pill", this.tone !== "neutral" ? `zr-pill--${this.tone}` : ""].filter(Boolean).join(" ");
1280
- }
1281
1335
  render() {
1282
- const classes = this.surfaceClasses();
1336
+ const classes = classMap({
1337
+ "zr-pill": true,
1338
+ [`zr-pill--${this.tone}`]: this.tone !== "neutral"
1339
+ });
1283
1340
  if (this.href) return html`<a
1284
1341
  class=${classes}
1285
1342
  part="pill"
@@ -1302,10 +1359,10 @@ const zlPillManifest = {
1302
1359
  "aria-label"
1303
1360
  ],
1304
1361
  parts: ["pill"],
1305
- slots: [],
1362
+ slots: [""],
1306
1363
  events: []
1307
1364
  };
1308
1365
  //#endregion
1309
- export { __decorate as _, ZlPageShell as a, t as b, zlFieldManifest as c, ZlButton as d, zlButtonManifest as f, zlIconManifest as g, ZlIcon as h, zlPasskeyManifest as i, ZlCard as l, zlAlertManifest as m, zlPillManifest as n, zlPageShellManifest as o, ZlAlert as p, ZlPasskey as r, ZlField as s, ZlPill as t, zlCardManifest as u, focusVisibleStyles as v, baseHostStyles as y };
1366
+ export { __decorate as _, ZlPageShell as a, t as b, zlFieldManifest as c, ZlButton as d, zlButtonManifest as f, zlIconManifest as g, ZlIcon as h, zlPasskeyManifest as i, ZlCard as l, zlAlertManifest as m, zlPillManifest as n, zlPageShellManifest as o, ZlAlert as p, ZlPasskey as r, ZlField as s, ZlPill as t, zlCardManifest as u, focusVisibleStyles as v, emit as x, baseHostStyles as y };
1310
1367
 
1311
- //# sourceMappingURL=atoms-CmOTltTH.mjs.map
1368
+ //# sourceMappingURL=atoms-eOxuoGDq.mjs.map