@nymbalhq/web-components 1.0.0 → 1.2.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 (187) hide show
  1. package/astro/NymbalElement.astro +19 -0
  2. package/dist/base-element-CPMgAdyQ.d.ts +91 -0
  3. package/dist/chunk-2TPQNQYO.js +155 -0
  4. package/dist/chunk-2TPQNQYO.js.map +1 -0
  5. package/dist/chunk-2XXBQPDB.js +113 -0
  6. package/dist/chunk-2XXBQPDB.js.map +1 -0
  7. package/dist/chunk-42SSME5H.js +84 -0
  8. package/dist/chunk-42SSME5H.js.map +1 -0
  9. package/dist/chunk-4COVK727.js +204 -0
  10. package/dist/chunk-4COVK727.js.map +1 -0
  11. package/dist/chunk-5VWZ2U5K.js +149 -0
  12. package/dist/chunk-5VWZ2U5K.js.map +1 -0
  13. package/dist/chunk-6XCCAAMF.js +656 -0
  14. package/dist/chunk-6XCCAAMF.js.map +1 -0
  15. package/dist/chunk-7JAAOVCE.js +114 -0
  16. package/dist/chunk-7JAAOVCE.js.map +1 -0
  17. package/dist/chunk-B73QVSA5.js +206 -0
  18. package/dist/chunk-B73QVSA5.js.map +1 -0
  19. package/dist/chunk-DR5QB5VN.js +17 -0
  20. package/dist/chunk-DR5QB5VN.js.map +1 -0
  21. package/dist/chunk-DXWMNB5F.js +70 -0
  22. package/dist/chunk-DXWMNB5F.js.map +1 -0
  23. package/dist/chunk-EBMA7JGV.js +130 -0
  24. package/dist/chunk-EBMA7JGV.js.map +1 -0
  25. package/dist/chunk-EYDMJNNK.js +176 -0
  26. package/dist/chunk-EYDMJNNK.js.map +1 -0
  27. package/dist/chunk-FIF6GQ6U.js +141 -0
  28. package/dist/chunk-FIF6GQ6U.js.map +1 -0
  29. package/dist/chunk-GHXTJ2CF.js +109 -0
  30. package/dist/chunk-GHXTJ2CF.js.map +1 -0
  31. package/dist/chunk-H3ZBYNHV.js +153 -0
  32. package/dist/chunk-H3ZBYNHV.js.map +1 -0
  33. package/dist/chunk-HPBC3OG7.js +174 -0
  34. package/dist/chunk-HPBC3OG7.js.map +1 -0
  35. package/dist/chunk-IYT7VXFS.js +105 -0
  36. package/dist/chunk-IYT7VXFS.js.map +1 -0
  37. package/dist/chunk-LHYXNQWY.js +105 -0
  38. package/dist/chunk-LHYXNQWY.js.map +1 -0
  39. package/dist/chunk-LO2EW5YP.js +25 -0
  40. package/dist/chunk-LO2EW5YP.js.map +1 -0
  41. package/dist/chunk-LSQPUZK6.js +291 -0
  42. package/dist/chunk-LSQPUZK6.js.map +1 -0
  43. package/dist/chunk-N4Y5DI4X.js +82 -0
  44. package/dist/chunk-N4Y5DI4X.js.map +1 -0
  45. package/dist/chunk-NE6UHTOT.js +148 -0
  46. package/dist/chunk-NE6UHTOT.js.map +1 -0
  47. package/dist/chunk-NW47OJVN.js +138 -0
  48. package/dist/chunk-NW47OJVN.js.map +1 -0
  49. package/dist/chunk-O2YKCDR2.js +77 -0
  50. package/dist/chunk-O2YKCDR2.js.map +1 -0
  51. package/dist/chunk-PN6QKYE4.js +71 -0
  52. package/dist/chunk-PN6QKYE4.js.map +1 -0
  53. package/dist/chunk-RAOGZH3Z.js +188 -0
  54. package/dist/chunk-RAOGZH3Z.js.map +1 -0
  55. package/dist/chunk-RVSKX2RX.js +11 -0
  56. package/dist/chunk-RVSKX2RX.js.map +1 -0
  57. package/dist/chunk-RZVFA3N5.js +154 -0
  58. package/dist/chunk-RZVFA3N5.js.map +1 -0
  59. package/dist/chunk-SM7TASEW.js +135 -0
  60. package/dist/chunk-SM7TASEW.js.map +1 -0
  61. package/dist/chunk-U2PU4CWB.js +124 -0
  62. package/dist/chunk-U2PU4CWB.js.map +1 -0
  63. package/dist/chunk-UCEVCLQ7.js +5 -0
  64. package/dist/chunk-UCEVCLQ7.js.map +1 -0
  65. package/dist/chunk-UYSZOEOA.js +32 -0
  66. package/dist/chunk-UYSZOEOA.js.map +1 -0
  67. package/dist/chunk-V55K2CS5.js +126 -0
  68. package/dist/chunk-V55K2CS5.js.map +1 -0
  69. package/dist/chunk-VTQVGNVC.js +346 -0
  70. package/dist/chunk-VTQVGNVC.js.map +1 -0
  71. package/dist/chunk-W23P7SI4.js +239 -0
  72. package/dist/chunk-W23P7SI4.js.map +1 -0
  73. package/dist/chunk-W7D3STJH.js +279 -0
  74. package/dist/chunk-W7D3STJH.js.map +1 -0
  75. package/dist/chunk-WEEHXWM3.js +172 -0
  76. package/dist/chunk-WEEHXWM3.js.map +1 -0
  77. package/dist/chunk-WTEVTCIL.js +128 -0
  78. package/dist/chunk-WTEVTCIL.js.map +1 -0
  79. package/dist/chunk-XE6IWISA.js +137 -0
  80. package/dist/chunk-XE6IWISA.js.map +1 -0
  81. package/dist/elements/nymbal-add-to-cart.d.ts +14 -0
  82. package/dist/elements/nymbal-add-to-cart.js +10 -0
  83. package/dist/elements/nymbal-add-to-cart.js.map +1 -0
  84. package/dist/elements/nymbal-address-book.d.ts +30 -0
  85. package/dist/elements/nymbal-address-book.js +13 -0
  86. package/dist/elements/nymbal-address-book.js.map +1 -0
  87. package/dist/elements/nymbal-address-form.d.ts +29 -0
  88. package/dist/elements/nymbal-address-form.js +12 -0
  89. package/dist/elements/nymbal-address-form.js.map +1 -0
  90. package/dist/elements/nymbal-breadcrumb.d.ts +15 -0
  91. package/dist/elements/nymbal-breadcrumb.js +11 -0
  92. package/dist/elements/nymbal-breadcrumb.js.map +1 -0
  93. package/dist/elements/nymbal-cart-drawer.d.ts +24 -0
  94. package/dist/elements/nymbal-cart-drawer.js +11 -0
  95. package/dist/elements/nymbal-cart-drawer.js.map +1 -0
  96. package/dist/elements/nymbal-cart-page.d.ts +20 -0
  97. package/dist/elements/nymbal-cart-page.js +14 -0
  98. package/dist/elements/nymbal-cart-page.js.map +1 -0
  99. package/dist/elements/nymbal-category-nav.d.ts +15 -0
  100. package/dist/elements/nymbal-category-nav.js +11 -0
  101. package/dist/elements/nymbal-category-nav.js.map +1 -0
  102. package/dist/elements/nymbal-checkout.d.ts +77 -0
  103. package/dist/elements/nymbal-checkout.js +15 -0
  104. package/dist/elements/nymbal-checkout.js.map +1 -0
  105. package/dist/elements/nymbal-image-gallery.d.ts +19 -0
  106. package/dist/elements/nymbal-image-gallery.js +10 -0
  107. package/dist/elements/nymbal-image-gallery.js.map +1 -0
  108. package/dist/elements/nymbal-login-form.d.ts +17 -0
  109. package/dist/elements/nymbal-login-form.js +12 -0
  110. package/dist/elements/nymbal-login-form.js.map +1 -0
  111. package/dist/elements/nymbal-mini-cart.d.ts +17 -0
  112. package/dist/elements/nymbal-mini-cart.js +10 -0
  113. package/dist/elements/nymbal-mini-cart.js.map +1 -0
  114. package/dist/elements/nymbal-order-summary.d.ts +20 -0
  115. package/dist/elements/nymbal-order-summary.js +11 -0
  116. package/dist/elements/nymbal-order-summary.js.map +1 -0
  117. package/dist/elements/nymbal-payment-element.d.ts +4 -0
  118. package/dist/elements/nymbal-payment-element.js +10 -0
  119. package/dist/elements/nymbal-payment-element.js.map +1 -0
  120. package/dist/elements/nymbal-product-card.d.ts +4 -0
  121. package/dist/elements/nymbal-product-card.js +12 -0
  122. package/dist/elements/nymbal-product-card.js.map +1 -0
  123. package/dist/elements/nymbal-product-filter.d.ts +32 -0
  124. package/dist/elements/nymbal-product-filter.js +10 -0
  125. package/dist/elements/nymbal-product-filter.js.map +1 -0
  126. package/dist/elements/nymbal-product-grid.d.ts +24 -0
  127. package/dist/elements/nymbal-product-grid.js +14 -0
  128. package/dist/elements/nymbal-product-grid.js.map +1 -0
  129. package/dist/elements/nymbal-product-price.d.ts +18 -0
  130. package/dist/elements/nymbal-product-price.js +12 -0
  131. package/dist/elements/nymbal-product-price.js.map +1 -0
  132. package/dist/elements/nymbal-profile-form.d.ts +19 -0
  133. package/dist/elements/nymbal-profile-form.js +12 -0
  134. package/dist/elements/nymbal-profile-form.js.map +1 -0
  135. package/dist/elements/nymbal-quantity-selector.d.ts +20 -0
  136. package/dist/elements/nymbal-quantity-selector.js +10 -0
  137. package/dist/elements/nymbal-quantity-selector.js.map +1 -0
  138. package/dist/elements/nymbal-register-form.d.ts +17 -0
  139. package/dist/elements/nymbal-register-form.js +12 -0
  140. package/dist/elements/nymbal-register-form.js.map +1 -0
  141. package/dist/elements/nymbal-review-form.d.ts +17 -0
  142. package/dist/elements/nymbal-review-form.js +12 -0
  143. package/dist/elements/nymbal-review-form.js.map +1 -0
  144. package/dist/elements/nymbal-review-list.d.ts +14 -0
  145. package/dist/elements/nymbal-review-list.js +10 -0
  146. package/dist/elements/nymbal-review-list.js.map +1 -0
  147. package/dist/elements/nymbal-search-bar.d.ts +19 -0
  148. package/dist/elements/nymbal-search-bar.js +10 -0
  149. package/dist/elements/nymbal-search-bar.js.map +1 -0
  150. package/dist/elements/nymbal-search-results.d.ts +29 -0
  151. package/dist/elements/nymbal-search-results.js +14 -0
  152. package/dist/elements/nymbal-search-results.js.map +1 -0
  153. package/dist/elements/nymbal-site-footer.d.ts +15 -0
  154. package/dist/elements/nymbal-site-footer.js +11 -0
  155. package/dist/elements/nymbal-site-footer.js.map +1 -0
  156. package/dist/elements/nymbal-site-header.d.ts +19 -0
  157. package/dist/elements/nymbal-site-header.js +11 -0
  158. package/dist/elements/nymbal-site-header.js.map +1 -0
  159. package/dist/elements/nymbal-sort-dropdown.d.ts +28 -0
  160. package/dist/elements/nymbal-sort-dropdown.js +10 -0
  161. package/dist/elements/nymbal-sort-dropdown.js.map +1 -0
  162. package/dist/elements/nymbal-stock-badge.d.ts +16 -0
  163. package/dist/elements/nymbal-stock-badge.js +11 -0
  164. package/dist/elements/nymbal-stock-badge.js.map +1 -0
  165. package/dist/elements/nymbal-toast.d.ts +18 -0
  166. package/dist/elements/nymbal-toast.js +10 -0
  167. package/dist/elements/nymbal-toast.js.map +1 -0
  168. package/dist/elements/nymbal-variant-selector.d.ts +16 -0
  169. package/dist/elements/nymbal-variant-selector.js +10 -0
  170. package/dist/elements/nymbal-variant-selector.js.map +1 -0
  171. package/dist/form-element-C-qo3gpD.d.ts +25 -0
  172. package/dist/hydrate-support.d.ts +2 -0
  173. package/dist/hydrate-support.js +3 -0
  174. package/dist/hydrate-support.js.map +1 -0
  175. package/dist/index.d.ts +37 -105
  176. package/dist/index.js +130 -1098
  177. package/dist/index.js.map +1 -1
  178. package/dist/nymbal-payment-element-Bt8EF42T.d.ts +51 -0
  179. package/dist/nymbal-product-card-C8HkE_rG.d.ts +47 -0
  180. package/dist/register-components.d.ts +46 -0
  181. package/dist/register-components.js +48 -0
  182. package/dist/register-components.js.map +1 -0
  183. package/dist/selected-variant-Dym0shlJ.d.ts +23 -0
  184. package/dist/ssr/index.d.ts +30 -0
  185. package/dist/ssr/index.js +143 -0
  186. package/dist/ssr/index.js.map +1 -0
  187. package/package.json +33 -6
@@ -0,0 +1,19 @@
1
+ ---
2
+ // One Nymbal element rendered on the server: the tag with its attributes, its declarative shadow root, then the slot's
3
+ // content as its light DOM. The browser parses the template into the element's shadow root, and the element, once
4
+ // defined, takes that markup over. A project's own class under the tag renders instead when its elements entry
5
+ // registered it (registerServerElements).
6
+ import { renderElement } from '../dist/ssr/index.js'
7
+
8
+ interface Props {
9
+ tag: string
10
+ /** The host's attributes; a JSON attribute's value is its JSON text. */
11
+ attributes?: Record<string, string>
12
+ }
13
+
14
+ const { tag, attributes } = Astro.props
15
+ const children = Astro.slots.has('default') ? await Astro.slots.render('default') : ''
16
+ const html = renderElement(tag, { attributes, children })
17
+ ---
18
+
19
+ <Fragment set:html={html} />
@@ -0,0 +1,91 @@
1
+ import { LitElement, PropertyValues } from 'lit';
2
+ import { NymbalClient } from '@nymbalhq/sdk';
3
+
4
+ /** A Nymbal element class, as `define` takes it. */
5
+ interface NymbalElementClass extends CustomElementConstructor {
6
+ schema: ElementSchema;
7
+ /** The Nymbal elements it renders in its own shadow root, which must be defined for it to work. */
8
+ uses?: readonly NymbalElementClass[];
9
+ /** What the element needs registered before it runs; called whether or not its tag is still free. */
10
+ beforeDefine?(): void;
11
+ }
12
+ /**
13
+ * Defines each element under its schema's tag, with the elements it renders, except a tag that is already defined:
14
+ * an element the project defined first under a Nymbal tag wins.
15
+ */
16
+ declare function define(...elements: NymbalElementClass[]): void;
17
+
18
+ /** How an attribute's value reads: the React wrapper types its prop from this, and JSON travels stringified. */
19
+ type ElementAttributeType = 'string' | 'number' | 'boolean' | 'json';
20
+ /**
21
+ * An element's public interface, declared once on the class. Its Lit properties are derived from `attributes`, and the
22
+ * React wrappers are generated from it, so neither can disagree with the element.
23
+ */
24
+ interface ElementSchema {
25
+ tag: string;
26
+ /** The React wrapper's component name. */
27
+ reactName: string;
28
+ /** `name` is the HTML attribute, `prop` the React prop and the Lit property. */
29
+ attributes: Array<{
30
+ name: string;
31
+ prop: string;
32
+ type: ElementAttributeType;
33
+ }>;
34
+ /** `name` is the DOM event, `prop` the React handler, `detail` the TypeScript type of its detail. */
35
+ events: Array<{
36
+ name: string;
37
+ prop: string;
38
+ detail: string;
39
+ }>;
40
+ /** Every `part` the element renders, for `::part()` styling. */
41
+ parts: string[];
42
+ /** Every named `slot` it renders, each with its default content as the fallback. */
43
+ slots: string[];
44
+ /** Whether the React wrapper passes children through. */
45
+ children: boolean;
46
+ }
47
+ interface Subscribable {
48
+ subscribe(fn: () => void): () => void;
49
+ getState(): unknown;
50
+ }
51
+ declare abstract class NymbalElement extends LitElement {
52
+ static schema: ElementSchema;
53
+ /** Defines this element, and those it renders, unless its tag is already defined (see `define`). */
54
+ static define(this: NymbalElementClass): void;
55
+ private _unsubs;
56
+ /** Set while the element's first render takes over a server's shadow root (see `readsStores`). */
57
+ private _serverRender;
58
+ protected get client(): NymbalClient;
59
+ /** Whether a client is registered: never on a server. Without one the element subscribes to no store. */
60
+ protected get hasClient(): boolean;
61
+ /**
62
+ * Whether this render reads the client's stores. Not on a server, and not in the first render of an element taking
63
+ * over a server's shadow root: hydration needs the server's render (a store still loading would change it), so that
64
+ * render is the server's, and the element renders again from its stores straight after.
65
+ */
66
+ protected get readsStores(): boolean;
67
+ /** The SDK stores the element renders from; it re-renders on each change while connected. */
68
+ protected stores(): Subscribable[];
69
+ /**
70
+ * A store `stores()` named has settled (an update that is not `loading`): the properties a server rendered this
71
+ * element from give way to it. An update while loading leaves them showing, so a count does not flip to 0 and back.
72
+ */
73
+ protected storeSettled(_store: Subscribable): void;
74
+ connectedCallback(): void;
75
+ /**
76
+ * A store that settled before this element connected sends it no update, so the properties a server gave (a page
77
+ * restored from a router's cache after the cart changed elsewhere) give way to it here.
78
+ */
79
+ private takeSettledStores;
80
+ /**
81
+ * React inserts a soft navigation's server HTML with `innerHTML`, which leaves the declarative shadow root an unparsed
82
+ * template: it becomes this element's shadow root here, before Lit looks for one, so the element hydrates it rather
83
+ * than rendering a second. A parsed declarative shadow root (a full load) is already `shadowRoot`.
84
+ */
85
+ protected createRenderRoot(): HTMLElement | DocumentFragment;
86
+ protected update(changed: PropertyValues): void;
87
+ disconnectedCallback(): void;
88
+ }
89
+
90
+ export { NymbalElement as N, define as d };
91
+ export type { ElementAttributeType as E, Subscribable as S, ElementSchema as a, NymbalElementClass as b };
@@ -0,0 +1,155 @@
1
+ import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
2
+ import {
3
+ NymbalElement,
4
+ baseStyles,
5
+ propertiesOf
6
+ } from "./chunk-EYDMJNNK.js";
7
+
8
+ // src/components/toast.ts
9
+ import { css, html } from "lit";
10
+ import { repeat } from "lit/directives/repeat.js";
11
+ var SCHEMA = {
12
+ tag: "nymbal-toast",
13
+ reactName: "Toast",
14
+ attributes: [
15
+ { name: "position", prop: "position", type: "string" },
16
+ { name: "duration-ms", prop: "durationMs", type: "number" }
17
+ ],
18
+ events: [],
19
+ parts: ["item", "message", "close"],
20
+ slots: [],
21
+ children: false
22
+ };
23
+ var nextId = 0;
24
+ var NymbalToast = class extends NymbalElement {
25
+ static schema = SCHEMA;
26
+ static properties = propertiesOf(SCHEMA);
27
+ static styles = [
28
+ baseStyles,
29
+ css`
30
+ :host {
31
+ position: fixed;
32
+ z-index: var(--nymbal-z-toast, 300);
33
+ display: flex;
34
+ flex-direction: column;
35
+ gap: var(--nymbal-spacing-sm, 0.5rem);
36
+ pointer-events: none;
37
+ font-family: var(--nymbal-font-family, system-ui, -apple-system, sans-serif);
38
+ }
39
+ :host([position='top-right']),
40
+ :host(:not([position])) {
41
+ top: var(--nymbal-spacing-lg, 1.5rem);
42
+ right: var(--nymbal-spacing-lg, 1.5rem);
43
+ }
44
+ :host([position='top-left']) {
45
+ top: var(--nymbal-spacing-lg, 1.5rem);
46
+ left: var(--nymbal-spacing-lg, 1.5rem);
47
+ }
48
+ :host([position='bottom-right']) {
49
+ bottom: var(--nymbal-spacing-lg, 1.5rem);
50
+ right: var(--nymbal-spacing-lg, 1.5rem);
51
+ }
52
+ :host([position='bottom-left']) {
53
+ bottom: var(--nymbal-spacing-lg, 1.5rem);
54
+ left: var(--nymbal-spacing-lg, 1.5rem);
55
+ }
56
+ [part~='item'] {
57
+ pointer-events: auto;
58
+ display: flex;
59
+ align-items: center;
60
+ gap: var(--nymbal-spacing-sm, 0.5rem);
61
+ padding: var(--nymbal-spacing-sm, 0.5rem) var(--nymbal-spacing-md, 1rem);
62
+ border-radius: var(--nymbal-radius-md, 0.375rem);
63
+ box-shadow: var(--nymbal-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));
64
+ font-size: var(--nymbal-font-size-sm, 0.875rem);
65
+ background: var(--nymbal-color-surface, #ffffff);
66
+ color: var(--nymbal-color-text, #18181b);
67
+ border: 1px solid var(--nymbal-color-border, #e4e4e7);
68
+ animation: nymbal-toast-in var(--nymbal-transition-normal, 200ms ease) forwards;
69
+ max-width: 360px;
70
+ }
71
+ [part~='item'][data-type='success'] {
72
+ border-left: 3px solid var(--nymbal-color-success, #16a34a);
73
+ }
74
+ [part~='item'][data-type='error'] {
75
+ border-left: 3px solid var(--nymbal-color-error, #dc2626);
76
+ }
77
+ [part~='item'][data-type='warning'] {
78
+ border-left: 3px solid var(--nymbal-color-warning, #d97706);
79
+ }
80
+ [part~='item'][data-type='info'] {
81
+ border-left: 3px solid var(--nymbal-color-accent, #2563eb);
82
+ }
83
+ [part~='close'] {
84
+ background: none;
85
+ border: none;
86
+ cursor: pointer;
87
+ color: var(--nymbal-color-text-muted, #71717a);
88
+ font-size: var(--nymbal-font-size-base, 1rem);
89
+ padding: 0;
90
+ margin-left: auto;
91
+ }
92
+ @keyframes nymbal-toast-in {
93
+ from {
94
+ opacity: 0;
95
+ transform: translateY(-8px);
96
+ }
97
+ to {
98
+ opacity: 1;
99
+ transform: translateY(0);
100
+ }
101
+ }
102
+ `
103
+ ];
104
+ _items = [];
105
+ connectedCallback() {
106
+ super.connectedCallback();
107
+ this.setAttribute("data-testid", "toast");
108
+ }
109
+ show(message, type = "info") {
110
+ const durationMs = Number(this.getAttribute("duration-ms")) || 4e3;
111
+ const item = { id: ++nextId, message, type };
112
+ this._items = [...this._items, item];
113
+ this.requestUpdate();
114
+ setTimeout(() => this.dismiss(item.id), durationMs);
115
+ }
116
+ dismiss(id) {
117
+ const remaining = this._items.filter((i) => i.id !== id);
118
+ if (remaining.length === this._items.length) return;
119
+ this._items = remaining;
120
+ this.requestUpdate();
121
+ }
122
+ render() {
123
+ return repeat(
124
+ this._items,
125
+ (item) => item.id,
126
+ (item) => html`
127
+ <div part="item" class="nymbal-toast-item" data-type=${item.type} role="alert">
128
+ <span part="message">${item.message}</span>
129
+ <button
130
+ type="button"
131
+ part="close"
132
+ class="nymbal-toast-close"
133
+ aria-label="Dismiss"
134
+ @click=${() => this.dismiss(item.id)}
135
+ >
136
+ ×
137
+ </button>
138
+ </div>
139
+ `
140
+ );
141
+ }
142
+ static showGlobal(message, type = "info") {
143
+ let toastEl = document.querySelector("nymbal-toast");
144
+ if (!toastEl) {
145
+ toastEl = document.createElement("nymbal-toast");
146
+ document.body.appendChild(toastEl);
147
+ }
148
+ toastEl.show(message, type);
149
+ }
150
+ };
151
+
152
+ export {
153
+ NymbalToast
154
+ };
155
+ //# sourceMappingURL=chunk-2TPQNQYO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/toast.ts"],"sourcesContent":["import { css, html } from 'lit'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { baseStyles, NymbalElement, propertiesOf, type ElementSchema } from '../base-element.js'\n\ntype ToastType = 'success' | 'error' | 'warning' | 'info'\n\ninterface ToastItem {\n id: number\n message: string\n type: ToastType\n}\n\nconst SCHEMA: ElementSchema = {\n tag: 'nymbal-toast',\n reactName: 'Toast',\n attributes: [\n { name: 'position', prop: 'position', type: 'string' },\n { name: 'duration-ms', prop: 'durationMs', type: 'number' },\n ],\n events: [],\n parts: ['item', 'message', 'close'],\n slots: [],\n children: false,\n}\n\nlet nextId = 0\n\nexport class NymbalToast extends NymbalElement {\n static override schema = SCHEMA\n static override properties = propertiesOf(SCHEMA)\n\n static override styles = [\n baseStyles,\n css`\n :host {\n position: fixed;\n z-index: var(--nymbal-z-toast, 300);\n display: flex;\n flex-direction: column;\n gap: var(--nymbal-spacing-sm, 0.5rem);\n pointer-events: none;\n font-family: var(--nymbal-font-family, system-ui, -apple-system, sans-serif);\n }\n :host([position='top-right']),\n :host(:not([position])) {\n top: var(--nymbal-spacing-lg, 1.5rem);\n right: var(--nymbal-spacing-lg, 1.5rem);\n }\n :host([position='top-left']) {\n top: var(--nymbal-spacing-lg, 1.5rem);\n left: var(--nymbal-spacing-lg, 1.5rem);\n }\n :host([position='bottom-right']) {\n bottom: var(--nymbal-spacing-lg, 1.5rem);\n right: var(--nymbal-spacing-lg, 1.5rem);\n }\n :host([position='bottom-left']) {\n bottom: var(--nymbal-spacing-lg, 1.5rem);\n left: var(--nymbal-spacing-lg, 1.5rem);\n }\n [part~='item'] {\n pointer-events: auto;\n display: flex;\n align-items: center;\n gap: var(--nymbal-spacing-sm, 0.5rem);\n padding: var(--nymbal-spacing-sm, 0.5rem) var(--nymbal-spacing-md, 1rem);\n border-radius: var(--nymbal-radius-md, 0.375rem);\n box-shadow: var(--nymbal-shadow-lg, 0 10px 15px rgba(0, 0, 0, 0.1));\n font-size: var(--nymbal-font-size-sm, 0.875rem);\n background: var(--nymbal-color-surface, #ffffff);\n color: var(--nymbal-color-text, #18181b);\n border: 1px solid var(--nymbal-color-border, #e4e4e7);\n animation: nymbal-toast-in var(--nymbal-transition-normal, 200ms ease) forwards;\n max-width: 360px;\n }\n [part~='item'][data-type='success'] {\n border-left: 3px solid var(--nymbal-color-success, #16a34a);\n }\n [part~='item'][data-type='error'] {\n border-left: 3px solid var(--nymbal-color-error, #dc2626);\n }\n [part~='item'][data-type='warning'] {\n border-left: 3px solid var(--nymbal-color-warning, #d97706);\n }\n [part~='item'][data-type='info'] {\n border-left: 3px solid var(--nymbal-color-accent, #2563eb);\n }\n [part~='close'] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--nymbal-color-text-muted, #71717a);\n font-size: var(--nymbal-font-size-base, 1rem);\n padding: 0;\n margin-left: auto;\n }\n @keyframes nymbal-toast-in {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n `,\n ]\n\n private _items: ToastItem[] = []\n\n override connectedCallback(): void {\n super.connectedCallback()\n this.setAttribute('data-testid', 'toast')\n }\n\n show(message: string, type: ToastType = 'info'): void {\n const durationMs = Number(this.getAttribute('duration-ms')) || 4000\n const item: ToastItem = { id: ++nextId, message, type }\n this._items = [...this._items, item]\n this.requestUpdate()\n setTimeout(() => this.dismiss(item.id), durationMs)\n }\n\n private dismiss(id: number): void {\n const remaining = this._items.filter((i) => i.id !== id)\n if (remaining.length === this._items.length) return\n this._items = remaining\n this.requestUpdate()\n }\n\n protected override render() {\n return repeat(\n this._items,\n (item) => item.id,\n (item) => html`\n <div part=\"item\" class=\"nymbal-toast-item\" data-type=${item.type} role=\"alert\">\n <span part=\"message\">${item.message}</span>\n <button\n type=\"button\"\n part=\"close\"\n class=\"nymbal-toast-close\"\n aria-label=\"Dismiss\"\n @click=${() => this.dismiss(item.id)}\n >\n ×\n </button>\n </div>\n `,\n )\n }\n\n static showGlobal(message: string, type: ToastType = 'info'): void {\n let toastEl = document.querySelector('nymbal-toast') as NymbalToast | null\n if (!toastEl) {\n toastEl = document.createElement('nymbal-toast') as NymbalToast\n document.body.appendChild(toastEl)\n }\n toastEl.show(message, type)\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,KAAK,YAAY;AAC1B,SAAS,cAAc;AAWvB,IAAM,SAAwB;AAAA,EAC5B,KAAK;AAAA,EACL,WAAW;AAAA,EACX,YAAY;AAAA,IACV,EAAE,MAAM,YAAY,MAAM,YAAY,MAAM,SAAS;AAAA,IACrD,EAAE,MAAM,eAAe,MAAM,cAAc,MAAM,SAAS;AAAA,EAC5D;AAAA,EACA,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC,QAAQ,WAAW,OAAO;AAAA,EAClC,OAAO,CAAC;AAAA,EACR,UAAU;AACZ;AAEA,IAAI,SAAS;AAEN,IAAM,cAAN,cAA0B,cAAc;AAAA,EAC7C,OAAgB,SAAS;AAAA,EACzB,OAAgB,aAAa,aAAa,MAAM;AAAA,EAEhD,OAAgB,SAAS;AAAA,IACvB;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0EF;AAAA,EAEQ,SAAsB,CAAC;AAAA,EAEtB,oBAA0B;AACjC,UAAM,kBAAkB;AACxB,SAAK,aAAa,eAAe,OAAO;AAAA,EAC1C;AAAA,EAEA,KAAK,SAAiB,OAAkB,QAAc;AACpD,UAAM,aAAa,OAAO,KAAK,aAAa,aAAa,CAAC,KAAK;AAC/D,UAAM,OAAkB,EAAE,IAAI,EAAE,QAAQ,SAAS,KAAK;AACtD,SAAK,SAAS,CAAC,GAAG,KAAK,QAAQ,IAAI;AACnC,SAAK,cAAc;AACnB,eAAW,MAAM,KAAK,QAAQ,KAAK,EAAE,GAAG,UAAU;AAAA,EACpD;AAAA,EAEQ,QAAQ,IAAkB;AAChC,UAAM,YAAY,KAAK,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACvD,QAAI,UAAU,WAAW,KAAK,OAAO,OAAQ;AAC7C,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACrB;AAAA,EAEmB,SAAS;AAC1B,WAAO;AAAA,MACL,KAAK;AAAA,MACL,CAAC,SAAS,KAAK;AAAA,MACf,CAAC,SAAS;AAAA,+DAC+C,KAAK,IAAI;AAAA,iCACvC,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMxB,MAAM,KAAK,QAAQ,KAAK,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM5C;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,SAAiB,OAAkB,QAAc;AACjE,QAAI,UAAU,SAAS,cAAc,cAAc;AACnD,QAAI,CAAC,SAAS;AACZ,gBAAU,SAAS,cAAc,cAAc;AAC/C,eAAS,KAAK,YAAY,OAAO;AAAA,IACnC;AACA,YAAQ,KAAK,SAAS,IAAI;AAAA,EAC5B;AACF;","names":[]}
@@ -0,0 +1,113 @@
1
+ import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
2
+ import {
3
+ NymbalElement,
4
+ baseStyles,
5
+ propertiesOf
6
+ } from "./chunk-EYDMJNNK.js";
7
+
8
+ // src/components/mini-cart.ts
9
+ import { css, html, nothing } from "lit";
10
+ var SCHEMA = {
11
+ tag: "nymbal-mini-cart",
12
+ reactName: "MiniCart",
13
+ // The cart's item count a server read, shown until the cart store settles.
14
+ attributes: [{ name: "count", prop: "count", type: "number" }],
15
+ events: [{ name: "nymbal:mini-cart:clicked", prop: "onClick", detail: "void" }],
16
+ parts: ["button", "icon", "badge"],
17
+ slots: ["icon"],
18
+ children: false
19
+ };
20
+ var NymbalMiniCart = class extends NymbalElement {
21
+ static schema = SCHEMA;
22
+ static properties = propertiesOf(SCHEMA);
23
+ static styles = [
24
+ baseStyles,
25
+ css`
26
+ :host {
27
+ display: inline-block;
28
+ position: relative;
29
+ }
30
+ [part~='button'] {
31
+ background: none;
32
+ border: none;
33
+ cursor: pointer;
34
+ position: relative;
35
+ padding: var(--nymbal-spacing-sm, 0.5rem);
36
+ font-family: var(--nymbal-font-family, system-ui, -apple-system, sans-serif);
37
+ color: var(--nymbal-color-text, #18181b);
38
+ }
39
+ [part~='icon'] {
40
+ display: block;
41
+ width: 24px;
42
+ height: 24px;
43
+ }
44
+ [part~='badge'] {
45
+ position: absolute;
46
+ top: 0;
47
+ right: 0;
48
+ background: var(--nymbal-color-accent, #2563eb);
49
+ color: var(--nymbal-color-text-inverse, #ffffff);
50
+ font-size: var(--nymbal-font-size-xs, 0.75rem);
51
+ font-weight: var(--nymbal-font-weight-bold, 700);
52
+ min-width: 18px;
53
+ height: 18px;
54
+ border-radius: var(--nymbal-radius-full, 9999px);
55
+ display: flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ line-height: 1;
59
+ }
60
+ [part~='badge']:empty {
61
+ display: none;
62
+ }
63
+ `
64
+ ];
65
+ stores() {
66
+ return [this.client.cart];
67
+ }
68
+ storeSettled() {
69
+ this.count = void 0;
70
+ }
71
+ itemCount() {
72
+ if (typeof this.count === "number" && Number.isFinite(this.count)) return this.count;
73
+ return this.readsStores ? this.client.cart.getState().itemCount : 0;
74
+ }
75
+ render() {
76
+ const itemCount = this.itemCount();
77
+ return html`<button
78
+ type="button"
79
+ part="button"
80
+ data-testid="mini-cart"
81
+ aria-label="Cart (${itemCount} items)"
82
+ @click=${this.handleClick}
83
+ >
84
+ <slot name="icon"
85
+ ><svg
86
+ part="icon"
87
+ viewBox="0 0 24 24"
88
+ fill="none"
89
+ stroke="currentColor"
90
+ stroke-width="2"
91
+ stroke-linecap="round"
92
+ stroke-linejoin="round"
93
+ >
94
+ <circle cx="9" cy="21" r="1" />
95
+ <circle cx="20" cy="21" r="1" />
96
+ <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" /></svg
97
+ ></slot>
98
+ <span part="badge" class="nymbal-mini-cart-badge" data-testid="mini-cart-badge"
99
+ >${itemCount > 0 ? itemCount : nothing}</span
100
+ >
101
+ </button>`;
102
+ }
103
+ handleClick = () => {
104
+ this.dispatchEvent(
105
+ new CustomEvent("nymbal:mini-cart:clicked", { bubbles: true, composed: true })
106
+ );
107
+ };
108
+ };
109
+
110
+ export {
111
+ NymbalMiniCart
112
+ };
113
+ //# sourceMappingURL=chunk-2XXBQPDB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/mini-cart.ts"],"sourcesContent":["import { css, html, nothing } from 'lit'\nimport { baseStyles, NymbalElement, propertiesOf, type ElementSchema } from '../base-element.js'\n\nconst SCHEMA: ElementSchema = {\n tag: 'nymbal-mini-cart',\n reactName: 'MiniCart',\n // The cart's item count a server read, shown until the cart store settles.\n attributes: [{ name: 'count', prop: 'count', type: 'number' }],\n events: [{ name: 'nymbal:mini-cart:clicked', prop: 'onClick', detail: 'void' }],\n parts: ['button', 'icon', 'badge'],\n slots: ['icon'],\n children: false,\n}\n\nexport class NymbalMiniCart extends NymbalElement {\n static override schema = SCHEMA\n static override properties = propertiesOf(SCHEMA)\n\n static override styles = [\n baseStyles,\n css`\n :host {\n display: inline-block;\n position: relative;\n }\n [part~='button'] {\n background: none;\n border: none;\n cursor: pointer;\n position: relative;\n padding: var(--nymbal-spacing-sm, 0.5rem);\n font-family: var(--nymbal-font-family, system-ui, -apple-system, sans-serif);\n color: var(--nymbal-color-text, #18181b);\n }\n [part~='icon'] {\n display: block;\n width: 24px;\n height: 24px;\n }\n [part~='badge'] {\n position: absolute;\n top: 0;\n right: 0;\n background: var(--nymbal-color-accent, #2563eb);\n color: var(--nymbal-color-text-inverse, #ffffff);\n font-size: var(--nymbal-font-size-xs, 0.75rem);\n font-weight: var(--nymbal-font-weight-bold, 700);\n min-width: 18px;\n height: 18px;\n border-radius: var(--nymbal-radius-full, 9999px);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n }\n [part~='badge']:empty {\n display: none;\n }\n `,\n ]\n\n declare count: number | undefined\n\n protected override stores() {\n return [this.client.cart]\n }\n\n protected override storeSettled(): void {\n this.count = undefined\n }\n\n private itemCount(): number {\n if (typeof this.count === 'number' && Number.isFinite(this.count)) return this.count\n return this.readsStores ? this.client.cart.getState().itemCount : 0\n }\n\n protected override render() {\n const itemCount = this.itemCount()\n // An empty badge is `nothing`, not '': Lit's hydration records a server-rendered '' as a committed text node the\n // server never wrote, so the first count after it (a header mounted once the cart has loaded) lands in the part's\n // end marker and the badge stays empty.\n return html`<button\n type=\"button\"\n part=\"button\"\n data-testid=\"mini-cart\"\n aria-label=\"Cart (${itemCount} items)\"\n @click=${this.handleClick}\n >\n <slot name=\"icon\"\n ><svg\n part=\"icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"9\" cy=\"21\" r=\"1\" />\n <circle cx=\"20\" cy=\"21\" r=\"1\" />\n <path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\" /></svg\n ></slot>\n <span part=\"badge\" class=\"nymbal-mini-cart-badge\" data-testid=\"mini-cart-badge\"\n >${itemCount > 0 ? itemCount : nothing}</span\n >\n </button>`\n }\n\n private handleClick = (): void => {\n this.dispatchEvent(\n new CustomEvent('nymbal:mini-cart:clicked', { bubbles: true, composed: true }),\n )\n }\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,KAAK,MAAM,eAAe;AAGnC,IAAM,SAAwB;AAAA,EAC5B,KAAK;AAAA,EACL,WAAW;AAAA;AAAA,EAEX,YAAY,CAAC,EAAE,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC;AAAA,EAC7D,QAAQ,CAAC,EAAE,MAAM,4BAA4B,MAAM,WAAW,QAAQ,OAAO,CAAC;AAAA,EAC9E,OAAO,CAAC,UAAU,QAAQ,OAAO;AAAA,EACjC,OAAO,CAAC,MAAM;AAAA,EACd,UAAU;AACZ;AAEO,IAAM,iBAAN,cAA6B,cAAc;AAAA,EAChD,OAAgB,SAAS;AAAA,EACzB,OAAgB,aAAa,aAAa,MAAM;AAAA,EAEhD,OAAgB,SAAS;AAAA,IACvB;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCF;AAAA,EAImB,SAAS;AAC1B,WAAO,CAAC,KAAK,OAAO,IAAI;AAAA,EAC1B;AAAA,EAEmB,eAAqB;AACtC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEQ,YAAoB;AAC1B,QAAI,OAAO,KAAK,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,EAAG,QAAO,KAAK;AAC/E,WAAO,KAAK,cAAc,KAAK,OAAO,KAAK,SAAS,EAAE,YAAY;AAAA,EACpE;AAAA,EAEmB,SAAS;AAC1B,UAAM,YAAY,KAAK,UAAU;AAIjC,WAAO;AAAA;AAAA;AAAA;AAAA,0BAIe,SAAS;AAAA,eACpB,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAiBpB,YAAY,IAAI,YAAY,OAAO;AAAA;AAAA;AAAA,EAG5C;AAAA,EAEQ,cAAc,MAAY;AAChC,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B,EAAE,SAAS,MAAM,UAAU,KAAK,CAAC;AAAA,IAC/E;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,84 @@
1
+ import '@lit-labs/ssr-client/lit-element-hydrate-support.js'
2
+ import {
3
+ NymbalFormElement,
4
+ renderField
5
+ } from "./chunk-PN6QKYE4.js";
6
+ import {
7
+ buttonStyles,
8
+ fieldStyles
9
+ } from "./chunk-GHXTJ2CF.js";
10
+ import {
11
+ baseStyles,
12
+ propertiesOf
13
+ } from "./chunk-EYDMJNNK.js";
14
+
15
+ // src/components/login-form.ts
16
+ import { html } from "lit";
17
+ var SCHEMA = {
18
+ tag: "nymbal-login-form",
19
+ reactName: "LoginForm",
20
+ attributes: [],
21
+ events: [
22
+ {
23
+ name: "nymbal:auth:signed-in",
24
+ prop: "onSignedIn",
25
+ detail: "{ customer: unknown }"
26
+ }
27
+ ],
28
+ parts: ["form", "field", "label", "input", "error", "submit"],
29
+ slots: ["submit-label"],
30
+ children: false
31
+ };
32
+ var NymbalLoginForm = class extends NymbalFormElement {
33
+ static schema = SCHEMA;
34
+ static properties = propertiesOf(SCHEMA);
35
+ static styles = [baseStyles, buttonStyles, fieldStyles];
36
+ // The page leaves on success; a second sign-in while it does would only race the redirect.
37
+ lockOnSuccess = true;
38
+ async send() {
39
+ await this.client.auth.login(this.value("email"), this.value("password"));
40
+ this.emit("nymbal:auth:signed-in", { customer: this.client.auth.getState().customer });
41
+ }
42
+ failureText(err) {
43
+ return err instanceof Error && err.message !== "" ? err.message : "Invalid email or password.";
44
+ }
45
+ render() {
46
+ return html`
47
+ ${this.renderError()}
48
+ <form part="form" data-testid="login-form" @submit=${this.onSubmit}>
49
+ ${renderField({
50
+ id: "login-email",
51
+ name: "email",
52
+ label: "Email",
53
+ type: "email",
54
+ autocomplete: "email",
55
+ required: true,
56
+ placeholder: "you@example.com"
57
+ })}
58
+ ${renderField({
59
+ id: "login-password",
60
+ name: "password",
61
+ label: "Password",
62
+ type: "password",
63
+ autocomplete: "current-password",
64
+ required: true,
65
+ placeholder: "Your password"
66
+ })}
67
+ <button
68
+ type="submit"
69
+ part="submit"
70
+ class="btn btn-primary"
71
+ data-testid="login-submit"
72
+ ?disabled=${this.pending}
73
+ >
74
+ ${this.pending ? "Signing in..." : html`<slot name="submit-label">Sign In</slot>`}
75
+ </button>
76
+ </form>
77
+ `;
78
+ }
79
+ };
80
+
81
+ export {
82
+ NymbalLoginForm
83
+ };
84
+ //# sourceMappingURL=chunk-42SSME5H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/login-form.ts"],"sourcesContent":["import { html } from 'lit'\nimport { baseStyles, propertiesOf, type ElementSchema } from '../base-element.js'\nimport { NymbalFormElement, renderField } from '../form-element.js'\nimport { buttonStyles, fieldStyles } from '../view-styles.js'\n\nconst SCHEMA: ElementSchema = {\n tag: 'nymbal-login-form',\n reactName: 'LoginForm',\n attributes: [],\n events: [\n {\n name: 'nymbal:auth:signed-in',\n prop: 'onSignedIn',\n detail: '{ customer: unknown }',\n },\n ],\n parts: ['form', 'field', 'label', 'input', 'error', 'submit'],\n slots: ['submit-label'],\n children: false,\n}\n\n/** Signs the shopper in; the page decides where they go next (`nymbal:auth:signed-in`). */\nexport class NymbalLoginForm extends NymbalFormElement {\n static override schema = SCHEMA\n static override properties = propertiesOf(SCHEMA)\n static override styles = [baseStyles, buttonStyles, fieldStyles]\n\n // The page leaves on success; a second sign-in while it does would only race the redirect.\n protected override readonly lockOnSuccess = true\n\n protected override async send(): Promise<void> {\n await this.client.auth.login(this.value('email'), this.value('password'))\n this.emit('nymbal:auth:signed-in', { customer: this.client.auth.getState().customer })\n }\n\n protected override failureText(err: unknown): string {\n return err instanceof Error && err.message !== '' ? err.message : 'Invalid email or password.'\n }\n\n protected override render() {\n return html`\n ${this.renderError()}\n <form part=\"form\" data-testid=\"login-form\" @submit=${this.onSubmit}>\n ${renderField({\n id: 'login-email',\n name: 'email',\n label: 'Email',\n type: 'email',\n autocomplete: 'email',\n required: true,\n placeholder: 'you@example.com',\n })}\n ${renderField({\n id: 'login-password',\n name: 'password',\n label: 'Password',\n type: 'password',\n autocomplete: 'current-password',\n required: true,\n placeholder: 'Your password',\n })}\n <button\n type=\"submit\"\n part=\"submit\"\n class=\"btn btn-primary\"\n data-testid=\"login-submit\"\n ?disabled=${this.pending}\n >\n ${this.pending ? 'Signing in...' : html`<slot name=\"submit-label\">Sign In</slot>`}\n </button>\n </form>\n `\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,YAAY;AAKrB,IAAM,SAAwB;AAAA,EAC5B,KAAK;AAAA,EACL,WAAW;AAAA,EACX,YAAY,CAAC;AAAA,EACb,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,OAAO,CAAC,QAAQ,SAAS,SAAS,SAAS,SAAS,QAAQ;AAAA,EAC5D,OAAO,CAAC,cAAc;AAAA,EACtB,UAAU;AACZ;AAGO,IAAM,kBAAN,cAA8B,kBAAkB;AAAA,EACrD,OAAgB,SAAS;AAAA,EACzB,OAAgB,aAAa,aAAa,MAAM;AAAA,EAChD,OAAgB,SAAS,CAAC,YAAY,cAAc,WAAW;AAAA;AAAA,EAGnC,gBAAgB;AAAA,EAE5C,MAAyB,OAAsB;AAC7C,UAAM,KAAK,OAAO,KAAK,MAAM,KAAK,MAAM,OAAO,GAAG,KAAK,MAAM,UAAU,CAAC;AACxE,SAAK,KAAK,yBAAyB,EAAE,UAAU,KAAK,OAAO,KAAK,SAAS,EAAE,SAAS,CAAC;AAAA,EACvF;AAAA,EAEmB,YAAY,KAAsB;AACnD,WAAO,eAAe,SAAS,IAAI,YAAY,KAAK,IAAI,UAAU;AAAA,EACpE;AAAA,EAEmB,SAAS;AAC1B,WAAO;AAAA,QACH,KAAK,YAAY,CAAC;AAAA,2DACiC,KAAK,QAAQ;AAAA,UAC9D,YAAY;AAAA,MACZ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,MACN,cAAc;AAAA,MACd,UAAU;AAAA,MACV,aAAa;AAAA,IACf,CAAC,CAAC;AAAA,UACA,YAAY;AAAA,MACZ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,MACN,cAAc;AAAA,MACd,UAAU;AAAA,MACV,aAAa;AAAA,IACf,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAMY,KAAK,OAAO;AAAA;AAAA,YAEtB,KAAK,UAAU,kBAAkB,8CAA8C;AAAA;AAAA;AAAA;AAAA,EAIzF;AACF;","names":[]}