@f-ewald/components 0.7.0 → 1.0.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.
- package/README.md +76 -47
- package/custom-elements.json +3049 -910
- package/dist/address-autocomplete.d.ts +8 -0
- package/dist/address-autocomplete.d.ts.map +1 -1
- package/dist/address-autocomplete.js +165 -15
- package/dist/address-autocomplete.js.map +1 -1
- package/dist/animate-confetti.d.ts +8 -5
- package/dist/animate-confetti.d.ts.map +1 -1
- package/dist/animate-confetti.js +46 -19
- package/dist/animate-confetti.js.map +1 -1
- package/dist/autocomplete-input.d.ts +8 -0
- package/dist/autocomplete-input.d.ts.map +1 -1
- package/dist/autocomplete-input.js +165 -15
- package/dist/autocomplete-input.js.map +1 -1
- package/dist/calendar-entry.d.ts +33 -0
- package/dist/calendar-entry.d.ts.map +1 -0
- package/dist/calendar-entry.js +64 -0
- package/dist/calendar-entry.js.map +1 -0
- package/dist/calendar-month.d.ts +67 -0
- package/dist/calendar-month.d.ts.map +1 -0
- package/dist/calendar-month.js +469 -0
- package/dist/calendar-month.js.map +1 -0
- package/dist/calendar-year.d.ts +43 -0
- package/dist/calendar-year.d.ts.map +1 -0
- package/dist/calendar-year.js +145 -0
- package/dist/calendar-year.js.map +1 -0
- package/dist/chat-message.d.ts.map +1 -1
- package/dist/chat-message.js +77 -24
- package/dist/chat-message.js.map +1 -1
- package/dist/confirm-dialog.d.ts +8 -1
- package/dist/confirm-dialog.d.ts.map +1 -1
- package/dist/confirm-dialog.js +130 -18
- package/dist/confirm-dialog.js.map +1 -1
- package/dist/copy-link-button.d.ts +2 -0
- package/dist/copy-link-button.d.ts.map +1 -1
- package/dist/copy-link-button.js +35 -3
- package/dist/copy-link-button.js.map +1 -1
- package/dist/data-table.d.ts +2 -0
- package/dist/data-table.d.ts.map +1 -1
- package/dist/data-table.js +83 -11
- package/dist/data-table.js.map +1 -1
- package/dist/distance-value.d.ts +0 -1
- package/dist/distance-value.d.ts.map +1 -1
- package/dist/distance-value.js +3 -8
- package/dist/distance-value.js.map +1 -1
- package/dist/distribution-chart.d.ts.map +1 -1
- package/dist/distribution-chart.js +54 -17
- package/dist/distribution-chart.js.map +1 -1
- package/dist/dropdown-button.d.ts.map +1 -1
- package/dist/dropdown-button.js +60 -11
- package/dist/dropdown-button.js.map +1 -1
- package/dist/editable-text.d.ts.map +1 -1
- package/dist/editable-text.js +46 -13
- package/dist/editable-text.js.map +1 -1
- package/dist/form-select.d.ts +21 -2
- package/dist/form-select.d.ts.map +1 -1
- package/dist/form-select.js +489 -37
- package/dist/form-select.js.map +1 -1
- package/dist/frame-box.d.ts.map +1 -1
- package/dist/frame-box.js +20 -12
- package/dist/frame-box.js.map +1 -1
- package/dist/icon-button.d.ts.map +1 -1
- package/dist/icon-button.js +11 -0
- package/dist/icon-button.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/kbd-hint.d.ts +30 -0
- package/dist/kbd-hint.d.ts.map +1 -0
- package/dist/kbd-hint.js +184 -0
- package/dist/kbd-hint.js.map +1 -0
- package/dist/live-timer.d.ts +0 -1
- package/dist/live-timer.d.ts.map +1 -1
- package/dist/live-timer.js +1 -6
- package/dist/live-timer.js.map +1 -1
- package/dist/map-circle.d.ts +3 -0
- package/dist/map-circle.d.ts.map +1 -1
- package/dist/map-circle.js +19 -1
- package/dist/map-circle.js.map +1 -1
- package/dist/map-pin.d.ts.map +1 -1
- package/dist/map-pin.js +16 -1
- package/dist/map-pin.js.map +1 -1
- package/dist/percent-bar-chart.d.ts +3 -0
- package/dist/percent-bar-chart.d.ts.map +1 -1
- package/dist/percent-bar-chart.js +60 -4
- package/dist/percent-bar-chart.js.map +1 -1
- package/dist/photo-gallery.d.ts.map +1 -1
- package/dist/photo-gallery.js +12 -3
- package/dist/photo-gallery.js.map +1 -1
- package/dist/popover-panel.d.ts.map +1 -1
- package/dist/popover-panel.js +132 -23
- package/dist/popover-panel.js.map +1 -1
- package/dist/price-history-chart.d.ts.map +1 -1
- package/dist/price-history-chart.js +52 -18
- package/dist/price-history-chart.js.map +1 -1
- package/dist/radio-cards.d.ts +2 -0
- package/dist/radio-cards.d.ts.map +1 -1
- package/dist/radio-cards.js +51 -5
- package/dist/radio-cards.js.map +1 -1
- package/dist/radio-pills.d.ts +2 -0
- package/dist/radio-pills.d.ts.map +1 -1
- package/dist/radio-pills.js +46 -4
- package/dist/radio-pills.js.map +1 -1
- package/dist/relative-time.d.ts +0 -1
- package/dist/relative-time.d.ts.map +1 -1
- package/dist/relative-time.js +1 -6
- package/dist/relative-time.js.map +1 -1
- package/dist/reveal-button.d.ts +2 -0
- package/dist/reveal-button.d.ts.map +1 -1
- package/dist/reveal-button.js +42 -5
- package/dist/reveal-button.js.map +1 -1
- package/dist/roman-numeral.js +1 -1
- package/dist/roman-numeral.js.map +1 -1
- package/dist/slide-panel.d.ts +7 -3
- package/dist/slide-panel.d.ts.map +1 -1
- package/dist/slide-panel.js +95 -23
- package/dist/slide-panel.js.map +1 -1
- package/dist/stat-meter.d.ts.map +1 -1
- package/dist/stat-meter.js +17 -7
- package/dist/stat-meter.js.map +1 -1
- package/dist/status-pill.d.ts.map +1 -1
- package/dist/status-pill.js +26 -12
- package/dist/status-pill.js.map +1 -1
- package/dist/tile-grid.d.ts +8 -0
- package/dist/tile-grid.d.ts.map +1 -1
- package/dist/tile-grid.js +88 -12
- package/dist/tile-grid.js.map +1 -1
- package/dist/toast-notification.d.ts.map +1 -1
- package/dist/toast-notification.js +40 -11
- package/dist/toast-notification.js.map +1 -1
- package/dist/tokens.css +23 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +16 -0
- package/dist/tokens.js.map +1 -1
- package/dist/ui-button.d.ts +2 -0
- package/dist/ui-button.d.ts.map +1 -1
- package/dist/ui-button.js +58 -9
- package/dist/ui-button.js.map +1 -1
- package/dist/user-avatar.d.ts.map +1 -1
- package/dist/user-avatar.js +18 -3
- package/dist/user-avatar.js.map +1 -1
- package/dist/utils/calendar.d.ts +77 -0
- package/dist/utils/calendar.d.ts.map +1 -0
- package/dist/utils/calendar.js +135 -0
- package/dist/utils/calendar.js.map +1 -0
- package/dist/utils/form.d.ts +3 -0
- package/dist/utils/form.d.ts.map +1 -0
- package/dist/utils/form.js +14 -0
- package/dist/utils/form.js.map +1 -0
- package/dist/utils/layer-stack.d.ts +9 -0
- package/dist/utils/layer-stack.d.ts.map +1 -0
- package/dist/utils/layer-stack.js +35 -0
- package/dist/utils/layer-stack.js.map +1 -0
- package/dist/weight-bar-chart.d.ts.map +1 -1
- package/dist/weight-bar-chart.js +27 -8
- package/dist/weight-bar-chart.js.map +1 -1
- package/docs/address-autocomplete.md +5 -0
- package/docs/autocomplete-input.md +5 -0
- package/docs/calendar-entry.md +53 -0
- package/docs/calendar-month.md +79 -0
- package/docs/calendar-year.md +53 -0
- package/docs/chat-message.md +4 -0
- package/docs/confirm-dialog.md +2 -0
- package/docs/copy-link-button.md +2 -0
- package/docs/data-table.md +2 -0
- package/docs/design-language.md +149 -0
- package/docs/distribution-chart.md +4 -0
- package/docs/dropdown-button.md +1 -0
- package/docs/form-select.md +15 -3
- package/docs/frame-box.md +2 -0
- package/docs/kbd-hint.md +42 -0
- package/docs/map-circle.md +4 -0
- package/docs/percent-bar-chart.md +4 -1
- package/docs/photo-gallery.md +1 -0
- package/docs/popover-panel.md +2 -0
- package/docs/price-history-chart.md +8 -1
- package/docs/radio-cards.md +2 -0
- package/docs/radio-pills.md +2 -0
- package/docs/reveal-button.md +3 -0
- package/docs/slide-panel.md +4 -2
- package/docs/status-pill.md +3 -0
- package/docs/tile-grid.md +10 -1
- package/docs/toast-notification.md +4 -1
- package/docs/ui-button.md +2 -0
- package/docs/user-avatar.md +1 -0
- package/llms.txt +175 -61
- package/package.json +14 -2
- package/dist/map-point.d.ts +0 -31
- package/dist/map-point.d.ts.map +0 -1
- package/dist/map-point.js +0 -83
- package/dist/map-point.js.map +0 -1
- package/docs/map-point.md +0 -44
package/dist/radio-cards.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-cards.js","sourceRoot":"","sources":["../src/radio-cards.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB;;;;;;;;;GASG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;
|
|
1
|
+
{"version":3,"file":"radio-cards.js","sourceRoot":"","sources":["../src/radio-cards.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB;;;;;;;;;GASG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;QAoFL,wCAAwC;QACR,YAAO,GAAsB,EAAE,CAAC;QAChE,gCAAgC;QACpB,UAAK,GAAG,EAAE,CAAC;QACvB,gDAAgD;QACnB,aAAQ,GAAG,KAAK,CAAC;QAErC,UAAK,GAAG,eAAe,EAAE,aAAa,EAAE,CAAC;IAiCpD,CAAC;aA3HiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8EF;KACF,AAjFqB,CAiFpB;IASO,KAAK,CAAoC;IAE1C,SAAS,CAAC,KAAa;QAC7B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtG,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAA;;UAEL,MAAM,CACN,IAAI,CAAC,OAAO,EACZ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAClB,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAA;;;;uBAIA,IAAI,CAAC,KAAK;2BACN,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;4BACvB,IAAI,CAAC,QAAQ;0BACf,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;;;2CAGd,GAAG,CAAC,KAAK;kBAClC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAA,kCAAkC,GAAG,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC,OAAO;;;WAGjG,CACF;;KAEJ,CAAC;IACJ,CAAC;CACF,CAAA;AAvCiC;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;2CAAiC;AAEpD;IAAX,QAAQ,EAAE;yCAAY;AAEM;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CAAkB;AAzFnC,UAAU;IADtB,aAAa,CAAC,aAAa,CAAC;GAChB,UAAU,CA4HtB","sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { tokens } from \"./tokens.js\";\n\nexport interface RadioCardOption {\n value: string;\n label: string;\n description?: string;\n}\n\nlet instanceCount = 0;\n\n/**\n * Single-select group of full-width cards, each with a label and optional\n * description — for a handful of meaningfully different choices where the\n * description matters. For many short, same-shaped options (a color swatch,\n * a basemap style), use `radio-pills` instead. Wraps native radio inputs for\n * keyboard/a11y and fires `change` rather than relying on form submission.\n *\n * @element radio-cards\n * @fires change - A card was selected; detail: { value }.\n */\n@customElement(\"radio-cards\")\nexport class RadioCards extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n }\n .options {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n }\n .card {\n flex: 1 1 11.25rem;\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size-sm, 0.75rem);\n }\n .card:has(input:checked) {\n border-color: var(--ui-primary, #4f46e5);\n background: var(--ui-surface-muted, #f8fafc);\n }\n .card input {\n width: auto;\n margin-top: 0.25rem;\n accent-color: var(--ui-primary, #4f46e5);\n cursor: pointer;\n }\n .card-label {\n font-weight: 600;\n color: var(--ui-text, #0f172a);\n }\n .card-description {\n display: block;\n color: var(--ui-text-muted, #64748b);\n font-weight: 400;\n }\n .card:has(input:focus-visible) {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .card:has(input:disabled) {\n cursor: not-allowed;\n opacity: 0.6;\n }\n .card:has(input:disabled) input {\n cursor: not-allowed;\n }\n @media (forced-colors: active) {\n .card:has(input:focus-visible) {\n outline: 2px solid CanvasText;\n outline-offset: 2px;\n box-shadow: none;\n }\n .card:has(input:checked) {\n border-color: Highlight;\n }\n .card:has(input:disabled) {\n color: GrayText;\n opacity: 1;\n }\n .card:has(input:disabled) .card-label,\n .card:has(input:disabled) .card-description {\n color: GrayText;\n }\n }\n `,\n ];\n\n /** Options to render, one card each. */\n @property({ attribute: false }) options: RadioCardOption[] = [];\n /** Currently selected value. */\n @property() value = \"\";\n /** Disables every native radio in the group. */\n @property({ type: Boolean }) disabled = false;\n\n readonly #name = `radio-cards-${++instanceCount}`;\n\n private _onChange(value: string) {\n if (this.disabled) return;\n this.value = value;\n this.dispatchEvent(new CustomEvent(\"change\", { detail: { value }, bubbles: true, composed: true }));\n }\n\n override render() {\n return html`\n <div class=\"options\">\n ${repeat(\n this.options,\n (opt) => opt.value,\n (opt) => html`\n <label class=\"card\">\n <input\n type=\"radio\"\n name=${this.#name}\n ?checked=${this.value === opt.value}\n ?disabled=${this.disabled}\n @change=${() => this._onChange(opt.value)}\n />\n <span>\n <span class=\"card-label\">${opt.label}</span>\n ${opt.description ? html`<span class=\"card-description\">${opt.description}</span>` : nothing}\n </span>\n </label>\n `,\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"radio-cards\": RadioCards;\n }\n}\n"]}
|
package/dist/radio-pills.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export declare class RadioPills extends LitElement {
|
|
|
20
20
|
options: RadioPillOption[];
|
|
21
21
|
/** Currently selected value. */
|
|
22
22
|
value: string;
|
|
23
|
+
/** Disables every native radio in the group. */
|
|
24
|
+
disabled: boolean;
|
|
23
25
|
private _onChange;
|
|
24
26
|
render(): import("lit-html").TemplateResult<1>;
|
|
25
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-pills.d.ts","sourceRoot":"","sources":["../src/radio-pills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAK5C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;;;GASG;AACH,qBACa,UAAW,SAAQ,UAAU;;IACxC,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"radio-pills.d.ts","sourceRoot":"","sources":["../src/radio-pills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAK5C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;;;GASG;AACH,qBACa,UAAW,SAAQ,UAAU;;IACxC,OAAgB,MAAM,4BAqEpB;IAEF,wCAAwC;IACR,OAAO,EAAE,eAAe,EAAE,CAAM;IAChE,gCAAgC;IACpB,KAAK,SAAM;IACvB,gDAAgD;IACnB,QAAQ,UAAS;IAI9C,OAAO,CAAC,SAAS;IAMR,MAAM,yCAqBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
package/dist/radio-pills.js
CHANGED
|
@@ -26,6 +26,8 @@ let RadioPills = class RadioPills extends LitElement {
|
|
|
26
26
|
this.options = [];
|
|
27
27
|
/** Currently selected value. */
|
|
28
28
|
this.value = "";
|
|
29
|
+
/** Disables every native radio in the group. */
|
|
30
|
+
this.disabled = false;
|
|
29
31
|
this.#name = `radio-pills-${++instanceCount}`;
|
|
30
32
|
}
|
|
31
33
|
static { this.styles = [
|
|
@@ -37,17 +39,26 @@ let RadioPills = class RadioPills extends LitElement {
|
|
|
37
39
|
.options {
|
|
38
40
|
display: flex;
|
|
39
41
|
flex-wrap: wrap;
|
|
40
|
-
gap: 0.
|
|
42
|
+
gap: 0.5rem;
|
|
41
43
|
}
|
|
42
44
|
.pill {
|
|
43
45
|
display: flex;
|
|
44
46
|
align-items: center;
|
|
45
|
-
gap: 0.
|
|
46
|
-
padding: 0.
|
|
47
|
+
gap: 0.25rem;
|
|
48
|
+
padding: 0.25rem 0.75rem;
|
|
47
49
|
border: 1px solid var(--ui-border, #e2e8f0);
|
|
48
50
|
border-radius: 999px;
|
|
49
51
|
cursor: pointer;
|
|
50
|
-
font-family: var(
|
|
52
|
+
font-family: var(
|
|
53
|
+
--ui-font,
|
|
54
|
+
ui-sans-serif,
|
|
55
|
+
system-ui,
|
|
56
|
+
sans-serif,
|
|
57
|
+
"Apple Color Emoji",
|
|
58
|
+
"Segoe UI Emoji",
|
|
59
|
+
"Segoe UI Symbol",
|
|
60
|
+
"Noto Color Emoji"
|
|
61
|
+
);
|
|
51
62
|
font-size: var(--ui-font-size-sm, 0.75rem);
|
|
52
63
|
color: var(--ui-text, #0f172a);
|
|
53
64
|
}
|
|
@@ -62,10 +73,37 @@ let RadioPills = class RadioPills extends LitElement {
|
|
|
62
73
|
cursor: pointer;
|
|
63
74
|
margin: 0;
|
|
64
75
|
}
|
|
76
|
+
.pill:has(input:focus-visible) {
|
|
77
|
+
outline: none;
|
|
78
|
+
box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));
|
|
79
|
+
}
|
|
80
|
+
.pill:has(input:disabled) {
|
|
81
|
+
cursor: not-allowed;
|
|
82
|
+
opacity: 0.6;
|
|
83
|
+
}
|
|
84
|
+
.pill:has(input:disabled) input {
|
|
85
|
+
cursor: not-allowed;
|
|
86
|
+
}
|
|
87
|
+
@media (forced-colors: active) {
|
|
88
|
+
.pill:has(input:focus-visible) {
|
|
89
|
+
outline: 2px solid CanvasText;
|
|
90
|
+
outline-offset: 2px;
|
|
91
|
+
box-shadow: none;
|
|
92
|
+
}
|
|
93
|
+
.pill:has(input:checked) {
|
|
94
|
+
border-color: Highlight;
|
|
95
|
+
}
|
|
96
|
+
.pill:has(input:disabled) {
|
|
97
|
+
color: GrayText;
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
65
101
|
`,
|
|
66
102
|
]; }
|
|
67
103
|
#name;
|
|
68
104
|
_onChange(value) {
|
|
105
|
+
if (this.disabled)
|
|
106
|
+
return;
|
|
69
107
|
this.value = value;
|
|
70
108
|
this.dispatchEvent(new CustomEvent("change", { detail: { value }, bubbles: true, composed: true }));
|
|
71
109
|
}
|
|
@@ -78,6 +116,7 @@ let RadioPills = class RadioPills extends LitElement {
|
|
|
78
116
|
type="radio"
|
|
79
117
|
name=${this.#name}
|
|
80
118
|
?checked=${this.value === opt.value}
|
|
119
|
+
?disabled=${this.disabled}
|
|
81
120
|
@change=${() => this._onChange(opt.value)}
|
|
82
121
|
/>
|
|
83
122
|
<span>${opt.label}</span>
|
|
@@ -93,6 +132,9 @@ __decorate([
|
|
|
93
132
|
__decorate([
|
|
94
133
|
property()
|
|
95
134
|
], RadioPills.prototype, "value", void 0);
|
|
135
|
+
__decorate([
|
|
136
|
+
property({ type: Boolean })
|
|
137
|
+
], RadioPills.prototype, "disabled", void 0);
|
|
96
138
|
RadioPills = __decorate([
|
|
97
139
|
customElement("radio-pills")
|
|
98
140
|
], RadioPills);
|
package/dist/radio-pills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-pills.js","sourceRoot":"","sources":["../src/radio-pills.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB;;;;;;;;;GASG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;
|
|
1
|
+
{"version":3,"file":"radio-pills.js","sourceRoot":"","sources":["../src/radio-pills.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB;;;;;;;;;GASG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;QAwEL,wCAAwC;QACR,YAAO,GAAsB,EAAE,CAAC;QAChE,gCAAgC;QACpB,UAAK,GAAG,EAAE,CAAC;QACvB,gDAAgD;QACnB,aAAQ,GAAG,KAAK,CAAC;QAErC,UAAK,GAAG,eAAe,EAAE,aAAa,EAAE,CAAC;IA8BpD,CAAC;aA5GiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkEF;KACF,AArEqB,CAqEpB;IASO,KAAK,CAAoC;IAE1C,SAAS,CAAC,KAAa;QAC7B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtG,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAA;;UAEL,MAAM,CACN,IAAI,CAAC,OAAO,EACZ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAClB,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAA;;;;uBAIA,IAAI,CAAC,KAAK;2BACN,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;4BACvB,IAAI,CAAC,QAAQ;0BACf,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;;sBAEnC,GAAG,CAAC,KAAK;;WAEpB,CACF;;KAEJ,CAAC;IACJ,CAAC;CACF,CAAA;AApCiC;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;2CAAiC;AAEpD;IAAX,QAAQ,EAAE;yCAAY;AAEM;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CAAkB;AA7EnC,UAAU;IADtB,aAAa,CAAC,aAAa,CAAC;GAChB,UAAU,CA6GtB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { tokens } from \"./tokens.js\";\n\nexport interface RadioPillOption {\n value: string;\n label: string;\n}\n\nlet instanceCount = 0;\n\n/**\n * Single-select group of compact pill-shaped options — for many short,\n * same-shaped choices (a basemap style, a unit toggle). For a handful of\n * choices where a description matters, use `radio-cards` instead. Wraps\n * native radio inputs for keyboard/a11y and fires `change` rather than\n * relying on form submission.\n *\n * @element radio-pills\n * @fires change - A pill was selected; detail: { value }.\n */\n@customElement(\"radio-pills\")\nexport class RadioPills extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n }\n .options {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n }\n .pill {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.75rem;\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: 999px;\n cursor: pointer;\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size-sm, 0.75rem);\n color: var(--ui-text, #0f172a);\n }\n .pill:has(input:checked) {\n border-color: var(--ui-primary, #4f46e5);\n background: var(--ui-surface-muted, #f8fafc);\n }\n .pill input {\n width: 0.85rem;\n height: 0.85rem;\n accent-color: var(--ui-primary, #4f46e5);\n cursor: pointer;\n margin: 0;\n }\n .pill:has(input:focus-visible) {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .pill:has(input:disabled) {\n cursor: not-allowed;\n opacity: 0.6;\n }\n .pill:has(input:disabled) input {\n cursor: not-allowed;\n }\n @media (forced-colors: active) {\n .pill:has(input:focus-visible) {\n outline: 2px solid CanvasText;\n outline-offset: 2px;\n box-shadow: none;\n }\n .pill:has(input:checked) {\n border-color: Highlight;\n }\n .pill:has(input:disabled) {\n color: GrayText;\n opacity: 1;\n }\n }\n `,\n ];\n\n /** Options to render, one pill each. */\n @property({ attribute: false }) options: RadioPillOption[] = [];\n /** Currently selected value. */\n @property() value = \"\";\n /** Disables every native radio in the group. */\n @property({ type: Boolean }) disabled = false;\n\n readonly #name = `radio-pills-${++instanceCount}`;\n\n private _onChange(value: string) {\n if (this.disabled) return;\n this.value = value;\n this.dispatchEvent(new CustomEvent(\"change\", { detail: { value }, bubbles: true, composed: true }));\n }\n\n override render() {\n return html`\n <div class=\"options\">\n ${repeat(\n this.options,\n (opt) => opt.value,\n (opt) => html`\n <label class=\"pill\">\n <input\n type=\"radio\"\n name=${this.#name}\n ?checked=${this.value === opt.value}\n ?disabled=${this.disabled}\n @change=${() => this._onChange(opt.value)}\n />\n <span>${opt.label}</span>\n </label>\n `,\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"radio-pills\": RadioPills;\n }\n}\n"]}
|
package/dist/relative-time.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../src/relative-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../src/relative-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAMvC;;;;;;;;GAQG;AACH,qBACa,YAAa,SAAQ,UAAU;IAC1C,4CAA4C;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAElC,OAAO,CAAC,IAAI,CAAc;IAEnC,OAAO,CAAC,MAAM,CAA+C;IAEpD,iBAAiB,SAKzB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCAKd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
|
package/dist/relative-time.js
CHANGED
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
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
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { LitElement,
|
|
7
|
+
import { LitElement, html } from "lit";
|
|
8
8
|
import { customElement, property, state } from "lit/decorators.js";
|
|
9
9
|
import { parseTimestamp, formatRelativeTime } from "./utils/time.js";
|
|
10
10
|
const REFRESH_INTERVAL_MS = 60_000;
|
|
@@ -25,11 +25,6 @@ let RelativeTime = class RelativeTime extends LitElement {
|
|
|
25
25
|
this._now = Date.now();
|
|
26
26
|
this._timer = null;
|
|
27
27
|
}
|
|
28
|
-
static { this.styles = css `
|
|
29
|
-
:host {
|
|
30
|
-
display: inline;
|
|
31
|
-
}
|
|
32
|
-
`; }
|
|
33
28
|
connectedCallback() {
|
|
34
29
|
super.connectedCallback();
|
|
35
30
|
this._timer = setInterval(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../src/relative-time.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../src/relative-time.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErE,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEnC;;;;;;;;GAQG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAArC;;QACL,4CAA4C;QAChC,aAAQ,GAAkB,IAAI,CAAC;QAE1B,SAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,WAAM,GAA0C,IAAI,CAAC;IAqB/D,CAAC;IAnBU,iBAAiB;QACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC1B,CAAC;IAEQ,oBAAoB;QAC3B,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;YAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAEQ,MAAM;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChE,OAAO,IAAI,CAAA,eAAe,IAAI,CAAC,cAAc,EAAE,IAAI,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;IAClG,CAAC;CACF,CAAA;AAzBa;IAAX,QAAQ,EAAE;8CAAgC;AAE1B;IAAhB,KAAK,EAAE;0CAA2B;AAJxB,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CA2BxB","sourcesContent":["import { LitElement, html } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { parseTimestamp, formatRelativeTime } from \"./utils/time.js\";\n\nconst REFRESH_INTERVAL_MS = 60_000;\n\n/**\n * Inline relative-time display (e.g. \"3 hours ago\"). Accepts either a\n * standard ISO 8601 string or a SQLite `datetime('now')` string\n * (\"YYYY-MM-DD HH:MM:SS\", UTC, no zone marker) via `datetime`. Shows the\n * full date/time in the viewer's local timezone as a hover tooltip, and\n * re-renders on an interval so the text stays current while visible.\n *\n * @element relative-time\n */\n@customElement(\"relative-time\")\nexport class RelativeTime extends LitElement {\n /** Timestamp to render, relative to now. */\n @property() datetime: string | null = null;\n\n @state() private _now = Date.now();\n\n private _timer: ReturnType<typeof setInterval> | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n this._timer = setInterval(() => {\n this._now = Date.now();\n }, REFRESH_INTERVAL_MS);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this._timer != null) clearInterval(this._timer);\n this._timer = null;\n }\n\n override render() {\n if (!this.datetime) return html``;\n const date = parseTimestamp(this.datetime);\n if (Number.isNaN(date.getTime())) return html`${this.datetime}`;\n return html`<span title=${date.toLocaleString()}>${formatRelativeTime(date, this._now)}</span>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"relative-time\": RelativeTime;\n }\n}\n"]}
|
package/dist/reveal-button.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare class RevealButton extends LitElement {
|
|
|
8
8
|
static styles: import("lit").CSSResult[];
|
|
9
9
|
/** Label shown on the button before it's clicked. */
|
|
10
10
|
label: string;
|
|
11
|
+
/** Disables revealing the slotted content. */
|
|
12
|
+
disabled: boolean;
|
|
11
13
|
private _reveal;
|
|
12
14
|
protected render(): import("lit-html").TemplateResult<1>;
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reveal-button.d.ts","sourceRoot":"","sources":["../src/reveal-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;GAIG;AACH,qBACa,YAAa,SAAQ,UAAU;IAC1C,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"reveal-button.d.ts","sourceRoot":"","sources":["../src/reveal-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;GAIG;AACH,qBACa,YAAa,SAAQ,UAAU;IAC1C,OAAgB,MAAM,4BAgDpB;IAEF,qDAAqD;IAErD,KAAK,EAAE,MAAM,CAA2B;IACxC,8CAA8C;IACjB,QAAQ,UAAS;IAE9C,OAAO,CAAC,OAAO;IAQf,UAAmB,MAAM,yCAOxB;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
|
package/dist/reveal-button.js
CHANGED
|
@@ -17,6 +17,8 @@ let RevealButton = class RevealButton extends LitElement {
|
|
|
17
17
|
super(...arguments);
|
|
18
18
|
/** Label shown on the button before it's clicked. */
|
|
19
19
|
this.label = "Reveal hidden content";
|
|
20
|
+
/** Disables revealing the slotted content. */
|
|
21
|
+
this.disabled = false;
|
|
20
22
|
}
|
|
21
23
|
static { this.styles = [
|
|
22
24
|
tokens,
|
|
@@ -25,21 +27,51 @@ let RevealButton = class RevealButton extends LitElement {
|
|
|
25
27
|
display: none;
|
|
26
28
|
}
|
|
27
29
|
button {
|
|
28
|
-
font-family: var(
|
|
30
|
+
font-family: var(
|
|
31
|
+
--ui-font,
|
|
32
|
+
ui-sans-serif,
|
|
33
|
+
system-ui,
|
|
34
|
+
sans-serif,
|
|
35
|
+
"Apple Color Emoji",
|
|
36
|
+
"Segoe UI Emoji",
|
|
37
|
+
"Segoe UI Symbol",
|
|
38
|
+
"Noto Color Emoji"
|
|
39
|
+
);
|
|
29
40
|
font-size: var(--ui-font-size, 0.875rem);
|
|
30
41
|
background: var(--ui-primary, #4f46e5);
|
|
31
|
-
color: #
|
|
42
|
+
color: var(--ui-on-accent, #ffffff);
|
|
32
43
|
border: none;
|
|
33
44
|
border-radius: var(--ui-radius-sm, 0.25rem);
|
|
34
|
-
padding: 0.5rem
|
|
45
|
+
padding: 0.5rem 1rem;
|
|
35
46
|
cursor: pointer;
|
|
36
47
|
}
|
|
37
|
-
button:hover {
|
|
48
|
+
button:hover:not(:disabled) {
|
|
38
49
|
background: var(--ui-primary-hover, #4338ca);
|
|
39
50
|
}
|
|
51
|
+
button:disabled {
|
|
52
|
+
cursor: not-allowed;
|
|
53
|
+
opacity: 0.6;
|
|
54
|
+
}
|
|
55
|
+
button:focus-visible {
|
|
56
|
+
outline: none;
|
|
57
|
+
box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));
|
|
58
|
+
}
|
|
59
|
+
@media (forced-colors: active) {
|
|
60
|
+
button:focus-visible {
|
|
61
|
+
outline: 2px solid CanvasText;
|
|
62
|
+
outline-offset: 2px;
|
|
63
|
+
box-shadow: none;
|
|
64
|
+
}
|
|
65
|
+
button:disabled {
|
|
66
|
+
color: GrayText;
|
|
67
|
+
opacity: 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
40
70
|
`,
|
|
41
71
|
]; }
|
|
42
72
|
_reveal() {
|
|
73
|
+
if (this.disabled)
|
|
74
|
+
return;
|
|
43
75
|
const div = this.shadowRoot.querySelector("div");
|
|
44
76
|
const button = this.shadowRoot.querySelector("button");
|
|
45
77
|
div?.classList.toggle("hidden");
|
|
@@ -48,13 +80,18 @@ let RevealButton = class RevealButton extends LitElement {
|
|
|
48
80
|
render() {
|
|
49
81
|
return html `
|
|
50
82
|
<div class="hidden"><slot></slot></div>
|
|
51
|
-
<button
|
|
83
|
+
<button type="button" ?disabled=${this.disabled} @click=${this._reveal}>
|
|
84
|
+
${this.label}
|
|
85
|
+
</button>
|
|
52
86
|
`;
|
|
53
87
|
}
|
|
54
88
|
};
|
|
55
89
|
__decorate([
|
|
56
90
|
property({ type: String })
|
|
57
91
|
], RevealButton.prototype, "label", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
property({ type: Boolean })
|
|
94
|
+
], RevealButton.prototype, "disabled", void 0);
|
|
58
95
|
RevealButton = __decorate([
|
|
59
96
|
customElement("reveal-button")
|
|
60
97
|
], RevealButton);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reveal-button.js","sourceRoot":"","sources":["../src/reveal-button.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAArC;;
|
|
1
|
+
{"version":3,"file":"reveal-button.js","sourceRoot":"","sources":["../src/reveal-button.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAArC;;QAmDL,qDAAqD;QAErD,UAAK,GAAW,uBAAuB,CAAC;QACxC,8CAA8C;QACjB,aAAQ,GAAG,KAAK,CAAC;IAkBhD,CAAC;aAxEiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CF;KACF,AAhDqB,CAgDpB;IAQM,OAAO;QACb,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,UAAW,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxD,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAEkB,MAAM;QACvB,OAAO,IAAI,CAAA;;wCAEyB,IAAI,CAAC,QAAQ,WAAW,IAAI,CAAC,OAAO;UAClE,IAAI,CAAC,KAAK;;KAEf,CAAC;IACJ,CAAC;CACF,CAAA;AApBC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACa;AAEX;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;8CAAkB;AAvDnC,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CAyExB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * Button that reveals hidden slotted content when clicked.\n *\n * @element reveal-button\n */\n@customElement(\"reveal-button\")\nexport class RevealButton extends LitElement {\n static override styles = [\n tokens,\n css`\n .hidden {\n display: none;\n }\n button {\n font-family: var(\n --ui-font,\n ui-sans-serif,\n system-ui,\n sans-serif,\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"Segoe UI Symbol\",\n \"Noto Color Emoji\"\n );\n font-size: var(--ui-font-size, 0.875rem);\n background: var(--ui-primary, #4f46e5);\n color: var(--ui-on-accent, #ffffff);\n border: none;\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 0.5rem 1rem;\n cursor: pointer;\n }\n button:hover:not(:disabled) {\n background: var(--ui-primary-hover, #4338ca);\n }\n button:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n @media (forced-colors: active) {\n button:focus-visible {\n outline: 2px solid CanvasText;\n outline-offset: 2px;\n box-shadow: none;\n }\n button:disabled {\n color: GrayText;\n opacity: 1;\n }\n }\n `,\n ];\n\n /** Label shown on the button before it's clicked. */\n @property({ type: String })\n label: string = \"Reveal hidden content\";\n /** Disables revealing the slotted content. */\n @property({ type: Boolean }) disabled = false;\n\n private _reveal() {\n if (this.disabled) return;\n const div = this.shadowRoot!.querySelector(\"div\");\n const button = this.shadowRoot!.querySelector(\"button\");\n div?.classList.toggle(\"hidden\");\n button?.classList.toggle(\"hidden\");\n }\n\n protected override render() {\n return html`\n <div class=\"hidden\"><slot></slot></div>\n <button type=\"button\" ?disabled=${this.disabled} @click=${this._reveal}>\n ${this.label}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"reveal-button\": RevealButton;\n }\n}\n"]}
|
package/dist/roman-numeral.js
CHANGED
|
@@ -31,7 +31,7 @@ let RomanNumeral = class RomanNumeral extends LitElement {
|
|
|
31
31
|
return html `${this._convertToRoman(this.value)}`;
|
|
32
32
|
}
|
|
33
33
|
_convertToRoman(num) {
|
|
34
|
-
if (!num) {
|
|
34
|
+
if (num == null || !Number.isInteger(num) || num <= 0) {
|
|
35
35
|
return "NaN";
|
|
36
36
|
}
|
|
37
37
|
let remaining = num;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roman-numeral.js","sourceRoot":"","sources":["../src/roman-numeral.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,cAAc,GAA2B;IAC7C,CAAC,EAAE,IAAI;IACP,EAAE,EAAE,GAAG;IACP,CAAC,EAAE,GAAG;IACN,EAAE,EAAE,GAAG;IACP,CAAC,EAAE,GAAG;IACN,EAAE,EAAE,EAAE;IACN,CAAC,EAAE,EAAE;IACL,EAAE,EAAE,EAAE;IACN,CAAC,EAAE,EAAE;IACL,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,CAAC;IACJ,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,CAAC;CACL,CAAC;AAEF;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAKvB,MAAM;QACvB,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACnD,CAAC;IAEO,eAAe,CAAC,GAAY;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"roman-numeral.js","sourceRoot":"","sources":["../src/roman-numeral.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,cAAc,GAA2B;IAC7C,CAAC,EAAE,IAAI;IACP,EAAE,EAAE,GAAG;IACP,CAAC,EAAE,GAAG;IACN,EAAE,EAAE,GAAG;IACP,CAAC,EAAE,GAAG;IACN,EAAE,EAAE,EAAE;IACN,CAAC,EAAE,EAAE;IACL,EAAE,EAAE,EAAE;IACN,CAAC,EAAE,EAAE;IACL,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,CAAC;IACJ,EAAE,EAAE,CAAC;IACL,CAAC,EAAE,CAAC;CACL,CAAC;AAEF;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAKvB,MAAM;QACvB,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACnD,CAAC;IAEO,eAAe,CAAC,GAAY;QAClC,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,SAAS,GAAG,GAAG,CAAC;QACpB,IAAI,GAAG,GAAG,EAAE,CAAC;QAEb,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7D,SAAS,IAAI,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAC5C,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAA;AAtBC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2CACZ;AAHJ,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CAyBxB","sourcesContent":["import { LitElement, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\n\nconst ROMAN_NUMERALS: Record<string, number> = {\n M: 1000,\n CM: 900,\n D: 500,\n CD: 400,\n C: 100,\n XC: 90,\n L: 50,\n XL: 40,\n X: 10,\n IX: 9,\n V: 5,\n IV: 4,\n I: 1,\n};\n\n/**\n * Converts an integer to a roman numeral inline.\n *\n * @element roman-numeral\n */\n@customElement(\"roman-numeral\")\nexport class RomanNumeral extends LitElement {\n /** Integer value to render as a roman numeral. */\n @property({ type: Number })\n value?: number;\n\n protected override render() {\n return html`${this._convertToRoman(this.value)}`;\n }\n\n private _convertToRoman(num?: number): string {\n if (num == null || !Number.isInteger(num) || num <= 0) {\n return \"NaN\";\n }\n\n let remaining = num;\n let str = \"\";\n\n for (const symbol of Object.keys(ROMAN_NUMERALS)) {\n const count = Math.floor(remaining / ROMAN_NUMERALS[symbol]);\n remaining -= count * ROMAN_NUMERALS[symbol];\n str += symbol.repeat(count);\n }\n\n return str;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"roman-numeral\": RomanNumeral;\n }\n}\n"]}
|
package/dist/slide-panel.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { LitElement } from "lit";
|
|
1
|
+
import { LitElement, type PropertyValues } from "lit";
|
|
2
2
|
/**
|
|
3
3
|
* Generic sliding panel shell. Handles positioning, open/close animation,
|
|
4
4
|
* header chrome, and a close button. Body content is provided via the
|
|
5
5
|
* default slot; the consumer controls its own padding and overflow.
|
|
6
6
|
*
|
|
7
|
-
* Desktop:
|
|
8
|
-
* Mobile (≤
|
|
7
|
+
* Desktop: fixed right-side panel that slides from the right.
|
|
8
|
+
* Mobile (≤48rem): bottom-sheet drawer (60vh) — reserved for future use.
|
|
9
9
|
*
|
|
10
10
|
* @element slide-panel
|
|
11
11
|
* @fires panel-close - User clicked the close (✕) button.
|
|
@@ -16,7 +16,11 @@ export declare class SlidePanel extends LitElement {
|
|
|
16
16
|
/** Title text shown in the panel header (overridable via slot="title"). */
|
|
17
17
|
heading: string;
|
|
18
18
|
static styles: import("lit").CSSResult[];
|
|
19
|
+
private _previousFocus;
|
|
19
20
|
private _close;
|
|
21
|
+
private _onWindowKeydown;
|
|
22
|
+
protected updated(changed: PropertyValues): void;
|
|
23
|
+
disconnectedCallback(): void;
|
|
20
24
|
render(): import("lit-html").TemplateResult<1>;
|
|
21
25
|
}
|
|
22
26
|
declare global {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slide-panel.d.ts","sourceRoot":"","sources":["../src/slide-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"slide-panel.d.ts","sourceRoot":"","sources":["../src/slide-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAM1E;;;;;;;;;;GAUG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,8CAA8C;IACjB,IAAI,UAAS;IAC1C,2EAA2E;IAC/D,OAAO,SAAM;IAEzB,OAAgB,MAAM,4BAuHpB;IAEF,OAAO,CAAC,cAAc,CAA4B;IAElD,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,gBAAgB,CAGtB;IAEF,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAaxD;IAEQ,oBAAoB,IAAI,IAAI,CAOpC;IAEQ,MAAM,yCAwBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
package/dist/slide-panel.js
CHANGED
|
@@ -4,17 +4,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
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
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { LitElement, css, html } from "lit";
|
|
7
|
+
import { LitElement, css, html, nothing } from "lit";
|
|
8
8
|
import { customElement, property } from "lit/decorators.js";
|
|
9
9
|
import { iconX } from "./icons.js";
|
|
10
10
|
import { tokens } from "./tokens.js";
|
|
11
|
+
import { activateLayer, claimEscape, deactivateLayer } from "./utils/layer-stack.js";
|
|
11
12
|
/**
|
|
12
13
|
* Generic sliding panel shell. Handles positioning, open/close animation,
|
|
13
14
|
* header chrome, and a close button. Body content is provided via the
|
|
14
15
|
* default slot; the consumer controls its own padding and overflow.
|
|
15
16
|
*
|
|
16
|
-
* Desktop:
|
|
17
|
-
* Mobile (≤
|
|
17
|
+
* Desktop: fixed right-side panel that slides from the right.
|
|
18
|
+
* Mobile (≤48rem): bottom-sheet drawer (60vh) — reserved for future use.
|
|
18
19
|
*
|
|
19
20
|
* @element slide-panel
|
|
20
21
|
* @fires panel-close - User clicked the close (✕) button.
|
|
@@ -26,6 +27,12 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
26
27
|
this.open = false;
|
|
27
28
|
/** Title text shown in the panel header (overridable via slot="title"). */
|
|
28
29
|
this.heading = "";
|
|
30
|
+
this._previousFocus = null;
|
|
31
|
+
this._onWindowKeydown = (event) => {
|
|
32
|
+
if (!this.open || !claimEscape(this, event))
|
|
33
|
+
return;
|
|
34
|
+
this._close();
|
|
35
|
+
};
|
|
29
36
|
}
|
|
30
37
|
static { this.styles = [
|
|
31
38
|
tokens,
|
|
@@ -38,12 +45,12 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
38
45
|
top: 0;
|
|
39
46
|
right: 0;
|
|
40
47
|
bottom: 0;
|
|
41
|
-
width:
|
|
42
|
-
z-index: 20;
|
|
43
|
-
background: var(--ui-surface, #
|
|
48
|
+
width: 18.75rem;
|
|
49
|
+
z-index: var(--component-layer-z, 20);
|
|
50
|
+
background: var(--ui-surface, #ffffff);
|
|
44
51
|
box-shadow: var(--ui-shadow-lg, 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1));
|
|
45
52
|
transform: translateX(110%);
|
|
46
|
-
transition: transform
|
|
53
|
+
transition: transform 250ms ease;
|
|
47
54
|
display: flex;
|
|
48
55
|
flex-direction: column;
|
|
49
56
|
overflow: hidden;
|
|
@@ -55,14 +62,23 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
55
62
|
display: flex;
|
|
56
63
|
align-items: center;
|
|
57
64
|
justify-content: space-between;
|
|
58
|
-
padding: 0.5rem
|
|
65
|
+
padding: 0.5rem;
|
|
59
66
|
border-bottom: 1px solid var(--ui-border, #e2e8f0);
|
|
60
67
|
flex: 0 0 auto;
|
|
61
68
|
}
|
|
62
69
|
.panel-title {
|
|
63
70
|
font-weight: 600;
|
|
64
71
|
font-size: var(--ui-font-size, 0.875rem);
|
|
65
|
-
font-family: var(
|
|
72
|
+
font-family: var(
|
|
73
|
+
--ui-font,
|
|
74
|
+
ui-sans-serif,
|
|
75
|
+
system-ui,
|
|
76
|
+
sans-serif,
|
|
77
|
+
"Apple Color Emoji",
|
|
78
|
+
"Segoe UI Emoji",
|
|
79
|
+
"Segoe UI Symbol",
|
|
80
|
+
"Noto Color Emoji"
|
|
81
|
+
);
|
|
66
82
|
color: var(--ui-text, #0f172a);
|
|
67
83
|
flex: 1 1 auto;
|
|
68
84
|
overflow: hidden;
|
|
@@ -85,10 +101,26 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
85
101
|
.close-btn:hover {
|
|
86
102
|
background: var(--ui-surface-muted, #f8fafc);
|
|
87
103
|
}
|
|
104
|
+
.close-btn:focus-visible {
|
|
105
|
+
outline: none;
|
|
106
|
+
box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));
|
|
107
|
+
}
|
|
88
108
|
.handle {
|
|
89
109
|
display: none;
|
|
90
110
|
}
|
|
91
|
-
@media (
|
|
111
|
+
@media (prefers-reduced-motion: reduce) {
|
|
112
|
+
.panel {
|
|
113
|
+
transition: none;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
@media (forced-colors: active) {
|
|
117
|
+
.close-btn:focus-visible {
|
|
118
|
+
outline: 2px solid CanvasText;
|
|
119
|
+
outline-offset: 2px;
|
|
120
|
+
box-shadow: none;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
@media (max-width: 48rem) {
|
|
92
124
|
.panel {
|
|
93
125
|
top: auto;
|
|
94
126
|
right: 0;
|
|
@@ -96,8 +128,12 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
96
128
|
left: 0;
|
|
97
129
|
width: auto;
|
|
98
130
|
height: 60vh;
|
|
99
|
-
border-radius:
|
|
100
|
-
box-shadow:
|
|
131
|
+
border-radius: var(--ui-radius, 0.5rem) var(--ui-radius, 0.5rem) 0 0;
|
|
132
|
+
box-shadow: var(
|
|
133
|
+
--ui-shadow-lg,
|
|
134
|
+
0 20px 25px -5px rgb(0 0 0 / 0.1),
|
|
135
|
+
0 8px 10px -6px rgb(0 0 0 / 0.1)
|
|
136
|
+
);
|
|
101
137
|
transform: translateY(110%);
|
|
102
138
|
}
|
|
103
139
|
.panel.open {
|
|
@@ -105,15 +141,15 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
105
141
|
}
|
|
106
142
|
.handle {
|
|
107
143
|
display: block;
|
|
108
|
-
width:
|
|
109
|
-
height:
|
|
144
|
+
width: 2.25rem;
|
|
145
|
+
height: 0.25rem;
|
|
110
146
|
background: var(--ui-border, #e2e8f0);
|
|
111
|
-
border-radius:
|
|
112
|
-
margin:
|
|
147
|
+
border-radius: 9999px;
|
|
148
|
+
margin: 0.5rem auto 0;
|
|
113
149
|
flex: 0 0 auto;
|
|
114
150
|
}
|
|
115
151
|
.panel-header {
|
|
116
|
-
padding:
|
|
152
|
+
padding: 0.25rem 0.5rem 0.5rem;
|
|
117
153
|
}
|
|
118
154
|
}
|
|
119
155
|
`,
|
|
@@ -121,15 +157,51 @@ let SlidePanel = class SlidePanel extends LitElement {
|
|
|
121
157
|
_close() {
|
|
122
158
|
this.dispatchEvent(new CustomEvent("panel-close", { bubbles: true, composed: true }));
|
|
123
159
|
}
|
|
160
|
+
updated(changed) {
|
|
161
|
+
if (!changed.has("open"))
|
|
162
|
+
return;
|
|
163
|
+
if (this.open) {
|
|
164
|
+
activateLayer(this);
|
|
165
|
+
this._previousFocus = document.activeElement;
|
|
166
|
+
window.addEventListener("keydown", this._onWindowKeydown);
|
|
167
|
+
this.shadowRoot?.querySelector(".close-btn")?.focus();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
deactivateLayer(this);
|
|
171
|
+
window.removeEventListener("keydown", this._onWindowKeydown);
|
|
172
|
+
if (this._previousFocus?.isConnected)
|
|
173
|
+
this._previousFocus.focus();
|
|
174
|
+
this._previousFocus = null;
|
|
175
|
+
}
|
|
176
|
+
disconnectedCallback() {
|
|
177
|
+
super.disconnectedCallback();
|
|
178
|
+
window.removeEventListener("keydown", this._onWindowKeydown);
|
|
179
|
+
deactivateLayer(this);
|
|
180
|
+
if (this._previousFocus?.isConnected)
|
|
181
|
+
this._previousFocus.focus();
|
|
182
|
+
this._previousFocus = null;
|
|
183
|
+
this.open = false;
|
|
184
|
+
}
|
|
124
185
|
render() {
|
|
186
|
+
const explicitLabel = this.getAttribute("aria-label");
|
|
125
187
|
return html `
|
|
126
|
-
<div
|
|
127
|
-
|
|
188
|
+
<div
|
|
189
|
+
class="panel ${this.open ? "open" : ""}"
|
|
190
|
+
role="dialog"
|
|
191
|
+
aria-modal="false"
|
|
192
|
+
aria-label=${explicitLabel ?? nothing}
|
|
193
|
+
aria-labelledby=${explicitLabel ? nothing : "panel-title"}
|
|
194
|
+
aria-hidden=${String(!this.open)}
|
|
195
|
+
?inert=${!this.open}
|
|
196
|
+
>
|
|
197
|
+
<div class="handle" aria-hidden="true"></div>
|
|
128
198
|
<div class="panel-header">
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
</
|
|
132
|
-
<button class="close-btn" aria-label="Close panel" @click=${this._close}
|
|
199
|
+
<span id="panel-title" class="panel-title">
|
|
200
|
+
<slot name="title">${this.heading || "Panel"}</slot>
|
|
201
|
+
</span>
|
|
202
|
+
<button class="close-btn" aria-label="Close panel" @click=${this._close}>
|
|
203
|
+
<span aria-hidden="true">${iconX(18)}</span>
|
|
204
|
+
</button>
|
|
133
205
|
</div>
|
|
134
206
|
<slot></slot>
|
|
135
207
|
</div>
|