@quieto/ui 0.0.0-stage → 0.1.1

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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -2
  3. package/custom-elements.json +6121 -0
  4. package/dist/components/qds-accordion/qds-accordion.d.ts +39 -0
  5. package/dist/components/qds-accordion/qds-accordion.d.ts.map +1 -0
  6. package/dist/components/qds-accordion/qds-accordion.js +130 -0
  7. package/dist/components/qds-accordion/qds-accordion.js.map +1 -0
  8. package/dist/components/qds-accordion-item/qds-accordion-item.d.ts +68 -0
  9. package/dist/components/qds-accordion-item/qds-accordion-item.d.ts.map +1 -0
  10. package/dist/components/qds-accordion-item/qds-accordion-item.js +250 -0
  11. package/dist/components/qds-accordion-item/qds-accordion-item.js.map +1 -0
  12. package/dist/components/qds-button/qds-button.d.ts +92 -0
  13. package/dist/components/qds-button/qds-button.d.ts.map +1 -0
  14. package/dist/components/qds-button/qds-button.js +418 -0
  15. package/dist/components/qds-button/qds-button.js.map +1 -0
  16. package/dist/components/qds-card/qds-card.d.ts +48 -0
  17. package/dist/components/qds-card/qds-card.d.ts.map +1 -0
  18. package/dist/components/qds-card/qds-card.js +152 -0
  19. package/dist/components/qds-card/qds-card.js.map +1 -0
  20. package/dist/components/qds-checkbox/qds-checkbox.d.ts +85 -0
  21. package/dist/components/qds-checkbox/qds-checkbox.d.ts.map +1 -0
  22. package/dist/components/qds-checkbox/qds-checkbox.js +316 -0
  23. package/dist/components/qds-checkbox/qds-checkbox.js.map +1 -0
  24. package/dist/components/qds-chip/qds-chip.d.ts +79 -0
  25. package/dist/components/qds-chip/qds-chip.d.ts.map +1 -0
  26. package/dist/components/qds-chip/qds-chip.js +314 -0
  27. package/dist/components/qds-chip/qds-chip.js.map +1 -0
  28. package/dist/components/qds-input/qds-input.d.ts +64 -0
  29. package/dist/components/qds-input/qds-input.d.ts.map +1 -0
  30. package/dist/components/qds-input/qds-input.js +224 -0
  31. package/dist/components/qds-input/qds-input.js.map +1 -0
  32. package/dist/components/qds-modal/qds-modal.d.ts +76 -0
  33. package/dist/components/qds-modal/qds-modal.d.ts.map +1 -0
  34. package/dist/components/qds-modal/qds-modal.js +362 -0
  35. package/dist/components/qds-modal/qds-modal.js.map +1 -0
  36. package/dist/components/qds-progress-bar/qds-progress-bar.d.ts +47 -0
  37. package/dist/components/qds-progress-bar/qds-progress-bar.d.ts.map +1 -0
  38. package/dist/components/qds-progress-bar/qds-progress-bar.js +180 -0
  39. package/dist/components/qds-progress-bar/qds-progress-bar.js.map +1 -0
  40. package/dist/components/qds-radio/qds-radio.d.ts +62 -0
  41. package/dist/components/qds-radio/qds-radio.d.ts.map +1 -0
  42. package/dist/components/qds-radio/qds-radio.js +213 -0
  43. package/dist/components/qds-radio/qds-radio.js.map +1 -0
  44. package/dist/components/qds-radio-group/qds-radio-group.d.ts +72 -0
  45. package/dist/components/qds-radio-group/qds-radio-group.d.ts.map +1 -0
  46. package/dist/components/qds-radio-group/qds-radio-group.js +317 -0
  47. package/dist/components/qds-radio-group/qds-radio-group.js.map +1 -0
  48. package/dist/components/qds-stack/qds-stack.d.ts +46 -0
  49. package/dist/components/qds-stack/qds-stack.d.ts.map +1 -0
  50. package/dist/components/qds-stack/qds-stack.js +149 -0
  51. package/dist/components/qds-stack/qds-stack.js.map +1 -0
  52. package/dist/components/qds-tab/qds-tab.d.ts +55 -0
  53. package/dist/components/qds-tab/qds-tab.d.ts.map +1 -0
  54. package/dist/components/qds-tab/qds-tab.js +162 -0
  55. package/dist/components/qds-tab/qds-tab.js.map +1 -0
  56. package/dist/components/qds-tab-panel/qds-tab-panel.d.ts +32 -0
  57. package/dist/components/qds-tab-panel/qds-tab-panel.d.ts.map +1 -0
  58. package/dist/components/qds-tab-panel/qds-tab-panel.js +72 -0
  59. package/dist/components/qds-tab-panel/qds-tab-panel.js.map +1 -0
  60. package/dist/components/qds-tabs/qds-tabs.d.ts +54 -0
  61. package/dist/components/qds-tabs/qds-tabs.d.ts.map +1 -0
  62. package/dist/components/qds-tabs/qds-tabs.js +196 -0
  63. package/dist/components/qds-tabs/qds-tabs.js.map +1 -0
  64. package/dist/components/qds-text-field/qds-text-field.d.ts +94 -0
  65. package/dist/components/qds-text-field/qds-text-field.d.ts.map +1 -0
  66. package/dist/components/qds-text-field/qds-text-field.js +332 -0
  67. package/dist/components/qds-text-field/qds-text-field.js.map +1 -0
  68. package/dist/components/qds-toggle/qds-toggle.d.ts +68 -0
  69. package/dist/components/qds-toggle/qds-toggle.d.ts.map +1 -0
  70. package/dist/components/qds-toggle/qds-toggle.js +260 -0
  71. package/dist/components/qds-toggle/qds-toggle.js.map +1 -0
  72. package/dist/index.d.ts +50 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +40 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/internal/qds-element.d.ts +31 -0
  77. package/dist/internal/qds-element.d.ts.map +1 -0
  78. package/dist/internal/qds-element.js +68 -0
  79. package/dist/internal/qds-element.js.map +1 -0
  80. package/dist/internal/qds-text-control.d.ts +79 -0
  81. package/dist/internal/qds-text-control.d.ts.map +1 -0
  82. package/dist/internal/qds-text-control.js +159 -0
  83. package/dist/internal/qds-text-control.js.map +1 -0
  84. package/package.json +125 -3
@@ -0,0 +1,418 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { css, html, nothing } from 'lit';
8
+ import { customElement, property } from 'lit/decorators.js';
9
+ import { QdsElement } from '../../internal/qds-element.js';
10
+ /**
11
+ * A button.
12
+ *
13
+ * Every visual property resolves through the component tier of the token system,
14
+ * so `--qds-component-button-*` is simultaneously the token API and the styling
15
+ * API — overriding one of those variables is the supported way to restyle a
16
+ * button, and it is the same variable the design tokens define.
17
+ *
18
+ * When it submits a form, `event.submitter` is not the `qds-button` itself: a
19
+ * custom element cannot be a submitter, so it submits through a temporary native
20
+ * button carrying its `name` and `value`, which exists only while the submit
21
+ * event is being dispatched. Read `event.submitter.value` (or
22
+ * `new FormData(form, event.submitter)`) inside the submit handler, and give
23
+ * buttons distinct values to tell them apart.
24
+ *
25
+ * @element qds-button
26
+ *
27
+ * @slot - The button label.
28
+ * @slot start - Content before the label, typically an icon.
29
+ * @slot end - Content after the label, typically an icon.
30
+ *
31
+ * @fires {CustomEvent<void>} qds-click - Fired on activation. Not fired when
32
+ * disabled or loading. Prefer this over listening for `click`, which a disabled
33
+ * host can still receive.
34
+ *
35
+ * @csspart button - The native button element.
36
+ * @csspart label - The wrapper around the default slot.
37
+ *
38
+ * @cssprop [--qds-component-button-border-radius] - Corner radius.
39
+ * @cssprop [--qds-component-button-border-width] - Border thickness.
40
+ * @cssprop [--qds-component-button-font-weight] - Label weight.
41
+ * @cssprop [--qds-component-button-duration] - State transition duration.
42
+ * @cssprop [--qds-component-button-{variant}-color-background-{state}] - Background per variant and state.
43
+ * @cssprop [--qds-component-button-{variant}-color-content-{state}] - Label color per variant and state.
44
+ * @cssprop [--qds-component-button-{variant}-color-border-{state}] - Border color per variant and state.
45
+ * @cssprop [--qds-component-button-{size}-padding-block] - Vertical padding per size.
46
+ * @cssprop [--qds-component-button-{size}-padding-inline] - Horizontal padding per size.
47
+ */
48
+ let QdsButton = class QdsButton extends QdsElement {
49
+ /**
50
+ * `delegatesFocus` makes the host focusable by forwarding focus to the inner
51
+ * button, so `qds-button.focus()` and tab order behave like a native button
52
+ * without the host needing its own tabindex.
53
+ */
54
+ static { this.shadowRootOptions = {
55
+ ...QdsElement.shadowRootOptions,
56
+ delegatesFocus: true,
57
+ }; }
58
+ /**
59
+ * Form association is what lets a button inside shadow DOM submit the form
60
+ * around it. `attachInternals().form` finds the containing form across the
61
+ * shadow boundary, which `HTMLFormElement`'s own logic cannot do — a plain
62
+ * shadow-DOM button silently fails to submit.
63
+ */
64
+ static { this.formAssociated = true; }
65
+ static { this.styles = [
66
+ QdsElement.baseStyles,
67
+ css `
68
+ /*
69
+ * Variant and size resolve to private custom properties here, because CSS
70
+ * cannot interpolate an attribute value into a variable name — there is no
71
+ * way to write var(--qds-component-button-{variant}-…). Each variant block
72
+ * remaps the same eight private properties, and the button rules below are
73
+ * written once against those.
74
+ *
75
+ * Fallbacks are second values inside var(), so the component still renders
76
+ * sensibly if a consumer forgets to load @quieto/design-tokens/css.
77
+ */
78
+ :host {
79
+ display: inline-block;
80
+
81
+ --_bg: var(--qds-component-button-primary-color-background-rest, #2563eb);
82
+ --_bg-hover: var(--qds-component-button-primary-color-background-hover, #1d4ed8);
83
+ --_bg-active: var(--qds-component-button-primary-color-background-active, #1e40af);
84
+ --_bg-disabled: var(--qds-component-button-primary-color-background-disabled, #e2e8f0);
85
+ --_fg: var(--qds-component-button-primary-color-content-rest, #f8fafc);
86
+ --_fg-disabled: var(--qds-component-button-primary-color-content-disabled, #64748b);
87
+ --_border: var(--qds-component-button-primary-color-border-rest, transparent);
88
+ --_border-disabled: var(--qds-component-button-primary-color-border-disabled, transparent);
89
+
90
+ --_padding-block: var(--qds-component-button-md-padding-block, 0.5rem);
91
+ --_padding-inline: var(--qds-component-button-md-padding-inline, 1rem);
92
+ --_gap: var(--qds-component-button-md-gap, 0.5rem);
93
+ --_font-size: var(--qds-component-button-md-font-size, 0.875rem);
94
+ }
95
+
96
+ :host([variant='secondary']) {
97
+ --_bg: var(--qds-component-button-secondary-color-background-rest, #f1f5f9);
98
+ --_bg-hover: var(--qds-component-button-secondary-color-background-hover, #e2e8f0);
99
+ --_bg-active: var(--qds-component-button-secondary-color-background-active, #cbd5e1);
100
+ --_bg-disabled: var(--qds-component-button-secondary-color-background-disabled, #f1f5f9);
101
+ --_fg: var(--qds-component-button-secondary-color-content-rest, #0f172a);
102
+ --_fg-disabled: var(--qds-component-button-secondary-color-content-disabled, #64748b);
103
+ --_border: var(--qds-component-button-secondary-color-border-rest, #cbd5e1);
104
+ --_border-disabled: var(--qds-component-button-secondary-color-border-disabled, #e2e8f0);
105
+ }
106
+
107
+ :host([variant='ghost']) {
108
+ --_bg: var(--qds-component-button-ghost-color-background-rest, transparent);
109
+ --_bg-hover: var(--qds-component-button-ghost-color-background-hover, #e2e8f0);
110
+ --_bg-active: var(--qds-component-button-ghost-color-background-active, #cbd5e1);
111
+ --_bg-disabled: var(--qds-component-button-ghost-color-background-disabled, transparent);
112
+ --_fg: var(--qds-component-button-ghost-color-content-rest, #1d4ed8);
113
+ --_fg-disabled: var(--qds-component-button-ghost-color-content-disabled, #94a3b8);
114
+ --_border: var(--qds-component-button-ghost-color-border-rest, transparent);
115
+ --_border-disabled: var(--qds-component-button-ghost-color-border-disabled, transparent);
116
+ }
117
+
118
+ :host([variant='danger']) {
119
+ --_bg: var(--qds-component-button-danger-color-background-rest, #dc2626);
120
+ --_bg-hover: var(--qds-component-button-danger-color-background-hover, #b91c1c);
121
+ --_bg-active: var(--qds-component-button-danger-color-background-active, #991b1b);
122
+ --_bg-disabled: var(--qds-component-button-danger-color-background-disabled, #e2e8f0);
123
+ --_fg: var(--qds-component-button-danger-color-content-rest, #f8fafc);
124
+ --_fg-disabled: var(--qds-component-button-danger-color-content-disabled, #64748b);
125
+ --_border: var(--qds-component-button-danger-color-border-rest, transparent);
126
+ --_border-disabled: var(--qds-component-button-danger-color-border-disabled, transparent);
127
+ }
128
+
129
+ :host([size='sm']) {
130
+ --_padding-block: var(--qds-component-button-sm-padding-block, 0.25rem);
131
+ --_padding-inline: var(--qds-component-button-sm-padding-inline, 0.75rem);
132
+ --_gap: var(--qds-component-button-sm-gap, 0.25rem);
133
+ --_font-size: var(--qds-component-button-sm-font-size, 0.75rem);
134
+ }
135
+
136
+ :host([size='lg']) {
137
+ --_padding-block: var(--qds-component-button-lg-padding-block, 0.75rem);
138
+ --_padding-inline: var(--qds-component-button-lg-padding-inline, 1.5rem);
139
+ --_gap: var(--qds-component-button-lg-gap, 0.5rem);
140
+ --_font-size: var(--qds-component-button-lg-font-size, 1rem);
141
+ }
142
+
143
+ :host([full-width]) {
144
+ display: block;
145
+ }
146
+
147
+ :host([full-width]) button {
148
+ width: 100%;
149
+ }
150
+
151
+ button {
152
+ position: relative;
153
+ display: inline-flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ gap: var(--_gap);
157
+
158
+ margin: 0;
159
+ padding: var(--_padding-block) var(--_padding-inline);
160
+
161
+ font-family: var(--qds-typography-font-family-sans, inherit);
162
+ font-size: var(--_font-size);
163
+ font-weight: var(--qds-component-button-font-weight, 500);
164
+ line-height: var(--qds-component-button-line-height, 1.375);
165
+
166
+ color: var(--_fg);
167
+ background-color: var(--_bg);
168
+ border: var(--qds-component-button-border-width, 0.0625rem) solid var(--_border);
169
+ border-radius: var(--qds-component-button-border-radius, 0.375rem);
170
+
171
+ cursor: pointer;
172
+ user-select: none;
173
+ -webkit-appearance: none;
174
+ appearance: none;
175
+
176
+ transition:
177
+ background-color var(--qds-component-button-duration, 120ms),
178
+ border-color var(--qds-component-button-duration, 120ms),
179
+ color var(--qds-component-button-duration, 120ms);
180
+ }
181
+
182
+ /* :where() keeps specificity at zero so the disabled rules below win. */
183
+ button:where(:hover) {
184
+ background-color: var(--_bg-hover);
185
+ }
186
+
187
+ button:where(:active) {
188
+ background-color: var(--_bg-active);
189
+ }
190
+
191
+ button:focus-visible {
192
+ outline: var(--_focus-ring);
193
+ outline-offset: 0.125rem;
194
+ }
195
+
196
+ button:disabled,
197
+ button[aria-disabled='true'] {
198
+ color: var(--_fg-disabled);
199
+ background-color: var(--_bg-disabled);
200
+ border-color: var(--_border-disabled);
201
+ cursor: not-allowed;
202
+ }
203
+
204
+ .content {
205
+ display: inline-flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+ gap: var(--_gap);
209
+ }
210
+
211
+ .label {
212
+ display: contents;
213
+ }
214
+
215
+ /*
216
+ * opacity, NOT visibility or display.
217
+ *
218
+ * visibility:hidden and display:none both remove the subtree from the
219
+ * accessibility tree, which leaves the button with no accessible name for
220
+ * exactly as long as it is loading — a screen reader announces an unnamed
221
+ * button mid-submit. opacity:0 keeps the content in the a11y tree and keeps
222
+ * it in layout, so the button also does not change width when the spinner
223
+ * appears.
224
+ *
225
+ * Fading one wrapper rather than the label plus each slot matters: a bare
226
+ * text child is not an element, so ::slotted(*) never matches it, and slots
227
+ * are display:contents, which opacity does not apply to.
228
+ */
229
+ :host([loading]) .content {
230
+ opacity: 0;
231
+ }
232
+
233
+ .spinner {
234
+ position: absolute;
235
+ inset: 0;
236
+ width: 1em;
237
+ height: 1em;
238
+ margin: auto;
239
+ border: 0.125em solid currentColor;
240
+ border-block-start-color: transparent;
241
+ border-radius: 50%;
242
+ animation: spin 600ms linear infinite;
243
+ }
244
+
245
+ @keyframes spin {
246
+ to {
247
+ transform: rotate(360deg);
248
+ }
249
+ }
250
+
251
+ /*
252
+ * A continuous spin is a vestibular trigger. Stepping it into eight discrete
253
+ * frames keeps the "work is happening" signal without smooth motion.
254
+ */
255
+ @media (prefers-reduced-motion: reduce) {
256
+ .spinner {
257
+ animation-duration: 1600ms;
258
+ animation-timing-function: steps(8, end);
259
+ }
260
+
261
+ button {
262
+ transition: none;
263
+ }
264
+ }
265
+
266
+ /*
267
+ * In forced-colors mode the author's colors are discarded, so the disabled
268
+ * state would become visually identical to the resting one. GrayText is the
269
+ * system keyword that survives.
270
+ */
271
+ @media (forced-colors: active) {
272
+ button {
273
+ border: 0.0625rem solid ButtonText;
274
+ }
275
+
276
+ button:disabled,
277
+ button[aria-disabled='true'] {
278
+ color: GrayText;
279
+ border-color: GrayText;
280
+ }
281
+ }
282
+ `,
283
+ ]; }
284
+ #internals;
285
+ constructor() {
286
+ super();
287
+ /** Visual emphasis. */
288
+ this.variant = 'primary';
289
+ /** Control size. */
290
+ this.size = 'md';
291
+ /** Behavior within a form. */
292
+ this.type = 'button';
293
+ /** Prevents interaction and removes the button from the tab order. */
294
+ this.disabled = false;
295
+ /**
296
+ * Shows a spinner and blocks activation, while keeping the button focusable so
297
+ * focus is not lost mid-interaction.
298
+ */
299
+ this.loading = false;
300
+ /** Stretches the button to fill its container. */
301
+ this.fullWidth = false;
302
+ /** Accessible name, for when the button has no text (an icon-only button). */
303
+ this.label = null;
304
+ /** Submitted as the name of this button's entry when it submits a form. */
305
+ this.name = '';
306
+ /**
307
+ * Submitted with `name` when this button submits a form, and reported as the
308
+ * dialog's `returnValue` when it submits a `<form method="dialog">`.
309
+ */
310
+ this.value = '';
311
+ this.#internals = this.attachInternals();
312
+ }
313
+ /** True while the button should reject activation. */
314
+ get #inert() {
315
+ return this.disabled || this.loading;
316
+ }
317
+ #handleClick(event) {
318
+ if (this.#inert) {
319
+ // A `loading` button is not `disabled`, so the browser still dispatches its
320
+ // click. Stop it here, and stop propagation too — otherwise the event
321
+ // escapes the shadow root and any listener on the host fires anyway.
322
+ event.preventDefault();
323
+ event.stopPropagation();
324
+ return;
325
+ }
326
+ this.dispatchEvent(new CustomEvent('qds-click', { bubbles: true, composed: true }));
327
+ // Submit and reset do not cross the shadow boundary on their own: the native
328
+ // button's implicit form is its shadow root, which is not a form.
329
+ const form = this.#internals.form;
330
+ if (!form)
331
+ return;
332
+ if (this.type === 'submit') {
333
+ this.#submit(form);
334
+ }
335
+ else if (this.type === 'reset') {
336
+ form.reset();
337
+ }
338
+ }
339
+ /**
340
+ * Submit through a temporary native button carrying this button's name and
341
+ * value.
342
+ *
343
+ * A custom element cannot be a form's submitter — requestSubmit(this) throws —
344
+ * so a plain requestSubmit() would submit with no submitter at all: the name and
345
+ * value would be missing from the form data, event.submitter would be null, and
346
+ * a dialog form's returnValue would be empty. The proxy makes all three behave
347
+ * as they would for a native submit button. requestSubmit() rather than
348
+ * submit(), so validation and the submit event still run.
349
+ */
350
+ #submit(form) {
351
+ const proxy = document.createElement('button');
352
+ proxy.type = 'submit';
353
+ proxy.hidden = true;
354
+ if (this.name)
355
+ proxy.name = this.name;
356
+ proxy.value = this.value;
357
+ form.append(proxy);
358
+ try {
359
+ form.requestSubmit(proxy);
360
+ }
361
+ finally {
362
+ proxy.remove();
363
+ }
364
+ }
365
+ render() {
366
+ return html `
367
+ <button
368
+ part="button"
369
+ class="button"
370
+ type="button"
371
+ ?disabled=${this.disabled}
372
+ aria-disabled=${this.loading ? 'true' : nothing}
373
+ aria-busy=${this.loading ? 'true' : nothing}
374
+ aria-label=${this.label ?? nothing}
375
+ @click=${this.#handleClick}
376
+ >
377
+ ${this.loading ? html `<span class="spinner" part="spinner"></span>` : nothing}
378
+ <span class="content" part="content">
379
+ <slot name="start"></slot>
380
+ <span class="label" part="label"><slot></slot></span>
381
+ <slot name="end"></slot>
382
+ </span>
383
+ </button>
384
+ `;
385
+ }
386
+ };
387
+ __decorate([
388
+ property({ reflect: true })
389
+ ], QdsButton.prototype, "variant", void 0);
390
+ __decorate([
391
+ property({ reflect: true })
392
+ ], QdsButton.prototype, "size", void 0);
393
+ __decorate([
394
+ property()
395
+ ], QdsButton.prototype, "type", void 0);
396
+ __decorate([
397
+ property({ type: Boolean, reflect: true })
398
+ ], QdsButton.prototype, "disabled", void 0);
399
+ __decorate([
400
+ property({ type: Boolean, reflect: true })
401
+ ], QdsButton.prototype, "loading", void 0);
402
+ __decorate([
403
+ property({ type: Boolean, reflect: true, attribute: 'full-width' })
404
+ ], QdsButton.prototype, "fullWidth", void 0);
405
+ __decorate([
406
+ property({ attribute: 'label' })
407
+ ], QdsButton.prototype, "label", void 0);
408
+ __decorate([
409
+ property()
410
+ ], QdsButton.prototype, "name", void 0);
411
+ __decorate([
412
+ property()
413
+ ], QdsButton.prototype, "value", void 0);
414
+ QdsButton = __decorate([
415
+ customElement('qds-button')
416
+ ], QdsButton);
417
+ export { QdsButton };
418
+ //# sourceMappingURL=qds-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qds-button.js","sourceRoot":"","sources":["../../../src/components/qds-button/qds-button.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type TemplateResult } from 'lit';
2
+ import { QdsElement } from '../../internal/qds-element.js';
3
+ export type QdsCardVariant = 'outlined' | 'elevated' | 'filled';
4
+ /**
5
+ * A container that groups related content and actions.
6
+ *
7
+ * The card is layout only: it has no role and is not interactive, so it adds
8
+ * nothing to the accessibility tree. Put a heading in the `header` slot when the
9
+ * card starts a section of the page, so it can be found by heading navigation.
10
+ *
11
+ * Empty regions take no space, with no script involved, so a server-rendered
12
+ * card is laid out correctly before any JavaScript runs. Style slotted content
13
+ * directly; the media, header, and footer have no wrapper parts.
14
+ *
15
+ * @element qds-card
16
+ *
17
+ * @slot - The body.
18
+ * @slot media - Full-bleed content above the header, such as an image.
19
+ * @slot header - The title area, typically a heading.
20
+ * @slot footer - Actions or metadata at the bottom.
21
+ *
22
+ * @csspart base - The card surface.
23
+ * @csspart body - The wrapper around the default slot.
24
+ *
25
+ * @cssprop [--qds-component-card-padding] - Inner padding.
26
+ * @cssprop [--qds-component-card-gap] - Space between the header, body, and footer.
27
+ * @cssprop [--qds-component-card-border-radius] - Corner radius.
28
+ * @cssprop [--qds-component-card-border-width] - Border thickness.
29
+ * @cssprop [--qds-component-card-color-content-rest] - Text color.
30
+ * @cssprop [--qds-component-card-header-font-size] - Header text size.
31
+ * @cssprop [--qds-component-card-header-font-weight] - Header text weight.
32
+ * @cssprop [--qds-component-card-header-line-height] - Header line height.
33
+ * @cssprop [--qds-component-card-{variant}-color-background-rest] - Fill per variant.
34
+ * @cssprop [--qds-component-card-{variant}-color-border-rest] - Border per variant.
35
+ * @cssprop [--qds-component-card-elevated-box-shadow] - Shadow of the elevated variant.
36
+ */
37
+ export declare class QdsCard extends QdsElement {
38
+ static styles: import("lit").CSSResult[];
39
+ /** Surface style. */
40
+ variant: QdsCardVariant;
41
+ render(): TemplateResult;
42
+ }
43
+ declare global {
44
+ interface HTMLElementTagNameMap {
45
+ 'qds-card': QdsCard;
46
+ }
47
+ }
48
+ //# sourceMappingURL=qds-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qds-card.d.ts","sourceRoot":"","sources":["../../../src/components/qds-card/qds-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACrC,OAAgB,MAAM,4BAoFpB;IAEF,qBAAqB;IAErB,OAAO,EAAE,cAAc,CAAc;IAE5B,MAAM,IAAI,cAAc;CAUlC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
@@ -0,0 +1,152 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { css, html } from 'lit';
8
+ import { customElement, property } from 'lit/decorators.js';
9
+ import { QdsElement } from '../../internal/qds-element.js';
10
+ /**
11
+ * A container that groups related content and actions.
12
+ *
13
+ * The card is layout only: it has no role and is not interactive, so it adds
14
+ * nothing to the accessibility tree. Put a heading in the `header` slot when the
15
+ * card starts a section of the page, so it can be found by heading navigation.
16
+ *
17
+ * Empty regions take no space, with no script involved, so a server-rendered
18
+ * card is laid out correctly before any JavaScript runs. Style slotted content
19
+ * directly; the media, header, and footer have no wrapper parts.
20
+ *
21
+ * @element qds-card
22
+ *
23
+ * @slot - The body.
24
+ * @slot media - Full-bleed content above the header, such as an image.
25
+ * @slot header - The title area, typically a heading.
26
+ * @slot footer - Actions or metadata at the bottom.
27
+ *
28
+ * @csspart base - The card surface.
29
+ * @csspart body - The wrapper around the default slot.
30
+ *
31
+ * @cssprop [--qds-component-card-padding] - Inner padding.
32
+ * @cssprop [--qds-component-card-gap] - Space between the header, body, and footer.
33
+ * @cssprop [--qds-component-card-border-radius] - Corner radius.
34
+ * @cssprop [--qds-component-card-border-width] - Border thickness.
35
+ * @cssprop [--qds-component-card-color-content-rest] - Text color.
36
+ * @cssprop [--qds-component-card-header-font-size] - Header text size.
37
+ * @cssprop [--qds-component-card-header-font-weight] - Header text weight.
38
+ * @cssprop [--qds-component-card-header-line-height] - Header line height.
39
+ * @cssprop [--qds-component-card-{variant}-color-background-rest] - Fill per variant.
40
+ * @cssprop [--qds-component-card-{variant}-color-border-rest] - Border per variant.
41
+ * @cssprop [--qds-component-card-elevated-box-shadow] - Shadow of the elevated variant.
42
+ */
43
+ let QdsCard = class QdsCard extends QdsElement {
44
+ constructor() {
45
+ super(...arguments);
46
+ /** Surface style. */
47
+ this.variant = 'outlined';
48
+ }
49
+ static { this.styles = [
50
+ QdsElement.baseStyles,
51
+ css `
52
+ :host {
53
+ display: block;
54
+
55
+ --_padding: var(--qds-component-card-padding, 1.5rem);
56
+ --_bg: var(--qds-component-card-outlined-color-background-rest, #f8fafc);
57
+ --_border: var(--qds-component-card-outlined-color-border-rest, #cbd5e1);
58
+ --_shadow: none;
59
+ }
60
+
61
+ :host([variant='elevated']) {
62
+ --_bg: var(--qds-component-card-elevated-color-background-rest, #f8fafc);
63
+ --_border: var(--qds-component-card-elevated-color-border-rest, #e2e8f0);
64
+ --_shadow: var(
65
+ --qds-component-card-elevated-box-shadow,
66
+ 0 0.375rem 1rem 0.0625rem rgb(15 23 42 / 0.12)
67
+ );
68
+ }
69
+
70
+ :host([variant='filled']) {
71
+ --_bg: var(--qds-component-card-filled-color-background-rest, #f1f5f9);
72
+ --_border: var(--qds-component-card-filled-color-border-rest, transparent);
73
+ }
74
+
75
+ .base {
76
+ display: flex;
77
+ flex-direction: column;
78
+ gap: var(--qds-component-card-gap, 0.75rem);
79
+ height: 100%;
80
+ padding: var(--_padding);
81
+ /* Clip full-bleed media to the rounded corners. */
82
+ overflow: hidden;
83
+
84
+ font-family: var(--qds-typography-font-family-sans, inherit);
85
+ color: var(--qds-component-card-color-content-rest, #0f172a);
86
+
87
+ background-color: var(--_bg);
88
+ border: var(--qds-component-card-border-width, 0.0625rem) solid var(--_border);
89
+ border-radius: var(--qds-component-card-border-radius, 0.5rem);
90
+ box-shadow: var(--_shadow);
91
+ }
92
+
93
+ /*
94
+ * The media, header, and footer slots are deliberately not wrapped. A slot
95
+ * is display: contents, so an empty one generates no box and the flex gap
96
+ * is not applied around it — empty regions take no space with no script,
97
+ * which also means a server-rendered card is laid out correctly before it
98
+ * hydrates. Their content is styled with ::slotted() instead.
99
+ *
100
+ * (:host(:has(> [slot])) would read more directly, but Chromium does not
101
+ * match :has() inside :host().)
102
+ */
103
+ ::slotted([slot='media']) {
104
+ display: block;
105
+ /* Bleed to the card edges by cancelling the padding around it. */
106
+ margin: calc(-1 * var(--_padding)) calc(-1 * var(--_padding)) 0;
107
+ width: calc(100% + 2 * var(--_padding));
108
+ max-width: none;
109
+ height: auto;
110
+ }
111
+
112
+ ::slotted([slot='header']) {
113
+ margin: 0;
114
+ font-size: var(--qds-component-card-header-font-size, 1.125rem);
115
+ font-weight: var(--qds-component-card-header-font-weight, 600);
116
+ line-height: var(--qds-component-card-header-line-height, 1.375);
117
+ }
118
+
119
+ .body {
120
+ flex: 1;
121
+ }
122
+
123
+ ::slotted([slot='footer']) {
124
+ margin-block-start: auto;
125
+ }
126
+
127
+ @media (forced-colors: active) {
128
+ .base {
129
+ border-color: CanvasText;
130
+ }
131
+ }
132
+ `,
133
+ ]; }
134
+ render() {
135
+ return html `
136
+ <div class="base" part="base">
137
+ <slot name="media"></slot>
138
+ <slot name="header"></slot>
139
+ <div class="body" part="body"><slot></slot></div>
140
+ <slot name="footer"></slot>
141
+ </div>
142
+ `;
143
+ }
144
+ };
145
+ __decorate([
146
+ property({ reflect: true })
147
+ ], QdsCard.prototype, "variant", void 0);
148
+ QdsCard = __decorate([
149
+ customElement('qds-card')
150
+ ], QdsCard);
151
+ export { QdsCard };
152
+ //# sourceMappingURL=qds-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qds-card.js","sourceRoot":"","sources":["../../../src/components/qds-card/qds-card.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAuB,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEI,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAAhC;;QAuFL,qBAAqB;QAErB,YAAO,GAAmB,UAAU,CAAC;IAYvC,CAAC;aApGiB,WAAM,GAAG;QACvB,UAAU,CAAC,UAAU;QACrB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiFF;KACF,AApFqB,CAoFpB;IAMO,MAAM;QACb,OAAO,IAAI,CAAA;;;;;;;KAOV,CAAC;IACJ,CAAC;;AAXD;IADC,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;wCACS;AAzF1B,OAAO;IADnB,aAAa,CAAC,UAAU,CAAC;GACb,OAAO,CAqGnB"}