@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
package/llms.txt CHANGED
@@ -33,9 +33,9 @@ Supports two suggestion sources:
33
33
 
34
34
  Import: `import "@f-ewald/components/address-autocomplete.js";`
35
35
 
36
- Properties: `value` (attribute `value`) : string, default ""; `placeholder` (attribute `placeholder`) : string, default ""; `required` (attribute `required`) : boolean, default false; `types` (attribute `types`) : string, default "address"; `endpoint` (attribute `endpoint`) : string, default "https://api.mapbox.com/search/geocode/v6/forward"; `accessToken` (attribute `access-token`) : string, default ""; `bbox` (attribute `bbox`) : string, default ""; `proximity` (attribute `proximity`) : string, default ""; `debounce` (attribute `debounce`) : number, default 300; `minLength` (attribute `min-length`) : number, default 3; `suggestions` (JS property only) : AddressSuggestion[] | null, default null; `selectedSuggestion` (JS property only) : AddressSuggestion | null, default —
36
+ Properties: `value` (attribute `value`) : string, default ""; `placeholder` (attribute `placeholder`) : string, default ""; `required` (attribute `required`) : boolean, default false; `disabled` (attribute `disabled`) : boolean, default false; `types` (attribute `types`) : string, default "address"; `endpoint` (attribute `endpoint`) : string, default "https://api.mapbox.com/search/geocode/v6/forward"; `accessToken` (attribute `access-token`) : string, default ""; `bbox` (attribute `bbox`) : string, default ""; `proximity` (attribute `proximity`) : string, default ""; `debounce` (attribute `debounce`) : number, default 300; `minLength` (attribute `min-length`) : number, default 3; `suggestions` (JS property only) : AddressSuggestion[] | null, default null; `selectedSuggestion` (JS property only) : AddressSuggestion | null, default —
37
37
  Events: `address-select`
38
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`
38
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
39
39
 
40
40
  Example:
41
41
  ```html
@@ -83,9 +83,9 @@ Supports two suggestion sources:
83
83
 
84
84
  Import: `import "@f-ewald/components/autocomplete-input.js";`
85
85
 
86
- Properties: `value` (attribute `value`) : string, default ""; `placeholder` (attribute `placeholder`) : string, default ""; `required` (attribute `required`) : boolean, default false; `endpoint` (attribute `endpoint`) : string, default ""; `queryParam` (attribute `query-param`) : string, default "q"; `debounce` (attribute `debounce`) : number, default 300; `minLength` (attribute `min-length`) : number, default 3; `options` (JS property only) : AutocompleteOption[] | null, default null; `selectedOption` (JS property only) : AutocompleteOption | null, default —
86
+ Properties: `value` (attribute `value`) : string, default ""; `placeholder` (attribute `placeholder`) : string, default ""; `required` (attribute `required`) : boolean, default false; `disabled` (attribute `disabled`) : boolean, default false; `endpoint` (attribute `endpoint`) : string, default ""; `queryParam` (attribute `query-param`) : string, default "q"; `debounce` (attribute `debounce`) : number, default 300; `minLength` (attribute `min-length`) : number, default 3; `options` (JS property only) : AutocompleteOption[] | null, default null; `selectedOption` (JS property only) : AutocompleteOption | null, default —
87
87
  Events: `option-select`
88
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`
88
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
89
89
 
90
90
  Example:
91
91
  ```html
@@ -104,6 +104,104 @@ Example:
104
104
  </script>
105
105
  ```
106
106
 
107
+ ## <calendar-entry>
108
+
109
+ Declarative metadata for one calendar event, consumed by a parent
110
+ `calendar-month` or `calendar-year`. Read-only/non-interactive; renders
111
+ nothing itself.
112
+
113
+ Import: `import "@f-ewald/components/calendar-entry.js";`
114
+
115
+ Properties: `start` (attribute `start`) : string, default ""; `end` (attribute `end`) : string, default ""; `label` (attribute `label`) : string, default ""; `color` (attribute `color`) : StatusPillColor, default "neutral"; `href` (attribute `href`) : string | undefined, default —
116
+ Events: none
117
+ CSS custom properties: none
118
+
119
+ Example:
120
+ ```html
121
+ <calendar-entry
122
+ start="2026-07-10"
123
+ end="2026-07-18"
124
+ label="Vacation"
125
+ color="success"
126
+ >
127
+ <span slot="title">Vacation</span>
128
+ <span slot="detail">Out of office</span>
129
+ <span slot="detail">Road trip along the California coast with several scenic stops</span>
130
+ <span slot="footer">Return July 19 at 6 PM</span>
131
+ </calendar-entry>
132
+ ```
133
+
134
+ ## <calendar-month>
135
+
136
+ One month rendered as a top-to-bottom list of days — weekends and today
137
+ highlighted, with declarative `calendar-entry` children shown as colored
138
+ bars spanning the days they cover. An entry's title uses its first visible
139
+ day; every remaining visible day becomes one shared body for wrapped
140
+ details and an optional ending footer. Overlapping entries stack into
141
+ side-by-side lanes rather than being layered/hidden. Read-only.
142
+
143
+ Lanes are computed independently per instance, from only the entries
144
+ overlapping this month — an entry spanning a month boundary may therefore
145
+ land in a different lane index in the adjacent month's `calendar-month`.
146
+ This is an accepted v1 limitation: cross-month lane continuity would
147
+ require a shared parent (`calendar-year`) to assign lanes globally.
148
+
149
+ Entry attributes and slotted title/detail text are observed, so a
150
+ standalone month re-renders when consumers update declarative metadata.
151
+
152
+ Import: `import "@f-ewald/components/calendar-month.js";`
153
+
154
+ Properties: `year` (attribute `year`) : number, default —; `month` (attribute `month`) : number, default 1
155
+ Events: none
156
+ CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-font-size-xs`, `--ui-hover-overlay`, `--ui-info`, `--ui-primary`, `--ui-radius-sm`, `--ui-success`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`, `--ui-warning`
157
+
158
+ Example:
159
+ ```html
160
+ <calendar-month year="2026" month="7">
161
+ <calendar-entry start="2026-07-10" end="2026-07-18" label="Vacation" color="success">
162
+ <span slot="title">Vacation</span>
163
+ <span slot="detail">Out of office</span>
164
+ <span slot="detail">Road trip along the California coast with several scenic stops</span>
165
+ <span slot="footer">Return July 19 at 6 PM</span>
166
+ </calendar-entry>
167
+ <calendar-entry start="2026-07-15" end="2026-07-20" label="Conference" color="warning" href="#conf">
168
+ <span slot="detail">Talks and workshops</span>
169
+ <span slot="footer">Closing keynote · July 20</span>
170
+ </calendar-entry>
171
+ </calendar-month>
172
+ ```
173
+
174
+ ## <calendar-year>
175
+
176
+ A full year of `calendar-month` blocks, generated from declarative
177
+ `calendar-entry` children. Each entry is re-projected into the
178
+ `calendar-month` blocks it overlaps as a freshly-created `calendar-entry`
179
+ element — the original elements stay slotted here and are never moved,
180
+ since a DOM node can only have one parent. Read-only.
181
+
182
+ Import: `import "@f-ewald/components/calendar-year.js";`
183
+
184
+ Properties: `year` (attribute `year`) : number, default —
185
+ Events: none
186
+ CSS custom properties: `--ui-font`
187
+
188
+ Example:
189
+ ```html
190
+ <calendar-year year="2026">
191
+ <calendar-entry start="2026-01-28" end="2026-02-03" label="Offsite" color="primary" href="#offsite">
192
+ <span slot="detail">New York</span>
193
+ <span slot="detail">Team workshops</span>
194
+ <span slot="footer">Closing dinner Friday</span>
195
+ </calendar-entry>
196
+ <calendar-entry start="2026-03-05" end="2026-03-18" label="Product launch" color="success" href="#launch">
197
+ <span slot="detail">Coordinate the release across engineering, design, support, and marketing.</span>
198
+ <span slot="detail">Monitor adoption and production health throughout the rollout.</span>
199
+ <span slot="footer">Public launch · March 18 at 9 AM</span>
200
+ </calendar-entry>
201
+ <calendar-entry start="2026-07-10" end="2026-07-18" label="Vacation" color="success"></calendar-entry>
202
+ </calendar-year>
203
+ ```
204
+
107
205
  ## <chat-message>
108
206
 
109
207
  One conversation entry in a chat-style activity feed. Tool calls and
@@ -115,7 +213,7 @@ Import: `import "@f-ewald/components/chat-message.js";`
115
213
 
116
214
  Properties: `role` (attribute `role`) : ChatMessageRole, default "agent"; `variant` (attribute `variant`) : ChatMessageVariant, default "normal"; `author` (attribute `author`) : string, default ""; `timestamp` (attribute `timestamp`) : string | null, default null; `summary` (attribute `summary`) : string, default ""; `collapsible` (attribute `collapsible`) : boolean, default false; `collapsed` (attribute `collapsed`) : boolean, default false
117
215
  Events: `toggle`
118
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size`, `--ui-primary`, `--ui-radius`, `--ui-surface`, `--ui-text`, `--ui-text-muted`
216
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-mono`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-text`, `--ui-text-muted`
119
217
 
120
218
  Example:
121
219
  ```html
@@ -140,7 +238,7 @@ Import: `import "@f-ewald/components/confirm-dialog.js";`
140
238
 
141
239
  Properties: `open` (attribute `open`) : boolean, default false; `confirmLabel` (attribute `confirm-label`) : string, default "Delete"; `cancelLabel` (attribute `cancel-label`) : string, default "Cancel"; `danger` (attribute `danger`) : boolean, default true; `busy` (attribute `busy`) : boolean, default false; `error` (attribute `error`) : string | null, default null
142
240
  Events: `confirm`, `cancel`
143
- CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-danger-hover`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-overlay`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-text`, `--ui-text-muted`
241
+ CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-danger-hover`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-on-accent`, `--ui-overlay`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-text`, `--ui-text-muted`
144
242
 
145
243
  Example:
146
244
  ```html
@@ -159,9 +257,9 @@ without a toast element can react. Defaults to the current page URL if
159
257
 
160
258
  Import: `import "@f-ewald/components/copy-link-button.js";`
161
259
 
162
- Properties: `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default "Copy link"
260
+ Properties: `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default "Copy link"; `disabled` (attribute `disabled`) : boolean, default false
163
261
  Events: `copy-success`, `copy-error`
164
- CSS custom properties: `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
262
+ CSS custom properties: `--ui-focus-ring`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
165
263
 
166
264
  Example:
167
265
  ```html
@@ -181,9 +279,9 @@ cell's rendered content might contain.
181
279
 
182
280
  Import: `import "@f-ewald/components/data-table.js";`
183
281
 
184
- Properties: `columns` (JS property only) : DataTableColumn[], default []; `rows` (JS property only) : unknown[], default []; `rowKey` (JS property only) : (row: unknown, index: number) => string | number, default —; `renderCell` (JS property only) : (row: unknown, key: string) => unknown, default —; `rowHref` (JS property only) : ((row: unknown) => string | null) | null, default null
282
+ Properties: `columns` (JS property only) : DataTableColumn[], default []; `rows` (JS property only) : unknown[], default []; `rowKey` (JS property only) : (row: unknown, index: number) => string | number, default —; `renderCell` (JS property only) : (row: unknown, key: string) => unknown, default —; `rowHref` (JS property only) : ((row: unknown) => string | null) | null, default null; `rowLabel` (JS property only) : ((row: unknown) => string) | null, default null
185
283
  Events: none
186
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
284
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
187
285
 
188
286
  Example:
189
287
  ```html
@@ -236,7 +334,7 @@ Import: `import "@f-ewald/components/distribution-chart.js";`
236
334
 
237
335
  Properties: `metric` (attribute `metric`) : string, default ""; `values` (JS property only) : DistributionValue[], default []; `markerColors` (JS property only) : string[], default ["#4f46e5", "#d97706", "#0d9488", "#e11d48"]; `fontSize` (attribute `font-size`) : number, default 11
238
336
  Events: none
239
- CSS custom properties: `--ui-danger`, `--ui-font-size-sm`, `--ui-radius-sm`, `--ui-text-muted`
337
+ CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text-muted`
240
338
 
241
339
  Example:
242
340
  ```html
@@ -257,7 +355,7 @@ Import: `import "@f-ewald/components/dropdown-button.js";`
257
355
 
258
356
  Properties: `label` (attribute `label`) : string, default ""; `options` (JS property only) : DropdownOption[], default []; `disabled` (attribute `disabled`) : boolean, default false
259
357
  Events: `select`
260
- CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`
358
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-on-accent`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`
261
359
 
262
360
  Example:
263
361
  ```html
@@ -306,21 +404,32 @@ pushes the chevron to the far edge), but the host itself stays
306
404
  bar, a status picker) keep shrink-to-fit auto-width unchanged. To make an
307
405
  instance full-width, size the host itself: `form-select { width: 100%; }`.
308
406
 
407
+ Set `searchable` to replace the button trigger with an editable combobox
408
+ that filters the predefined options by case-insensitive label infix. Typed
409
+ text is only a query: `value` changes exclusively when an actual option is
410
+ selected, and an uncommitted query is discarded when the list closes.
411
+ Each option may also provide a pre-rendered `icon` and square `iconSize`;
412
+ iconless options reserve no leading space.
413
+
309
414
  Import: `import "@f-ewald/components/form-select.js";`
310
415
 
311
- Properties: `options` (JS property only) : SelectOption[], default []; `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
416
+ Properties: `options` (JS property only) : SelectOption[], default []; `value` (attribute `value`) : string, default ""; `label` (attribute `label`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false; `searchable` (attribute `searchable`) : boolean, default false
312
417
  Events: `change`
313
418
  CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-shadow`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
314
419
 
315
420
  Example:
316
421
  ```html
317
- <form-select label="Task state"></form-select>
422
+ <form-select label="Task state" searchable></form-select>
318
423
  <script type="module">
424
+ import { iconArrowPath, iconCheckCircle, iconListBullet } from "@f-ewald/components/icons.js";
425
+
319
426
  const select = document.querySelector("form-select");
320
427
  select.options = [
428
+ { value: "backlog", label: "Backlog", icon: iconListBullet(14), iconSize: 14 },
321
429
  { value: "open", label: "Open" },
322
- { value: "in_progress", label: "In progress" },
323
- { value: "done", label: "Done" },
430
+ { value: "in_progress", label: "In progress", icon: iconArrowPath(16), iconSize: 16 },
431
+ { value: "review", label: "Needs review" },
432
+ { value: "done", label: "Done", icon: iconCheckCircle(16), iconSize: 16 },
324
433
  ];
325
434
  select.value = "open";
326
435
  select.addEventListener("change", (e) => console.log(e.detail.value));
@@ -338,7 +447,7 @@ Import: `import "@f-ewald/components/frame-box.js";`
338
447
 
339
448
  Properties: `label` (attribute `label`) : string, default ""
340
449
  Events: none
341
- CSS custom properties: `--ui-border`, `--ui-radius-sm`, `--ui-surface`, `--ui-text-muted`
450
+ CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-xs`, `--ui-radius-sm`, `--ui-surface`, `--ui-text-muted`
342
451
 
343
452
  Example:
344
453
  ```html
@@ -413,6 +522,25 @@ Example:
413
522
  </script>
414
523
  ```
415
524
 
525
+ ## <kbd-hint>
526
+
527
+ Renders a keyboard shortcut as one boxed keycap per `+`-separated token.
528
+ Modifier keys are platform-aware: `Mod` becomes Command on macOS and
529
+ Control elsewhere. Keycaps derive their presentation from `currentColor`,
530
+ so the hint works inside neutral and accent-colored controls.
531
+
532
+ Import: `import "@f-ewald/components/kbd-hint.js";`
533
+
534
+ Properties: `keys` (attribute `keys`) : string, default ""; `platform` (attribute `platform`) : KbdPlatform, default "auto"
535
+ Events: none
536
+ CSS custom properties: `--ui-font-mono`, `--ui-font-size-xs`, `--ui-radius-sm`
537
+
538
+ Example:
539
+ ```html
540
+ <kbd-hint keys="Mod+K"></kbd-hint>
541
+ <kbd-hint keys="Mod+Shift+Enter" platform="mac"></kbd-hint>
542
+ ```
543
+
416
544
  ## <live-timer>
417
545
 
418
546
  Per-second ticking count-up timer, e.g. a live "running for 12s" or
@@ -438,6 +566,9 @@ outer ring, no point/tail (unlike `<map-pin>`) — for markers that don't
438
566
  need to visually "point" at their exact coordinate. Purely a visual
439
567
  primitive — it has no `mapbox-gl` (or any mapping library) dependency;
440
568
  the consumer positions it, e.g. via `new mapboxgl.Marker({ element: el })`.
569
+ It can also replace the former `<map-point>` dense-layer primitive: use
570
+ `size="14" ring-width="3"`, leave the slot empty, and rasterize one marker
571
+ per color for use as a map `icon-image`.
441
572
 
442
573
  Import: `import "@f-ewald/components/map-circle.js";`
443
574
 
@@ -448,6 +579,7 @@ CSS custom properties: `--ui-font`
448
579
  Example:
449
580
  ```html
450
581
  <map-circle color="#6b7280"></map-circle>
582
+ <map-circle color="#0099D8" size="14" ring-width="3"></map-circle>
451
583
  <map-circle color="#1a73e8" size="24" ring-width="5" highlighted>1</map-circle>
452
584
  ```
453
585
 
@@ -470,30 +602,6 @@ Example:
470
602
  <map-pin color="#22c55e" size="26" highlighted>🏠</map-pin>
471
603
  ```
472
604
 
473
- ## <map-point>
474
-
475
- A small plain-colored map marker for dense point layers (transit stops,
476
- amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
477
- white ring, no badge/content slot — every instance on a given layer shares
478
- the same look, so there's nothing to render per-feature (unlike
479
- `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
480
- Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
481
- dependency; typically rasterized once per color and used as a Mapbox
482
- `icon-image` on a `symbol` layer rather than mounted as individual DOM
483
- markers, so a whole layer's worth of points shares one icon image.
484
-
485
- Import: `import "@f-ewald/components/map-point.js";`
486
-
487
- Properties: `color` (attribute `color`) : string, default "#4f46e5"; `size` (attribute `size`) : number, default 14; `ringWidth` (attribute `ring-width`) : number, default 3
488
- Events: none
489
- CSS custom properties: none
490
-
491
- Example:
492
- ```html
493
- <map-point color="#0099D8"></map-point>
494
- <map-point color="#fb8072" size="10" ring-width="2"></map-point>
495
- ```
496
-
497
605
  ## <percent-bar-chart>
498
606
 
499
607
  Horizontal bar chart for labeled percentage rows, using D3's linear scale.
@@ -503,7 +611,7 @@ Import: `import "@f-ewald/components/percent-bar-chart.js";`
503
611
 
504
612
  Properties: `groups` (JS property only) : PercentBarGroup[], default []
505
613
  Events: none
506
- CSS custom properties: none
614
+ CSS custom properties: `--ui-font`, `--ui-text-muted`
507
615
 
508
616
  Example:
509
617
  ```html
@@ -525,7 +633,7 @@ Import: `import "@f-ewald/components/photo-gallery.js";`
525
633
 
526
634
  Properties: `currentIndex` (attribute `current-index`) : number, default 0; `delay` (attribute `delay`) : number, default 0; `showControls` (attribute `show-controls`) : boolean, default true; `showCounter` (attribute `show-counter`) : boolean, default false; `showIndicators` (attribute `show-indicators`) : boolean, default false; `showAutoplayControl` (attribute `show-autoplay-control`) : boolean, default true; `paused` (attribute `paused`) : boolean, default false; `aspectRatio` (attribute `aspect-ratio`) : string, default "16 / 9"; `objectFit` (attribute `object-fit`) : PhotoGalleryObjectFit, default "cover"
527
635
  Events: `slide-change`
528
- CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-overlay`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
636
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-font-size-sm`, `--ui-on-accent`, `--ui-overlay`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
529
637
 
530
638
  Example:
531
639
  ```html
@@ -565,7 +673,7 @@ Import: `import "@f-ewald/components/popover-panel.js";`
565
673
 
566
674
  Properties: `open` (attribute `open`) : boolean, default false; `heading` (attribute `heading`) : string, default ""; `centered` (attribute `centered`) : boolean, default false
567
675
  Events: `panel-close`
568
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
676
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-overlay`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
569
677
 
570
678
  Example:
571
679
  ```html
@@ -593,7 +701,7 @@ Import: `import "@f-ewald/components/price-history-chart.js";`
593
701
 
594
702
  Properties: `history` (attribute `history`) : PricePoint[], default []; `yLabels` (attribute `y-labels`) : "auto" | "always" | "never", default "auto"; `maxXLabels` (attribute `max-x-labels`) : number, default 3
595
703
  Events: none
596
- CSS custom properties: none
704
+ CSS custom properties: `--ui-border`, `--ui-font`, `--ui-on-accent`, `--ui-primary`, `--ui-text-muted`, `--ui-tooltip`
597
705
 
598
706
  Example:
599
707
  ```html
@@ -616,9 +724,9 @@ keyboard/a11y and fires `change` rather than relying on form submission.
616
724
 
617
725
  Import: `import "@f-ewald/components/radio-cards.js";`
618
726
 
619
- Properties: `options` (JS property only) : RadioCardOption[], default []; `value` (attribute `value`) : string, default ""
727
+ Properties: `options` (JS property only) : RadioCardOption[], default []; `value` (attribute `value`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
620
728
  Events: `change`
621
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
729
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-radius-sm`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
622
730
 
623
731
  Example:
624
732
  ```html
@@ -644,9 +752,9 @@ relying on form submission.
644
752
 
645
753
  Import: `import "@f-ewald/components/radio-pills.js";`
646
754
 
647
- Properties: `options` (JS property only) : RadioPillOption[], default []; `value` (attribute `value`) : string, default ""
755
+ Properties: `options` (JS property only) : RadioPillOption[], default []; `value` (attribute `value`) : string, default ""; `disabled` (attribute `disabled`) : boolean, default false
648
756
  Events: `change`
649
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-surface-muted`, `--ui-text`
757
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-surface-muted`, `--ui-text`
650
758
 
651
759
  Example:
652
760
  ```html
@@ -687,9 +795,9 @@ Button that reveals hidden slotted content when clicked.
687
795
 
688
796
  Import: `import "@f-ewald/components/reveal-button.js";`
689
797
 
690
- Properties: `label` (attribute `label`) : string, default "Reveal hidden content"
798
+ Properties: `label` (attribute `label`) : string, default "Reveal hidden content"; `disabled` (attribute `disabled`) : boolean, default false
691
799
  Events: none
692
- CSS custom properties: `--ui-font`, `--ui-font-size`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`
800
+ CSS custom properties: `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-on-accent`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`
693
801
 
694
802
  Example:
695
803
  ```html
@@ -719,14 +827,14 @@ Generic sliding panel shell. Handles positioning, open/close animation,
719
827
  header chrome, and a close button. Body content is provided via the
720
828
  default slot; the consumer controls its own padding and overflow.
721
829
 
722
- Desktop: 300 px fixed right-side panel that slides from the right.
723
- Mobile (≤768px): bottom-sheet drawer (60vh) — reserved for future use.
830
+ Desktop: fixed right-side panel that slides from the right.
831
+ Mobile (≤48rem): bottom-sheet drawer (60vh) — reserved for future use.
724
832
 
725
833
  Import: `import "@f-ewald/components/slide-panel.js";`
726
834
 
727
835
  Properties: `open` (attribute `open`) : boolean, default false; `heading` (attribute `heading`) : string, default ""
728
836
  Events: `panel-close`
729
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
837
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-surface`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
730
838
 
731
839
  Example:
732
840
  ```html
@@ -765,7 +873,7 @@ Import: `import "@f-ewald/components/status-pill.js";`
765
873
 
766
874
  Properties: `label` (attribute `label`) : string, default ""; `color` (attribute `color`) : StatusPillColor, default "neutral"; `spinner` (attribute `spinner`) : boolean, default false
767
875
  Events: none
768
- CSS custom properties: `--ui-danger`, `--ui-font`, `--ui-primary`, `--ui-success`, `--ui-text-muted`
876
+ CSS custom properties: `--ui-danger`, `--ui-font`, `--ui-font-size-sm`, `--ui-info`, `--ui-primary`, `--ui-success`, `--ui-text-muted`, `--ui-warning`
769
877
 
770
878
  Example:
771
879
  ```html
@@ -784,15 +892,21 @@ Optional `itemHref` makes whole tiles clickable (navigating via
784
892
  `location.hash`), without hijacking clicks on nested interactive elements
785
893
  (links/buttons) a tile's rendered content might contain.
786
894
 
895
+ Optional `fileIcon` prefixes each tile with a decorative Heroicons
896
+ "document" glyph, for grids whose items represent files — the icon never
897
+ carries its own accessible name since the rendered tile content (e.g. a
898
+ filename) already identifies the item. Off by default, so it consumes no
899
+ layout space or markup for grids of non-file items.
900
+
787
901
  Import: `import "@f-ewald/components/tile-grid.js";`
788
902
 
789
- Properties: `items` (JS property only) : unknown[], default []; `itemKey` (JS property only) : (item: unknown, index: number) => string | number, default —; `renderTile` (JS property only) : (item: unknown) => unknown, default —; `itemHref` (JS property only) : ((item: unknown) => string | null) | null, default null
903
+ Properties: `items` (JS property only) : unknown[], default []; `itemKey` (JS property only) : (item: unknown, index: number) => string | number, default —; `renderTile` (JS property only) : (item: unknown) => unknown, default —; `itemHref` (JS property only) : ((item: unknown) => string | null) | null, default null; `fileIcon` (attribute `file-icon`) : boolean, default false
790
904
  Events: none
791
- CSS custom properties: `--ui-border`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius`, `--ui-surface-muted`, `--ui-text`
905
+ CSS custom properties: `--ui-border`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-radius`, `--ui-surface-muted`, `--ui-text`, `--ui-text-muted`
792
906
 
793
907
  Example:
794
908
  ```html
795
- <tile-grid></tile-grid>
909
+ <tile-grid file-icon></tile-grid>
796
910
  <script type="module">
797
911
  const grid = document.querySelector("tile-grid");
798
912
  grid.items = [
@@ -818,7 +932,7 @@ Import: `import "@f-ewald/components/toast-notification.js";`
818
932
 
819
933
  Properties: none
820
934
  Events: none
821
- CSS custom properties: `--ui-danger`, `--ui-font`, `--ui-font-size`, `--ui-primary`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-success`, `--ui-text`
935
+ CSS custom properties: `--ui-danger`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size`, `--ui-hover-overlay`, `--ui-info`, `--ui-on-accent`, `--ui-radius`, `--ui-radius-sm`, `--ui-shadow-lg`, `--ui-success`, `--ui-text`
822
936
 
823
937
  Example:
824
938
  ```html
@@ -848,7 +962,7 @@ Import: `import "@f-ewald/components/ui-button.js";`
848
962
 
849
963
  Properties: `variant` (attribute `variant`) : ButtonVariant, default "primary"; `href` (attribute `href`) : string | null, default null; `type` (attribute `type`) : "button" | "submit" | "reset", default "button"; `disabled` (attribute `disabled`) : boolean, default false; `busy` (attribute `busy`) : boolean, default false
850
964
  Events: none
851
- CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-danger-hover`, `--ui-font`, `--ui-font-size-sm`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`, `--ui-text`, `--ui-text-muted`
965
+ CSS custom properties: `--ui-border`, `--ui-danger`, `--ui-danger-hover`, `--ui-focus-ring`, `--ui-font`, `--ui-font-size-sm`, `--ui-on-accent`, `--ui-primary`, `--ui-primary-hover`, `--ui-radius-sm`, `--ui-text`, `--ui-text-muted`
852
966
 
853
967
  Example:
854
968
  ```html
@@ -872,7 +986,7 @@ Import: `import "@f-ewald/components/user-avatar.js";`
872
986
 
873
987
  Properties: `src` (attribute `src`) : string | null, default null; `name` (attribute `name`) : string | null, default null; `size` (attribute `size`) : string | number, default 32
874
988
  Events: none
875
- CSS custom properties: `--ui-font`, `--ui-primary`
989
+ CSS custom properties: `--ui-font`, `--ui-on-accent`, `--ui-primary`
876
990
 
877
991
  Example:
878
992
  ```html
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@f-ewald/components",
3
3
  "private": false,
4
- "version": "0.7.0",
4
+ "version": "1.0.2",
5
5
  "description": "A collection of universally usable web components for various tasks.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -30,17 +30,25 @@
30
30
  "docs"
31
31
  ],
32
32
  "sideEffects": [
33
- "./dist/**/*.js"
33
+ "./dist/**/*.js",
34
+ "./src/**/*.ts"
34
35
  ],
35
36
  "scripts": {
36
37
  "dev": "vite",
38
+ "typecheck": "tsc --noEmit",
37
39
  "build": "rm -rf dist && tsc && node scripts/generate-tokens-css.mjs && chmod +x dist/mcp-server.js",
38
40
  "build:demo": "vite build",
41
+ "build:site": "node scripts/generate-docs.mjs --site && vite build --base=./ --outDir=pages-dist/playground",
42
+ "preview:site": "vite preview --outDir=pages-dist",
39
43
  "analyze": "cem analyze --litelement --globs \"src/**/*.ts\"",
40
44
  "docs": "npm run analyze && node scripts/generate-docs.mjs",
41
45
  "icons": "node scripts/generate-icons.mjs",
42
46
  "mcp": "node dist/mcp-server.js",
43
47
  "test": "playwright test",
48
+ "test:design": "playwright test --config playwright.design.config.ts",
49
+ "test:visual": "playwright test --config playwright.visual.config.ts",
50
+ "test:visual:update": "playwright test --config playwright.visual.config.ts --update-snapshots",
51
+ "test:site": "playwright test --config playwright.site.config.ts",
44
52
  "prepublishOnly": "npm run build && npm run docs && npm run test"
45
53
  },
46
54
  "keywords": [
@@ -48,6 +56,10 @@
48
56
  ],
49
57
  "author": "Friedrich Ewald",
50
58
  "license": "BSD-3-Clause",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/f-ewald/components.git"
62
+ },
51
63
  "dependencies": {
52
64
  "@modelcontextprotocol/sdk": "^1.29.0",
53
65
  "d3-array": "^3.2.4",
@@ -1,31 +0,0 @@
1
- import { LitElement } from "lit";
2
- /**
3
- * A small plain-colored map marker for dense point layers (transit stops,
4
- * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
5
- * white ring, no badge/content slot — every instance on a given layer shares
6
- * the same look, so there's nothing to render per-feature (unlike
7
- * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
8
- * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
9
- * dependency; typically rasterized once per color and used as a Mapbox
10
- * `icon-image` on a `symbol` layer rather than mounted as individual DOM
11
- * markers, so a whole layer's worth of points shares one icon image.
12
- *
13
- * @element map-point
14
- */
15
- export declare class MapPoint extends LitElement {
16
- static styles: import("lit").CSSResult[];
17
- /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */
18
- color: string;
19
- /** Diameter, in CSS pixels. */
20
- size: number;
21
- /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */
22
- ringWidth: number;
23
- private readonly _gradId;
24
- render(): import("lit-html").TemplateResult<1>;
25
- }
26
- declare global {
27
- interface HTMLElementTagNameMap {
28
- "map-point": MapPoint;
29
- }
30
- }
31
- //# sourceMappingURL=map-point.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"map-point.d.ts","sourceRoot":"","sources":["../src/map-point.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C;;;;;;;;;;;;GAYG;AACH,qBACa,QAAS,SAAQ,UAAU;IACtC,OAAgB,MAAM,4BAWpB;IAEF,4FAA4F;IAChF,KAAK,SAAa;IAC9B,+BAA+B;IACH,IAAI,SAAM;IACtC,wFAAwF;IACnC,SAAS,SAAK;IAEnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAE1D,MAAM,yCAoBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
package/dist/map-point.js DELETED
@@ -1,83 +0,0 @@
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
- import { mixHex } from "./utils/color.js";
11
- let gradientIdCounter = 0;
12
- /**
13
- * A small plain-colored map marker for dense point layers (transit stops,
14
- * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin
15
- * white ring, no badge/content slot — every instance on a given layer shares
16
- * the same look, so there's nothing to render per-feature (unlike
17
- * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).
18
- * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)
19
- * dependency; typically rasterized once per color and used as a Mapbox
20
- * `icon-image` on a `symbol` layer rather than mounted as individual DOM
21
- * markers, so a whole layer's worth of points shares one icon image.
22
- *
23
- * @element map-point
24
- */
25
- let MapPoint = class MapPoint extends LitElement {
26
- constructor() {
27
- super(...arguments);
28
- /** Fill color; the gradient's light (top) and dark (bottom) stops are derived from this. */
29
- this.color = "#4f46e5";
30
- /** Diameter, in CSS pixels. */
31
- this.size = 14;
32
- /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */
33
- this.ringWidth = 3;
34
- this._gradId = `map-point-grad-${gradientIdCounter++}`;
35
- }
36
- static { this.styles = [
37
- tokens,
38
- css `
39
- :host {
40
- display: inline-block;
41
- line-height: 0;
42
- }
43
- svg {
44
- display: block;
45
- }
46
- `,
47
- ]; }
48
- render() {
49
- const light = mixHex(this.color, "#ffffff", 30);
50
- const dark = mixHex(this.color, "#000000", 30);
51
- return html `
52
- <svg
53
- width=${this.size}
54
- height=${this.size}
55
- viewBox="0 0 32 32"
56
- fill="none"
57
- xmlns="http://www.w3.org/2000/svg"
58
- >
59
- <defs>
60
- <linearGradient id=${this._gradId} x1="0" y1="0" x2="0" y2="1">
61
- <stop offset="0%" stop-color=${light} />
62
- <stop offset="100%" stop-color=${dark} />
63
- </linearGradient>
64
- </defs>
65
- <circle cx="16" cy="16" r="13" fill="url(#${this._gradId})" stroke="#ffffff" stroke-width=${this.ringWidth} />
66
- </svg>
67
- `;
68
- }
69
- };
70
- __decorate([
71
- property()
72
- ], MapPoint.prototype, "color", void 0);
73
- __decorate([
74
- property({ type: Number })
75
- ], MapPoint.prototype, "size", void 0);
76
- __decorate([
77
- property({ type: Number, attribute: "ring-width" })
78
- ], MapPoint.prototype, "ringWidth", void 0);
79
- MapPoint = __decorate([
80
- customElement("map-point")
81
- ], MapPoint);
82
- export { MapPoint };
83
- //# sourceMappingURL=map-point.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"map-point.js","sourceRoot":"","sources":["../src/map-point.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;;;;;;;;;;;;GAYG;AAEI,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAAjC;;QAcL,4FAA4F;QAChF,UAAK,GAAG,SAAS,CAAC;QAC9B,+BAA+B;QACH,SAAI,GAAG,EAAE,CAAC;QACtC,wFAAwF;QACnC,cAAS,GAAG,CAAC,CAAC;QAElD,YAAO,GAAG,kBAAkB,iBAAiB,EAAE,EAAE,CAAC;IAuBrE,CAAC;aA3CiB,WAAM,GAAG;QACvB,MAAM;QACN,GAAG,CAAA;;;;;;;;KAQF;KACF,AAXqB,CAWpB;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,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;;KAE7G,CAAC;IACJ,CAAC;CACF,CAAA;AA7Ba;IAAX,QAAQ,EAAE;uCAAmB;AAEF;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sCAAW;AAEe;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;2CAAe;AAnBxD,QAAQ;IADpB,aAAa,CAAC,WAAW,CAAC;GACd,QAAQ,CA4CpB","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 small plain-colored map marker for dense point layers (transit stops,\n * amenities, hazard points, etc.): a light-to-dark gradient fill with a thin\n * white ring, no badge/content slot — every instance on a given layer shares\n * the same look, so there's nothing to render per-feature (unlike\n * `<map-pin>`/`<map-circle>`, which carry per-marker slotted content).\n * Purely a visual primitive — it has no `mapbox-gl` (or any mapping library)\n * dependency; typically rasterized once per color and used as a Mapbox\n * `icon-image` on a `symbol` layer rather than mounted as individual DOM\n * markers, so a whole layer's worth of points shares one icon image.\n *\n * @element map-point\n */\n@customElement(\"map-point\")\nexport class MapPoint extends LitElement {\n static override styles = [\n tokens,\n css`\n :host {\n display: inline-block;\n line-height: 0;\n }\n svg {\n display: block;\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 = 14;\n /** White outer ring thickness, in the same viewBox units as `size` (scales with it). */\n @property({ type: Number, attribute: \"ring-width\" }) ringWidth = 3;\n\n private readonly _gradId = `map-point-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 `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"map-point\": MapPoint;\n }\n}\n"]}