@f-ewald/components 1.0.0 → 1.0.3

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 (172) hide show
  1. package/README.md +6 -0
  2. package/custom-elements.json +891 -22
  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-month.d.ts.map +1 -1
  16. package/dist/calendar-month.js +27 -13
  17. package/dist/calendar-month.js.map +1 -1
  18. package/dist/calendar-year.d.ts.map +1 -1
  19. package/dist/calendar-year.js +11 -2
  20. package/dist/calendar-year.js.map +1 -1
  21. package/dist/chat-message.d.ts.map +1 -1
  22. package/dist/chat-message.js +77 -24
  23. package/dist/chat-message.js.map +1 -1
  24. package/dist/confirm-dialog.d.ts +8 -1
  25. package/dist/confirm-dialog.d.ts.map +1 -1
  26. package/dist/confirm-dialog.js +130 -18
  27. package/dist/confirm-dialog.js.map +1 -1
  28. package/dist/copy-link-button.d.ts +2 -0
  29. package/dist/copy-link-button.d.ts.map +1 -1
  30. package/dist/copy-link-button.js +35 -3
  31. package/dist/copy-link-button.js.map +1 -1
  32. package/dist/data-table.d.ts +2 -0
  33. package/dist/data-table.d.ts.map +1 -1
  34. package/dist/data-table.js +83 -11
  35. package/dist/data-table.js.map +1 -1
  36. package/dist/distance-value.d.ts +0 -1
  37. package/dist/distance-value.d.ts.map +1 -1
  38. package/dist/distance-value.js +3 -8
  39. package/dist/distance-value.js.map +1 -1
  40. package/dist/distribution-chart.d.ts.map +1 -1
  41. package/dist/distribution-chart.js +54 -17
  42. package/dist/distribution-chart.js.map +1 -1
  43. package/dist/dropdown-button.d.ts.map +1 -1
  44. package/dist/dropdown-button.js +60 -11
  45. package/dist/dropdown-button.js.map +1 -1
  46. package/dist/editable-text.d.ts.map +1 -1
  47. package/dist/editable-text.js +46 -13
  48. package/dist/editable-text.js.map +1 -1
  49. package/dist/form-select.d.ts.map +1 -1
  50. package/dist/form-select.js +70 -22
  51. package/dist/form-select.js.map +1 -1
  52. package/dist/frame-box.d.ts.map +1 -1
  53. package/dist/frame-box.js +20 -12
  54. package/dist/frame-box.js.map +1 -1
  55. package/dist/icon-button.d.ts.map +1 -1
  56. package/dist/icon-button.js +11 -0
  57. package/dist/icon-button.js.map +1 -1
  58. package/dist/index.d.ts +1 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +1 -0
  61. package/dist/index.js.map +1 -1
  62. package/dist/kbd-hint.d.ts +30 -0
  63. package/dist/kbd-hint.d.ts.map +1 -0
  64. package/dist/kbd-hint.js +184 -0
  65. package/dist/kbd-hint.js.map +1 -0
  66. package/dist/live-timer.d.ts +0 -1
  67. package/dist/live-timer.d.ts.map +1 -1
  68. package/dist/live-timer.js +1 -6
  69. package/dist/live-timer.js.map +1 -1
  70. package/dist/map-circle.d.ts.map +1 -1
  71. package/dist/map-circle.js +16 -1
  72. package/dist/map-circle.js.map +1 -1
  73. package/dist/map-pin.d.ts.map +1 -1
  74. package/dist/map-pin.js +16 -1
  75. package/dist/map-pin.js.map +1 -1
  76. package/dist/percent-bar-chart.d.ts +3 -0
  77. package/dist/percent-bar-chart.d.ts.map +1 -1
  78. package/dist/percent-bar-chart.js +60 -4
  79. package/dist/percent-bar-chart.js.map +1 -1
  80. package/dist/photo-gallery.d.ts.map +1 -1
  81. package/dist/photo-gallery.js +12 -3
  82. package/dist/photo-gallery.js.map +1 -1
  83. package/dist/popover-panel.d.ts.map +1 -1
  84. package/dist/popover-panel.js +132 -23
  85. package/dist/popover-panel.js.map +1 -1
  86. package/dist/price-history-chart.d.ts.map +1 -1
  87. package/dist/price-history-chart.js +52 -18
  88. package/dist/price-history-chart.js.map +1 -1
  89. package/dist/radio-cards.d.ts +2 -0
  90. package/dist/radio-cards.d.ts.map +1 -1
  91. package/dist/radio-cards.js +51 -5
  92. package/dist/radio-cards.js.map +1 -1
  93. package/dist/radio-pills.d.ts +2 -0
  94. package/dist/radio-pills.d.ts.map +1 -1
  95. package/dist/radio-pills.js +46 -4
  96. package/dist/radio-pills.js.map +1 -1
  97. package/dist/relative-time.d.ts +0 -1
  98. package/dist/relative-time.d.ts.map +1 -1
  99. package/dist/relative-time.js +1 -6
  100. package/dist/relative-time.js.map +1 -1
  101. package/dist/reveal-button.d.ts +2 -0
  102. package/dist/reveal-button.d.ts.map +1 -1
  103. package/dist/reveal-button.js +42 -5
  104. package/dist/reveal-button.js.map +1 -1
  105. package/dist/roman-numeral.js +1 -1
  106. package/dist/roman-numeral.js.map +1 -1
  107. package/dist/slide-panel.d.ts +7 -3
  108. package/dist/slide-panel.d.ts.map +1 -1
  109. package/dist/slide-panel.js +95 -23
  110. package/dist/slide-panel.js.map +1 -1
  111. package/dist/stat-meter.d.ts.map +1 -1
  112. package/dist/stat-meter.js +17 -7
  113. package/dist/stat-meter.js.map +1 -1
  114. package/dist/status-pill.d.ts.map +1 -1
  115. package/dist/status-pill.js +26 -12
  116. package/dist/status-pill.js.map +1 -1
  117. package/dist/tile-grid.d.ts +8 -0
  118. package/dist/tile-grid.d.ts.map +1 -1
  119. package/dist/tile-grid.js +88 -12
  120. package/dist/tile-grid.js.map +1 -1
  121. package/dist/toast-notification.d.ts.map +1 -1
  122. package/dist/toast-notification.js +40 -11
  123. package/dist/toast-notification.js.map +1 -1
  124. package/dist/tokens.css +19 -0
  125. package/dist/tokens.d.ts.map +1 -1
  126. package/dist/tokens.js +13 -0
  127. package/dist/tokens.js.map +1 -1
  128. package/dist/ui-button.d.ts +2 -0
  129. package/dist/ui-button.d.ts.map +1 -1
  130. package/dist/ui-button.js +58 -9
  131. package/dist/ui-button.js.map +1 -1
  132. package/dist/user-avatar.d.ts.map +1 -1
  133. package/dist/user-avatar.js +18 -3
  134. package/dist/user-avatar.js.map +1 -1
  135. package/dist/utils/form.d.ts +3 -0
  136. package/dist/utils/form.d.ts.map +1 -0
  137. package/dist/utils/form.js +14 -0
  138. package/dist/utils/form.js.map +1 -0
  139. package/dist/utils/layer-stack.d.ts +9 -0
  140. package/dist/utils/layer-stack.d.ts.map +1 -0
  141. package/dist/utils/layer-stack.js +35 -0
  142. package/dist/utils/layer-stack.js.map +1 -0
  143. package/dist/weight-bar-chart.d.ts.map +1 -1
  144. package/dist/weight-bar-chart.js +27 -8
  145. package/dist/weight-bar-chart.js.map +1 -1
  146. package/docs/address-autocomplete.md +5 -0
  147. package/docs/autocomplete-input.md +5 -0
  148. package/docs/calendar-month.md +2 -0
  149. package/docs/chat-message.md +4 -0
  150. package/docs/confirm-dialog.md +2 -0
  151. package/docs/copy-link-button.md +2 -0
  152. package/docs/data-table.md +2 -0
  153. package/docs/design-language.md +149 -0
  154. package/docs/distribution-chart.md +4 -0
  155. package/docs/dropdown-button.md +1 -0
  156. package/docs/frame-box.md +2 -0
  157. package/docs/kbd-hint.md +42 -0
  158. package/docs/percent-bar-chart.md +4 -1
  159. package/docs/photo-gallery.md +1 -0
  160. package/docs/popover-panel.md +2 -0
  161. package/docs/price-history-chart.md +8 -1
  162. package/docs/radio-cards.md +2 -0
  163. package/docs/radio-pills.md +2 -0
  164. package/docs/reveal-button.md +3 -0
  165. package/docs/slide-panel.md +4 -2
  166. package/docs/status-pill.md +3 -0
  167. package/docs/tile-grid.md +10 -1
  168. package/docs/toast-notification.md +4 -1
  169. package/docs/ui-button.md +2 -0
  170. package/docs/user-avatar.md +1 -0
  171. package/llms.txt +59 -34
  172. package/package.json +5 -1
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ export { TileGrid } from "./tile-grid.js";
33
33
  export { PopoverPanel } from "./popover-panel.js";
34
34
  export { DropdownButton } from "./dropdown-button.js";
35
35
  export { IconButton } from "./icon-button.js";
36
+ export { KbdHint } from "./kbd-hint.js";
36
37
  export { FrameBox } from "./frame-box.js";
37
38
  export { CalendarEntry } from "./calendar-entry.js";
38
39
  export { CalendarMonth } from "./calendar-month.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,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,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 { 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"]}
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(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"live-timer.js","sourceRoot":"","sources":["../src/live-timer.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAE1E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;;;;GAMG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAOL,kEAAkE;QACtD,UAAK,GAAkB,IAAI,CAAC;QACxC,6FAA6F;QACjF,WAAM,GAAmB,SAAS,CAAC;QAC/C,gDAAgD;QAC3B,WAAM,GAAG,EAAE,CAAC;QACjC,+CAA+C;QACnC,WAAM,GAAG,EAAE,CAAC;QAEP,SAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,WAAM,GAA0C,IAAI,CAAC;IAsB/D,CAAC;aAvCiB,WAAM,GAAG,GAAG,CAAA;;;;GAI3B,AAJqB,CAIpB;IAeO,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,gBAAgB,CAAC,CAAC;IACvB,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,KAAK;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACnF,CAAC;CACF,CAAA;AAhCa;IAAX,QAAQ,EAAE;wCAA6B;AAE5B;IAAX,QAAQ,EAAE;yCAAoC;AAE1B;IAApB,QAAQ,EAAE;yCAAsB;AAErB;IAAX,QAAQ,EAAE;yCAAa;AAEP;IAAhB,KAAK,EAAE;uCAA2B;AAhBxB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAwCrB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\n\nconst TICK_INTERVAL_MS = 1000;\n\n/**\n * Per-second ticking count-up timer, e.g. a live \"running for 12s\" or\n * \"Sleeping for 3 seconds\" indicator. Renders nothing while `since` is unset\n * or unparseable.\n *\n * @element live-timer\n */\n@customElement(\"live-timer\")\nexport class LiveTimer extends LitElement {\n static override styles = css`\n :host {\n display: inline;\n }\n `;\n\n /** ISO-8601 start instant; elapsed time is measured from here. */\n @property() since: string | null = null;\n /** `\"seconds\"` -> \"1 second\", \"12 seconds\"; `\"compact\"` -> \"12s\", \"3m 12s\", \"1h 03m 12s\". */\n @property() format: DurationFormat = \"seconds\";\n /** Text rendered before the formatted value. */\n @property() override prefix = \"\";\n /** Text rendered after the formatted value. */\n @property() suffix = \"\";\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 }, TICK_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.since) return html``;\n const start = Date.parse(this.since);\n if (Number.isNaN(start)) return html``;\n const elapsed = Math.max(0, this._now - start);\n return html`${this.prefix}${formatDuration(elapsed, this.format)}${this.suffix}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"live-timer\": LiveTimer;\n }\n}\n"]}
1
+ {"version":3,"file":"live-timer.js","sourceRoot":"","sources":["../src/live-timer.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,EAAuB,MAAM,qBAAqB,CAAC;AAE1E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;;;;GAMG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QACL,kEAAkE;QACtD,UAAK,GAAkB,IAAI,CAAC;QACxC,6FAA6F;QACjF,WAAM,GAAmB,SAAS,CAAC;QAC/C,gDAAgD;QAC3B,WAAM,GAAG,EAAE,CAAC;QACjC,+CAA+C;QACnC,WAAM,GAAG,EAAE,CAAC;QAEP,SAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE3B,WAAM,GAA0C,IAAI,CAAC;IAsB/D,CAAC;IApBU,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,gBAAgB,CAAC,CAAC;IACvB,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,KAAK;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IACnF,CAAC;CACF,CAAA;AAhCa;IAAX,QAAQ,EAAE;wCAA6B;AAE5B;IAAX,QAAQ,EAAE;yCAAoC;AAE1B;IAApB,QAAQ,EAAE;yCAAsB;AAErB;IAAX,QAAQ,EAAE;yCAAa;AAEP;IAAhB,KAAK,EAAE;uCAA2B;AAVxB,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAkCrB","sourcesContent":["import { LitElement, html } from \"lit\";\nimport { customElement, property, state } from \"lit/decorators.js\";\nimport { formatDuration, type DurationFormat } from \"./utils/duration.js\";\n\nconst TICK_INTERVAL_MS = 1000;\n\n/**\n * Per-second ticking count-up timer, e.g. a live \"running for 12s\" or\n * \"Sleeping for 3 seconds\" indicator. Renders nothing while `since` is unset\n * or unparseable.\n *\n * @element live-timer\n */\n@customElement(\"live-timer\")\nexport class LiveTimer extends LitElement {\n /** ISO-8601 start instant; elapsed time is measured from here. */\n @property() since: string | null = null;\n /** `\"seconds\"` -> \"1 second\", \"12 seconds\"; `\"compact\"` -> \"12s\", \"3m 12s\", \"1h 03m 12s\". */\n @property() format: DurationFormat = \"seconds\";\n /** Text rendered before the formatted value. */\n @property() override prefix = \"\";\n /** Text rendered after the formatted value. */\n @property() suffix = \"\";\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 }, TICK_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.since) return html``;\n const start = Date.parse(this.since);\n if (Number.isNaN(start)) return html``;\n const elapsed = Math.max(0, this._now - start);\n return html`${this.prefix}${formatDuration(elapsed, this.format)}${this.suffix}`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"live-timer\": LiveTimer;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"map-circle.d.ts","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;;;;GAaG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,4BA8BpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IACnE,sFAAsF;IAC1C,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAE3D,MAAM,yCAuBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"map-circle.d.ts","sourceRoot":"","sources":["../src/map-circle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;;;;GAaG;AACH,qBACa,SAAU,SAAQ,UAAU;IACvC,OAAgB,MAAM,4BA4CpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IACnE,sFAAsF;IAC1C,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IAE3D,MAAM,yCAwBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
@@ -58,13 +58,27 @@ let MapCircle = class MapCircle extends LitElement {
58
58
  left: 50%;
59
59
  transform: translate(-50%, -50%);
60
60
  color: #fff;
61
- font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
61
+ font-family: var(
62
+ --ui-font,
63
+ ui-sans-serif,
64
+ system-ui,
65
+ sans-serif,
66
+ "Apple Color Emoji",
67
+ "Segoe UI Emoji",
68
+ "Segoe UI Symbol",
69
+ "Noto Color Emoji"
70
+ );
62
71
  font-weight: 700;
63
72
  line-height: 1;
64
73
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
65
74
  pointer-events: none;
66
75
  white-space: nowrap;
67
76
  }
77
+ @media (prefers-reduced-motion: reduce) {
78
+ svg {
79
+ transition: none;
80
+ }
81
+ }
68
82
  `,
69
83
  ]; }
70
84
  render() {
@@ -72,6 +86,7 @@ let MapCircle = class MapCircle extends LitElement {
72
86
  const dark = mixHex(this.color, "#000000", 30);
73
87
  return html `
74
88
  <svg
89
+ aria-hidden="true"
75
90
  width=${this.size}
76
91
  height=${this.size}
77
92
  viewBox="0 0 32 32"
@@ -1 +1 @@
1
- {"version":3,"file":"map-circle.js","sourceRoot":"","sources":["../src/map-circle.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;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QAiCL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QACnE,sFAAsF;QAC1C,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,mBAAmB,iBAAiB,EAAE,EAAE,CAAC;IA0BtE,CAAC;aAnEiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BF;KACF,AA9BqB,CA8BpB;IAaO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,IAAI;;;;;;+BAMK,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;oDAGG,IAAI,CAAC,OAAO,oCAAoC,IAAI,CAAC,SAAS;;8CAEpE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAlCa;IAAX,QAAQ,EAAE;wCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;4CAAe;AAEvB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CAAqB;AAxCrD,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAoErB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A plain circular map marker: a light-to-dark gradient fill with a white\n * outer ring, no point/tail (unlike `<map-pin>`) — for markers that don't\n * need to visually \"point\" at their exact coordinate. Purely a visual\n * primitive — it has no `mapbox-gl` (or any mapping library) dependency;\n * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.\n * It can also replace the former `<map-point>` dense-layer primitive: use\n * `size=\"14\" ring-width=\"3\"`, leave the slot empty, and rasterize one marker\n * per color for use as a map `icon-image`.\n *\n * @element map-circle\n * @slot - Optional badge content shown centered on the circle — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-circle\")\nexport class MapCircle extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter, in CSS pixels. */\n @property({ type: Number }) size = 18;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 4;\n /** Scales and glows the circle — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-circle-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n return html`\n <svg\n width=${this.size}\n height=${this.size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <circle cx=\"16\" cy=\"16\" r=\"13\" fill=\"url(#${this._gradId})\" stroke=\"#ffffff\" stroke-width=${this.ringWidth} />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-circle\": MapCircle;\n }\n}\n"]}
1
+ {"version":3,"file":"map-circle.js","sourceRoot":"","sources":["../src/map-circle.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;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;IAAlC;;QA+CL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QACnE,sFAAsF;QAC1C,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,mBAAmB,iBAAiB,EAAE,EAAE,CAAC;IA2BtE,CAAC;aAlFiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyCF;KACF,AA5CqB,CA4CpB;IAaO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,IAAI;iBACR,IAAI,CAAC,IAAI;;;;;;+BAMK,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;oDAGG,IAAI,CAAC,OAAO,oCAAoC,IAAI,CAAC,SAAS;;8CAEpE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAnCa;IAAX,QAAQ,EAAE;wCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;4CAAe;AAEvB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CAAqB;AAtDrD,SAAS;IADrB,aAAa,CAAC,YAAY,CAAC;GACf,SAAS,CAmFrB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A plain circular map marker: a light-to-dark gradient fill with a white\n * outer ring, no point/tail (unlike `<map-pin>`) — for markers that don't\n * need to visually \"point\" at their exact coordinate. Purely a visual\n * primitive — it has no `mapbox-gl` (or any mapping library) dependency;\n * the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.\n * It can also replace the former `<map-point>` dense-layer primitive: use\n * `size=\"14\" ring-width=\"3\"`, leave the slot empty, and rasterize one marker\n * per color for use as a map `icon-image`.\n *\n * @element map-circle\n * @slot - Optional badge content shown centered on the circle — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-circle\")\nexport class MapCircle extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\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-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n svg {\n transition: none;\n }\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter, in CSS pixels. */\n @property({ type: Number }) size = 18;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 4;\n /** Scales and glows the circle — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-circle-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n return html`\n <svg\n aria-hidden=\"true\"\n width=${this.size}\n height=${this.size}\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <circle cx=\"16\" cy=\"16\" r=\"13\" fill=\"url(#${this._gradId})\" stroke=\"#ffffff\" stroke-width=${this.ringWidth} />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-circle\": MapCircle;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"map-pin.d.ts","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;GASG;AACH,qBACa,MAAO,SAAQ,UAAU;IACpC,OAAgB,MAAM,4BAiCpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,oDAAoD;IACxB,IAAI,SAAM;IACtC,mFAAmF;IACvC,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAExD,MAAM,yCA6Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
1
+ {"version":3,"file":"map-pin.d.ts","sourceRoot":"","sources":["../src/map-pin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;GASG;AACH,qBACa,MAAO,SAAQ,UAAU;IACpC,OAAgB,MAAM,4BA+CpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,oDAAoD;IACxB,IAAI,SAAM;IACtC,mFAAmF;IACvC,WAAW,UAAS;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAExD,MAAM,yCA8Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
package/dist/map-pin.js CHANGED
@@ -55,13 +55,27 @@ let MapPin = class MapPin extends LitElement {
55
55
  left: 50%;
56
56
  transform: translate(-50%, -50%);
57
57
  color: #fff;
58
- font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
58
+ font-family: var(
59
+ --ui-font,
60
+ ui-sans-serif,
61
+ system-ui,
62
+ sans-serif,
63
+ "Apple Color Emoji",
64
+ "Segoe UI Emoji",
65
+ "Segoe UI Symbol",
66
+ "Noto Color Emoji"
67
+ );
59
68
  font-weight: 700;
60
69
  line-height: 1;
61
70
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);
62
71
  pointer-events: none;
63
72
  white-space: nowrap;
64
73
  }
74
+ @media (prefers-reduced-motion: reduce) {
75
+ svg {
76
+ transition: none;
77
+ }
78
+ }
65
79
  `,
66
80
  ]; }
67
81
  render() {
@@ -70,6 +84,7 @@ let MapPin = class MapPin extends LitElement {
70
84
  const height = Math.round(this.size * (34 / 32));
71
85
  return html `
72
86
  <svg
87
+ aria-hidden="true"
73
88
  width=${this.size}
74
89
  height=${height}
75
90
  viewBox="0 0 32 34"
@@ -1 +1 @@
1
- {"version":3,"file":"map-pin.js","sourceRoot":"","sources":["../src/map-pin.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;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,UAAU;IAA/B;;QAoCL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,oDAAoD;QACxB,SAAI,GAAG,EAAE,CAAC;QACtC,mFAAmF;QACvC,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,gBAAgB,iBAAiB,EAAE,EAAE,CAAC;IAgCnE,CAAC;aA1EiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA8BF;KACF,AAjCqB,CAiCpB;IAWO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAA;;gBAEC,IAAI,CAAC,IAAI;iBACR,MAAM;;;;;;+BAMQ,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;;;uBAK1B,IAAI,CAAC,OAAO;;;;;8CAKW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAtCa;IAAX,QAAQ,EAAE;qCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAW;AAEM;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAqB;AAzCrD,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CA2ElB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A circular \"Apple Maps\"-style map pin: a light-to-dark gradient fill with\n * a slight point at the bottom. Purely a visual primitive — it has no\n * `mapbox-gl` (or any mapping library) dependency; the consumer positions\n * it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.\n *\n * @element map-pin\n * @slot - Badge content shown centered on the pin's circular head — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-pin\")\nexport class MapPin extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n /* The path's circular head is centered at viewBox y=13 of 34 total\n (13/34 ≈ 38%) — not the pin's full bounding box, which is pulled\n down by the point below the circle. */\n top: 38%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter of the circular head, in CSS pixels. */\n @property({ type: Number }) size = 32;\n /** Scales and glows the pin — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-pin-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n const height = Math.round(this.size * (34 / 32));\n return html`\n <svg\n width=${this.size}\n height=${height}\n viewBox=\"0 0 32 34\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <path\n d=\"M16 30 C10 24 4 19.5 4 13 A12 12 0 1 1 28 13 C28 19.5 22 24 16 30 Z\"\n fill=\"url(#${this._gradId})\"\n stroke=\"#ffffff\"\n stroke-width=\"1.5\"\n />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-pin\": MapPin;\n }\n}\n"]}
1
+ {"version":3,"file":"map-pin.js","sourceRoot":"","sources":["../src/map-pin.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;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;;;;;;;;GASG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAO,SAAQ,UAAU;IAA/B;;QAkDL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,oDAAoD;QACxB,SAAI,GAAG,EAAE,CAAC;QACtC,mFAAmF;QACvC,gBAAW,GAAG,KAAK,CAAC;QAE/C,YAAO,GAAG,gBAAgB,iBAAiB,EAAE,EAAE,CAAC;IAiCnE,CAAC;aAzFiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4CF;KACF,AA/CqB,CA+CpB;IAWO,MAAM;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAA;;;gBAGC,IAAI,CAAC,IAAI;iBACR,MAAM;;;;;;+BAMQ,IAAI,CAAC,OAAO;2CACA,KAAK;6CACH,IAAI;;;;;uBAK1B,IAAI,CAAC,OAAO;;;;;8CAKW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;;;KAGpE,CAAC;IACJ,CAAC;CACF,CAAA;AAvCa;IAAX,QAAQ,EAAE;qCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oCAAW;AAEM;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAqB;AAvDrD,MAAM;IADlB,aAAa,CAAC,SAAS,CAAC;GACZ,MAAM,CA0FlB","sourcesContent":["import { LitElement, css, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { tokens } from \"./tokens.js\";\nimport { mixHex } from \"./utils/color.js\";\n\nlet gradientIdCounter = 0;\n\n/**\n * A circular \"Apple Maps\"-style map pin: a light-to-dark gradient fill with\n * a slight point at the bottom. Purely a visual primitive — it has no\n * `mapbox-gl` (or any mapping library) dependency; the consumer positions\n * it, e.g. via `new mapboxgl.Marker({ element: pinEl })`.\n *\n * @element map-pin\n * @slot - Badge content shown centered on the pin's circular head — a rank\n * number, an emoji, a small icon.\n */\n@customElement(\"map-pin\")\nexport class MapPin extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n position: relative;\n line-height: 0;\n }\n svg {\n display: block;\n transition: transform 120ms ease, filter 120ms ease;\n }\n :host([highlighted]) svg {\n transform: scale(1.12);\n filter: brightness(1.08) drop-shadow(0 0 5px rgb(0 0 0 / 0.35));\n }\n .content {\n position: absolute;\n /* The path's circular head is centered at viewBox y=13 of 34 total\n (13/34 ≈ 38%) — not the pin's full bounding box, which is pulled\n down by the point below the circle. */\n top: 38%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #fff;\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-weight: 700;\n line-height: 1;\n text-shadow: 0 1px 2px rgb(0 0 0 / 0.35);\n pointer-events: none;\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n svg {\n transition: none;\n }\n }\n `,\n ];\n\n /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */\n @property() color = \"#4f46e5\";\n /** Diameter of the circular head, in CSS pixels. */\n @property({ type: Number }) size = 32;\n /** Scales and glows the pin — a generic emphasis state (e.g. hover, selection). */\n @property({ type: Boolean, reflect: true }) highlighted = false;\n\n private readonly _gradId = `map-pin-grad-${gradientIdCounter++}`;\n\n override render() {\n const light = mixHex(this.color, \"#ffffff\", 30);\n const dark = mixHex(this.color, \"#000000\", 30);\n const height = Math.round(this.size * (34 / 32));\n return html`\n <svg\n aria-hidden=\"true\"\n width=${this.size}\n height=${height}\n viewBox=\"0 0 32 34\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <linearGradient id=${this._gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=${light} />\n <stop offset=\"100%\" stop-color=${dark} />\n </linearGradient>\n </defs>\n <path\n d=\"M16 30 C10 24 4 19.5 4 13 A12 12 0 1 1 28 13 C28 19.5 22 24 16 30 Z\"\n fill=\"url(#${this._gradId})\"\n stroke=\"#ffffff\"\n stroke-width=\"1.5\"\n />\n </svg>\n <div class=\"content\" style=\"font-size:${Math.round(this.size * 0.4)}px\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-pin\": MapPin;\n }\n}\n"]}
@@ -17,6 +17,9 @@ export declare class PercentBarChart extends LitElement {
17
17
  groups: PercentBarGroup[];
18
18
  private _width;
19
19
  private _ro;
20
+ private readonly _gradIdBase;
21
+ /** Per-row gradient id, unique across instances and rows. */
22
+ private _gradId;
20
23
  firstUpdated(): void;
21
24
  disconnectedCallback(): void;
22
25
  render(): import("lit-html").TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"percent-bar-chart.d.ts","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AAKjD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAOD;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,MAAM,4BAYpB;IAEF,qCAAqC;IACL,MAAM,EAAE,eAAe,EAAE,CAAM;IACtD,OAAO,CAAC,MAAM,CAAK;IAE5B,OAAO,CAAC,GAAG,CAA+B;IAEjC,YAAY,SAMpB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCA4Bd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
1
+ {"version":3,"file":"percent-bar-chart.d.ts","sourceRoot":"","sources":["../src/percent-bar-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AAMjD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AASD;;;;;GAKG;AACH,qBACa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,MAAM,4BA+BpB;IAEF,qCAAqC;IACL,MAAM,EAAE,eAAe,EAAE,CAAM;IACtD,OAAO,CAAC,MAAM,CAAK;IAE5B,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6C;IAEzE,6DAA6D;IAC7D,OAAO,CAAC,OAAO;IAIN,YAAY,SAMpB;IAEQ,oBAAoB,SAI5B;IAEQ,MAAM,yCA2Dd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
@@ -6,12 +6,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { LitElement, css, html, svg } from "lit";
8
8
  import { customElement, property, state } from "lit/decorators.js";
9
+ import { styleMap } from "lit/directives/style-map.js";
9
10
  import { scaleLinear } from "d3-scale";
10
11
  import { tokens } from "./tokens.js";
11
12
  const ROW_H = 20;
12
13
  const LABEL_W = 56;
13
14
  const PCT_W = 36;
14
15
  const PAD = { top: 4, right: 4, bottom: 4, left: 4 };
16
+ let gradientIdCounter = 0;
15
17
  /**
16
18
  * Horizontal bar chart for labeled percentage rows, using D3's linear scale.
17
19
  * Each group gets its own labeled row; bars are proportional to percentage of 100.
@@ -25,6 +27,7 @@ let PercentBarChart = class PercentBarChart extends LitElement {
25
27
  this.groups = [];
26
28
  this._width = 0;
27
29
  this._ro = null;
30
+ this._gradIdBase = `percent-bar-grad-${gradientIdCounter++}`;
28
31
  }
29
32
  static { this.styles = [
30
33
  tokens,
@@ -36,9 +39,32 @@ let PercentBarChart = class PercentBarChart extends LitElement {
36
39
  svg {
37
40
  display: block;
38
41
  overflow: visible;
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
+ }
53
+ .chart-label {
54
+ fill: var(--ui-text-muted, #64748b);
55
+ }
56
+ .gradient-start {
57
+ stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #ffffff);
58
+ }
59
+ .gradient-end {
60
+ stop-color: color-mix(in srgb, var(--percent-bar-color) 70%, #000000);
39
61
  }
40
62
  `,
41
63
  ]; }
64
+ /** Per-row gradient id, unique across instances and rows. */
65
+ _gradId(index) {
66
+ return `${this._gradIdBase}-${index}`;
67
+ }
42
68
  firstUpdated() {
43
69
  this._ro = new ResizeObserver((entries) => {
44
70
  const w = Math.floor(entries[0].contentRect.width);
@@ -59,21 +85,51 @@ let PercentBarChart = class PercentBarChart extends LitElement {
59
85
  const barMaxW = innerW - LABEL_W - PCT_W;
60
86
  const svgH = PAD.top + this.groups.length * ROW_H + PAD.bottom;
61
87
  const xScale = scaleLinear().domain([0, 100]).range([0, barMaxW]);
88
+ // CSS stop styles preserve every valid CSS color format while matching
89
+ // map-circle's 30% white/black vertical depth.
90
+ const rowFills = this.groups.map((g, i) => {
91
+ const color = g.color.trim();
92
+ const gradId = this._gradId(i);
93
+ return {
94
+ fill: `url(#${gradId})`,
95
+ gradient: svg `
96
+ <linearGradient
97
+ id=${gradId}
98
+ x1="0"
99
+ y1="0"
100
+ x2="0"
101
+ y2="1"
102
+ style=${styleMap({ "--percent-bar-color": color })}
103
+ >
104
+ <stop class="gradient-start" offset="0%" />
105
+ <stop class="gradient-end" offset="100%" />
106
+ </linearGradient>
107
+ `,
108
+ };
109
+ });
110
+ const gradients = rowFills.map((row) => row.gradient);
62
111
  const rows = this.groups.map((g, i) => {
63
112
  const cy = PAD.top + i * ROW_H + ROW_H / 2;
64
113
  const bw = Math.max(0, xScale(g.pct));
65
114
  return svg `
66
- <text x=${PAD.left} y=${cy} font-size="10" fill="#64748b"
115
+ <text class="chart-label" x=${PAD.left} y=${cy} font-size="10"
67
116
  text-anchor="start" dominant-baseline="middle">${g.label}</text>
68
117
  <rect x=${PAD.left + LABEL_W} y=${cy - 5}
69
118
  width=${bw} height="10" rx="2"
70
- fill=${g.color} fill-opacity="0.82" />
71
- <text x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size="10" fill="#64748b"
119
+ fill=${rowFills[i].fill} />
120
+ <text class="chart-label" x=${PAD.left + LABEL_W + barMaxW + 4} y=${cy} font-size="10"
72
121
  text-anchor="start" dominant-baseline="middle">${g.pct.toFixed(1)}%</text>
73
122
  `;
74
123
  });
75
124
  return html `
76
- <svg viewBox="0 0 ${this._width} ${svgH}" width=${this._width} height=${svgH}>
125
+ <svg
126
+ viewBox="0 0 ${this._width} ${svgH}"
127
+ width=${this._width}
128
+ height=${svgH}
129
+ role="img"
130
+ aria-label=${`Percentages: ${this.groups.map((group) => `${group.label} ${group.pct.toFixed(1)}%`).join(", ")}`}
131
+ >
132
+ <defs>${gradients}</defs>
77
133
  ${rows}
78
134
  </svg>
79
135
  `;