@internetarchive/elements 1.1.3-webdev-9241.0 → 1.1.4-webdev-9274.0

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 (186) hide show
  1. package/README.md +2 -2
  2. package/dist/src/elements/ia-donation-thermometer/ia-donation-thermometer.d.ts +93 -0
  3. package/dist/src/elements/ia-donation-thermometer/ia-donation-thermometer.d.ts.map +1 -0
  4. package/dist/src/elements/ia-donation-thermometer/ia-donation-thermometer.js +369 -0
  5. package/dist/src/elements/ia-donation-thermometer/ia-donation-thermometer.js.map +1 -0
  6. package/dist/src/elements/ia-radio-player/ia-radio-player.d.ts +2 -0
  7. package/dist/src/elements/ia-radio-player/ia-radio-player.d.ts.map +1 -1
  8. package/dist/src/elements/ia-radio-player/ia-radio-player.js +6 -1
  9. package/dist/src/elements/ia-radio-player/ia-radio-player.js.map +1 -1
  10. package/dist/src/elements/ia-status-indicator/ia-status-indicator.d.ts +16 -1
  11. package/dist/src/elements/ia-status-indicator/ia-status-indicator.d.ts.map +1 -1
  12. package/dist/src/elements/ia-status-indicator/ia-status-indicator.js +136 -8
  13. package/dist/src/elements/ia-status-indicator/ia-status-indicator.js.map +1 -1
  14. package/package.json +3 -5
  15. package/dist/src/elements/ia-topnav/assets/img/icon-audio.d.ts +0 -3
  16. package/dist/src/elements/ia-topnav/assets/img/icon-audio.d.ts.map +0 -1
  17. package/dist/src/elements/ia-topnav/assets/img/icon-audio.js +0 -28
  18. package/dist/src/elements/ia-topnav/assets/img/icon-audio.js.map +0 -1
  19. package/dist/src/elements/ia-topnav/assets/img/icon-close.d.ts +0 -3
  20. package/dist/src/elements/ia-topnav/assets/img/icon-close.d.ts.map +0 -1
  21. package/dist/src/elements/ia-topnav/assets/img/icon-close.js +0 -20
  22. package/dist/src/elements/ia-topnav/assets/img/icon-close.js.map +0 -1
  23. package/dist/src/elements/ia-topnav/assets/img/icon-donate-unpadded.d.ts +0 -3
  24. package/dist/src/elements/ia-topnav/assets/img/icon-donate-unpadded.d.ts.map +0 -1
  25. package/dist/src/elements/ia-topnav/assets/img/icon-donate-unpadded.js +0 -19
  26. package/dist/src/elements/ia-topnav/assets/img/icon-donate-unpadded.js.map +0 -1
  27. package/dist/src/elements/ia-topnav/assets/img/icon-donate.d.ts +0 -3
  28. package/dist/src/elements/ia-topnav/assets/img/icon-donate.d.ts.map +0 -1
  29. package/dist/src/elements/ia-topnav/assets/img/icon-donate.js +0 -18
  30. package/dist/src/elements/ia-topnav/assets/img/icon-donate.js.map +0 -1
  31. package/dist/src/elements/ia-topnav/assets/img/icon-ellipses.d.ts +0 -3
  32. package/dist/src/elements/ia-topnav/assets/img/icon-ellipses.d.ts.map +0 -1
  33. package/dist/src/elements/ia-topnav/assets/img/icon-ellipses.js +0 -19
  34. package/dist/src/elements/ia-topnav/assets/img/icon-ellipses.js.map +0 -1
  35. package/dist/src/elements/ia-topnav/assets/img/icon-ia-logo.d.ts +0 -3
  36. package/dist/src/elements/ia-topnav/assets/img/icon-ia-logo.d.ts.map +0 -1
  37. package/dist/src/elements/ia-topnav/assets/img/icon-ia-logo.js +0 -30
  38. package/dist/src/elements/ia-topnav/assets/img/icon-ia-logo.js.map +0 -1
  39. package/dist/src/elements/ia-topnav/assets/img/icon-images.d.ts +0 -3
  40. package/dist/src/elements/ia-topnav/assets/img/icon-images.d.ts.map +0 -1
  41. package/dist/src/elements/ia-topnav/assets/img/icon-images.js +0 -19
  42. package/dist/src/elements/ia-topnav/assets/img/icon-images.js.map +0 -1
  43. package/dist/src/elements/ia-topnav/assets/img/icon-search.d.ts +0 -3
  44. package/dist/src/elements/ia-topnav/assets/img/icon-search.d.ts.map +0 -1
  45. package/dist/src/elements/ia-topnav/assets/img/icon-search.js +0 -19
  46. package/dist/src/elements/ia-topnav/assets/img/icon-search.js.map +0 -1
  47. package/dist/src/elements/ia-topnav/assets/img/icon-software.d.ts +0 -3
  48. package/dist/src/elements/ia-topnav/assets/img/icon-software.d.ts.map +0 -1
  49. package/dist/src/elements/ia-topnav/assets/img/icon-software.js +0 -18
  50. package/dist/src/elements/ia-topnav/assets/img/icon-software.js.map +0 -1
  51. package/dist/src/elements/ia-topnav/assets/img/icon-texts.d.ts +0 -3
  52. package/dist/src/elements/ia-topnav/assets/img/icon-texts.d.ts.map +0 -1
  53. package/dist/src/elements/ia-topnav/assets/img/icon-texts.js +0 -18
  54. package/dist/src/elements/ia-topnav/assets/img/icon-texts.js.map +0 -1
  55. package/dist/src/elements/ia-topnav/assets/img/icon-upload-unpadded.d.ts +0 -3
  56. package/dist/src/elements/ia-topnav/assets/img/icon-upload-unpadded.d.ts.map +0 -1
  57. package/dist/src/elements/ia-topnav/assets/img/icon-upload-unpadded.js +0 -18
  58. package/dist/src/elements/ia-topnav/assets/img/icon-upload-unpadded.js.map +0 -1
  59. package/dist/src/elements/ia-topnav/assets/img/icon-upload.d.ts +0 -3
  60. package/dist/src/elements/ia-topnav/assets/img/icon-upload.d.ts.map +0 -1
  61. package/dist/src/elements/ia-topnav/assets/img/icon-upload.js +0 -21
  62. package/dist/src/elements/ia-topnav/assets/img/icon-upload.js.map +0 -1
  63. package/dist/src/elements/ia-topnav/assets/img/icon-user.d.ts +0 -3
  64. package/dist/src/elements/ia-topnav/assets/img/icon-user.d.ts.map +0 -1
  65. package/dist/src/elements/ia-topnav/assets/img/icon-user.js +0 -19
  66. package/dist/src/elements/ia-topnav/assets/img/icon-user.js.map +0 -1
  67. package/dist/src/elements/ia-topnav/assets/img/icon-video.d.ts +0 -3
  68. package/dist/src/elements/ia-topnav/assets/img/icon-video.d.ts.map +0 -1
  69. package/dist/src/elements/ia-topnav/assets/img/icon-video.js +0 -19
  70. package/dist/src/elements/ia-topnav/assets/img/icon-video.js.map +0 -1
  71. package/dist/src/elements/ia-topnav/assets/img/icon-web.d.ts +0 -3
  72. package/dist/src/elements/ia-topnav/assets/img/icon-web.d.ts.map +0 -1
  73. package/dist/src/elements/ia-topnav/assets/img/icon-web.js +0 -19
  74. package/dist/src/elements/ia-topnav/assets/img/icon-web.js.map +0 -1
  75. package/dist/src/elements/ia-topnav/assets/img/icon.d.ts +0 -6
  76. package/dist/src/elements/ia-topnav/assets/img/icon.d.ts.map +0 -1
  77. package/dist/src/elements/ia-topnav/assets/img/icon.js +0 -17
  78. package/dist/src/elements/ia-topnav/assets/img/icon.js.map +0 -1
  79. package/dist/src/elements/ia-topnav/assets/img/icons.d.ts +0 -19
  80. package/dist/src/elements/ia-topnav/assets/img/icons.d.ts.map +0 -1
  81. package/dist/src/elements/ia-topnav/assets/img/icons.js +0 -33
  82. package/dist/src/elements/ia-topnav/assets/img/icons.js.map +0 -1
  83. package/dist/src/elements/ia-topnav/assets/img/wayback-logo.d.ts +0 -3
  84. package/dist/src/elements/ia-topnav/assets/img/wayback-logo.d.ts.map +0 -1
  85. package/dist/src/elements/ia-topnav/assets/img/wayback-logo.js +0 -21
  86. package/dist/src/elements/ia-topnav/assets/img/wayback-logo.js.map +0 -1
  87. package/dist/src/elements/ia-topnav/assets/img/wordmark-stacked.d.ts +0 -3
  88. package/dist/src/elements/ia-topnav/assets/img/wordmark-stacked.d.ts.map +0 -1
  89. package/dist/src/elements/ia-topnav/assets/img/wordmark-stacked.js +0 -13
  90. package/dist/src/elements/ia-topnav/assets/img/wordmark-stacked.js.map +0 -1
  91. package/dist/src/elements/ia-topnav/data/menus.d.ts +0 -17
  92. package/dist/src/elements/ia-topnav/data/menus.d.ts.map +0 -1
  93. package/dist/src/elements/ia-topnav/data/menus.js +0 -680
  94. package/dist/src/elements/ia-topnav/data/menus.js.map +0 -1
  95. package/dist/src/elements/ia-topnav/dropdown-menu.d.ts +0 -21
  96. package/dist/src/elements/ia-topnav/dropdown-menu.d.ts.map +0 -1
  97. package/dist/src/elements/ia-topnav/dropdown-menu.js +0 -315
  98. package/dist/src/elements/ia-topnav/dropdown-menu.js.map +0 -1
  99. package/dist/src/elements/ia-topnav/ia-topnav-desktop-subnav.d.ts +0 -11
  100. package/dist/src/elements/ia-topnav/ia-topnav-desktop-subnav.d.ts.map +0 -1
  101. package/dist/src/elements/ia-topnav/ia-topnav-desktop-subnav.js +0 -89
  102. package/dist/src/elements/ia-topnav/ia-topnav-desktop-subnav.js.map +0 -1
  103. package/dist/src/elements/ia-topnav/ia-topnav-icon-hamburger.d.ts +0 -6
  104. package/dist/src/elements/ia-topnav/ia-topnav-icon-hamburger.d.ts.map +0 -1
  105. package/dist/src/elements/ia-topnav/ia-topnav-icon-hamburger.js +0 -47
  106. package/dist/src/elements/ia-topnav/ia-topnav-icon-hamburger.js.map +0 -1
  107. package/dist/src/elements/ia-topnav/ia-topnav-login-button.d.ts +0 -20
  108. package/dist/src/elements/ia-topnav/ia-topnav-login-button.d.ts.map +0 -1
  109. package/dist/src/elements/ia-topnav/ia-topnav-login-button.js +0 -183
  110. package/dist/src/elements/ia-topnav/ia-topnav-login-button.js.map +0 -1
  111. package/dist/src/elements/ia-topnav/ia-topnav-media-button.d.ts +0 -31
  112. package/dist/src/elements/ia-topnav/ia-topnav-media-button.d.ts.map +0 -1
  113. package/dist/src/elements/ia-topnav/ia-topnav-media-button.js +0 -287
  114. package/dist/src/elements/ia-topnav/ia-topnav-media-button.js.map +0 -1
  115. package/dist/src/elements/ia-topnav/ia-topnav-media-menu.d.ts +0 -21
  116. package/dist/src/elements/ia-topnav/ia-topnav-media-menu.d.ts.map +0 -1
  117. package/dist/src/elements/ia-topnav/ia-topnav-media-menu.js +0 -222
  118. package/dist/src/elements/ia-topnav/ia-topnav-media-menu.js.map +0 -1
  119. package/dist/src/elements/ia-topnav/ia-topnav-media-slider.d.ts +0 -16
  120. package/dist/src/elements/ia-topnav/ia-topnav-media-slider.d.ts.map +0 -1
  121. package/dist/src/elements/ia-topnav/ia-topnav-media-slider.js +0 -221
  122. package/dist/src/elements/ia-topnav/ia-topnav-media-slider.js.map +0 -1
  123. package/dist/src/elements/ia-topnav/ia-topnav-media-subnav.d.ts +0 -20
  124. package/dist/src/elements/ia-topnav/ia-topnav-media-subnav.d.ts.map +0 -1
  125. package/dist/src/elements/ia-topnav/ia-topnav-media-subnav.js +0 -285
  126. package/dist/src/elements/ia-topnav/ia-topnav-media-subnav.js.map +0 -1
  127. package/dist/src/elements/ia-topnav/ia-topnav-more-slider.d.ts +0 -12
  128. package/dist/src/elements/ia-topnav/ia-topnav-more-slider.d.ts.map +0 -1
  129. package/dist/src/elements/ia-topnav/ia-topnav-more-slider.js +0 -65
  130. package/dist/src/elements/ia-topnav/ia-topnav-more-slider.js.map +0 -1
  131. package/dist/src/elements/ia-topnav/ia-topnav-primary-nav.d.ts +0 -53
  132. package/dist/src/elements/ia-topnav/ia-topnav-primary-nav.d.ts.map +0 -1
  133. package/dist/src/elements/ia-topnav/ia-topnav-primary-nav.js +0 -653
  134. package/dist/src/elements/ia-topnav/ia-topnav-primary-nav.js.map +0 -1
  135. package/dist/src/elements/ia-topnav/ia-topnav-save-page-form.d.ts +0 -12
  136. package/dist/src/elements/ia-topnav/ia-topnav-save-page-form.d.ts.map +0 -1
  137. package/dist/src/elements/ia-topnav/ia-topnav-save-page-form.js +0 -128
  138. package/dist/src/elements/ia-topnav/ia-topnav-save-page-form.js.map +0 -1
  139. package/dist/src/elements/ia-topnav/ia-topnav-signed-out-dropdown.d.ts +0 -4
  140. package/dist/src/elements/ia-topnav/ia-topnav-signed-out-dropdown.d.ts.map +0 -1
  141. package/dist/src/elements/ia-topnav/ia-topnav-signed-out-dropdown.js +0 -10
  142. package/dist/src/elements/ia-topnav/ia-topnav-signed-out-dropdown.js.map +0 -1
  143. package/dist/src/elements/ia-topnav/ia-topnav-user-menu.d.ts +0 -7
  144. package/dist/src/elements/ia-topnav/ia-topnav-user-menu.d.ts.map +0 -1
  145. package/dist/src/elements/ia-topnav/ia-topnav-user-menu.js +0 -39
  146. package/dist/src/elements/ia-topnav/ia-topnav-user-menu.js.map +0 -1
  147. package/dist/src/elements/ia-topnav/ia-topnav-wayback-search.d.ts +0 -10
  148. package/dist/src/elements/ia-topnav/ia-topnav-wayback-search.d.ts.map +0 -1
  149. package/dist/src/elements/ia-topnav/ia-topnav-wayback-search.js +0 -64
  150. package/dist/src/elements/ia-topnav/ia-topnav-wayback-search.js.map +0 -1
  151. package/dist/src/elements/ia-topnav/ia-topnav-wayback-slider.d.ts +0 -20
  152. package/dist/src/elements/ia-topnav/ia-topnav-wayback-slider.d.ts.map +0 -1
  153. package/dist/src/elements/ia-topnav/ia-topnav-wayback-slider.js +0 -131
  154. package/dist/src/elements/ia-topnav/ia-topnav-wayback-slider.js.map +0 -1
  155. package/dist/src/elements/ia-topnav/ia-topnav.d.ts +0 -85
  156. package/dist/src/elements/ia-topnav/ia-topnav.d.ts.map +0 -1
  157. package/dist/src/elements/ia-topnav/ia-topnav.js +0 -434
  158. package/dist/src/elements/ia-topnav/ia-topnav.js.map +0 -1
  159. package/dist/src/elements/ia-topnav/lib/helpers.d.ts +0 -13
  160. package/dist/src/elements/ia-topnav/lib/helpers.d.ts.map +0 -1
  161. package/dist/src/elements/ia-topnav/lib/helpers.js +0 -24
  162. package/dist/src/elements/ia-topnav/lib/helpers.js.map +0 -1
  163. package/dist/src/elements/ia-topnav/lib/keyboard-navigation.d.ts +0 -46
  164. package/dist/src/elements/ia-topnav/lib/keyboard-navigation.d.ts.map +0 -1
  165. package/dist/src/elements/ia-topnav/lib/keyboard-navigation.js +0 -136
  166. package/dist/src/elements/ia-topnav/lib/keyboard-navigation.js.map +0 -1
  167. package/dist/src/elements/ia-topnav/models.d.ts +0 -59
  168. package/dist/src/elements/ia-topnav/models.d.ts.map +0 -1
  169. package/dist/src/elements/ia-topnav/models.js +0 -10
  170. package/dist/src/elements/ia-topnav/models.js.map +0 -1
  171. package/dist/src/elements/ia-topnav/subnav-list-styles.d.ts +0 -2
  172. package/dist/src/elements/ia-topnav/subnav-list-styles.d.ts.map +0 -1
  173. package/dist/src/elements/ia-topnav/subnav-list-styles.js +0 -49
  174. package/dist/src/elements/ia-topnav/subnav-list-styles.js.map +0 -1
  175. package/dist/src/elements/ia-topnav/tracked-element.d.ts +0 -6
  176. package/dist/src/elements/ia-topnav/tracked-element.d.ts.map +0 -1
  177. package/dist/src/elements/ia-topnav/tracked-element.js +0 -29
  178. package/dist/src/elements/ia-topnav/tracked-element.js.map +0 -1
  179. package/dist/src/elements/ia-wayback-search-form/ia-wayback-search-form.d.ts +0 -24
  180. package/dist/src/elements/ia-wayback-search-form/ia-wayback-search-form.d.ts.map +0 -1
  181. package/dist/src/elements/ia-wayback-search-form/ia-wayback-search-form.js +0 -240
  182. package/dist/src/elements/ia-wayback-search-form/ia-wayback-search-form.js.map +0 -1
  183. package/dist/src/elements/index.d.ts +0 -41
  184. package/dist/src/elements/index.d.ts.map +0 -1
  185. package/dist/src/elements/index.js +0 -41
  186. package/dist/src/elements/index.js.map +0 -1
package/README.md CHANGED
@@ -87,7 +87,7 @@ Add to Jest config:
87
87
 
88
88
  ## Development
89
89
 
90
- Requires Node 24+ and pnpm 11+. `engine-strict=true` in `.npmrc` makes an older
90
+ Requires Node 24+ and pnpm 12+. `engine-strict=true` in `.npmrc` makes an older
91
91
  Node fail the install instead of warning, but nothing hard-blocks `npm install`:
92
92
  npm ignores `engines.pnpm`, and there's deliberately no preinstall guard since it
93
93
  would run for consumers too. Use pnpm. `packageManager` and the committed
@@ -141,7 +141,7 @@ src
141
141
  - ia-foobar.test.ts // the element's tests
142
142
  - ia-foobar-story.ts // an element that demos your element
143
143
  ```
144
- Export your component in `src/index.ts`
144
+ Consumers import each element by its own subpath (`@internetarchive/elements/ia-button/ia-button`). There's no package root export, so there's no barrel file to update.
145
145
 
146
146
  ### Naming
147
147
  Custom elements all share one global registry, and that registry is shared with every other script on the host page. Give each element a name specific enough that nothing else would plausibly want it.
@@ -0,0 +1,93 @@
1
+ import { LitElement, type CSSResultGroup, type TemplateResult } from 'lit';
2
+ /** What the text beside the bar says: the goal amount, a message, or nothing. */
3
+ export type GoalMessageMode = 'off' | 'amount' | 'message';
4
+ /** Whether the current amount is printed on the bar. */
5
+ export type CurrentAmountMode = 'on' | 'off';
6
+ /**
7
+ * A horizontal progress bar for a fundraising goal, as shown in the
8
+ * archive.org donation banner. The fill grows with `currentAmount`, the amount
9
+ * raised is printed on the fill when it fits and beside it when it doesn't,
10
+ * and the goal (or a goal message) sits to the right of the bar.
11
+ */
12
+ export declare class IADonationThermometer extends LitElement {
13
+ goalMessageMode: GoalMessageMode;
14
+ goalNearMessage: string;
15
+ goalReachedMessage: string;
16
+ /** The accessible name of the progress bar, for screen readers. */
17
+ label: string;
18
+ goalAmount: number;
19
+ currentAmountMode: CurrentAmountMode;
20
+ currentAmount: number;
21
+ private thermometerValue?;
22
+ private thermometerFill?;
23
+ private thermometerValueWidth;
24
+ private thermometerFillWidth;
25
+ /**
26
+ * Watches the fill and the value label so the label can move to whichever
27
+ * side of the fill has room for it.
28
+ */
29
+ private resizeObserver?;
30
+ /**
31
+ * The observed nodes are tracked so each is observed exactly once. Calling
32
+ * `observe` on an already-observed target re-reports its size, which costs a
33
+ * notification on every render. Lit also discards the value label when
34
+ * `currentAmountMode` turns it off, so a replacement has to be picked up.
35
+ */
36
+ private observedFillElement;
37
+ private observedValueElement;
38
+ render(): TemplateResult;
39
+ private get thermometerValueTemplate();
40
+ /**
41
+ * Which side of the fill's end the value label sits on, as a class name for
42
+ * the CSS that places it. The label sits over the fill when the fill is
43
+ * wider than the label plus a little breathing room, and just past the
44
+ * fill's right edge otherwise.
45
+ */
46
+ private get thermometerValuePosition();
47
+ connectedCallback(): void;
48
+ disconnectedCallback(): void;
49
+ updated(): void;
50
+ /** Observes the fill and the value label, picking up either if it is replaced. */
51
+ private observeParts;
52
+ /**
53
+ * Swaps `observed` for `current` on the observer and returns whichever is
54
+ * now being watched. A target that hasn't changed is left alone.
55
+ */
56
+ private observeInPlaceOf;
57
+ private handleResize;
58
+ private get goalMessage();
59
+ private get currentAmountDisplayValue();
60
+ private get goalAmountDisplayValue();
61
+ /**
62
+ * Formats a dollar amount in millions, e.g. `$0.5MM` or `$35MM`. Amounts
63
+ * under ten million keep one decimal place, larger ones round to a whole
64
+ * number.
65
+ */
66
+ private formatNumber;
67
+ private get currentGoalMessage();
68
+ /**
69
+ * The goal the bar measures against. A goal that isn't a positive, finite
70
+ * number leaves the bar empty, since there is no range to report progress
71
+ * against. Named clear of `ariaValueMax`, which `HTMLElement` declares as a
72
+ * public string.
73
+ */
74
+ private get progressMax();
75
+ /**
76
+ * The progress reported to screen readers, clamped into the
77
+ * `aria-valuemin`/`aria-valuemax` range the spec requires.
78
+ * `aria-valuetext` carries the amount as it is displayed.
79
+ */
80
+ private get progressValue();
81
+ /**
82
+ * How much of the bar is filled, as a percentage, clamped to `0`-`100`. An
83
+ * amount or goal that can't produce a usable percentage empties the bar.
84
+ */
85
+ private get percentComplete();
86
+ static get styles(): CSSResultGroup;
87
+ }
88
+ declare global {
89
+ interface HTMLElementTagNameMap {
90
+ 'ia-donation-thermometer': IADonationThermometer;
91
+ }
92
+ }
93
+ //# sourceMappingURL=ia-donation-thermometer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ia-donation-thermometer.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-donation-thermometer/ia-donation-thermometer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAOb,iFAAiF;AACjF,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3D,wDAAwD;AACxD,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,KAAK,CAAC;AAE7C;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,UAAU;IACvB,eAAe,EAAE,eAAe,CAAY;IAE5C,eAAe,SAEzC;IAE0B,kBAAkB,SAE5C;IAEF,mEAAmE;IACvC,KAAK,SAA4B;IAEjC,UAAU,SAAa;IAEvB,iBAAiB,EAAE,iBAAiB,CAAQ;IAE5C,aAAa,SAAK;IAEjB,OAAO,CAAC,gBAAgB,CAAC,CAAiB;IAE3C,OAAO,CAAC,eAAe,CAAC,CAAiB;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,oBAAoB,CAAK;IAE1C;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAC,CAAiB;IAExC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB,CAAwB;IAEnD,OAAO,CAAC,oBAAoB,CAAwB;IAEpD,MAAM,IAAI,cAAc;IA2BxB,OAAO,KAAK,wBAAwB,GAMnC;IAED;;;;;OAKG;IACH,OAAO,KAAK,wBAAwB,GAKnC;IAED,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAQ5B,OAAO,IAAI,IAAI;IAIf,kFAAkF;IAClF,OAAO,CAAC,YAAY;IAgBpB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,YAAY;IAYpB,OAAO,KAAK,WAAW,GAItB;IAED,OAAO,KAAK,yBAAyB,GAEpC;IAED,OAAO,KAAK,sBAAsB,GAEjC;IAED;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAYpB,OAAO,KAAK,kBAAkB,GAS7B;IAED;;;;;OAKG;IACH,OAAO,KAAK,WAAW,GAItB;IAED;;;;OAIG;IACH,OAAO,KAAK,aAAa,GAGxB;IAED;;;OAGG;IACH,OAAO,KAAK,eAAe,GAK1B;IAED,MAAM,KAAK,MAAM,IAAI,cAAc,CAmIlC;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,yBAAyB,EAAE,qBAAqB,CAAC;KAClD;CACF"}
@@ -0,0 +1,369 @@
1
+ import { __decorate } from "tslib";
2
+ import { css, html, LitElement, nothing, } from 'lit';
3
+ import { property, query, state } from 'lit/decorators.js';
4
+ import { customElement } from '../../util/custom-element.js';
5
+ import { msg, str } from '@lit/localize';
6
+ import themeStyles from '../../themes/theme-styles.js';
7
+ /**
8
+ * A horizontal progress bar for a fundraising goal, as shown in the
9
+ * archive.org donation banner. The fill grows with `currentAmount`, the amount
10
+ * raised is printed on the fill when it fits and beside it when it doesn't,
11
+ * and the goal (or a goal message) sits to the right of the bar.
12
+ */
13
+ let IADonationThermometer = class IADonationThermometer extends LitElement {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.goalMessageMode = 'amount';
17
+ this.goalNearMessage = msg('We’ve almost reached our goal!');
18
+ this.goalReachedMessage = msg('We’ve reached our goal!');
19
+ /** The accessible name of the progress bar, for screen readers. */
20
+ this.label = msg('Donation progress');
21
+ this.goalAmount = 7_500_000;
22
+ this.currentAmountMode = 'on';
23
+ this.currentAmount = 0;
24
+ this.thermometerValueWidth = 0;
25
+ this.thermometerFillWidth = 0;
26
+ /**
27
+ * The observed nodes are tracked so each is observed exactly once. Calling
28
+ * `observe` on an already-observed target re-reports its size, which costs a
29
+ * notification on every render. Lit also discards the value label when
30
+ * `currentAmountMode` turns it off, so a replacement has to be picked up.
31
+ */
32
+ this.observedFillElement = null;
33
+ this.observedValueElement = null;
34
+ }
35
+ render() {
36
+ return html `
37
+ <div class="thermometer-message-container">
38
+ <div class="thermometer-container">
39
+ <div
40
+ class="thermometer-background ${this.thermometerValuePosition}"
41
+ style="--fill-end--: ${this.percentComplete}%"
42
+ role="progressbar"
43
+ aria-label="${this.label}"
44
+ aria-valuemin="0"
45
+ aria-valuemax="${this.progressMax}"
46
+ aria-valuenow="${this.progressValue}"
47
+ aria-valuetext="${this.currentAmountDisplayValue}"
48
+ >
49
+ <div class="thermometer-clip">
50
+ <div class="thermometer-fill"></div>
51
+ </div>
52
+ ${this.thermometerValueTemplate}
53
+ </div>
54
+ </div>
55
+ ${this.goalMessageMode !== 'off'
56
+ ? html `<div class="donate-goal">${this.currentGoalMessage}</div>`
57
+ : nothing}
58
+ </div>
59
+ `;
60
+ }
61
+ get thermometerValueTemplate() {
62
+ return this.currentAmountMode === 'off'
63
+ ? nothing
64
+ : html `
65
+ <div class="thermometer-value">${this.currentAmountDisplayValue}</div>
66
+ `;
67
+ }
68
+ /**
69
+ * Which side of the fill's end the value label sits on, as a class name for
70
+ * the CSS that places it. The label sits over the fill when the fill is
71
+ * wider than the label plus a little breathing room, and just past the
72
+ * fill's right edge otherwise.
73
+ */
74
+ get thermometerValuePosition() {
75
+ const buffer = 10;
76
+ return this.thermometerValueWidth + buffer < this.thermometerFillWidth
77
+ ? 'value-left'
78
+ : 'value-right';
79
+ }
80
+ connectedCallback() {
81
+ super.connectedCallback();
82
+ this.resizeObserver = new ResizeObserver((entries) => this.handleResize(entries));
83
+ // On a re-connect the fill already exists; on first connect it doesn't
84
+ // until the first render, and `updated` picks it up then.
85
+ this.observeParts();
86
+ }
87
+ disconnectedCallback() {
88
+ super.disconnectedCallback();
89
+ this.resizeObserver?.disconnect();
90
+ this.resizeObserver = undefined;
91
+ this.observedFillElement = null;
92
+ this.observedValueElement = null;
93
+ }
94
+ updated() {
95
+ this.observeParts();
96
+ }
97
+ /** Observes the fill and the value label, picking up either if it is replaced. */
98
+ observeParts() {
99
+ const observer = this.resizeObserver;
100
+ if (!observer)
101
+ return;
102
+ this.observedFillElement = this.observeInPlaceOf(observer, this.observedFillElement, this.thermometerFill ?? null);
103
+ this.observedValueElement = this.observeInPlaceOf(observer, this.observedValueElement, this.thermometerValue ?? null);
104
+ }
105
+ /**
106
+ * Swaps `observed` for `current` on the observer and returns whichever is
107
+ * now being watched. A target that hasn't changed is left alone.
108
+ */
109
+ observeInPlaceOf(observer, observed, current) {
110
+ if (current === observed)
111
+ return observed;
112
+ if (observed)
113
+ observer.unobserve(observed);
114
+ if (current)
115
+ observer.observe(current);
116
+ return current;
117
+ }
118
+ handleResize(entries) {
119
+ for (const entry of entries) {
120
+ const width = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
121
+ if (entry.target === this.observedFillElement) {
122
+ this.thermometerFillWidth = width;
123
+ }
124
+ else if (entry.target === this.observedValueElement) {
125
+ this.thermometerValueWidth = width;
126
+ }
127
+ }
128
+ }
129
+ get goalMessage() {
130
+ return this.currentAmount >= this.goalAmount
131
+ ? this.goalReachedMessage
132
+ : this.goalNearMessage;
133
+ }
134
+ get currentAmountDisplayValue() {
135
+ return this.formatNumber(this.currentAmount);
136
+ }
137
+ get goalAmountDisplayValue() {
138
+ return this.formatNumber(this.goalAmount);
139
+ }
140
+ /**
141
+ * Formats a dollar amount in millions, e.g. `$0.5MM` or `$35MM`. Amounts
142
+ * under ten million keep one decimal place, larger ones round to a whole
143
+ * number.
144
+ */
145
+ formatNumber(number) {
146
+ if (!Number.isFinite(number) || number === 0)
147
+ return '$0';
148
+ const suffix = 'MM';
149
+ const divisor = 1_000_000;
150
+ const result = number / divisor;
151
+ const roundToOne = result < 10;
152
+ const rounded = roundToOne
153
+ ? Math.round((result + Number.EPSILON) * 10) / 10
154
+ : Math.round(result);
155
+ return `$${rounded}${suffix}`;
156
+ }
157
+ get currentGoalMessage() {
158
+ switch (this.goalMessageMode) {
159
+ case 'amount':
160
+ return msg(str `${this.goalAmountDisplayValue} goal`);
161
+ case 'message':
162
+ return this.goalMessage;
163
+ case 'off':
164
+ return '';
165
+ }
166
+ }
167
+ /**
168
+ * The goal the bar measures against. A goal that isn't a positive, finite
169
+ * number leaves the bar empty, since there is no range to report progress
170
+ * against. Named clear of `ariaValueMax`, which `HTMLElement` declares as a
171
+ * public string.
172
+ */
173
+ get progressMax() {
174
+ return Number.isFinite(this.goalAmount) && this.goalAmount > 0
175
+ ? this.goalAmount
176
+ : 0;
177
+ }
178
+ /**
179
+ * The progress reported to screen readers, clamped into the
180
+ * `aria-valuemin`/`aria-valuemax` range the spec requires.
181
+ * `aria-valuetext` carries the amount as it is displayed.
182
+ */
183
+ get progressValue() {
184
+ if (!Number.isFinite(this.currentAmount))
185
+ return 0;
186
+ return Math.min(Math.max(this.currentAmount, 0), this.progressMax);
187
+ }
188
+ /**
189
+ * How much of the bar is filled, as a percentage, clamped to `0`-`100`. An
190
+ * amount or goal that can't produce a usable percentage empties the bar.
191
+ */
192
+ get percentComplete() {
193
+ const goal = this.progressMax;
194
+ if (goal === 0 || !Number.isFinite(this.currentAmount))
195
+ return 0;
196
+ const percent = (this.currentAmount / goal) * 100;
197
+ return Math.min(Math.max(percent, 0), 100);
198
+ }
199
+ static get styles() {
200
+ return [
201
+ themeStyles,
202
+ css `
203
+ :host {
204
+ --donation-thermometer-height--: var(
205
+ --ia-donation-thermometer-height,
206
+ 20px
207
+ );
208
+ --donation-thermometer-fill-color--: var(
209
+ --ia-donation-thermometer-fill-color,
210
+ #23765d
211
+ );
212
+ --donation-thermometer-track-color--: var(
213
+ --ia-donation-thermometer-track-color,
214
+ #b8f5e2
215
+ );
216
+ --donation-thermometer-border--: var(
217
+ --ia-donation-thermometer-border,
218
+ 1px solid var(--donation-thermometer-fill-color--)
219
+ );
220
+ /* Large enough to round any height into a pill */
221
+ --donation-thermometer-border-radius--: var(
222
+ --ia-donation-thermometer-border-radius,
223
+ 9999px
224
+ );
225
+ --donation-thermometer-value-on-fill-color--: var(
226
+ --ia-donation-thermometer-value-on-fill-color,
227
+ var(--true-white)
228
+ );
229
+ --donation-thermometer-value-on-track-color--: var(
230
+ --ia-donation-thermometer-value-on-track-color,
231
+ var(--donation-thermometer-fill-color--)
232
+ );
233
+ --donation-thermometer-goal-color--: var(--primary-text-color);
234
+ --donation-thermometer-goal-padding--: var(
235
+ --ia-donation-thermometer-goal-padding,
236
+ 0 10px
237
+ );
238
+
239
+ display: block;
240
+ height: var(--donation-thermometer-height--);
241
+ }
242
+
243
+ .thermometer-message-container {
244
+ height: 100%;
245
+ display: flex;
246
+ align-items: center;
247
+ }
248
+
249
+ .thermometer-container {
250
+ height: 100%;
251
+ flex: 1;
252
+ }
253
+
254
+ .thermometer-background {
255
+ box-sizing: border-box;
256
+ position: relative;
257
+ background-color: var(--donation-thermometer-track-color--);
258
+ height: 100%;
259
+ border-radius: var(--donation-thermometer-border-radius--);
260
+ border: var(--donation-thermometer-border--);
261
+ }
262
+
263
+ /*
264
+ * Clips the square-ended fill to the rounded track. It covers only the
265
+ * fill, so the label is never cut off by it.
266
+ */
267
+ .thermometer-clip {
268
+ position: absolute;
269
+ inset: 0;
270
+ overflow: hidden;
271
+ border-radius: var(--donation-thermometer-border-radius--);
272
+ }
273
+
274
+ .thermometer-fill {
275
+ background-color: var(--donation-thermometer-fill-color--);
276
+ height: 100%;
277
+ /*
278
+ * The fallback matters: without it a missing --fill-end-- makes the
279
+ * declaration invalid, width resolves to auto, and the bar paints as
280
+ * a fully funded fundraiser.
281
+ */
282
+ width: var(--fill-end--, 0%);
283
+ }
284
+
285
+ /*
286
+ * The label is placed by offset from the end of the fill, so it is one
287
+ * node in one position in the DOM whichever side it shows on, and it
288
+ * never counts towards the width of the fill it is measured against.
289
+ */
290
+ .thermometer-value {
291
+ position: absolute;
292
+ top: 0;
293
+ bottom: 0;
294
+ left: var(--fill-end--, 0%);
295
+ /*
296
+ * Without this, the left offset caps the shrink-to-fit width of a
297
+ * translated label and it collapses to its padding.
298
+ */
299
+ width: max-content;
300
+ display: flex;
301
+ align-items: center;
302
+ font-weight: bold;
303
+ white-space: nowrap;
304
+ }
305
+
306
+ /*
307
+ * Both paddings total 1.5rem, so changing sides leaves the label the
308
+ * same width and cannot feed back into the side it is placed on.
309
+ */
310
+ .value-left .thermometer-value {
311
+ transform: translateX(-100%);
312
+ color: var(--donation-thermometer-value-on-fill-color--);
313
+ padding: 0 0.5rem 0 1rem;
314
+ }
315
+
316
+ .value-right .thermometer-value {
317
+ color: var(--donation-thermometer-value-on-track-color--);
318
+ padding: 0 1rem 0 0.5rem;
319
+ }
320
+
321
+ .donate-goal {
322
+ text-align: left;
323
+ padding: var(--donation-thermometer-goal-padding--);
324
+ text-transform: uppercase;
325
+ font-weight: bold;
326
+ color: var(--donation-thermometer-goal-color--);
327
+ }
328
+ `,
329
+ ];
330
+ }
331
+ };
332
+ __decorate([
333
+ property({ type: String })
334
+ ], IADonationThermometer.prototype, "goalMessageMode", void 0);
335
+ __decorate([
336
+ property({ type: String })
337
+ ], IADonationThermometer.prototype, "goalNearMessage", void 0);
338
+ __decorate([
339
+ property({ type: String })
340
+ ], IADonationThermometer.prototype, "goalReachedMessage", void 0);
341
+ __decorate([
342
+ property({ type: String })
343
+ ], IADonationThermometer.prototype, "label", void 0);
344
+ __decorate([
345
+ property({ type: Number })
346
+ ], IADonationThermometer.prototype, "goalAmount", void 0);
347
+ __decorate([
348
+ property({ type: String })
349
+ ], IADonationThermometer.prototype, "currentAmountMode", void 0);
350
+ __decorate([
351
+ property({ type: Number })
352
+ ], IADonationThermometer.prototype, "currentAmount", void 0);
353
+ __decorate([
354
+ query('.thermometer-value')
355
+ ], IADonationThermometer.prototype, "thermometerValue", void 0);
356
+ __decorate([
357
+ query('.thermometer-fill')
358
+ ], IADonationThermometer.prototype, "thermometerFill", void 0);
359
+ __decorate([
360
+ state()
361
+ ], IADonationThermometer.prototype, "thermometerValueWidth", void 0);
362
+ __decorate([
363
+ state()
364
+ ], IADonationThermometer.prototype, "thermometerFillWidth", void 0);
365
+ IADonationThermometer = __decorate([
366
+ customElement('ia-donation-thermometer')
367
+ ], IADonationThermometer);
368
+ export { IADonationThermometer };
369
+ //# sourceMappingURL=ia-donation-thermometer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ia-donation-thermometer.js","sourceRoot":"","sources":["../../../../src/elements/ia-donation-thermometer/ia-donation-thermometer.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n nothing,\n type CSSResultGroup,\n type TemplateResult,\n} from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { customElement } from '@src/util/custom-element';\nimport { msg, str } from '@lit/localize';\n\nimport themeStyles from '@src/themes/theme-styles';\n\n/** What the text beside the bar says: the goal amount, a message, or nothing. */\nexport type GoalMessageMode = 'off' | 'amount' | 'message';\n\n/** Whether the current amount is printed on the bar. */\nexport type CurrentAmountMode = 'on' | 'off';\n\n/**\n * A horizontal progress bar for a fundraising goal, as shown in the\n * archive.org donation banner. The fill grows with `currentAmount`, the amount\n * raised is printed on the fill when it fits and beside it when it doesn't,\n * and the goal (or a goal message) sits to the right of the bar.\n */\n@customElement('ia-donation-thermometer')\nexport class IADonationThermometer extends LitElement {\n @property({ type: String }) goalMessageMode: GoalMessageMode = 'amount';\n\n @property({ type: String }) goalNearMessage = msg(\n 'We’ve almost reached our goal!',\n );\n\n @property({ type: String }) goalReachedMessage = msg(\n 'We’ve reached our goal!',\n );\n\n /** The accessible name of the progress bar, for screen readers. */\n @property({ type: String }) label = msg('Donation progress');\n\n @property({ type: Number }) goalAmount = 7_500_000;\n\n @property({ type: String }) currentAmountMode: CurrentAmountMode = 'on';\n\n @property({ type: Number }) currentAmount = 0;\n\n @query('.thermometer-value') private thermometerValue?: HTMLDivElement;\n\n @query('.thermometer-fill') private thermometerFill?: HTMLDivElement;\n\n @state() private thermometerValueWidth = 0;\n\n @state() private thermometerFillWidth = 0;\n\n /**\n * Watches the fill and the value label so the label can move to whichever\n * side of the fill has room for it.\n */\n private resizeObserver?: ResizeObserver;\n\n /**\n * The observed nodes are tracked so each is observed exactly once. Calling\n * `observe` on an already-observed target re-reports its size, which costs a\n * notification on every render. Lit also discards the value label when\n * `currentAmountMode` turns it off, so a replacement has to be picked up.\n */\n private observedFillElement: Element | null = null;\n\n private observedValueElement: Element | null = null;\n\n render(): TemplateResult {\n return html`\n <div class=\"thermometer-message-container\">\n <div class=\"thermometer-container\">\n <div\n class=\"thermometer-background ${this.thermometerValuePosition}\"\n style=\"--fill-end--: ${this.percentComplete}%\"\n role=\"progressbar\"\n aria-label=\"${this.label}\"\n aria-valuemin=\"0\"\n aria-valuemax=\"${this.progressMax}\"\n aria-valuenow=\"${this.progressValue}\"\n aria-valuetext=\"${this.currentAmountDisplayValue}\"\n >\n <div class=\"thermometer-clip\">\n <div class=\"thermometer-fill\"></div>\n </div>\n ${this.thermometerValueTemplate}\n </div>\n </div>\n ${this.goalMessageMode !== 'off'\n ? html`<div class=\"donate-goal\">${this.currentGoalMessage}</div>`\n : nothing}\n </div>\n `;\n }\n\n private get thermometerValueTemplate(): TemplateResult | typeof nothing {\n return this.currentAmountMode === 'off'\n ? nothing\n : html`\n <div class=\"thermometer-value\">${this.currentAmountDisplayValue}</div>\n `;\n }\n\n /**\n * Which side of the fill's end the value label sits on, as a class name for\n * the CSS that places it. The label sits over the fill when the fill is\n * wider than the label plus a little breathing room, and just past the\n * fill's right edge otherwise.\n */\n private get thermometerValuePosition(): 'value-left' | 'value-right' {\n const buffer = 10;\n return this.thermometerValueWidth + buffer < this.thermometerFillWidth\n ? 'value-left'\n : 'value-right';\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.resizeObserver = new ResizeObserver((entries) =>\n this.handleResize(entries),\n );\n // On a re-connect the fill already exists; on first connect it doesn't\n // until the first render, and `updated` picks it up then.\n this.observeParts();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n this.observedFillElement = null;\n this.observedValueElement = null;\n }\n\n updated(): void {\n this.observeParts();\n }\n\n /** Observes the fill and the value label, picking up either if it is replaced. */\n private observeParts(): void {\n const observer = this.resizeObserver;\n if (!observer) return;\n\n this.observedFillElement = this.observeInPlaceOf(\n observer,\n this.observedFillElement,\n this.thermometerFill ?? null,\n );\n this.observedValueElement = this.observeInPlaceOf(\n observer,\n this.observedValueElement,\n this.thermometerValue ?? null,\n );\n }\n\n /**\n * Swaps `observed` for `current` on the observer and returns whichever is\n * now being watched. A target that hasn't changed is left alone.\n */\n private observeInPlaceOf(\n observer: ResizeObserver,\n observed: Element | null,\n current: Element | null,\n ): Element | null {\n if (current === observed) return observed;\n if (observed) observer.unobserve(observed);\n if (current) observer.observe(current);\n return current;\n }\n\n private handleResize(entries: ResizeObserverEntry[]): void {\n for (const entry of entries) {\n const width =\n entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n if (entry.target === this.observedFillElement) {\n this.thermometerFillWidth = width;\n } else if (entry.target === this.observedValueElement) {\n this.thermometerValueWidth = width;\n }\n }\n }\n\n private get goalMessage(): string {\n return this.currentAmount >= this.goalAmount\n ? this.goalReachedMessage\n : this.goalNearMessage;\n }\n\n private get currentAmountDisplayValue(): string {\n return this.formatNumber(this.currentAmount);\n }\n\n private get goalAmountDisplayValue(): string {\n return this.formatNumber(this.goalAmount);\n }\n\n /**\n * Formats a dollar amount in millions, e.g. `$0.5MM` or `$35MM`. Amounts\n * under ten million keep one decimal place, larger ones round to a whole\n * number.\n */\n private formatNumber(number: number): string {\n if (!Number.isFinite(number) || number === 0) return '$0';\n const suffix = 'MM';\n const divisor = 1_000_000;\n const result = number / divisor;\n const roundToOne = result < 10;\n const rounded = roundToOne\n ? Math.round((result + Number.EPSILON) * 10) / 10\n : Math.round(result);\n return `$${rounded}${suffix}`;\n }\n\n private get currentGoalMessage(): string {\n switch (this.goalMessageMode) {\n case 'amount':\n return msg(str`${this.goalAmountDisplayValue} goal`);\n case 'message':\n return this.goalMessage;\n case 'off':\n return '';\n }\n }\n\n /**\n * The goal the bar measures against. A goal that isn't a positive, finite\n * number leaves the bar empty, since there is no range to report progress\n * against. Named clear of `ariaValueMax`, which `HTMLElement` declares as a\n * public string.\n */\n private get progressMax(): number {\n return Number.isFinite(this.goalAmount) && this.goalAmount > 0\n ? this.goalAmount\n : 0;\n }\n\n /**\n * The progress reported to screen readers, clamped into the\n * `aria-valuemin`/`aria-valuemax` range the spec requires.\n * `aria-valuetext` carries the amount as it is displayed.\n */\n private get progressValue(): number {\n if (!Number.isFinite(this.currentAmount)) return 0;\n return Math.min(Math.max(this.currentAmount, 0), this.progressMax);\n }\n\n /**\n * How much of the bar is filled, as a percentage, clamped to `0`-`100`. An\n * amount or goal that can't produce a usable percentage empties the bar.\n */\n private get percentComplete(): number {\n const goal = this.progressMax;\n if (goal === 0 || !Number.isFinite(this.currentAmount)) return 0;\n const percent = (this.currentAmount / goal) * 100;\n return Math.min(Math.max(percent, 0), 100);\n }\n\n static get styles(): CSSResultGroup {\n return [\n themeStyles,\n css`\n :host {\n --donation-thermometer-height--: var(\n --ia-donation-thermometer-height,\n 20px\n );\n --donation-thermometer-fill-color--: var(\n --ia-donation-thermometer-fill-color,\n #23765d\n );\n --donation-thermometer-track-color--: var(\n --ia-donation-thermometer-track-color,\n #b8f5e2\n );\n --donation-thermometer-border--: var(\n --ia-donation-thermometer-border,\n 1px solid var(--donation-thermometer-fill-color--)\n );\n /* Large enough to round any height into a pill */\n --donation-thermometer-border-radius--: var(\n --ia-donation-thermometer-border-radius,\n 9999px\n );\n --donation-thermometer-value-on-fill-color--: var(\n --ia-donation-thermometer-value-on-fill-color,\n var(--true-white)\n );\n --donation-thermometer-value-on-track-color--: var(\n --ia-donation-thermometer-value-on-track-color,\n var(--donation-thermometer-fill-color--)\n );\n --donation-thermometer-goal-color--: var(--primary-text-color);\n --donation-thermometer-goal-padding--: var(\n --ia-donation-thermometer-goal-padding,\n 0 10px\n );\n\n display: block;\n height: var(--donation-thermometer-height--);\n }\n\n .thermometer-message-container {\n height: 100%;\n display: flex;\n align-items: center;\n }\n\n .thermometer-container {\n height: 100%;\n flex: 1;\n }\n\n .thermometer-background {\n box-sizing: border-box;\n position: relative;\n background-color: var(--donation-thermometer-track-color--);\n height: 100%;\n border-radius: var(--donation-thermometer-border-radius--);\n border: var(--donation-thermometer-border--);\n }\n\n /*\n * Clips the square-ended fill to the rounded track. It covers only the\n * fill, so the label is never cut off by it.\n */\n .thermometer-clip {\n position: absolute;\n inset: 0;\n overflow: hidden;\n border-radius: var(--donation-thermometer-border-radius--);\n }\n\n .thermometer-fill {\n background-color: var(--donation-thermometer-fill-color--);\n height: 100%;\n /*\n * The fallback matters: without it a missing --fill-end-- makes the\n * declaration invalid, width resolves to auto, and the bar paints as\n * a fully funded fundraiser.\n */\n width: var(--fill-end--, 0%);\n }\n\n /*\n * The label is placed by offset from the end of the fill, so it is one\n * node in one position in the DOM whichever side it shows on, and it\n * never counts towards the width of the fill it is measured against.\n */\n .thermometer-value {\n position: absolute;\n top: 0;\n bottom: 0;\n left: var(--fill-end--, 0%);\n /*\n * Without this, the left offset caps the shrink-to-fit width of a\n * translated label and it collapses to its padding.\n */\n width: max-content;\n display: flex;\n align-items: center;\n font-weight: bold;\n white-space: nowrap;\n }\n\n /*\n * Both paddings total 1.5rem, so changing sides leaves the label the\n * same width and cannot feed back into the side it is placed on.\n */\n .value-left .thermometer-value {\n transform: translateX(-100%);\n color: var(--donation-thermometer-value-on-fill-color--);\n padding: 0 0.5rem 0 1rem;\n }\n\n .value-right .thermometer-value {\n color: var(--donation-thermometer-value-on-track-color--);\n padding: 0 1rem 0 0.5rem;\n }\n\n .donate-goal {\n text-align: left;\n padding: var(--donation-thermometer-goal-padding--);\n text-transform: uppercase;\n font-weight: bold;\n color: var(--donation-thermometer-goal-color--);\n }\n `,\n ];\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ia-donation-thermometer': IADonationThermometer;\n }\n}\n"]}
@@ -32,6 +32,8 @@ export declare class IARadioPlayer extends LitElement {
32
32
  searchTerm: string;
33
33
  /** Whether to skip past the music sections rather than play them */
34
34
  skipMusicSections: boolean;
35
+ /** Whether to shade the music sections on the waveform */
36
+ showMusicZones: boolean;
35
37
  private percentComplete;
36
38
  private isPlaying;
37
39
  private duration;
@@ -1 +1 @@
1
- {"version":3,"file":"ia-radio-player.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-radio-player/ia-radio-player.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEV,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAQb,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,yCAAyC,CAAC;AAKjD,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAGtE,OAAO,iDAAiD,CAAC;AACzD,OAAO,iEAAiE,CAAC;AACzE,OAAO,yDAAyD,CAAC;AACjE,OAAO,+CAA+C,CAAC;AACvD,OAAO,uDAAuD,CAAC;AAC/D,OAAO,qDAAqD,CAAC;AAC7D,OAAO,yDAAyD,CAAC;AACjE,OAAO,8BAA8B,CAAC;AAqCtC;;;;;;GAMG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,sDAAsD;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAEvD,mEAAmE;IACvC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAEnE,uDAAuD;IAC3B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEhE,0EAA0E;IAC9C,uBAAuB,CAAC,EAAE,gBAAgB,CAAC;IAEvE,oCAAoC;IACR,WAAW,SAAK;IAE5C,0CAA0C;IACd,UAAU,SAAM;IAE5C,oEAAoE;IACvC,iBAAiB,UAAS;IAE9C,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAK;IAErB,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,MAAM,CAAK;IAEnB,OAAO,CAAC,WAAW,CAAS;IAErC,2EAA2E;IAC3E,OAAO,CAAC,cAAc,CAAK;IAEA,OAAO,CAAC,YAAY,CAAC,CAAwB;IAE3C,OAAO,CAAC,cAAc,CAAC,CAA0B;IAG9E,OAAO,CAAC,qBAAqB,CAAC,CAAiC;IAE/D,MAAM,IAAI,cAAc;IAcxB,sBAAsB;IACtB,IAAI,IAAI,IAAI;IAIZ,sBAAsB;IACtB,KAAK,IAAI,IAAI;IAIb,mDAAmD;IACnD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,KAAK,oBAAoB,GAa/B;IAED,OAAO,KAAK,iBAAiB,GAO5B;IAED,OAAO,KAAK,sBAAsB,GAWjC;IAED,OAAO,KAAK,wBAAwB,GAiBnC;IAED,OAAO,KAAK,wBAAwB,GAanC;IAED,OAAO,KAAK,mBAAmB,GAQ9B;IAED,OAAO,KAAK,sBAAsB,GAUjC;IAED,OAAO,KAAK,qBAAqB,GA8BhC;IAED,6EAA6E;IAC7E,OAAO,KAAK,qBAAqB,GAoBhC;IAED,sEAAsE;IACtE,OAAO,KAAK,mBAAmB,GAS9B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,aAAa,GAIxB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,wEAAwE;IACxE,OAAO,KAAK,cAAc,GAOzB;IAED,8DAA8D;IAC9D,OAAO,KAAK,UAAU,GAKrB;IAED;;;;;OAKG;IACH,OAAO,KAAK,wBAAwB,GASnC;IAED,OAAO,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI;IAoBhD,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,uBAAuB;IAS/B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,6BAA6B;IAiBrC,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,mBAAmB;IAY3B;;;;;;;;;;;OAWG;YACW,aAAa;IA4B3B,OAAO,CAAC,8BAA8B;IAiBtC,0EAA0E;IAC1E,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,OAAO;IAIf,oEAAoE;IACpE,OAAO,CAAC,aAAa;IASrB,MAAM,KAAK,MAAM,IAAI,cAAc,CAyKlC;CACF"}
1
+ {"version":3,"file":"ia-radio-player.d.ts","sourceRoot":"","sources":["../../../../src/elements/ia-radio-player/ia-radio-player.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,8 @@ let IARadioPlayer = class IARadioPlayer extends LitElement {
59
59
  this.searchTerm = '';
60
60
  /** Whether to skip past the music sections rather than play them */
61
61
  this.skipMusicSections = false;
62
+ /** Whether to shade the music sections on the waveform */
63
+ this.showMusicZones = false;
62
64
  this.percentComplete = 0;
63
65
  this.isPlaying = false;
64
66
  this.duration = 0;
@@ -154,7 +156,7 @@ let IARadioPlayer = class IARadioPlayer extends LitElement {
154
156
  interactive
155
157
  .waveformUrl=${waveformUrl}
156
158
  .percentComplete=${this.percentComplete}
157
- .zonesOfSilence=${this.zonesOfSilence}
159
+ .zonesOfSilence=${this.showMusicZones ? this.zonesOfSilence : []}
158
160
  @valuechange=${this.handleScrub}
159
161
  ></ia-waveform-progress>
160
162
  `;
@@ -715,6 +717,9 @@ __decorate([
715
717
  __decorate([
716
718
  property({ type: Boolean })
717
719
  ], IARadioPlayer.prototype, "skipMusicSections", void 0);
720
+ __decorate([
721
+ property({ type: Boolean })
722
+ ], IARadioPlayer.prototype, "showMusicZones", void 0);
718
723
  __decorate([
719
724
  state()
720
725
  ], IARadioPlayer.prototype, "percentComplete", void 0);