@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.
Files changed (193) hide show
  1. package/README.md +76 -47
  2. package/custom-elements.json +3049 -910
  3. package/dist/address-autocomplete.d.ts +8 -0
  4. package/dist/address-autocomplete.d.ts.map +1 -1
  5. package/dist/address-autocomplete.js +165 -15
  6. package/dist/address-autocomplete.js.map +1 -1
  7. package/dist/animate-confetti.d.ts +8 -5
  8. package/dist/animate-confetti.d.ts.map +1 -1
  9. package/dist/animate-confetti.js +46 -19
  10. package/dist/animate-confetti.js.map +1 -1
  11. package/dist/autocomplete-input.d.ts +8 -0
  12. package/dist/autocomplete-input.d.ts.map +1 -1
  13. package/dist/autocomplete-input.js +165 -15
  14. package/dist/autocomplete-input.js.map +1 -1
  15. package/dist/calendar-entry.d.ts +33 -0
  16. package/dist/calendar-entry.d.ts.map +1 -0
  17. package/dist/calendar-entry.js +64 -0
  18. package/dist/calendar-entry.js.map +1 -0
  19. package/dist/calendar-month.d.ts +67 -0
  20. package/dist/calendar-month.d.ts.map +1 -0
  21. package/dist/calendar-month.js +469 -0
  22. package/dist/calendar-month.js.map +1 -0
  23. package/dist/calendar-year.d.ts +43 -0
  24. package/dist/calendar-year.d.ts.map +1 -0
  25. package/dist/calendar-year.js +145 -0
  26. package/dist/calendar-year.js.map +1 -0
  27. package/dist/chat-message.d.ts.map +1 -1
  28. package/dist/chat-message.js +77 -24
  29. package/dist/chat-message.js.map +1 -1
  30. package/dist/confirm-dialog.d.ts +8 -1
  31. package/dist/confirm-dialog.d.ts.map +1 -1
  32. package/dist/confirm-dialog.js +130 -18
  33. package/dist/confirm-dialog.js.map +1 -1
  34. package/dist/copy-link-button.d.ts +2 -0
  35. package/dist/copy-link-button.d.ts.map +1 -1
  36. package/dist/copy-link-button.js +35 -3
  37. package/dist/copy-link-button.js.map +1 -1
  38. package/dist/data-table.d.ts +2 -0
  39. package/dist/data-table.d.ts.map +1 -1
  40. package/dist/data-table.js +83 -11
  41. package/dist/data-table.js.map +1 -1
  42. package/dist/distance-value.d.ts +0 -1
  43. package/dist/distance-value.d.ts.map +1 -1
  44. package/dist/distance-value.js +3 -8
  45. package/dist/distance-value.js.map +1 -1
  46. package/dist/distribution-chart.d.ts.map +1 -1
  47. package/dist/distribution-chart.js +54 -17
  48. package/dist/distribution-chart.js.map +1 -1
  49. package/dist/dropdown-button.d.ts.map +1 -1
  50. package/dist/dropdown-button.js +60 -11
  51. package/dist/dropdown-button.js.map +1 -1
  52. package/dist/editable-text.d.ts.map +1 -1
  53. package/dist/editable-text.js +46 -13
  54. package/dist/editable-text.js.map +1 -1
  55. package/dist/form-select.d.ts +21 -2
  56. package/dist/form-select.d.ts.map +1 -1
  57. package/dist/form-select.js +489 -37
  58. package/dist/form-select.js.map +1 -1
  59. package/dist/frame-box.d.ts.map +1 -1
  60. package/dist/frame-box.js +20 -12
  61. package/dist/frame-box.js.map +1 -1
  62. package/dist/icon-button.d.ts.map +1 -1
  63. package/dist/icon-button.js +11 -0
  64. package/dist/icon-button.js.map +1 -1
  65. package/dist/index.d.ts +4 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +4 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/kbd-hint.d.ts +30 -0
  70. package/dist/kbd-hint.d.ts.map +1 -0
  71. package/dist/kbd-hint.js +184 -0
  72. package/dist/kbd-hint.js.map +1 -0
  73. package/dist/live-timer.d.ts +0 -1
  74. package/dist/live-timer.d.ts.map +1 -1
  75. package/dist/live-timer.js +1 -6
  76. package/dist/live-timer.js.map +1 -1
  77. package/dist/map-circle.d.ts +3 -0
  78. package/dist/map-circle.d.ts.map +1 -1
  79. package/dist/map-circle.js +19 -1
  80. package/dist/map-circle.js.map +1 -1
  81. package/dist/map-pin.d.ts.map +1 -1
  82. package/dist/map-pin.js +16 -1
  83. package/dist/map-pin.js.map +1 -1
  84. package/dist/percent-bar-chart.d.ts +3 -0
  85. package/dist/percent-bar-chart.d.ts.map +1 -1
  86. package/dist/percent-bar-chart.js +60 -4
  87. package/dist/percent-bar-chart.js.map +1 -1
  88. package/dist/photo-gallery.d.ts.map +1 -1
  89. package/dist/photo-gallery.js +12 -3
  90. package/dist/photo-gallery.js.map +1 -1
  91. package/dist/popover-panel.d.ts.map +1 -1
  92. package/dist/popover-panel.js +132 -23
  93. package/dist/popover-panel.js.map +1 -1
  94. package/dist/price-history-chart.d.ts.map +1 -1
  95. package/dist/price-history-chart.js +52 -18
  96. package/dist/price-history-chart.js.map +1 -1
  97. package/dist/radio-cards.d.ts +2 -0
  98. package/dist/radio-cards.d.ts.map +1 -1
  99. package/dist/radio-cards.js +51 -5
  100. package/dist/radio-cards.js.map +1 -1
  101. package/dist/radio-pills.d.ts +2 -0
  102. package/dist/radio-pills.d.ts.map +1 -1
  103. package/dist/radio-pills.js +46 -4
  104. package/dist/radio-pills.js.map +1 -1
  105. package/dist/relative-time.d.ts +0 -1
  106. package/dist/relative-time.d.ts.map +1 -1
  107. package/dist/relative-time.js +1 -6
  108. package/dist/relative-time.js.map +1 -1
  109. package/dist/reveal-button.d.ts +2 -0
  110. package/dist/reveal-button.d.ts.map +1 -1
  111. package/dist/reveal-button.js +42 -5
  112. package/dist/reveal-button.js.map +1 -1
  113. package/dist/roman-numeral.js +1 -1
  114. package/dist/roman-numeral.js.map +1 -1
  115. package/dist/slide-panel.d.ts +7 -3
  116. package/dist/slide-panel.d.ts.map +1 -1
  117. package/dist/slide-panel.js +95 -23
  118. package/dist/slide-panel.js.map +1 -1
  119. package/dist/stat-meter.d.ts.map +1 -1
  120. package/dist/stat-meter.js +17 -7
  121. package/dist/stat-meter.js.map +1 -1
  122. package/dist/status-pill.d.ts.map +1 -1
  123. package/dist/status-pill.js +26 -12
  124. package/dist/status-pill.js.map +1 -1
  125. package/dist/tile-grid.d.ts +8 -0
  126. package/dist/tile-grid.d.ts.map +1 -1
  127. package/dist/tile-grid.js +88 -12
  128. package/dist/tile-grid.js.map +1 -1
  129. package/dist/toast-notification.d.ts.map +1 -1
  130. package/dist/toast-notification.js +40 -11
  131. package/dist/toast-notification.js.map +1 -1
  132. package/dist/tokens.css +23 -0
  133. package/dist/tokens.d.ts.map +1 -1
  134. package/dist/tokens.js +16 -0
  135. package/dist/tokens.js.map +1 -1
  136. package/dist/ui-button.d.ts +2 -0
  137. package/dist/ui-button.d.ts.map +1 -1
  138. package/dist/ui-button.js +58 -9
  139. package/dist/ui-button.js.map +1 -1
  140. package/dist/user-avatar.d.ts.map +1 -1
  141. package/dist/user-avatar.js +18 -3
  142. package/dist/user-avatar.js.map +1 -1
  143. package/dist/utils/calendar.d.ts +77 -0
  144. package/dist/utils/calendar.d.ts.map +1 -0
  145. package/dist/utils/calendar.js +135 -0
  146. package/dist/utils/calendar.js.map +1 -0
  147. package/dist/utils/form.d.ts +3 -0
  148. package/dist/utils/form.d.ts.map +1 -0
  149. package/dist/utils/form.js +14 -0
  150. package/dist/utils/form.js.map +1 -0
  151. package/dist/utils/layer-stack.d.ts +9 -0
  152. package/dist/utils/layer-stack.d.ts.map +1 -0
  153. package/dist/utils/layer-stack.js +35 -0
  154. package/dist/utils/layer-stack.js.map +1 -0
  155. package/dist/weight-bar-chart.d.ts.map +1 -1
  156. package/dist/weight-bar-chart.js +27 -8
  157. package/dist/weight-bar-chart.js.map +1 -1
  158. package/docs/address-autocomplete.md +5 -0
  159. package/docs/autocomplete-input.md +5 -0
  160. package/docs/calendar-entry.md +53 -0
  161. package/docs/calendar-month.md +79 -0
  162. package/docs/calendar-year.md +53 -0
  163. package/docs/chat-message.md +4 -0
  164. package/docs/confirm-dialog.md +2 -0
  165. package/docs/copy-link-button.md +2 -0
  166. package/docs/data-table.md +2 -0
  167. package/docs/design-language.md +149 -0
  168. package/docs/distribution-chart.md +4 -0
  169. package/docs/dropdown-button.md +1 -0
  170. package/docs/form-select.md +15 -3
  171. package/docs/frame-box.md +2 -0
  172. package/docs/kbd-hint.md +42 -0
  173. package/docs/map-circle.md +4 -0
  174. package/docs/percent-bar-chart.md +4 -1
  175. package/docs/photo-gallery.md +1 -0
  176. package/docs/popover-panel.md +2 -0
  177. package/docs/price-history-chart.md +8 -1
  178. package/docs/radio-cards.md +2 -0
  179. package/docs/radio-pills.md +2 -0
  180. package/docs/reveal-button.md +3 -0
  181. package/docs/slide-panel.md +4 -2
  182. package/docs/status-pill.md +3 -0
  183. package/docs/tile-grid.md +10 -1
  184. package/docs/toast-notification.md +4 -1
  185. package/docs/ui-button.md +2 -0
  186. package/docs/user-avatar.md +1 -0
  187. package/llms.txt +175 -61
  188. package/package.json +14 -2
  189. package/dist/map-point.d.ts +0 -31
  190. package/dist/map-point.d.ts.map +0 -1
  191. package/dist/map-point.js +0 -83
  192. package/dist/map-point.js.map +0 -1
  193. package/docs/map-point.md +0 -44
@@ -1 +1 @@
1
- {"version":3,"file":"form-select.js","sourceRoot":"","sources":["../src/form-select.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\n/** A single selectable option. */\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\n/**\n * A styled dropdown select: a trigger button showing the current option's\n * label, opening a listbox popover on click. Drop-in generic replacement for\n * a native `<select>` wherever consistent cross-browser styling and a\n * `change` event carrying `{ value }` are wanted (e.g. a task's status\n * picker).\n *\n * The trigger fills its host's width (`justify-content: space-between`\n * pushes the chevron to the far edge), but the host itself stays\n * `display: inline-block` — so usages that never size the host (a filter\n * bar, a status picker) keep shrink-to-fit auto-width unchanged. To make an\n * instance full-width, size the host itself: `form-select { width: 100%; }`.\n *\n * @element form-select\n * @fires change - Fired with `{ value: string }` when a different option is picked.\n */\n@customElement(\"form-select\")\nexport class FormSelect extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-font-size-sm, 0.75rem);\n }\n button.trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.35rem;\n width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface, #fff);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 0.3rem 0.5rem;\n cursor: pointer;\n }\n button.trigger:hover {\n background: var(--ui-surface-muted, #f8fafc);\n }\n button.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n button.trigger:focus-visible {\n outline: none;\n border-color: var(--ui-primary, #4f46e5);\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .chevron {\n display: flex;\n color: var(--ui-text-muted, #64748b);\n transform: rotate(90deg);\n transition: transform 0.1s ease;\n }\n :host([open]) .chevron {\n transform: rotate(-90deg);\n }\n ul.options {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 10;\n min-width: 100%;\n max-height: 40vh;\n overflow-y: auto;\n margin: 2px 0 0;\n padding: 4px 0;\n list-style: none;\n white-space: nowrap;\n background: var(--ui-surface, #fff);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n box-shadow: var(--ui-shadow, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1));\n }\n li {\n padding: 0.35rem 0.6rem;\n cursor: pointer;\n }\n li.active,\n li:hover {\n background: var(--ui-surface-muted, #f8fafc);\n }\n li[aria-selected=\"true\"] {\n font-weight: 600;\n color: var(--ui-primary, #4f46e5);\n }\n `,\n ];\n\n /** The full list of selectable options. */\n @property({ attribute: false }) options: SelectOption[] = [];\n /** Currently selected value; must match one of `options[].value`. */\n @property() value = \"\";\n /** `aria-label` applied to the trigger button. */\n @property() label = \"\";\n /** Disables the trigger, preventing the popover from opening. */\n @property({ type: Boolean }) disabled = false;\n\n @state() private _open = false;\n @state() private _activeIndex = -1;\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener(\"mousedown\", this.#onWindowMousedown, true);\n }\n\n protected override updated(changed: PropertyValues): void {\n if (!changed.has(\"_open\")) return;\n this.toggleAttribute(\"open\", this._open);\n if (this._open) {\n window.addEventListener(\"mousedown\", this.#onWindowMousedown, true);\n } else {\n window.removeEventListener(\"mousedown\", this.#onWindowMousedown, true);\n }\n }\n\n #onWindowMousedown = (e: MouseEvent): void => {\n if (!e.composedPath().includes(this)) this._open = false;\n };\n\n #toggle(): void {\n if (this.disabled) return;\n this._open = !this._open;\n if (this._open) {\n this._activeIndex = Math.max(\n 0,\n this.options.findIndex((o) => o.value === this.value),\n );\n }\n }\n\n #select(option: SelectOption): void {\n this._open = false;\n if (option.value === this.value) return;\n this.value = option.value;\n this.dispatchEvent(new CustomEvent(\"change\", { detail: { value: option.value } }));\n }\n\n #onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!this._open) {\n this.#toggle();\n return;\n }\n if (e.key === \"ArrowDown\") this.#moveActive(1);\n else if (e.key === \"ArrowUp\") this.#moveActive(-1);\n else this.#confirmActive();\n } else if (e.key === \"Escape\" && this._open) {\n e.preventDefault();\n this._open = false;\n }\n }\n\n #moveActive(delta: number): void {\n if (this.options.length === 0) return;\n const n = this.options.length;\n this._activeIndex = (this._activeIndex + delta + n) % n;\n }\n\n #confirmActive(): void {\n const option = this.options[this._activeIndex];\n if (option) this.#select(option);\n }\n\n private renderListbox() {\n if (!this._open) return nothing;\n return html`\n <ul class=\"options\" role=\"listbox\">\n ${this.options.map(\n (o, i) => html`\n <li\n role=\"option\"\n aria-selected=${o.value === this.value}\n class=${i === this._activeIndex ? \"active\" : \"\"}\n @mousedown=${(e: MouseEvent) => {\n e.preventDefault();\n this.#select(o);\n }}\n >\n ${o.label}\n </li>\n `,\n )}\n </ul>\n `;\n }\n\n override render() {\n const current = this.options.find((o) => o.value === this.value);\n return html`\n <button\n type=\"button\"\n class=\"trigger\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this._open}\n aria-label=${this.label || nothing}\n ?disabled=${this.disabled}\n @click=${() => this.#toggle()}\n @keydown=${(e: KeyboardEvent) => this.#onTriggerKeydown(e)}\n >\n <span>${current?.label ?? this.value}</span>\n <span class=\"chevron\">${iconChevronRight(14)}</span>\n </button>\n ${this.renderListbox()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"form-select\": FormSelect;\n }\n}\n"]}
1
+ {"version":3,"file":"form-select.js","sourceRoot":"","sources":["../src/form-select.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LitElement,\n css,\n html,\n nothing,\n type PropertyValues,\n type TemplateResult,\n} from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { iconChevronRight } from \"./icons.js\";\nimport { tokens } from \"./tokens.js\";\n\nlet instanceCount = 0;\n\n/** A single selectable option. */\nexport interface SelectOption {\n value: string;\n label: string;\n /** Optional pre-rendered icon template displayed before the label. */\n icon?: TemplateResult;\n /** Square icon size in pixels. Defaults to 16 when `icon` is set. */\n iconSize?: number;\n}\n\n/**\n * A styled dropdown select: a trigger button showing the current option's\n * label, opening a listbox popover on click. Drop-in generic replacement for\n * a native `<select>` wherever consistent cross-browser styling and a\n * `change` event carrying `{ value }` are wanted (e.g. a task's status\n * picker).\n *\n * The trigger fills its host's width (`justify-content: space-between`\n * pushes the chevron to the far edge), but the host itself stays\n * `display: inline-block` — so usages that never size the host (a filter\n * bar, a status picker) keep shrink-to-fit auto-width unchanged. To make an\n * instance full-width, size the host itself: `form-select { width: 100%; }`.\n *\n * Set `searchable` to replace the button trigger with an editable combobox\n * that filters the predefined options by case-insensitive label infix. Typed\n * text is only a query: `value` changes exclusively when an actual option is\n * selected, and an uncommitted query is discarded when the list closes.\n * Each option may also provide a pre-rendered `icon` and square `iconSize`;\n * iconless options reserve no leading space.\n *\n * @element form-select\n * @fires change - Fired with `{ value: string }` when a different option is picked.\n */\n@customElement(\"form-select\")\nexport class FormSelect extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\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 button.trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.25rem;\n width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface, #ffffff);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 0.25rem 0.5rem;\n cursor: pointer;\n }\n button.trigger:hover:not(:disabled) {\n background: var(--ui-surface-muted, #f8fafc);\n }\n button.trigger:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n button.trigger:focus-visible {\n outline: none;\n border-color: var(--ui-primary, #4f46e5);\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .search-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.25rem;\n width: 100%;\n box-sizing: border-box;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface, #ffffff);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n cursor: text;\n }\n .search-trigger:hover:not(.disabled) {\n background: var(--ui-surface-muted, #f8fafc);\n }\n .search-trigger:not(.disabled):focus-within {\n border-color: var(--ui-primary, #4f46e5);\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));\n }\n .search-trigger.disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n .search-trigger.has-icon input.search-input {\n padding-left: 0;\n }\n input.search-input {\n min-width: 0;\n flex: 1;\n box-sizing: border-box;\n padding: 0.25rem 0 0.25rem 0.5rem;\n color: inherit;\n background: transparent;\n border: 0;\n outline: 0;\n font: inherit;\n }\n .chevron {\n display: flex;\n flex: 0 0 auto;\n margin-right: 0.5rem;\n color: var(--ui-text-muted, #64748b);\n pointer-events: none;\n transform: rotate(90deg);\n transition: transform 150ms ease;\n }\n button.trigger .chevron {\n margin-right: 0;\n }\n :host([open]) .chevron {\n transform: rotate(-90deg);\n }\n ul.options {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 10;\n min-width: 100%;\n max-height: 40vh;\n overflow-y: auto;\n scrollbar-gutter: stable;\n margin: 0.25rem 0 0;\n padding: 0.25rem 0;\n list-style: none;\n white-space: nowrap;\n color: var(--ui-text, #0f172a);\n background: var(--ui-surface, #ffffff);\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n box-shadow: var(--ui-shadow, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1));\n }\n ul.options::-webkit-scrollbar {\n width: 0.75rem;\n }\n ul.options::-webkit-scrollbar-thumb {\n background: var(--ui-border, #e2e8f0);\n border: 0.25rem solid transparent;\n border-radius: 999px;\n background-clip: padding-box;\n }\n li {\n padding: 0.5rem;\n cursor: pointer;\n }\n li.active,\n li:hover {\n background: var(--ui-surface-muted, #f8fafc);\n }\n li[aria-selected=\"true\"] {\n font-weight: 600;\n color: var(--ui-primary, #4f46e5);\n }\n .option-content {\n display: inline-flex;\n min-width: 0;\n align-items: center;\n gap: 0.5rem;\n }\n li .option-content {\n display: flex;\n width: 100%;\n }\n .option-icon {\n display: inline-flex;\n width: var(--form-select-icon-size);\n height: var(--form-select-icon-size);\n flex: 0 0 var(--form-select-icon-size);\n align-items: center;\n justify-content: center;\n }\n .option-icon > svg {\n width: 100%;\n height: 100%;\n }\n .selected-icon {\n margin-left: 0.5rem;\n }\n .option-label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n li.no-options {\n padding: 0.5rem;\n color: var(--ui-text-muted, #64748b);\n cursor: default;\n font-style: italic;\n }\n @media (prefers-reduced-motion: reduce) {\n .chevron {\n transition: none;\n }\n }\n @media (forced-colors: active) {\n button.trigger:focus-visible,\n .search-trigger:not(.disabled):focus-within {\n outline: 2px solid CanvasText;\n outline-offset: 2px;\n box-shadow: none;\n }\n button.trigger:disabled,\n .search-trigger.disabled {\n color: GrayText;\n opacity: 1;\n }\n li.active,\n li:hover {\n color: HighlightText;\n background: Highlight;\n }\n li[aria-selected=\"true\"] {\n color: Highlight;\n }\n li.active[aria-selected=\"true\"],\n li[aria-selected=\"true\"]:hover {\n color: HighlightText;\n }\n }\n `,\n ];\n\n /** The full list of selectable options. */\n @property({ attribute: false }) options: SelectOption[] = [];\n /** Currently selected value; must match one of `options[].value`. */\n @property() value = \"\";\n /** `aria-label` applied to the trigger button. */\n @property() label = \"\";\n /** Disables the trigger, preventing the popover from opening. */\n @property({ type: Boolean }) disabled = false;\n /**\n * Enables editable, case-insensitive infix filtering by option label.\n * Typed text never becomes the selected `value`.\n */\n @property({ type: Boolean, reflect: true }) searchable = false;\n\n @state() private _open = false;\n @state() private _activeIndex = -1;\n @state() private _query: string | null = null;\n\n #listboxPointerDown = false;\n #suppressNextBlur = false;\n #restoringSearchFocus = false;\n #searchSelection: [number | null, number | null] | null = null;\n #isComposing = false;\n #compositionJustEnded = false;\n #compositionEndTimer: ReturnType<typeof setTimeout> | null = null;\n #blurTimer: ReturnType<typeof setTimeout> | null = null;\n readonly #listboxId = `form-select-listbox-${++instanceCount}`;\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener(\"mousedown\", this.#onWindowMousedown, true);\n if (this.#blurTimer) clearTimeout(this.#blurTimer);\n if (this.#compositionEndTimer) clearTimeout(this.#compositionEndTimer);\n this.#listboxPointerDown = false;\n this.#suppressNextBlur = false;\n this.#searchSelection = null;\n this.#isComposing = false;\n this.#compositionJustEnded = false;\n this.#close();\n }\n\n protected override updated(changed: PropertyValues): void {\n if (changed.has(\"_open\")) {\n this.toggleAttribute(\"open\", this._open);\n if (this._open) {\n window.addEventListener(\"mousedown\", this.#onWindowMousedown, true);\n } else {\n window.removeEventListener(\"mousedown\", this.#onWindowMousedown, true);\n }\n }\n if ((changed.has(\"disabled\") && this.disabled) || changed.has(\"searchable\")) {\n this.#close();\n return;\n }\n if (changed.has(\"options\") && this._open) {\n this._activeIndex = this.#initialActiveIndex();\n } else if (changed.has(\"value\") && this._open && this._query === null) {\n this._activeIndex = this.#initialActiveIndex();\n }\n if (\n (changed.has(\"_activeIndex\") || changed.has(\"_query\") || changed.has(\"options\")) &&\n this._open &&\n this._activeIndex >= 0\n ) {\n this.renderRoot\n .querySelector<HTMLElement>(`#${this.#listboxId}-option-${this._activeIndex}`)\n ?.scrollIntoView({ block: \"nearest\", inline: \"nearest\" });\n }\n }\n\n #onWindowMousedown = (e: MouseEvent): void => {\n if (!e.composedPath().includes(this)) this.#close();\n };\n\n #toggle(): void {\n if (this.disabled) return;\n if (this._open) this.#close();\n else this.#open();\n }\n\n #open(): void {\n if (this.disabled) return;\n this._query = null;\n this._open = true;\n this._activeIndex = this.#initialActiveIndex();\n }\n\n #close(): void {\n this._open = false;\n this._query = null;\n this._activeIndex = -1;\n this.#searchSelection = null;\n }\n\n #initialActiveIndex(): number {\n const options = this.#visibleOptions();\n if (options.length === 0) return -1;\n if (this._query !== null) return 0;\n const selectedIndex = options.findIndex((option) => option.value === this.value);\n return selectedIndex >= 0 ? selectedIndex : 0;\n }\n\n #visibleOptions(): SelectOption[] {\n if (!this.searchable || this._query === null) return this.options;\n const needle = this._query.trim().toLocaleLowerCase();\n if (!needle) return this.options;\n return this.options.filter((option) =>\n option.label.toLocaleLowerCase().includes(needle),\n );\n }\n\n #select(option: SelectOption): void {\n this.#close();\n if (option.value === this.value) return;\n this.value = option.value;\n this.dispatchEvent(new CustomEvent(\"change\", { detail: { value: option.value } }));\n }\n\n #onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\" || e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!this._open) {\n this.#toggle();\n return;\n }\n if (e.key === \"ArrowDown\") this.#moveActive(1);\n else if (e.key === \"ArrowUp\") this.#moveActive(-1);\n else this.#confirmActive();\n } else if (e.key === \"Escape\" && this._open) {\n e.preventDefault();\n this.#close();\n }\n }\n\n #moveActive(delta: number): void {\n const options = this.#visibleOptions();\n if (options.length === 0) return;\n const n = options.length;\n this._activeIndex = (this._activeIndex + delta + n) % n;\n }\n\n #confirmActive(): void {\n const options = this.#visibleOptions();\n const option = options[this._activeIndex] ?? options[0];\n if (option) this.#select(option);\n }\n\n #onSearchFocus(e: FocusEvent): void {\n if (this.disabled) return;\n if (this.#blurTimer) {\n clearTimeout(this.#blurTimer);\n this.#blurTimer = null;\n }\n if (!this._open) this.#open();\n if (!this.#restoringSearchFocus) (e.currentTarget as HTMLInputElement).select();\n }\n\n #onSearchClick(e: MouseEvent): void {\n if (!this._open) this.#open();\n if (this._query === null) (e.currentTarget as HTMLInputElement).select();\n }\n\n #onSearchMousedown(e: MouseEvent): void {\n if (e.button !== 0) e.preventDefault();\n }\n\n #onSearchInput(e: InputEvent): void {\n this._query = (e.currentTarget as HTMLInputElement).value;\n this._open = true;\n const options = this.#visibleOptions();\n this._activeIndex = options.length > 0 ? 0 : -1;\n }\n\n #onSearchKeydown(e: KeyboardEvent): void {\n if (e.isComposing || e.keyCode === 229 || this.#isComposing || this.#compositionJustEnded) {\n return;\n }\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n if (!this._open) {\n this.#open();\n return;\n }\n this.#moveActive(e.key === \"ArrowDown\" ? 1 : -1);\n } else if (e.key === \"Enter\" && this._open) {\n e.preventDefault();\n this.#confirmActive();\n } else if (e.key === \"Escape\" && this._open) {\n e.preventDefault();\n this.#close();\n }\n }\n\n #onSearchBlur(): void {\n if (this.#blurTimer) clearTimeout(this.#blurTimer);\n this.#blurTimer = setTimeout(() => {\n this.#blurTimer = null;\n if (!this._open) return;\n if (!this.#listboxPointerDown && !this.#suppressNextBlur) this.#close();\n });\n }\n\n #focusSearchInput(e: MouseEvent): void {\n if (\n e.button !== 0 ||\n this.disabled ||\n e.composedPath()[0] instanceof HTMLInputElement\n ) {\n return;\n }\n e.preventDefault();\n const input = this.renderRoot.querySelector<HTMLInputElement>(\"input.search-input\");\n if (!this._open) this.#open();\n input?.focus();\n input?.select();\n }\n\n #onCompositionStart(): void {\n if (this.#compositionEndTimer) clearTimeout(this.#compositionEndTimer);\n this.#compositionEndTimer = null;\n this.#compositionJustEnded = false;\n this.#isComposing = true;\n }\n\n #onCompositionEnd(): void {\n this.#isComposing = false;\n this.#compositionJustEnded = true;\n if (this.#compositionEndTimer) clearTimeout(this.#compositionEndTimer);\n this.#compositionEndTimer = setTimeout(() => {\n this.#compositionJustEnded = false;\n this.#compositionEndTimer = null;\n });\n }\n\n #onListboxMousedown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.#listboxPointerDown = true;\n this.#suppressNextBlur = true;\n const input = this.renderRoot.querySelector<HTMLInputElement>(\"input.search-input\");\n this.#searchSelection = input\n ? [input.selectionStart, input.selectionEnd]\n : null;\n window.addEventListener(\n \"mouseup\",\n () => {\n this.#listboxPointerDown = false;\n if (this._open) {\n const searchInput =\n this.renderRoot.querySelector<HTMLInputElement>(\"input.search-input\");\n if (searchInput) {\n this.#restoringSearchFocus = true;\n searchInput.focus({ preventScroll: true });\n this.#restoringSearchFocus = false;\n const [start, end] = this.#searchSelection ?? [null, null];\n if (start !== null && end !== null) searchInput.setSelectionRange(start, end);\n }\n }\n this.#searchSelection = null;\n setTimeout(() => {\n this.#suppressNextBlur = false;\n });\n },\n { capture: true, once: true },\n );\n }\n\n #onOptionMousedown(e: MouseEvent, option: SelectOption): void {\n if (e.button !== 0) return;\n const optionElement = e.currentTarget as HTMLElement;\n const listbox = optionElement.parentElement;\n if (listbox) {\n const scrollbarWidth = listbox.offsetWidth - listbox.clientWidth;\n const bounds = listbox.getBoundingClientRect();\n const isRtl = getComputedStyle(listbox).direction === \"rtl\";\n const inScrollbarGutter = isRtl\n ? e.clientX <= bounds.left + scrollbarWidth\n : e.clientX >= bounds.right - scrollbarWidth;\n if (scrollbarWidth > 0 && inScrollbarGutter) return;\n }\n e.preventDefault();\n this.#select(option);\n }\n\n #optionIconSize(option: SelectOption): number {\n const size = option.iconSize ?? 16;\n return Number.isFinite(size) && size > 0 ? size : 16;\n }\n\n #renderOptionIcon(option: SelectOption, className = \"option-icon\") {\n if (!option.icon) return nothing;\n return html`\n <span\n class=${className}\n style=${`--form-select-icon-size: ${this.#optionIconSize(option)}px`}\n aria-hidden=\"true\"\n >\n ${option.icon}\n </span>\n `;\n }\n\n #renderOptionContent(option: SelectOption) {\n return html`\n <span class=\"option-content\">\n ${this.#renderOptionIcon(option)}\n <span class=\"option-label\">${option.label}</span>\n </span>\n `;\n }\n\n private renderListbox() {\n if (!this._open) return nothing;\n const options = this.#visibleOptions();\n return html`\n <ul\n id=${this.#listboxId}\n class=\"options\"\n role=\"listbox\"\n aria-label=${this.label ? `${this.label} options` : \"Options\"}\n @mousedown=${(e: MouseEvent) => this.#onListboxMousedown(e)}\n >\n ${options.map(\n (o, i) => html`\n <li\n id=${`${this.#listboxId}-option-${i}`}\n role=\"option\"\n aria-selected=${o.value === this.value}\n class=${i === this._activeIndex ? \"active\" : \"\"}\n @mousedown=${(e: MouseEvent) => this.#onOptionMousedown(e, o)}\n >\n ${this.#renderOptionContent(o)}\n </li>\n `,\n )}\n ${options.length === 0\n ? html`<li class=\"no-options\" role=\"presentation\"><span role=\"status\">No options found</span></li>`\n : nothing}\n </ul>\n `;\n }\n\n private renderSearchTrigger(current: SelectOption | undefined) {\n const displayValue = this._query ?? current?.label ?? this.value;\n const showSelectedIcon = this._query === null && Boolean(current?.icon);\n const activeDescendant =\n this._open && this._activeIndex >= 0\n ? `${this.#listboxId}-option-${this._activeIndex}`\n : nothing;\n return html`\n <div\n class=\"search-trigger ${this.disabled ? \"disabled\" : \"\"} ${showSelectedIcon\n ? \"has-icon\"\n : \"\"}\"\n @mousedown=${(e: MouseEvent) => this.#focusSearchInput(e)}\n >\n ${showSelectedIcon && current\n ? this.#renderOptionIcon(current, \"option-icon selected-icon\")\n : nothing}\n <input\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded=${this._open}\n aria-controls=${this.#listboxId}\n aria-activedescendant=${activeDescendant}\n aria-label=${this.label || \"Select an option\"}\n autocomplete=\"off\"\n ?disabled=${this.disabled}\n .value=${displayValue}\n @mousedown=${(e: MouseEvent) => this.#onSearchMousedown(e)}\n @focus=${(e: FocusEvent) => this.#onSearchFocus(e)}\n @click=${(e: MouseEvent) => this.#onSearchClick(e)}\n @input=${(e: InputEvent) => this.#onSearchInput(e)}\n @compositionstart=${() => this.#onCompositionStart()}\n @compositionend=${() => this.#onCompositionEnd()}\n @keydown=${(e: KeyboardEvent) => this.#onSearchKeydown(e)}\n @blur=${() => this.#onSearchBlur()}\n />\n <span class=\"chevron\">${iconChevronRight(14)}</span>\n </div>\n `;\n }\n\n private renderButtonTrigger(current: SelectOption | undefined) {\n const activeDescendant =\n this._open && this._activeIndex >= 0\n ? `${this.#listboxId}-option-${this._activeIndex}`\n : nothing;\n return html`\n <button\n type=\"button\"\n class=\"trigger\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this._open}\n aria-controls=${this.#listboxId}\n aria-activedescendant=${activeDescendant}\n aria-label=${this.label || nothing}\n ?disabled=${this.disabled}\n @click=${() => this.#toggle()}\n @keydown=${(e: KeyboardEvent) => this.#onTriggerKeydown(e)}\n >\n ${current\n ? this.#renderOptionContent(current)\n : html`<span class=\"option-label\">${this.value}</span>`}\n <span class=\"chevron\">${iconChevronRight(14)}</span>\n </button>\n `;\n }\n\n override render() {\n const current = this.options.find((o) => o.value === this.value);\n return html`\n ${this.searchable\n ? this.renderSearchTrigger(current)\n : this.renderButtonTrigger(current)}\n ${this.renderListbox()}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"form-select\": FormSelect;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"frame-box.d.ts","sourceRoot":"","sources":["../src/frame-box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;;;;;GAQG;AACH,qBACa,QAAS,SAAQ,UAAU;IACtC,OAAgB,MAAM,4BA0BpB;IAEF,iDAAiD;IACrC,KAAK,SAAM;IAEd,MAAM,yCAOd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
1
+ {"version":3,"file":"frame-box.d.ts","sourceRoot":"","sources":["../src/frame-box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C;;;;;;;;GAQG;AACH,qBACa,QAAS,SAAQ,UAAU;IACtC,OAAgB,MAAM,4BAkCpB;IAEF,iDAAiD;IACrC,KAAK,SAAM;IAEd,MAAM,yCAOd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
package/dist/frame-box.js CHANGED
@@ -27,21 +27,29 @@ let FrameBox = class FrameBox extends LitElement {
27
27
  css `
28
28
  :host {
29
29
  display: block;
30
- position: relative;
31
- margin-top: 0.6rem;
30
+ margin-top: 0.5rem;
32
31
  }
33
32
  .frame {
33
+ min-width: 0;
34
+ margin: 0;
34
35
  border: 1px solid var(--ui-border, #e2e8f0);
35
36
  border-radius: var(--ui-radius-sm, 0.25rem);
36
- padding: 1rem 0.75rem 0.75rem;
37
+ padding: 0.75rem;
37
38
  }
38
39
  .label {
39
- position: absolute;
40
- top: -0.55rem;
41
- left: 0.6rem;
42
- padding: 0 0.4rem;
43
- background: var(--ui-surface, #fff);
44
- font-size: 0.65rem;
40
+ padding: 0 0.5rem;
41
+ background: var(--ui-surface, #ffffff);
42
+ font-family: var(
43
+ --ui-font,
44
+ ui-sans-serif,
45
+ system-ui,
46
+ sans-serif,
47
+ "Apple Color Emoji",
48
+ "Segoe UI Emoji",
49
+ "Segoe UI Symbol",
50
+ "Noto Color Emoji"
51
+ );
52
+ font-size: var(--ui-font-size-xs, 0.6875rem);
45
53
  font-weight: 600;
46
54
  text-transform: uppercase;
47
55
  letter-spacing: 0.05em;
@@ -51,10 +59,10 @@ let FrameBox = class FrameBox extends LitElement {
51
59
  ]; }
52
60
  render() {
53
61
  return html `
54
- <div class="frame">
55
- ${this.label ? html `<span class="label">${this.label}</span>` : null}
62
+ <fieldset class="frame">
63
+ ${this.label ? html `<legend class="label">${this.label}</legend>` : null}
56
64
  <slot></slot>
57
- </div>
65
+ </fieldset>
58
66
  `;
59
67
  }
60
68
  };
@@ -1 +1 @@
1
- {"version":3,"file":"frame-box.js","sourceRoot":"","sources":["../src/frame-box.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;;;;;;;;GAQG;AAEI,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAAjC;;QA6BL,iDAAiD;QACrC,UAAK,GAAG,EAAE,CAAC;IAUzB,CAAC;aAvCiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;KAuBF;KACF,AA1BqB,CA0BpB;IAKO,MAAM;QACb,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA,uBAAuB,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI;;;KAGvE,CAAC;IACJ,CAAC;CACF,CAAA;AAVa;IAAX,QAAQ,EAAE;uCAAY;AA9BZ,QAAQ;IADpB,aAAa,CAAC,WAAW,CAAC;GACd,QAAQ,CAwCpB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * A titled frame around a slot: a gray border with a small uppercase,\n * muted label overlapping the top edge (fieldset/legend-style). Generic —\n * the label text is entirely up to the consumer (e.g. \"Debug\" to visually\n * fence off dev-only chrome from the product UI).\n *\n * @element frame-box\n * @slot - Framed content.\n */\n@customElement(\"frame-box\")\nexport class FrameBox extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n position: relative;\n margin-top: 0.6rem;\n }\n .frame {\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 1rem 0.75rem 0.75rem;\n }\n .label {\n position: absolute;\n top: -0.55rem;\n left: 0.6rem;\n padding: 0 0.4rem;\n background: var(--ui-surface, #fff);\n font-size: 0.65rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--ui-text-muted, #64748b);\n }\n `,\n ];\n\n /** The overlapping title label, e.g. \"Debug\". */\n @property() label = \"\";\n\n override render() {\n return html`\n <div class=\"frame\">\n ${this.label ? html`<span class=\"label\">${this.label}</span>` : null}\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"frame-box\": FrameBox;\n }\n}\n"]}
1
+ {"version":3,"file":"frame-box.js","sourceRoot":"","sources":["../src/frame-box.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;;;;;;;;GAQG;AAEI,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAAjC;;QAqCL,iDAAiD;QACrC,UAAK,GAAG,EAAE,CAAC;IAUzB,CAAC;aA/CiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+BF;KACF,AAlCqB,CAkCpB;IAKO,MAAM;QACb,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA,yBAAyB,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI;;;KAG3E,CAAC;IACJ,CAAC;CACF,CAAA;AAVa;IAAX,QAAQ,EAAE;uCAAY;AAtCZ,QAAQ;IADpB,aAAa,CAAC,WAAW,CAAC;GACd,QAAQ,CAgDpB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * A titled frame around a slot: a gray border with a small uppercase,\n * muted label overlapping the top edge (fieldset/legend-style). Generic —\n * the label text is entirely up to the consumer (e.g. \"Debug\" to visually\n * fence off dev-only chrome from the product UI).\n *\n * @element frame-box\n * @slot - Framed content.\n */\n@customElement(\"frame-box\")\nexport class FrameBox extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n margin-top: 0.5rem;\n }\n .frame {\n min-width: 0;\n margin: 0;\n border: 1px solid var(--ui-border, #e2e8f0);\n border-radius: var(--ui-radius-sm, 0.25rem);\n padding: 0.75rem;\n }\n .label {\n padding: 0 0.5rem;\n background: var(--ui-surface, #ffffff);\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-xs, 0.6875rem);\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--ui-text-muted, #64748b);\n }\n `,\n ];\n\n /** The overlapping title label, e.g. \"Debug\". */\n @property() label = \"\";\n\n override render() {\n return html`\n <fieldset class=\"frame\">\n ${this.label ? html`<legend class=\"label\">${this.label}</legend>` : null}\n <slot></slot>\n </fieldset>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"frame-box\": FrameBox;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../src/icon-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAI1C;;;;;;;;GAQG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,OAAgB,MAAM,4BAgCpB;IAEF,sFAAsF;IACtD,IAAI,EAAE,cAAc,GAAG,IAAI,CAAQ;IACnE,kEAAkE;IACtD,KAAK,SAAM;IACvB,uCAAuC;IACV,QAAQ,UAAS;IAErC,MAAM,sBAMd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../src/icon-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAI1C;;;;;;;;GAQG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,OAAgB,MAAM,4BA2CpB;IAEF,sFAAsF;IACtD,IAAI,EAAE,cAAc,GAAG,IAAI,CAAQ;IACnE,kEAAkE;IACtD,KAAK,SAAM;IACvB,uCAAuC;IACV,QAAQ,UAAS;IAErC,MAAM,sBAMd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
@@ -57,6 +57,17 @@ let IconButton = class IconButton extends LitElement {
57
57
  outline: none;
58
58
  box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35));
59
59
  }
60
+ @media (forced-colors: active) {
61
+ button:focus-visible {
62
+ outline: 2px solid CanvasText;
63
+ outline-offset: 2px;
64
+ box-shadow: none;
65
+ }
66
+ button:disabled {
67
+ color: GrayText;
68
+ opacity: 1;
69
+ }
70
+ }
60
71
  `,
61
72
  ]; }
62
73
  render() {
@@ -1 +1 @@
1
- {"version":3,"file":"icon-button.js","sourceRoot":"","sources":["../src/icon-button.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;GAQG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;QAmCL,sFAAsF;QACtD,SAAI,GAA0B,IAAI,CAAC;QACnE,kEAAkE;QACtD,UAAK,GAAG,EAAE,CAAC;QACvB,uCAAuC;QACV,aAAQ,GAAG,KAAK,CAAC;IAShD,CAAC;aAhDiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6BF;KACF,AAhCqB,CAgCpB;IASO,MAAM;QACb,OAAO,IAAI,CAAA;yCAC0B,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,QAAQ;UACxF,IAAI,CAAC,IAAI,IAAI,OAAO;;KAEzB,CAAC;IACJ,CAAC;CACF,CAAA;AAbiC;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;wCAAoC;AAEvD;IAAX,QAAQ,EAAE;yCAAY;AAEM;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CAAkB;AAxCnC,UAAU;IADtB,aAAa,CAAC,aAAa,CAAC;GAChB,UAAU,CAiDtB","sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type { TemplateResult } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * A borderless button wrapping a passed-in icon, with a rounded\n * hover-highlight background. Use for a low-emphasis affordance next to\n * content it acts on (e.g. an \"Edit\" pencil at the end of a table row)\n * where a bordered `ui-button` would be too heavy.\n *\n * @element icon-button\n * @fires click - Native click, bubbling as usual — listen on the element itself.\n */\n@customElement(\"icon-button\")\nexport class IconButton extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-flex;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n padding: 0;\n border: none;\n border-radius: var(--ui-radius-sm, 0.25rem);\n background: none;\n color: var(--ui-text-muted, #64748b);\n cursor: pointer;\n }\n button:hover:not(:disabled) {\n background: var(--ui-surface-muted, #f8fafc);\n color: var(--ui-text, #0f172a);\n }\n button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\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 `,\n ];\n\n /** Pre-rendered icon template, e.g. `iconPencil(16)` from this package's icon set. */\n @property({ attribute: false }) icon: TemplateResult | null = null;\n /** Required accessible label, applied as `aria-label`/`title`. */\n @property() label = \"\";\n /** Disables the button and dims it. */\n @property({ type: Boolean }) disabled = false;\n\n override render() {\n return html`\n <button type=\"button\" aria-label=${this.label} title=${this.label} ?disabled=${this.disabled}>\n ${this.icon ?? nothing}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"icon-button\": IconButton;\n }\n}\n"]}
1
+ {"version":3,"file":"icon-button.js","sourceRoot":"","sources":["../src/icon-button.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;GAQG;AAEI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,UAAU;IAAnC;;QA8CL,sFAAsF;QACtD,SAAI,GAA0B,IAAI,CAAC;QACnE,kEAAkE;QACtD,UAAK,GAAG,EAAE,CAAC;QACvB,uCAAuC;QACV,aAAQ,GAAG,KAAK,CAAC;IAShD,CAAC;aA3DiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwCF;KACF,AA3CqB,CA2CpB;IASO,MAAM;QACb,OAAO,IAAI,CAAA;yCAC0B,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,QAAQ;UACxF,IAAI,CAAC,IAAI,IAAI,OAAO;;KAEzB,CAAC;IACJ,CAAC;CACF,CAAA;AAbiC;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;wCAAoC;AAEvD;IAAX,QAAQ,EAAE;yCAAY;AAEM;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4CAAkB;AAnDnC,UAAU;IADtB,aAAa,CAAC,aAAa,CAAC;GAChB,UAAU,CA4DtB","sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type { TemplateResult } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/**\n * A borderless button wrapping a passed-in icon, with a rounded\n * hover-highlight background. Use for a low-emphasis affordance next to\n * content it acts on (e.g. an \"Edit\" pencil at the end of a table row)\n * where a bordered `ui-button` would be too heavy.\n *\n * @element icon-button\n * @fires click - Native click, bubbling as usual — listen on the element itself.\n */\n@customElement(\"icon-button\")\nexport class IconButton extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-flex;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n padding: 0;\n border: none;\n border-radius: var(--ui-radius-sm, 0.25rem);\n background: none;\n color: var(--ui-text-muted, #64748b);\n cursor: pointer;\n }\n button:hover:not(:disabled) {\n background: var(--ui-surface-muted, #f8fafc);\n color: var(--ui-text, #0f172a);\n }\n button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\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 /** Pre-rendered icon template, e.g. `iconPencil(16)` from this package's icon set. */\n @property({ attribute: false }) icon: TemplateResult | null = null;\n /** Required accessible label, applied as `aria-label`/`title`. */\n @property() label = \"\";\n /** Disables the button and dims it. */\n @property({ type: Boolean }) disabled = false;\n\n override render() {\n return html`\n <button type=\"button\" aria-label=${this.label} title=${this.label} ?disabled=${this.disabled}>\n ${this.icon ?? nothing}\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"icon-button\": IconButton;\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -19,7 +19,6 @@ export { AutocompleteInput, type AutocompleteOption, } from "./autocomplete-inpu
19
19
  export { UserAvatar } from "./user-avatar.js";
20
20
  export { MapPin } from "./map-pin.js";
21
21
  export { MapCircle } from "./map-circle.js";
22
- export { MapPoint } from "./map-point.js";
23
22
  export { RadioCards, type RadioCardOption } from "./radio-cards.js";
24
23
  export { RadioPills, type RadioPillOption } from "./radio-pills.js";
25
24
  export { UiButton, type ButtonVariant } from "./ui-button.js";
@@ -34,7 +33,11 @@ export { TileGrid } from "./tile-grid.js";
34
33
  export { PopoverPanel } from "./popover-panel.js";
35
34
  export { DropdownButton, type DropdownOption } from "./dropdown-button.js";
36
35
  export { IconButton } from "./icon-button.js";
36
+ export { KbdHint, type KbdPlatform } from "./kbd-hint.js";
37
37
  export { FrameBox } from "./frame-box.js";
38
+ export { CalendarEntry } from "./calendar-entry.js";
39
+ export { CalendarMonth } from "./calendar-month.js";
40
+ export { CalendarYear } from "./calendar-year.js";
38
41
  export { formatDuration, type DurationFormat } from "./utils/duration.js";
39
42
  export { tokens, tokenValues, darkTokenValues } from "./tokens.js";
40
43
  export * from "./icons.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,7 +19,6 @@ export { AutocompleteInput, } from "./autocomplete-input.js";
19
19
  export { UserAvatar } from "./user-avatar.js";
20
20
  export { MapPin } from "./map-pin.js";
21
21
  export { MapCircle } from "./map-circle.js";
22
- export { MapPoint } from "./map-point.js";
23
22
  export { RadioCards } from "./radio-cards.js";
24
23
  export { RadioPills } from "./radio-pills.js";
25
24
  export { UiButton } from "./ui-button.js";
@@ -34,7 +33,11 @@ export { TileGrid } from "./tile-grid.js";
34
33
  export { PopoverPanel } from "./popover-panel.js";
35
34
  export { DropdownButton } from "./dropdown-button.js";
36
35
  export { IconButton } from "./icon-button.js";
36
+ export { KbdHint } from "./kbd-hint.js";
37
37
  export { FrameBox } from "./frame-box.js";
38
+ export { CalendarEntry } from "./calendar-entry.js";
39
+ export { CalendarMonth } from "./calendar-month.js";
40
+ export { CalendarYear } from "./calendar-year.js";
38
41
  export { formatDuration } from "./utils/duration.js";
39
42
  export { tokens, tokenValues, darkTokenValues } from "./tokens.js";
40
43
  export * from "./icons.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,YAAY,GAIb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,GAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAwB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,GAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAsB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,WAAW,GAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,cAAc,YAAY,CAAC","sourcesContent":["export { AnimateConfetti } from \"./animate-confetti.js\";\nexport { GalleryItem } from \"./gallery-item.js\";\nexport { GalleryItemVariant } from \"./gallery-item-variant.js\";\nexport {\n PhotoGallery,\n type PhotoGalleryChangeReason,\n type PhotoGalleryObjectFit,\n type PhotoGallerySlideChangeDetail,\n} from \"./photo-gallery.js\";\nexport { RevealButton } from \"./reveal-button.js\";\nexport { RomanNumeral } from \"./roman-numeral.js\";\nexport { ConfirmDialog } from \"./confirm-dialog.js\";\nexport {\n ToastNotification,\n notifySuccess,\n notifyError,\n notifyInfo,\n type ToastVariant,\n} from \"./toast-notification.js\";\nexport { SlidePanel } from \"./slide-panel.js\";\nexport { CopyLinkButton } from \"./copy-link-button.js\";\nexport { RelativeTime } from \"./relative-time.js\";\nexport { DistanceValue } from \"./distance-value.js\";\nexport { PriceHistoryChart, type PricePoint } from \"./price-history-chart.js\";\nexport { DistributionChart, type DistributionValue } from \"./distribution-chart.js\";\nexport { PercentBarChart, type PercentBarGroup } from \"./percent-bar-chart.js\";\nexport { WeightBarChart, type WeightBarItem } from \"./weight-bar-chart.js\";\nexport {\n AddressAutocomplete,\n type AddressSuggestion,\n} from \"./address-autocomplete.js\";\nexport {\n AutocompleteInput,\n type AutocompleteOption,\n} from \"./autocomplete-input.js\";\nexport { UserAvatar } from \"./user-avatar.js\";\nexport { MapPin } from \"./map-pin.js\";\nexport { MapCircle } from \"./map-circle.js\";\nexport { MapPoint } from \"./map-point.js\";\nexport { RadioCards, type RadioCardOption } from \"./radio-cards.js\";\nexport { RadioPills, type RadioPillOption } from \"./radio-pills.js\";\nexport { UiButton, type ButtonVariant } from \"./ui-button.js\";\nexport { StatMeter } from \"./stat-meter.js\";\nexport { StatusPill, type StatusPillColor } from \"./status-pill.js\";\nexport { EditableText } from \"./editable-text.js\";\nexport { LiveTimer } from \"./live-timer.js\";\nexport {\n ChatMessage,\n type ChatMessageRole,\n type ChatMessageVariant,\n} from \"./chat-message.js\";\nexport { FormSelect, type SelectOption } from \"./form-select.js\";\nexport { DataTable, type DataTableColumn } from \"./data-table.js\";\nexport { TileGrid } from \"./tile-grid.js\";\nexport { PopoverPanel } from \"./popover-panel.js\";\nexport { DropdownButton, type DropdownOption } from \"./dropdown-button.js\";\nexport { IconButton } from \"./icon-button.js\";\nexport { FrameBox } from \"./frame-box.js\";\nexport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\nexport { tokens, tokenValues, darkTokenValues } from \"./tokens.js\";\nexport * from \"./icons.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,YAAY,GAIb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,UAAU,GAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAmB,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,eAAe,EAAwB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iBAAiB,GAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAsB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,WAAW,GAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAqB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAoB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,cAAc,YAAY,CAAC","sourcesContent":["export { AnimateConfetti } from \"./animate-confetti.js\";\nexport { GalleryItem } from \"./gallery-item.js\";\nexport { GalleryItemVariant } from \"./gallery-item-variant.js\";\nexport {\n PhotoGallery,\n type PhotoGalleryChangeReason,\n type PhotoGalleryObjectFit,\n type PhotoGallerySlideChangeDetail,\n} from \"./photo-gallery.js\";\nexport { RevealButton } from \"./reveal-button.js\";\nexport { RomanNumeral } from \"./roman-numeral.js\";\nexport { ConfirmDialog } from \"./confirm-dialog.js\";\nexport {\n ToastNotification,\n notifySuccess,\n notifyError,\n notifyInfo,\n type ToastVariant,\n} from \"./toast-notification.js\";\nexport { SlidePanel } from \"./slide-panel.js\";\nexport { CopyLinkButton } from \"./copy-link-button.js\";\nexport { RelativeTime } from \"./relative-time.js\";\nexport { DistanceValue } from \"./distance-value.js\";\nexport { PriceHistoryChart, type PricePoint } from \"./price-history-chart.js\";\nexport { DistributionChart, type DistributionValue } from \"./distribution-chart.js\";\nexport { PercentBarChart, type PercentBarGroup } from \"./percent-bar-chart.js\";\nexport { WeightBarChart, type WeightBarItem } from \"./weight-bar-chart.js\";\nexport {\n AddressAutocomplete,\n type AddressSuggestion,\n} from \"./address-autocomplete.js\";\nexport {\n AutocompleteInput,\n type AutocompleteOption,\n} from \"./autocomplete-input.js\";\nexport { UserAvatar } from \"./user-avatar.js\";\nexport { MapPin } from \"./map-pin.js\";\nexport { MapCircle } from \"./map-circle.js\";\nexport { RadioCards, type RadioCardOption } from \"./radio-cards.js\";\nexport { RadioPills, type RadioPillOption } from \"./radio-pills.js\";\nexport { UiButton, type ButtonVariant } from \"./ui-button.js\";\nexport { StatMeter } from \"./stat-meter.js\";\nexport { StatusPill, type StatusPillColor } from \"./status-pill.js\";\nexport { EditableText } from \"./editable-text.js\";\nexport { LiveTimer } from \"./live-timer.js\";\nexport {\n ChatMessage,\n type ChatMessageRole,\n type ChatMessageVariant,\n} from \"./chat-message.js\";\nexport { FormSelect, type SelectOption } from \"./form-select.js\";\nexport { DataTable, type DataTableColumn } from \"./data-table.js\";\nexport { TileGrid } from \"./tile-grid.js\";\nexport { PopoverPanel } from \"./popover-panel.js\";\nexport { DropdownButton, type DropdownOption } from \"./dropdown-button.js\";\nexport { IconButton } from \"./icon-button.js\";\nexport { KbdHint, type KbdPlatform } from \"./kbd-hint.js\";\nexport { FrameBox } from \"./frame-box.js\";\nexport { CalendarEntry } from \"./calendar-entry.js\";\nexport { CalendarMonth } from \"./calendar-month.js\";\nexport { CalendarYear } from \"./calendar-year.js\";\nexport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\nexport { tokens, tokenValues, darkTokenValues } from \"./tokens.js\";\nexport * from \"./icons.js\";\n"]}
@@ -0,0 +1,30 @@
1
+ import { LitElement } from "lit";
2
+ /** Platform mode used to render modifier keys. */
3
+ export type KbdPlatform = "auto" | "mac" | "other";
4
+ /**
5
+ * Renders a keyboard shortcut as one boxed keycap per `+`-separated token.
6
+ * Modifier keys are platform-aware: `Mod` becomes Command on macOS and
7
+ * Control elsewhere. Keycaps derive their presentation from `currentColor`,
8
+ * so the hint works inside neutral and accent-colored controls.
9
+ *
10
+ * @element kbd-hint
11
+ */
12
+ export declare class KbdHint extends LitElement {
13
+ /** Shortcut as case-insensitive, `+`-separated tokens, e.g. `"Mod+Enter"`. */
14
+ keys: string;
15
+ /** Platform override; `auto` detects macOS from the browser. */
16
+ platform: KbdPlatform;
17
+ static styles: import("lit").CSSResult[];
18
+ /** Whether modifier aliases should use macOS glyphs. */
19
+ private get isMac();
20
+ /** Parses the shortcut into visual/spoken key descriptors. */
21
+ private get parsedKeys();
22
+ /** Renders nothing for an empty shortcut, otherwise an accessible keycap group. */
23
+ render(): import("lit-html").TemplateResult<1>;
24
+ }
25
+ declare global {
26
+ interface HTMLElementTagNameMap {
27
+ "kbd-hint": KbdHint;
28
+ }
29
+ }
30
+ //# sourceMappingURL=kbd-hint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd-hint.d.ts","sourceRoot":"","sources":["../src/kbd-hint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAI5C,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;AA4FnD;;;;;;;GAOG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACrC,8EAA8E;IAClE,IAAI,SAAM;IAEtB,gEAAgE;IACpD,QAAQ,EAAE,WAAW,CAAU;IAE3C,OAAgB,MAAM,4BAqCpB;IAEF,wDAAwD;IACxD,OAAO,KAAK,KAAK,GAIhB;IAED,8DAA8D;IAC9D,OAAO,KAAK,UAAU,GAOrB;IAED,mFAAmF;IAC1E,MAAM,yCASd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
@@ -0,0 +1,184 @@
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 { LitElement, css, html } from "lit";
8
+ import { customElement, property } from "lit/decorators.js";
9
+ import { tokens } from "./tokens.js";
10
+ /**
11
+ * Detects macOS via User-Agent Client Hints when available, with legacy
12
+ * navigator fields as fallbacks.
13
+ */
14
+ function detectMac() {
15
+ if (typeof window === "undefined" ||
16
+ typeof document === "undefined" ||
17
+ typeof navigator === "undefined") {
18
+ return false;
19
+ }
20
+ const nav = navigator;
21
+ const source = nav.userAgentData?.platform || nav.platform || nav.userAgent || "";
22
+ return /mac/i.test(source);
23
+ }
24
+ /**
25
+ * Maps one case-insensitive shortcut token to its visual keycap and spoken
26
+ * name. Unknown tokens remain literal; single letters are uppercased.
27
+ */
28
+ function keyLabel(raw, mac) {
29
+ switch (raw.trim().toLowerCase()) {
30
+ case "mod":
31
+ return mac ? { label: "⌘", name: "Command" } : { label: "Ctrl", name: "Control" };
32
+ case "cmd":
33
+ case "command":
34
+ return mac ? { label: "⌘", name: "Command" } : { label: "Cmd", name: "Command" };
35
+ case "meta":
36
+ return mac ? { label: "⌘", name: "Command" } : { label: "Meta", name: "Meta" };
37
+ case "super":
38
+ return mac ? { label: "⌘", name: "Command" } : { label: "Super", name: "Super" };
39
+ case "win":
40
+ case "windows":
41
+ return { label: "Win", name: "Windows" };
42
+ case "ctrl":
43
+ case "control":
44
+ return mac ? { label: "⌃", name: "Control" } : { label: "Ctrl", name: "Control" };
45
+ case "alt":
46
+ case "opt":
47
+ case "option":
48
+ return mac ? { label: "⌥", name: "Option" } : { label: "Alt", name: "Alt" };
49
+ case "shift":
50
+ return mac ? { label: "⇧", name: "Shift" } : { label: "Shift", name: "Shift" };
51
+ case "enter":
52
+ case "return":
53
+ return { label: "⏎", name: "Enter" };
54
+ case "tab":
55
+ return { label: "⇥", name: "Tab" };
56
+ case "backspace":
57
+ return { label: "⌫", name: "Backspace" };
58
+ case "delete":
59
+ case "del":
60
+ return { label: "⌦", name: "Delete" };
61
+ case "esc":
62
+ case "escape":
63
+ return { label: "Esc", name: "Escape" };
64
+ case "space":
65
+ case "spacebar":
66
+ return { label: "Space", name: "Space" };
67
+ case "up":
68
+ case "arrowup":
69
+ return { label: "↑", name: "Up arrow" };
70
+ case "down":
71
+ case "arrowdown":
72
+ return { label: "↓", name: "Down arrow" };
73
+ case "left":
74
+ case "arrowleft":
75
+ return { label: "←", name: "Left arrow" };
76
+ case "right":
77
+ case "arrowright":
78
+ return { label: "→", name: "Right arrow" };
79
+ case "pageup":
80
+ return { label: "PgUp", name: "Page Up" };
81
+ case "pagedown":
82
+ return { label: "PgDn", name: "Page Down" };
83
+ default: {
84
+ const token = raw.trim();
85
+ const label = token.length === 1 ? token.toUpperCase() : token;
86
+ return { label, name: label };
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Renders a keyboard shortcut as one boxed keycap per `+`-separated token.
92
+ * Modifier keys are platform-aware: `Mod` becomes Command on macOS and
93
+ * Control elsewhere. Keycaps derive their presentation from `currentColor`,
94
+ * so the hint works inside neutral and accent-colored controls.
95
+ *
96
+ * @element kbd-hint
97
+ */
98
+ let KbdHint = class KbdHint extends LitElement {
99
+ constructor() {
100
+ super(...arguments);
101
+ /** Shortcut as case-insensitive, `+`-separated tokens, e.g. `"Mod+Enter"`. */
102
+ this.keys = "";
103
+ /** Platform override; `auto` detects macOS from the browser. */
104
+ this.platform = "auto";
105
+ }
106
+ static { this.styles = [
107
+ tokens,
108
+ css `
109
+ :host {
110
+ display: inline-flex;
111
+ vertical-align: middle;
112
+ }
113
+ .wrap {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ gap: 0.25rem;
117
+ }
118
+ kbd {
119
+ display: inline-flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ box-sizing: border-box;
123
+ min-width: 1.25em;
124
+ height: 1.5em;
125
+ padding: 0 0.25rem;
126
+ color: currentColor;
127
+ background: color-mix(in srgb, currentColor 14%, transparent);
128
+ border: 1px solid color-mix(in srgb, currentColor 38%, transparent);
129
+ border-radius: var(--ui-radius-sm, 0.25rem);
130
+ font-family: var(
131
+ --ui-font-mono,
132
+ ui-monospace,
133
+ SFMono-Regular,
134
+ Menlo,
135
+ Monaco,
136
+ Consolas,
137
+ monospace
138
+ );
139
+ font-size: var(--ui-font-size-xs, 0.6875rem);
140
+ line-height: 1;
141
+ }
142
+ `,
143
+ ]; }
144
+ /** Whether modifier aliases should use macOS glyphs. */
145
+ get isMac() {
146
+ if (this.platform === "mac")
147
+ return true;
148
+ if (this.platform === "other")
149
+ return false;
150
+ return detectMac();
151
+ }
152
+ /** Parses the shortcut into visual/spoken key descriptors. */
153
+ get parsedKeys() {
154
+ const mac = this.isMac;
155
+ return (this.keys ?? "")
156
+ .split("+")
157
+ .map((token) => token.trim())
158
+ .filter(Boolean)
159
+ .map((token) => keyLabel(token, mac));
160
+ }
161
+ /** Renders nothing for an empty shortcut, otherwise an accessible keycap group. */
162
+ render() {
163
+ const parsedKeys = this.parsedKeys;
164
+ if (parsedKeys.length === 0)
165
+ return html ``;
166
+ const label = parsedKeys.map((key) => key.name).join(" ");
167
+ return html `
168
+ <span class="wrap" role="img" aria-label=${label}>
169
+ ${parsedKeys.map((key) => html `<kbd aria-hidden="true">${key.label}</kbd>`)}
170
+ </span>
171
+ `;
172
+ }
173
+ };
174
+ __decorate([
175
+ property()
176
+ ], KbdHint.prototype, "keys", void 0);
177
+ __decorate([
178
+ property()
179
+ ], KbdHint.prototype, "platform", void 0);
180
+ KbdHint = __decorate([
181
+ customElement("kbd-hint")
182
+ ], KbdHint);
183
+ export { KbdHint };
184
+ //# sourceMappingURL=kbd-hint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd-hint.js","sourceRoot":"","sources":["../src/kbd-hint.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\n\n/** Platform mode used to render modifier keys. */\nexport type KbdPlatform = \"auto\" | \"mac\" | \"other\";\n\n/** Visual and spoken representations of one shortcut key. */\ninterface KeyRender {\n label: string;\n name: string;\n}\n\n/**\n * Detects macOS via User-Agent Client Hints when available, with legacy\n * navigator fields as fallbacks.\n */\nfunction detectMac(): boolean {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n typeof navigator === \"undefined\"\n ) {\n return false;\n }\n const nav = navigator as Navigator & { userAgentData?: { platform?: string } };\n const source = nav.userAgentData?.platform || nav.platform || nav.userAgent || \"\";\n return /mac/i.test(source);\n}\n\n/**\n * Maps one case-insensitive shortcut token to its visual keycap and spoken\n * name. Unknown tokens remain literal; single letters are uppercased.\n */\nfunction keyLabel(raw: string, mac: boolean): KeyRender {\n switch (raw.trim().toLowerCase()) {\n case \"mod\":\n return mac ? { label: \"⌘\", name: \"Command\" } : { label: \"Ctrl\", name: \"Control\" };\n case \"cmd\":\n case \"command\":\n return mac ? { label: \"⌘\", name: \"Command\" } : { label: \"Cmd\", name: \"Command\" };\n case \"meta\":\n return mac ? { label: \"⌘\", name: \"Command\" } : { label: \"Meta\", name: \"Meta\" };\n case \"super\":\n return mac ? { label: \"⌘\", name: \"Command\" } : { label: \"Super\", name: \"Super\" };\n case \"win\":\n case \"windows\":\n return { label: \"Win\", name: \"Windows\" };\n case \"ctrl\":\n case \"control\":\n return mac ? { label: \"⌃\", name: \"Control\" } : { label: \"Ctrl\", name: \"Control\" };\n case \"alt\":\n case \"opt\":\n case \"option\":\n return mac ? { label: \"⌥\", name: \"Option\" } : { label: \"Alt\", name: \"Alt\" };\n case \"shift\":\n return mac ? { label: \"⇧\", name: \"Shift\" } : { label: \"Shift\", name: \"Shift\" };\n case \"enter\":\n case \"return\":\n return { label: \"⏎\", name: \"Enter\" };\n case \"tab\":\n return { label: \"⇥\", name: \"Tab\" };\n case \"backspace\":\n return { label: \"⌫\", name: \"Backspace\" };\n case \"delete\":\n case \"del\":\n return { label: \"⌦\", name: \"Delete\" };\n case \"esc\":\n case \"escape\":\n return { label: \"Esc\", name: \"Escape\" };\n case \"space\":\n case \"spacebar\":\n return { label: \"Space\", name: \"Space\" };\n case \"up\":\n case \"arrowup\":\n return { label: \"↑\", name: \"Up arrow\" };\n case \"down\":\n case \"arrowdown\":\n return { label: \"↓\", name: \"Down arrow\" };\n case \"left\":\n case \"arrowleft\":\n return { label: \"←\", name: \"Left arrow\" };\n case \"right\":\n case \"arrowright\":\n return { label: \"→\", name: \"Right arrow\" };\n case \"pageup\":\n return { label: \"PgUp\", name: \"Page Up\" };\n case \"pagedown\":\n return { label: \"PgDn\", name: \"Page Down\" };\n default: {\n const token = raw.trim();\n const label = token.length === 1 ? token.toUpperCase() : token;\n return { label, name: label };\n }\n }\n}\n\n/**\n * Renders a keyboard shortcut as one boxed keycap per `+`-separated token.\n * Modifier keys are platform-aware: `Mod` becomes Command on macOS and\n * Control elsewhere. Keycaps derive their presentation from `currentColor`,\n * so the hint works inside neutral and accent-colored controls.\n *\n * @element kbd-hint\n */\n@customElement(\"kbd-hint\")\nexport class KbdHint extends LitElement {\n /** Shortcut as case-insensitive, `+`-separated tokens, e.g. `\"Mod+Enter\"`. */\n @property() keys = \"\";\n\n /** Platform override; `auto` detects macOS from the browser. */\n @property() platform: KbdPlatform = \"auto\";\n\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n .wrap {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n }\n kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-width: 1.25em;\n height: 1.5em;\n padding: 0 0.25rem;\n color: currentColor;\n background: color-mix(in srgb, currentColor 14%, transparent);\n border: 1px solid color-mix(in srgb, currentColor 38%, transparent);\n border-radius: var(--ui-radius-sm, 0.25rem);\n font-family: var(\n --ui-font-mono,\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace\n );\n font-size: var(--ui-font-size-xs, 0.6875rem);\n line-height: 1;\n }\n `,\n ];\n\n /** Whether modifier aliases should use macOS glyphs. */\n private get isMac(): boolean {\n if (this.platform === \"mac\") return true;\n if (this.platform === \"other\") return false;\n return detectMac();\n }\n\n /** Parses the shortcut into visual/spoken key descriptors. */\n private get parsedKeys(): KeyRender[] {\n const mac = this.isMac;\n return (this.keys ?? \"\")\n .split(\"+\")\n .map((token) => token.trim())\n .filter(Boolean)\n .map((token) => keyLabel(token, mac));\n }\n\n /** Renders nothing for an empty shortcut, otherwise an accessible keycap group. */\n override render() {\n const parsedKeys = this.parsedKeys;\n if (parsedKeys.length === 0) return html``;\n const label = parsedKeys.map((key) => key.name).join(\" \");\n return html`\n <span class=\"wrap\" role=\"img\" aria-label=${label}>\n ${parsedKeys.map((key) => html`<kbd aria-hidden=\"true\">${key.label}</kbd>`)}\n </span>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"kbd-hint\": KbdHint;\n }\n}\n"]}
@@ -8,7 +8,6 @@ import { type DurationFormat } from "./utils/duration.js";
8
8
  * @element live-timer
9
9
  */
10
10
  export declare class LiveTimer extends LitElement {
11
- static styles: import("lit").CSSResult;
12
11
  /** ISO-8601 start instant; elapsed time is measured from here. */
13
12
  since: string | null;
14
13
  /** `"seconds"` -> "1 second", "12 seconds"; `"compact"` -> "12s", "3m 12s", "1h 03m 12s". */
@@ -1 +1 @@
1
- {"version":3,"file":"live-timer.d.ts","sourceRoot":"","sources":["../src/live-timer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1E;;;;;;GAMG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,0BAIpB;IAEF,kEAAkE;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,6FAA6F;IACjF,MAAM,EAAE,cAAc,CAAa;IAC/C,gDAAgD;IAC3B,MAAM,SAAM;IACjC,+CAA+C;IACnC,MAAM,SAAM;IAEf,OAAO,CAAC,IAAI,CAAc;IAEnC,OAAO,CAAC,MAAM,CAA+C;IAEpD,iBAAiB,SAKzB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCAMd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"live-timer.d.ts","sourceRoot":"","sources":["../src/live-timer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1E;;;;;;GAMG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,kEAAkE;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,6FAA6F;IACjF,MAAM,EAAE,cAAc,CAAa;IAC/C,gDAAgD;IAC3B,MAAM,SAAM;IACjC,+CAA+C;IACnC,MAAM,SAAM;IAEf,OAAO,CAAC,IAAI,CAAc;IAEnC,OAAO,CAAC,MAAM,CAA+C;IAEpD,iBAAiB,SAKzB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCAMd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
@@ -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, css, html } from "lit";
7
+ import { LitElement, html } from "lit";
8
8
  import { customElement, property, state } from "lit/decorators.js";
9
9
  import { formatDuration } from "./utils/duration.js";
10
10
  const TICK_INTERVAL_MS = 1000;
@@ -29,11 +29,6 @@ let LiveTimer = class LiveTimer extends LitElement {
29
29
  this._now = Date.now();
30
30
  this._timer = null;
31
31
  }
32
- static { this.styles = css `
33
- :host {
34
- display: inline;
35
- }
36
- `; }
37
32
  connectedCallback() {
38
33
  super.connectedCallback();
39
34
  this._timer = setInterval(() => {