@redvars/peacock 3.3.3 → 3.5.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 (280) hide show
  1. package/dist/IndividualComponent-DUINtMGK.js +67 -0
  2. package/dist/IndividualComponent-DUINtMGK.js.map +1 -0
  3. package/dist/assets/images/empty-state/no-document.svg +11 -12
  4. package/dist/assets/images/empty-state/page.svg +15 -9
  5. package/dist/assets/styles.css +1 -1
  6. package/dist/assets/styles.css.map +1 -1
  7. package/dist/banner.js +202 -0
  8. package/dist/banner.js.map +1 -0
  9. package/dist/bottom-sheet.js +238 -0
  10. package/dist/bottom-sheet.js.map +1 -0
  11. package/dist/{button-ClzS8JLq.js → button-DMN1dPAg.js} +358 -218
  12. package/dist/button-DMN1dPAg.js.map +1 -0
  13. package/dist/button-group-CX9CUUXk.js +435 -0
  14. package/dist/button-group-CX9CUUXk.js.map +1 -0
  15. package/dist/button-group.js +11 -6
  16. package/dist/button-group.js.map +1 -1
  17. package/dist/button.js +10 -5
  18. package/dist/button.js.map +1 -1
  19. package/dist/card-content.js +29 -0
  20. package/dist/card-content.js.map +1 -0
  21. package/dist/card.js +428 -44
  22. package/dist/card.js.map +1 -1
  23. package/dist/{chart-bar-DbnXQgvS.js → chart-bar-cn6rrna-.js} +2 -2
  24. package/dist/{chart-bar-DbnXQgvS.js.map → chart-bar-cn6rrna-.js.map} +1 -1
  25. package/dist/chart-bar.js +5 -4
  26. package/dist/chart-bar.js.map +1 -1
  27. package/dist/chart-doughnut.js +2 -1
  28. package/dist/chart-doughnut.js.map +1 -1
  29. package/dist/chart-pie.js +2 -1
  30. package/dist/chart-pie.js.map +1 -1
  31. package/dist/chart-stacked-bar.js +5 -4
  32. package/dist/chart-stacked-bar.js.map +1 -1
  33. package/dist/{class-map-59YGWLnx.js → class-map-YU7g0o3B.js} +4 -10
  34. package/dist/class-map-YU7g0o3B.js.map +1 -0
  35. package/dist/clock.js +2 -1
  36. package/dist/clock.js.map +1 -1
  37. package/dist/code-editor.js +8 -6
  38. package/dist/code-editor.js.map +1 -1
  39. package/dist/code-highlighter.js +6 -4
  40. package/dist/code-highlighter.js.map +1 -1
  41. package/dist/custom-elements-jsdocs.json +6270 -5026
  42. package/dist/custom-elements.json +5763 -2049
  43. package/dist/directive-ZPhl09Yt.js +9 -0
  44. package/dist/directive-ZPhl09Yt.js.map +1 -0
  45. package/dist/dispatch-event-utils-CuEqjlPT.js +127 -0
  46. package/dist/dispatch-event-utils-CuEqjlPT.js.map +1 -0
  47. package/dist/fab-C5Nzxk0E.js +497 -0
  48. package/dist/fab-C5Nzxk0E.js.map +1 -0
  49. package/dist/fab.js +11 -0
  50. package/dist/fab.js.map +1 -0
  51. package/dist/index.js +24 -12
  52. package/dist/index.js.map +1 -1
  53. package/dist/{observe-theme-change-pALI5fmV.js → is-dark-mode-DicqGkCJ.js} +8 -3
  54. package/dist/is-dark-mode-DicqGkCJ.js.map +1 -0
  55. package/dist/notification.js +417 -0
  56. package/dist/notification.js.map +1 -0
  57. package/dist/number-counter.js +4 -3
  58. package/dist/number-counter.js.map +1 -1
  59. package/dist/observe-slot-change-BGJfgg2E.js +31 -0
  60. package/dist/observe-slot-change-BGJfgg2E.js.map +1 -0
  61. package/dist/peacock-loader.js +59 -10
  62. package/dist/peacock-loader.js.map +1 -1
  63. package/dist/property-1psGvXOq.js +10 -0
  64. package/dist/property-1psGvXOq.js.map +1 -0
  65. package/dist/search.js +452 -0
  66. package/dist/search.js.map +1 -0
  67. package/dist/{radio-b70_Ie9n.js → select-4pl4XBj7.js} +2439 -521
  68. package/dist/select-4pl4XBj7.js.map +1 -0
  69. package/dist/side-sheet.js +186 -0
  70. package/dist/side-sheet.js.map +1 -0
  71. package/dist/spread-B5cgadZl.js +32 -0
  72. package/dist/spread-B5cgadZl.js.map +1 -0
  73. package/dist/src/__base_element/BaseHyperlink.d.ts +20 -0
  74. package/dist/src/__utils/cache-fetch.d.ts +1 -0
  75. package/dist/src/__utils/is-dark-mode.d.ts +1 -0
  76. package/dist/src/__utils/is-in-viewport.d.ts +1 -0
  77. package/dist/src/__utils/observe-slot-change.d.ts +1 -0
  78. package/dist/src/__utils/sanitize-svg.d.ts +1 -0
  79. package/dist/src/__utils/throttle.d.ts +4 -0
  80. package/dist/src/accordion/accordion-item.d.ts +33 -9
  81. package/dist/src/accordion/accordion.d.ts +21 -5
  82. package/dist/src/banner/banner.d.ts +47 -0
  83. package/dist/src/banner/index.d.ts +1 -0
  84. package/dist/src/bottom-sheet/bottom-sheet.d.ts +42 -0
  85. package/dist/src/bottom-sheet/index.d.ts +1 -0
  86. package/dist/src/button/BaseButton.d.ts +7 -13
  87. package/dist/src/button/button/button.d.ts +4 -0
  88. package/dist/src/button/button-group/button-group.d.ts +32 -3
  89. package/dist/src/button/icon-button/icon-button.d.ts +4 -0
  90. package/dist/src/card/card-content.d.ts +15 -0
  91. package/dist/src/card/card.d.ts +37 -3
  92. package/dist/src/card/index.d.ts +1 -0
  93. package/dist/src/container/container.d.ts +1 -1
  94. package/dist/src/empty-state/empty-state.d.ts +1 -1
  95. package/dist/src/fab/fab.d.ts +111 -0
  96. package/dist/src/fab/index.d.ts +1 -0
  97. package/dist/src/focus-ring/focus-ring.d.ts +4 -1
  98. package/dist/src/index.d.ts +11 -1
  99. package/dist/src/link/link.d.ts +3 -10
  100. package/dist/src/menu/menu/menu.d.ts +4 -2
  101. package/dist/src/menu/menu-item/menu-item.d.ts +0 -1
  102. package/dist/src/menu/sub-menu/sub-menu.d.ts +1 -0
  103. package/dist/src/notification/index.d.ts +1 -0
  104. package/dist/src/notification/notification.d.ts +69 -0
  105. package/dist/src/pagination/pagination.d.ts +8 -1
  106. package/dist/src/ripple/ripple.d.ts +19 -3
  107. package/dist/src/search/index.d.ts +1 -0
  108. package/dist/src/search/search.d.ts +76 -0
  109. package/dist/src/segmented-button/index.d.ts +2 -0
  110. package/dist/src/segmented-button/segmented-button-group.d.ts +46 -0
  111. package/dist/src/segmented-button/segmented-button.d.ts +65 -0
  112. package/dist/src/select/index.d.ts +3 -0
  113. package/dist/src/select/option.d.ts +55 -0
  114. package/dist/src/select/select.d.ts +114 -0
  115. package/dist/src/side-sheet/index.d.ts +1 -0
  116. package/dist/src/side-sheet/side-sheet.d.ts +41 -0
  117. package/dist/src/slider/slider.d.ts +4 -0
  118. package/dist/src/snackbar/snackbar.d.ts +14 -1
  119. package/dist/src/tabs/tab-group.d.ts +0 -1
  120. package/dist/src/tabs/tab.d.ts +8 -2
  121. package/dist/src/tabs/tabs.d.ts +13 -1
  122. package/dist/src/toolbar/index.d.ts +1 -0
  123. package/dist/src/toolbar/toolbar.d.ts +86 -0
  124. package/dist/state-DwbEjqVk.js +10 -0
  125. package/dist/state-DwbEjqVk.js.map +1 -0
  126. package/dist/{style-map-DcB52w-l.js → style-map-DVmWOuYy.js} +3 -3
  127. package/dist/{style-map-DcB52w-l.js.map → style-map-DVmWOuYy.js.map} +1 -1
  128. package/dist/test/search.test.d.ts +1 -0
  129. package/dist/test/toolbar.test.d.ts +1 -0
  130. package/dist/throttle-C7ZAPqtu.js +24 -0
  131. package/dist/throttle-C7ZAPqtu.js.map +1 -0
  132. package/dist/toolbar.js +306 -0
  133. package/dist/toolbar.js.map +1 -0
  134. package/dist/tsconfig.tsbuildinfo +1 -1
  135. package/dist/{unsafe-html-C2r3PyzF.js → unsafe-html-BsGUjx94.js} +3 -3
  136. package/dist/{unsafe-html-C2r3PyzF.js.map → unsafe-html-BsGUjx94.js.map} +1 -1
  137. package/package.json +1 -1
  138. package/readme.md +2 -2
  139. package/scss/styles.scss +4 -0
  140. package/src/__base_element/BaseHyperlink.ts +42 -0
  141. package/src/__base_element/README.md +19 -0
  142. package/src/__utils/cache-fetch.ts +65 -0
  143. package/src/{utils → __utils}/dispatch-event-utils.ts +1 -0
  144. package/src/__utils/is-dark-mode.ts +3 -0
  145. package/src/__utils/is-in-viewport.ts +6 -0
  146. package/src/__utils/observe-slot-change.ts +38 -0
  147. package/src/__utils/sanitize-svg.ts +27 -0
  148. package/src/__utils/throttle.ts +27 -0
  149. package/src/accordion/accordion-item.scss +136 -65
  150. package/src/accordion/accordion-item.ts +117 -44
  151. package/src/accordion/accordion.scss +24 -5
  152. package/src/accordion/accordion.ts +29 -23
  153. package/src/accordion/demo/index.html +74 -35
  154. package/src/banner/banner.scss +87 -0
  155. package/src/banner/banner.ts +107 -0
  156. package/src/banner/index.ts +1 -0
  157. package/src/bottom-sheet/bottom-sheet.scss +88 -0
  158. package/src/bottom-sheet/bottom-sheet.ts +135 -0
  159. package/src/bottom-sheet/index.ts +1 -0
  160. package/src/button/BaseButton.ts +26 -30
  161. package/src/button/button/button-colors.scss +90 -19
  162. package/src/button/button/button-sizes.scss +39 -19
  163. package/src/button/button/button.scss +117 -116
  164. package/src/button/button/button.ts +29 -6
  165. package/src/button/button-group/button-group.scss +25 -22
  166. package/src/button/button-group/button-group.ts +122 -5
  167. package/src/button/icon-button/icon-button-sizes.scss +35 -15
  168. package/src/button/icon-button/icon-button.ts +25 -12
  169. package/src/card/card-colors.scss +10 -0
  170. package/src/card/card-content.ts +26 -0
  171. package/src/card/card.scss +221 -41
  172. package/src/card/card.ts +251 -8
  173. package/src/card/index.ts +1 -0
  174. package/src/chart-bar/chart-bar.ts +1 -1
  175. package/src/chart-bar/chart-stacked-bar.ts +3 -1
  176. package/src/chart-doughnut/chart-doughnut.ts +1 -1
  177. package/src/chart-pie/chart-pie.ts +1 -1
  178. package/src/checkbox/checkbox.ts +1 -1
  179. package/src/clock/clock.ts +1 -1
  180. package/src/code-editor/code-editor.ts +5 -5
  181. package/src/code-highlighter/code-highlighter.ts +2 -2
  182. package/src/container/container.ts +1 -1
  183. package/src/date-picker/date-picker.ts +5 -2
  184. package/src/divider/divider.ts +3 -1
  185. package/src/empty-state/empty-state.scss +9 -3
  186. package/src/empty-state/empty-state.ts +2 -2
  187. package/src/fab/fab-colors.scss +49 -0
  188. package/src/fab/fab-sizes.scss +47 -0
  189. package/src/fab/fab.scss +137 -0
  190. package/src/fab/fab.ts +285 -0
  191. package/src/fab/index.ts +1 -0
  192. package/src/field/field.ts +3 -1
  193. package/src/focus-ring/focus-ring.ts +37 -19
  194. package/src/icon/datasource.ts +1 -1
  195. package/src/icon/icon.ts +3 -1
  196. package/src/image/image.ts +3 -2
  197. package/src/index.ts +12 -1
  198. package/src/input/input.ts +5 -2
  199. package/src/link/link.ts +2 -15
  200. package/src/menu/menu/menu.scss +31 -3
  201. package/src/menu/menu/menu.ts +30 -6
  202. package/src/menu/menu-item/menu-item.scss +1 -0
  203. package/src/menu/menu-item/menu-item.ts +1 -9
  204. package/src/menu/sub-menu/sub-menu.ts +1 -0
  205. package/src/notification/index.ts +1 -0
  206. package/src/notification/notification.scss +201 -0
  207. package/src/notification/notification.ts +206 -0
  208. package/src/number-counter/number-counter.ts +3 -1
  209. package/src/number-field/number-field.ts +4 -2
  210. package/src/pagination/pagination.scss +33 -24
  211. package/src/pagination/pagination.ts +113 -60
  212. package/src/peacock-loader.ts +48 -0
  213. package/src/radio/radio.ts +3 -1
  214. package/src/ripple/ripple.ts +19 -3
  215. package/src/search/index.ts +1 -0
  216. package/src/search/search-colors.scss +14 -0
  217. package/src/search/search.scss +204 -0
  218. package/src/search/search.ts +240 -0
  219. package/src/segmented-button/index.ts +2 -0
  220. package/src/segmented-button/segmented-button-group.scss +21 -0
  221. package/src/segmented-button/segmented-button-group.ts +110 -0
  222. package/src/segmented-button/segmented-button.scss +115 -0
  223. package/src/segmented-button/segmented-button.ts +175 -0
  224. package/src/select/index.ts +3 -0
  225. package/src/select/option.ts +109 -0
  226. package/src/select/select.scss +125 -0
  227. package/src/select/select.ts +520 -0
  228. package/src/side-sheet/index.ts +1 -0
  229. package/src/side-sheet/side-sheet.scss +79 -0
  230. package/src/side-sheet/side-sheet.ts +100 -0
  231. package/src/slider/slider.scss +19 -1
  232. package/src/slider/slider.ts +30 -19
  233. package/src/snackbar/snackbar.scss +62 -31
  234. package/src/snackbar/snackbar.ts +92 -12
  235. package/src/switch/switch.ts +3 -1
  236. package/src/table/table.ts +3 -1
  237. package/src/tabs/demo/index.html +90 -0
  238. package/src/tabs/tab-group.ts +0 -3
  239. package/src/tabs/tab.scss +237 -25
  240. package/src/tabs/tab.ts +91 -14
  241. package/src/tabs/tabs.scss +37 -3
  242. package/src/tabs/tabs.ts +118 -2
  243. package/src/textarea/textarea.ts +4 -2
  244. package/src/time-picker/time-picker.ts +4 -2
  245. package/src/toolbar/index.ts +1 -0
  246. package/src/toolbar/toolbar-colors.scss +16 -0
  247. package/src/toolbar/toolbar.scss +165 -0
  248. package/src/toolbar/toolbar.ts +137 -0
  249. package/dist/IndividualComponent-Dt5xirYG.js +0 -73
  250. package/dist/IndividualComponent-Dt5xirYG.js.map +0 -1
  251. package/dist/button-ClzS8JLq.js.map +0 -1
  252. package/dist/button-group-BMS5WvaF.js +0 -292
  253. package/dist/button-group-BMS5WvaF.js.map +0 -1
  254. package/dist/chart-donut.js +0 -309
  255. package/dist/chart-donut.js.map +0 -1
  256. package/dist/class-map-59YGWLnx.js.map +0 -1
  257. package/dist/directive-Cuw6h7YA.js +0 -9
  258. package/dist/directive-Cuw6h7YA.js.map +0 -1
  259. package/dist/dispatch-event-utils-B4odODQf.js +0 -277
  260. package/dist/dispatch-event-utils-B4odODQf.js.map +0 -1
  261. package/dist/observe-theme-change-pALI5fmV.js.map +0 -1
  262. package/dist/radio-b70_Ie9n.js.map +0 -1
  263. package/dist/src/chart-donut/chart-donut.d.ts +0 -53
  264. package/dist/src/chart-donut/index.d.ts +0 -1
  265. package/dist/src/styleMixins.css.d.ts +0 -9
  266. package/dist/src/utils.d.ts +0 -9
  267. package/src/chart-donut/chart-donut.scss +0 -37
  268. package/src/chart-donut/chart-donut.ts +0 -287
  269. package/src/chart-donut/demo/index.html +0 -51
  270. package/src/chart-donut/index.ts +0 -1
  271. package/src/styleMixins.css.ts +0 -55
  272. package/src/utils.ts +0 -193
  273. /package/dist/src/{spread.d.ts → __directive/spread.d.ts} +0 -0
  274. /package/dist/src/{utils → __utils}/copy-to-clipboard.d.ts +0 -0
  275. /package/dist/src/{utils → __utils}/dispatch-event-utils.d.ts +0 -0
  276. /package/dist/src/{utils → __utils}/observe-theme-change.d.ts +0 -0
  277. /package/dist/test/{card.test.d.ts → banner.test.d.ts} +0 -0
  278. /package/src/{spread.ts → __directive/spread.ts} +0 -0
  279. /package/src/{utils → __utils}/copy-to-clipboard.ts +0 -0
  280. /package/src/{utils → __utils}/observe-theme-change.ts +0 -0
@@ -4,23 +4,44 @@
4
4
 
5
5
  .menu {
6
6
  display: flex;
7
- position: relative;
7
+ position: fixed;
8
8
  z-index: var(--menu-z-index, 1000);
9
+ width: var(--menu-width, max-content);
10
+ max-width: 100vw;
9
11
  min-width: 112px;
10
12
  padding-block: var(--spacing-050);
13
+ transform-origin: top center;
14
+
15
+ --_menu-enter-duration: var(--duration-medium1, 250ms);
16
+ --_menu-exit-duration: var(--duration-short4, 200ms);
17
+ --_menu-enter-easing: cubic-bezier(0.05, 0.7, 0.1, 1);
18
+ --_menu-exit-easing: cubic-bezier(0.3, 0, 0.8, 0.15);
19
+
20
+ transition-property: opacity, transform, visibility;
21
+ transition-duration: var(--_menu-exit-duration), var(--_menu-exit-duration), 0ms;
22
+ transition-delay: 0ms, 0ms, var(--_menu-exit-duration);
23
+ transition-timing-function: var(--_menu-exit-easing), var(--_menu-exit-easing), linear;
11
24
 
12
25
  &.closed {
13
- display: none;
14
26
  opacity: 0;
15
27
  visibility: hidden;
16
28
  pointer-events: none;
29
+ transform: translateY(-4px) scale(0.97);
17
30
  }
18
31
 
19
32
  &.open {
20
- display: flex;
21
33
  opacity: 1;
22
34
  visibility: visible;
23
35
  pointer-events: auto;
36
+ transform: translateY(0) scale(1);
37
+ transition-duration: var(--_menu-enter-duration), var(--_menu-enter-duration), 0ms;
38
+ transition-delay: 0ms, 0ms, 0ms;
39
+ transition-timing-function: var(--_menu-enter-easing), var(--_menu-enter-easing), linear;
40
+ }
41
+
42
+ &.preview {
43
+ position: relative;
44
+ pointer-events: auto;
24
45
  }
25
46
 
26
47
  .menu-content {
@@ -73,6 +94,13 @@
73
94
  }
74
95
  }
75
96
 
97
+ @media (prefers-reduced-motion: reduce) {
98
+ .menu {
99
+ transition: none;
100
+ transform: none;
101
+ }
102
+ }
103
+
76
104
  .menu {
77
105
  --_container-shape-start-start: var(--shape-corner-large);
78
106
  --_container-shape-start-end: var(--shape-corner-large);
@@ -22,9 +22,9 @@ type CloseReason =
22
22
  *
23
23
  * @example
24
24
  * ```html
25
- * <wc-menu>
25
+ * <wc-menu preview>
26
26
  * <wc-menu-item>Item 1</wc-menu-item>
27
- * <wc-menu-item>Item 2</wc-menu-item>
27
+ * <wc-menu-item selected>Item 2</wc-menu-item>
28
28
  * </wc-menu>
29
29
  * ```
30
30
  */
@@ -40,6 +40,8 @@ export class Menu extends LitElement {
40
40
 
41
41
  @property({ type: String }) anchor = '';
42
42
 
43
+ @property({ type: Boolean, reflect: true }) preview = false;
44
+
43
45
  @property({ type: Boolean, attribute: 'stay-open-on-outside-click' })
44
46
  stayOpenOnOutsideClick = false;
45
47
 
@@ -181,7 +183,6 @@ export class Menu extends LitElement {
181
183
  for (let index = 0; index < enabledItems.length; index += 1) {
182
184
  const currentItem = enabledItems[index];
183
185
  currentItem.tabIndex = index === this.activeIndex ? 0 : -1;
184
- currentItem.selected = index === this.activeIndex;
185
186
  }
186
187
  }
187
188
 
@@ -226,10 +227,23 @@ export class Menu extends LitElement {
226
227
  return this._enabledItems()[0] ?? null;
227
228
  }
228
229
 
230
+ private _ownsKeyboardEvent(event: KeyboardEvent) {
231
+ const path = event.composedPath();
232
+ const ownedItems = this.items;
233
+
234
+ return path.some(target => target instanceof MenuItem && ownedItems.includes(target));
235
+ }
236
+
229
237
  private _onItemActivate = (event: Event) => {
230
238
  const customEvent = event as CustomEvent<{ item: MenuItem }>;
239
+ const { item } = customEvent.detail;
240
+ const ownedItems = this.items;
241
+ if (!ownedItems.includes(item)) {
242
+ return;
243
+ }
244
+
231
245
  const enabledItems = this._enabledItems();
232
- const nextIndex = enabledItems.indexOf(customEvent.detail.item);
246
+ const nextIndex = enabledItems.indexOf(item);
233
247
  if (nextIndex >= 0) {
234
248
  this.activeIndex = nextIndex;
235
249
  this._syncRovingTabIndex();
@@ -238,10 +252,15 @@ export class Menu extends LitElement {
238
252
 
239
253
  private _onItemRequestClose = (event: Event) => {
240
254
  const customEvent = event as CustomEvent<{
255
+ item: MenuItem;
241
256
  reason: 'click-selection' | 'keydown';
242
257
  key?: string;
243
258
  }>;
244
259
 
260
+ if (!this.items.includes(customEvent.detail.item)) {
261
+ return;
262
+ }
263
+
245
264
  if (customEvent.defaultPrevented) {
246
265
  return;
247
266
  }
@@ -259,6 +278,10 @@ export class Menu extends LitElement {
259
278
  return;
260
279
  }
261
280
 
281
+ if (!this._ownsKeyboardEvent(event)) {
282
+ return;
283
+ }
284
+
262
285
  switch (event.key) {
263
286
  case 'ArrowDown':
264
287
  event.preventDefault();
@@ -427,8 +450,9 @@ export class Menu extends LitElement {
427
450
  return html`<div
428
451
  class=${classMap({
429
452
  'menu': true,
430
- open: this.open,
431
- closed: !this.open,
453
+ open: !this.preview && this.open,
454
+ closed: !this.preview && !this.open,
455
+ preview: this.preview,
432
456
  [`variant-${this.variant}`]: true,
433
457
  })}
434
458
  aria-hidden=${String(!this.open)}
@@ -4,6 +4,7 @@
4
4
 
5
5
  :host {
6
6
  padding-inline: var(--spacing-050);
7
+ outline: none;
7
8
  }
8
9
 
9
10
  .menu-item {
@@ -138,10 +138,6 @@ export class MenuItem extends LitElement {
138
138
  return !!this.href;
139
139
  }
140
140
 
141
- get focusTarget() {
142
- return this;
143
- }
144
-
145
141
  render() {
146
142
  const isLink = this.__isLink();
147
143
 
@@ -180,11 +176,7 @@ export class MenuItem extends LitElement {
180
176
 
181
177
  renderContent() {
182
178
  return html`
183
- <wc-focus-ring
184
- class="focus-ring"
185
- .control=${this}
186
- element="focusTarget"
187
- ></wc-focus-ring>
179
+ <wc-focus-ring class="focus-ring" .control=${this} .forElement=${this}></wc-focus-ring>
188
180
  <div class="background"></div>
189
181
  <wc-ripple class="ripple"></wc-ripple>
190
182
 
@@ -10,6 +10,7 @@ let subMenuIdCounter = 0;
10
10
  * @label Sub Menu
11
11
  * @tag wc-sub-menu
12
12
  * @rawTag sub-menu
13
+ * @parentRawTag menu
13
14
  * @summary Connects a menu item to a nested menu.
14
15
  */
15
16
  export class SubMenu extends LitElement {
@@ -0,0 +1 @@
1
+ export { Notification } from './notification.js';
@@ -0,0 +1,201 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ --notification-container-color: var(--color-primary-container);
7
+ --notification-text-color: var(--color-on-primary-container);
8
+ --notification-leading-icon-color: var(--color-on-primary-container);
9
+ --notification-accent-color: var(--color-primary);
10
+ --notification-border-radius: var(--shape-corner-medium);
11
+
12
+ display: block;
13
+ }
14
+
15
+ :host(:not([inline])) {
16
+ width: min(100%, 28rem);
17
+ }
18
+
19
+ .notification {
20
+ align-items: flex-start;
21
+ background: var(--notification-container-color);
22
+ border-inline-start: 4px solid var(--notification-accent-color);
23
+ border-radius: var(--notification-border-radius);
24
+ color: var(--notification-text-color);
25
+ display: grid;
26
+ gap: var(--spacing-100);
27
+ grid-template-columns: auto 1fr auto;
28
+ padding: var(--spacing-150) var(--spacing-100) var(--spacing-150) var(--spacing-150);
29
+ }
30
+
31
+ .state-icon {
32
+ align-items: center;
33
+ color: var(--notification-leading-icon-color);
34
+ display: inline-flex;
35
+ justify-content: center;
36
+ min-height: 2rem;
37
+
38
+ --icon-size: 1.25rem;
39
+ --icon-color: var(--notification-leading-icon-color);
40
+ }
41
+
42
+ .content {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: var(--spacing-100);
46
+ min-width: 0;
47
+ }
48
+
49
+ .content-text {
50
+ display: flex;
51
+ flex-direction: column;
52
+ gap: var(--spacing-025);
53
+ min-width: 0;
54
+ }
55
+
56
+ .title {
57
+ @include mixin.get-typography(label-large);
58
+ color: var(--notification-text-color);
59
+ overflow-wrap: anywhere;
60
+ }
61
+
62
+ .subtitle {
63
+ @include mixin.get-typography(body-medium);
64
+ color: var(--notification-text-color);
65
+ opacity: 0.88;
66
+ overflow-wrap: anywhere;
67
+ }
68
+
69
+ .title ::slotted(*),
70
+ .subtitle ::slotted(*) {
71
+ margin: 0;
72
+ }
73
+
74
+ .actions {
75
+ display: inline-flex;
76
+ gap: var(--spacing-100);
77
+ }
78
+
79
+ .action {
80
+ --outlined-button-label-text-color: var(--notification-text-color);
81
+ --outlined-button-outline-color: color-mix(in srgb, var(--notification-text-color) 40%, transparent);
82
+ --text-button-label-text-color: var(--notification-text-color);
83
+ }
84
+
85
+ .close-button-container {
86
+ display: inline-flex;
87
+ }
88
+
89
+ .close-button {
90
+ --text-button-label-text-color: var(--notification-text-color);
91
+ }
92
+
93
+ .notification.inline {
94
+ align-items: center;
95
+ }
96
+
97
+ .notification.inline .content {
98
+ align-items: center;
99
+ display: flex;
100
+ flex-direction: row;
101
+ gap: var(--spacing-150);
102
+ }
103
+
104
+ .notification.inline .content-text {
105
+ display: inline;
106
+ flex: 1;
107
+ }
108
+
109
+ .notification.inline .title,
110
+ .notification.inline .subtitle,
111
+ .notification.inline .title ::slotted(*),
112
+ .notification.inline .subtitle ::slotted(*) {
113
+ display: inline;
114
+ }
115
+
116
+ .notification:not(.has-subtitle) {
117
+ align-items: center;
118
+ }
119
+
120
+ .notification:not(.has-subtitle) .content {
121
+ gap: 0;
122
+ }
123
+
124
+ .notification.variant-info {
125
+ --notification-container-color: var(--color-primary-container);
126
+ --notification-text-color: var(--color-on-primary-container);
127
+ --notification-leading-icon-color: var(--color-on-primary-container);
128
+ --notification-accent-color: var(--color-primary);
129
+ }
130
+
131
+ .notification.variant-success {
132
+ --notification-container-color: var(--color-success-container);
133
+ --notification-text-color: var(--color-on-success-container);
134
+ --notification-leading-icon-color: var(--color-on-success-container);
135
+ --notification-accent-color: var(--color-success);
136
+ }
137
+
138
+ .notification.variant-warning {
139
+ --notification-container-color: var(--color-warning-container);
140
+ --notification-text-color: var(--color-on-warning-container);
141
+ --notification-leading-icon-color: var(--color-on-warning-container);
142
+ --notification-accent-color: var(--color-warning);
143
+ }
144
+
145
+ .notification.variant-error {
146
+ --notification-container-color: var(--color-error-container);
147
+ --notification-text-color: var(--color-on-error-container);
148
+ --notification-leading-icon-color: var(--color-on-error-container);
149
+ --notification-accent-color: var(--color-error);
150
+ }
151
+
152
+ .notification.high-contrast {
153
+ --notification-container-color: var(--color-inverse-surface);
154
+ --notification-text-color: var(--color-inverse-on-surface);
155
+ --notification-leading-icon-color: var(--color-inverse-on-surface);
156
+ }
157
+
158
+ .notification.high-contrast.variant-info {
159
+ --notification-accent-color: var(--color-primary);
160
+ }
161
+
162
+ .notification.high-contrast.variant-success {
163
+ --notification-accent-color: var(--color-success);
164
+ }
165
+
166
+ .notification.high-contrast.variant-warning {
167
+ --notification-accent-color: var(--color-warning);
168
+ }
169
+
170
+ .notification.high-contrast.variant-error {
171
+ --notification-accent-color: var(--color-error);
172
+ }
173
+
174
+ @media (max-width: 640px) {
175
+ :host(:not([inline])) {
176
+ width: 100%;
177
+ }
178
+
179
+ .notification.inline {
180
+ align-items: flex-start;
181
+ }
182
+
183
+ .notification.inline .content {
184
+ align-items: flex-start;
185
+ flex-direction: column;
186
+ gap: var(--spacing-100);
187
+ }
188
+
189
+ .notification.inline .content-text {
190
+ display: flex;
191
+ flex-direction: column;
192
+ gap: var(--spacing-025);
193
+ }
194
+
195
+ .notification.inline .title,
196
+ .notification.inline .subtitle,
197
+ .notification.inline .title ::slotted(*),
198
+ .notification.inline .subtitle ::slotted(*) {
199
+ display: initial;
200
+ }
201
+ }
@@ -0,0 +1,206 @@
1
+ import { LitElement, html, nothing } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+
5
+ import IndividualComponent from '@/IndividualComponent.js';
6
+ import styles from './notification.scss';
7
+
8
+ type NotificationVariant = 'success' | 'error' | 'info' | 'warning';
9
+
10
+ const VARIANT_LABELS: Record<NotificationVariant, string> = {
11
+ success: 'Success',
12
+ error: 'Error',
13
+ info: 'Information',
14
+ warning: 'Warning',
15
+ };
16
+
17
+ const VARIANT_ICONS: Record<NotificationVariant, string> = {
18
+ success: 'check_circle',
19
+ error: 'error',
20
+ info: 'info',
21
+ warning: 'warning',
22
+ };
23
+
24
+ /**
25
+ * @label Notification
26
+ * @tag wc-notification
27
+ * @rawTag notification
28
+ * @summary Notifications communicate contextual status, errors, warnings, and success messages.
29
+ *
30
+ * @cssprop --notification-container-color - Surface color for the notification container.
31
+ * @cssprop --notification-text-color - Label and supporting text color.
32
+ * @cssprop --notification-leading-icon-color - Leading state icon color.
33
+ * @cssprop --notification-accent-color - Start border color for status emphasis.
34
+ * @cssprop --notification-border-radius - Border radius of the notification container.
35
+ *
36
+ * @fires {CustomEvent} notification-dismiss - Fired when the notification is dismissed.
37
+ * @fires {CustomEvent} notification-action-click - Fired when the action button is clicked.
38
+ *
39
+ * @example
40
+ * ```html
41
+ * <wc-notification variant="success" action="Undo" dismissible>
42
+ * <span slot="title">Record saved</span>
43
+ * </wc-notification>
44
+ * ```
45
+ * @tags display, feedback
46
+ */
47
+ @IndividualComponent
48
+ export class Notification extends LitElement {
49
+ static styles = [styles];
50
+
51
+ /**
52
+ * If true, content and actions are laid out in a single row.
53
+ */
54
+ @property({ type: Boolean, reflect: true }) inline = false;
55
+
56
+ /**
57
+ * The visual variant of the notification.
58
+ */
59
+ @property({ type: String, reflect: true })
60
+ variant: NotificationVariant = 'info';
61
+
62
+ /**
63
+ * Enables a high contrast appearance.
64
+ */
65
+ @property({ type: Boolean, reflect: true, attribute: 'high-contrast' })
66
+ highContrast = false;
67
+
68
+ /**
69
+ * If true, renders a dismiss icon button.
70
+ */
71
+ @property({ type: Boolean, reflect: true }) dismissible = false;
72
+
73
+ /**
74
+ * Action label text. When provided, an action button is shown.
75
+ */
76
+ @property({ type: String }) action = '';
77
+
78
+ /**
79
+ * If true, the host controls visibility when dismissed.
80
+ */
81
+ @property({ type: Boolean, reflect: true }) managed = false;
82
+
83
+ @state() private isHidden = false;
84
+
85
+ @state() private hasSubtitle = false;
86
+
87
+ /**
88
+ * Programmatically reveals the notification.
89
+ */
90
+ show() {
91
+ this.isHidden = false;
92
+ }
93
+
94
+ /**
95
+ * Programmatically dismisses the notification.
96
+ */
97
+ dismiss() {
98
+ this.hideAndEmitDismiss('programmatic');
99
+ }
100
+
101
+ private get variantIcon() {
102
+ return VARIANT_ICONS[this.variant];
103
+ }
104
+
105
+ private get variantLabel() {
106
+ return VARIANT_LABELS[this.variant];
107
+ }
108
+
109
+ private emitActionClick() {
110
+ this.dispatchEvent(
111
+ new CustomEvent('notification-action-click', {
112
+ bubbles: true,
113
+ composed: true,
114
+ }),
115
+ );
116
+ }
117
+
118
+ private hideAndEmitDismiss(reason: 'dismiss' | 'programmatic') {
119
+ if (!this.managed) {
120
+ this.isHidden = true;
121
+ }
122
+
123
+ this.dispatchEvent(
124
+ new CustomEvent('notification-dismiss', {
125
+ detail: { reason },
126
+ bubbles: true,
127
+ composed: true,
128
+ }),
129
+ );
130
+ }
131
+
132
+ private handleSubtitleSlotChange(event: Event) {
133
+ const slot = event.target as HTMLSlotElement;
134
+ this.hasSubtitle = slot
135
+ .assignedNodes({ flatten: true })
136
+ .some(node => node.textContent?.trim());
137
+ }
138
+
139
+ render() {
140
+ if (this.isHidden) {
141
+ return nothing;
142
+ }
143
+
144
+ return html`
145
+ <div
146
+ class=${classMap({
147
+ notification: true,
148
+ inline: this.inline,
149
+ 'high-contrast': this.highContrast,
150
+ 'has-subtitle': this.hasSubtitle,
151
+ [`variant-${this.variant}`]: true,
152
+ })}
153
+ role="alert"
154
+ aria-live="polite"
155
+ aria-label=${this.variantLabel}
156
+ >
157
+ <div class="state-icon" aria-hidden="true">
158
+ <slot name="icon">
159
+ <wc-icon name=${this.variantIcon}></wc-icon>
160
+ </slot>
161
+ </div>
162
+
163
+ <div class="content">
164
+ <div class="content-text">
165
+ <div class="title">
166
+ <slot name="title"></slot>
167
+ <slot></slot>
168
+ </div>
169
+
170
+ <div class="subtitle">
171
+ <slot name="subtitle" @slotchange=${this.handleSubtitleSlotChange}></slot>
172
+ </div>
173
+ </div>
174
+
175
+ ${this.action
176
+ ? html`<div class="actions">
177
+ <wc-button
178
+ class="action"
179
+ size="sm"
180
+ variant=${this.inline ? 'text' : 'outlined'}
181
+ @click=${this.emitActionClick}
182
+ >
183
+ ${this.action}
184
+ </wc-button>
185
+ </div>`
186
+ : nothing}
187
+ </div>
188
+
189
+ ${this.dismissible
190
+ ? html`<div class="close-button-container">
191
+ <wc-icon-button
192
+ class="close-button"
193
+ variant="text"
194
+ size="sm"
195
+ aria-label="Close notification"
196
+ name="close"
197
+ @click=${() => {
198
+ this.hideAndEmitDismiss('dismiss');
199
+ }}
200
+ ></wc-icon-button>
201
+ </div>`
202
+ : nothing}
203
+ </div>
204
+ `;
205
+ }
206
+ }
@@ -1,7 +1,9 @@
1
1
  import { html, LitElement, nothing } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
3
  import { styleMap } from 'lit/directives/style-map.js';
4
- import IndividualComponent from 'src/IndividualComponent.js';
4
+
5
+ import IndividualComponent from '@/IndividualComponent.js';
6
+
5
7
  import styles from './number-counter.scss';
6
8
 
7
9
  /**
@@ -1,10 +1,12 @@
1
1
  import { html, nothing } from 'lit';
2
2
  import { property, query, state } from 'lit/decorators.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
- import { redispatchEvent } from 'src/utils/dispatch-event-utils.js';
4
+
5
+ import { redispatchEvent } from '@/__utils/dispatch-event-utils.js';
6
+ import { spread } from '@/__directive/spread.js';
7
+
5
8
  import BaseInput from '../input/BaseInput.js';
6
9
  import styles from './number-field.scss';
7
- import { spread } from '../spread.js';
8
10
 
9
11
  /**
10
12
  * @label Number Field