@redvars/peacock 3.2.10 → 3.3.1

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 (242) hide show
  1. package/dist/{PeacockComponent-CxJc63xj.js → IndividualComponent-tDnXrOLV.js} +3 -3
  2. package/dist/IndividualComponent-tDnXrOLV.js.map +1 -0
  3. package/dist/assets/components.css +1 -1
  4. package/dist/assets/components.css.map +1 -1
  5. package/dist/assets/styles.css +1 -1
  6. package/dist/assets/styles.css.map +1 -1
  7. package/dist/button-group-DA7xoziD.js +292 -0
  8. package/dist/button-group-DA7xoziD.js.map +1 -0
  9. package/dist/button-group.js +6 -107
  10. package/dist/button-group.js.map +1 -1
  11. package/dist/{button-DaL4va7Q.js → button-trIfcqC7.js} +21 -35
  12. package/dist/button-trIfcqC7.js.map +1 -0
  13. package/dist/button.js +5 -5
  14. package/dist/chart-donut.js +307 -0
  15. package/dist/chart-donut.js.map +1 -0
  16. package/dist/chart-doughnut.js +307 -0
  17. package/dist/chart-doughnut.js.map +1 -0
  18. package/dist/chart-pie.js +259 -0
  19. package/dist/chart-pie.js.map +1 -0
  20. package/dist/{class-map-BvQRv7eW.js → class-map-hJdvjl-W.js} +9 -3
  21. package/dist/class-map-hJdvjl-W.js.map +1 -0
  22. package/dist/clock.js +5 -6
  23. package/dist/clock.js.map +1 -1
  24. package/dist/code-editor.js +38 -25
  25. package/dist/code-editor.js.map +1 -1
  26. package/dist/code-highlighter.js +10 -14
  27. package/dist/code-highlighter.js.map +1 -1
  28. package/dist/custom-elements-jsdocs.json +8144 -3654
  29. package/dist/custom-elements.json +7925 -3901
  30. package/dist/{dispatch-event-utils-vbdiOSeC.js → dispatch-event-utils-B4odODQf.js} +2 -15
  31. package/dist/dispatch-event-utils-B4odODQf.js.map +1 -0
  32. package/dist/index.js +13 -10
  33. package/dist/index.js.map +1 -1
  34. package/dist/number-counter.js +12 -10
  35. package/dist/number-counter.js.map +1 -1
  36. package/dist/{observe-theme-change-NneLARW8.js → observe-theme-change-BISF-Gl5.js} +2 -2
  37. package/dist/{observe-theme-change-NneLARW8.js.map → observe-theme-change-BISF-Gl5.js.map} +1 -1
  38. package/dist/peacock-loader.js +94 -502
  39. package/dist/peacock-loader.js.map +1 -1
  40. package/dist/query-QBcUV-L_.js +15 -0
  41. package/dist/query-QBcUV-L_.js.map +1 -0
  42. package/dist/src/IndividualComponent.d.ts +1 -0
  43. package/dist/src/accordion/{accordion-item/accordion-item.d.ts → accordion-item.d.ts} +5 -4
  44. package/dist/src/accordion/{accordion/accordion.d.ts → accordion.d.ts} +6 -6
  45. package/dist/src/accordion/{accordion-item/index.d.ts → index.d.ts} +1 -0
  46. package/dist/src/avatar/avatar.d.ts +2 -2
  47. package/dist/src/badge/badge.d.ts +2 -2
  48. package/dist/src/breadcrumb/breadcrumb/breadcrumb.d.ts +9 -8
  49. package/dist/src/breadcrumb/breadcrumb-item/breadcrumb-item.d.ts +4 -3
  50. package/dist/src/button/button/button.d.ts +2 -2
  51. package/dist/src/button/button-group/button-group.d.ts +9 -5
  52. package/dist/src/button/icon-button/icon-button.d.ts +2 -2
  53. package/dist/src/chart-donut/chart-donut.d.ts +53 -0
  54. package/dist/src/chart-donut/index.d.ts +1 -0
  55. package/dist/src/chart-doughnut/chart-doughnut.d.ts +53 -0
  56. package/dist/src/chart-doughnut/index.d.ts +1 -0
  57. package/dist/src/chart-pie/chart-pie.d.ts +50 -0
  58. package/dist/src/chart-pie/index.d.ts +1 -0
  59. package/dist/src/checkbox/checkbox.d.ts +3 -6
  60. package/dist/src/chip/chip/chip.d.ts +4 -4
  61. package/dist/src/chip/tag/tag.d.ts +3 -3
  62. package/dist/src/clock/clock.d.ts +3 -4
  63. package/dist/src/code-editor/code-editor.d.ts +13 -10
  64. package/dist/src/code-highlighter/code-highlighter.d.ts +4 -7
  65. package/dist/src/container/container.d.ts +6 -11
  66. package/dist/src/date-picker/date-picker.d.ts +3 -3
  67. package/dist/src/divider/divider.d.ts +2 -2
  68. package/dist/src/elevation/elevation.d.ts +2 -2
  69. package/dist/src/empty-state/empty-state.d.ts +9 -2
  70. package/dist/src/field/field.d.ts +17 -0
  71. package/dist/src/focus-ring/focus-ring.d.ts +1 -1
  72. package/dist/src/icon/icon.d.ts +2 -2
  73. package/dist/src/image/image.d.ts +4 -12
  74. package/dist/src/index.d.ts +9 -1
  75. package/dist/src/input/input.d.ts +2 -2
  76. package/dist/src/link/link.d.ts +4 -5
  77. package/dist/src/menu/index.d.ts +3 -0
  78. package/dist/src/menu/menu/MenuSurfaceController.d.ts +18 -0
  79. package/dist/src/menu/menu/menu.d.ts +66 -8
  80. package/dist/src/menu/menu-item/menu-item.d.ts +24 -5
  81. package/dist/src/menu/sub-menu/sub-menu.d.ts +36 -0
  82. package/dist/src/number-counter/number-counter.d.ts +9 -7
  83. package/dist/src/number-field/number-field.d.ts +1 -1
  84. package/dist/src/pagination/index.d.ts +1 -0
  85. package/dist/src/pagination/pagination.d.ts +38 -0
  86. package/dist/src/popover/PopoverController.d.ts +4 -1
  87. package/dist/src/popover/index.d.ts +1 -1
  88. package/dist/src/progress/circular-progress/circular-progress.d.ts +3 -3
  89. package/dist/src/progress/linear-progress/linear-progress.d.ts +3 -3
  90. package/dist/src/ripple/ripple.d.ts +60 -4
  91. package/dist/src/skeleton/skeleton.d.ts +6 -5
  92. package/dist/src/slider/index.d.ts +1 -0
  93. package/dist/src/slider/slider.d.ts +52 -0
  94. package/dist/src/spinner/spinner.d.ts +2 -2
  95. package/dist/src/switch/switch.d.ts +2 -2
  96. package/dist/src/table/index.d.ts +1 -0
  97. package/dist/src/table/table.d.ts +110 -0
  98. package/dist/src/tabs/index.d.ts +4 -0
  99. package/dist/src/tabs/tab-group.d.ts +45 -0
  100. package/dist/src/tabs/tab-panel.d.ts +22 -0
  101. package/dist/src/tabs/tab.d.ts +59 -0
  102. package/dist/src/tabs/tabs.d.ts +29 -0
  103. package/dist/src/textarea/textarea.d.ts +3 -3
  104. package/dist/src/time-picker/time-picker.d.ts +3 -3
  105. package/dist/src/{popover/tooltip → tooltip}/tooltip.d.ts +4 -3
  106. package/dist/src/tree-view/index.d.ts +2 -0
  107. package/dist/src/tree-view/tree-node.d.ts +69 -0
  108. package/dist/src/tree-view/tree-view.d.ts +40 -0
  109. package/dist/src/tree-view/wc-tree-view.d.ts +6 -0
  110. package/dist/{style-map-B8xgVEc9.js → style-map-CfNHEkQp.js} +2 -2
  111. package/dist/{style-map-B8xgVEc9.js.map → style-map-CfNHEkQp.js.map} +1 -1
  112. package/dist/test/icon.test.d.ts +1 -1
  113. package/dist/test/menu.test.d.ts +1 -0
  114. package/dist/test/sub-menu.test.d.ts +1 -0
  115. package/dist/test/tree-view.test.d.ts +1 -0
  116. package/dist/transform-DRuHEvar.js +3312 -0
  117. package/dist/transform-DRuHEvar.js.map +1 -0
  118. package/dist/{image-v3BujlY5.js → tree-view-CLolVlU0.js} +4088 -672
  119. package/dist/tree-view-CLolVlU0.js.map +1 -0
  120. package/dist/tsconfig.tsbuildinfo +1 -1
  121. package/dist/{unsafe-html-B-dV3Jps.js → unsafe-html-CV6Je6HL.js} +2 -2
  122. package/dist/{unsafe-html-B-dV3Jps.js.map → unsafe-html-CV6Je6HL.js.map} +1 -1
  123. package/package.json +3 -1
  124. package/readme.md +40 -40
  125. package/src/{PeacockComponent.ts → IndividualComponent.ts} +1 -1
  126. package/src/accordion/{accordion-item/accordion-item.scss → accordion-item.scss} +1 -1
  127. package/src/accordion/{accordion-item/accordion-item.ts → accordion-item.ts} +7 -6
  128. package/src/accordion/{accordion/accordion.scss → accordion.scss} +2 -1
  129. package/src/accordion/{accordion/accordion.ts → accordion.ts} +6 -6
  130. package/src/accordion/{accordion-item/index.ts → index.ts} +2 -0
  131. package/src/avatar/avatar.ts +2 -2
  132. package/src/badge/badge.ts +2 -2
  133. package/src/breadcrumb/breadcrumb/breadcrumb.ts +10 -8
  134. package/src/breadcrumb/breadcrumb-item/breadcrumb-item.ts +4 -3
  135. package/src/button/BaseButton.ts +1 -1
  136. package/src/button/button/button.scss +9 -23
  137. package/src/button/button/button.ts +8 -8
  138. package/src/button/button-group/button-group.ts +13 -7
  139. package/src/button/icon-button/icon-button.ts +8 -8
  140. package/src/chart-donut/chart-donut.scss +37 -0
  141. package/src/chart-donut/chart-donut.ts +287 -0
  142. package/src/chart-donut/demo/index.html +51 -0
  143. package/src/chart-donut/index.ts +1 -0
  144. package/src/chart-doughnut/chart-donut.scss +37 -0
  145. package/src/chart-doughnut/chart-doughnut.ts +287 -0
  146. package/src/chart-doughnut/demo/index.html +51 -0
  147. package/src/chart-doughnut/index.ts +1 -0
  148. package/src/chart-pie/chart-pie.scss +27 -0
  149. package/src/chart-pie/chart-pie.ts +256 -0
  150. package/src/chart-pie/demo/index.html +51 -0
  151. package/src/chart-pie/index.ts +1 -0
  152. package/src/checkbox/checkbox.ts +3 -6
  153. package/src/chip/chip/chip.ts +6 -6
  154. package/src/chip/tag/tag.ts +6 -6
  155. package/src/clock/clock.ts +5 -6
  156. package/src/code-editor/code-editor.scss +3 -5
  157. package/src/code-editor/code-editor.ts +32 -16
  158. package/src/code-highlighter/code-highlighter.ts +8 -11
  159. package/src/container/container.ts +6 -11
  160. package/src/date-picker/date-picker.ts +7 -7
  161. package/src/divider/divider.scss +2 -2
  162. package/src/divider/divider.ts +2 -2
  163. package/src/elevation/elevation.ts +2 -2
  164. package/src/empty-state/empty-state.scss +1 -1
  165. package/src/empty-state/empty-state.ts +10 -3
  166. package/src/field/field.scss +4 -4
  167. package/src/field/field.ts +19 -2
  168. package/src/focus-ring/focus-ring.scss +2 -1
  169. package/src/focus-ring/focus-ring.ts +1 -1
  170. package/src/icon/icon.ts +2 -2
  171. package/src/icon/p-icon.ts +1 -1
  172. package/src/image/image.ts +4 -12
  173. package/src/index.ts +11 -3
  174. package/src/input/input.ts +6 -6
  175. package/src/link/link.ts +4 -5
  176. package/src/menu/index.ts +3 -0
  177. package/src/menu/menu/MenuSurfaceController.ts +61 -0
  178. package/src/menu/{menu-list/menu-list.scss → menu/menu.scss} +19 -4
  179. package/src/menu/menu/menu.ts +401 -77
  180. package/src/menu/menu-item/menu-item-colors.scss +2 -2
  181. package/src/menu/menu-item/menu-item.ts +128 -37
  182. package/src/menu/sub-menu/sub-menu.scss +7 -0
  183. package/src/menu/sub-menu/sub-menu.ts +243 -0
  184. package/src/number-counter/demo/index.html +1 -1
  185. package/src/number-counter/number-counter.ts +11 -9
  186. package/src/number-field/number-field.ts +7 -7
  187. package/src/pagination/index.ts +1 -0
  188. package/src/pagination/pagination.scss +59 -0
  189. package/src/pagination/pagination.ts +135 -0
  190. package/src/peacock-loader.ts +92 -51
  191. package/src/popover/PopoverController.ts +13 -7
  192. package/src/popover/index.ts +1 -1
  193. package/src/progress/circular-progress/circular-progress.scss +1 -1
  194. package/src/progress/circular-progress/circular-progress.ts +3 -3
  195. package/src/progress/linear-progress/linear-progress.ts +3 -3
  196. package/src/ripple/ripple.ts +478 -94
  197. package/src/skeleton/skeleton.ts +6 -5
  198. package/src/slider/index.ts +1 -0
  199. package/src/slider/slider.scss +130 -0
  200. package/src/slider/slider.ts +178 -0
  201. package/src/spinner/spinner.ts +2 -2
  202. package/src/switch/switch.ts +4 -4
  203. package/src/table/index.ts +1 -0
  204. package/src/table/table.scss +174 -0
  205. package/src/table/table.ts +475 -0
  206. package/src/tabs/index.ts +4 -0
  207. package/src/tabs/tab-group.scss +10 -0
  208. package/src/tabs/tab-group.ts +143 -0
  209. package/src/tabs/tab-panel.scss +12 -0
  210. package/src/tabs/tab-panel.ts +29 -0
  211. package/src/tabs/tab.scss +157 -0
  212. package/src/tabs/tab.ts +243 -0
  213. package/src/tabs/tabs.scss +19 -0
  214. package/src/tabs/tabs.ts +66 -0
  215. package/src/text/text.css-component.scss +6 -3
  216. package/src/textarea/textarea.ts +5 -5
  217. package/src/time-picker/time-picker.ts +7 -7
  218. package/src/{popover/tooltip → tooltip}/tooltip.scss +17 -14
  219. package/src/{popover/tooltip → tooltip}/tooltip.ts +12 -10
  220. package/src/tree-view/demo/index.html +57 -0
  221. package/src/tree-view/index.ts +2 -0
  222. package/src/tree-view/tree-node.scss +101 -0
  223. package/src/tree-view/tree-node.ts +268 -0
  224. package/src/tree-view/tree-view.scss +12 -0
  225. package/src/tree-view/tree-view.ts +182 -0
  226. package/src/tree-view/wc-tree-view.ts +9 -0
  227. package/dist/PeacockComponent-CxJc63xj.js.map +0 -1
  228. package/dist/button-DaL4va7Q.js.map +0 -1
  229. package/dist/class-map-BvQRv7eW.js.map +0 -1
  230. package/dist/dispatch-event-utils-vbdiOSeC.js.map +0 -1
  231. package/dist/image-v3BujlY5.js.map +0 -1
  232. package/dist/src/PeacockComponent.d.ts +0 -1
  233. package/dist/src/accordion/accordion/index.d.ts +0 -1
  234. package/dist/src/avatar/p-avatar.d.ts +0 -3
  235. package/dist/src/badge/p-badge.d.ts +0 -3
  236. package/dist/src/menu/menu-list/menu-list.d.ts +0 -7
  237. package/dist/state-B09bP3XH.js +0 -10
  238. package/dist/state-B09bP3XH.js.map +0 -1
  239. package/src/accordion/accordion/index.ts +0 -1
  240. package/src/avatar/p-avatar.ts +0 -5
  241. package/src/badge/p-badge.ts +0 -5
  242. package/src/menu/menu-list/menu-list.ts +0 -33
@@ -1,27 +1,45 @@
1
- import { html, LitElement } from 'lit';
2
- import { property, query } from 'lit/decorators.js';
1
+ import { html, LitElement, nothing } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
3
  import { classMap } from 'lit/directives/class-map.js';
4
4
  import styles from './menu-item.scss';
5
5
  import colorStyles from './menu-item-colors.scss';
6
6
 
7
+ /**
8
+ * @label Menu Item
9
+ * @tag wc-menu-item
10
+ * @rawTag menu-item
11
+ * @parentRawTag menu-list
12
+ * @summary An item in a menu list.
13
+ * @tags navigation
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <wc-menu-item>Menu Item</wc-menu-item>
18
+ * ```
19
+ */
7
20
  export class MenuItem extends LitElement {
8
21
  @property({ type: Boolean, reflect: true }) disabled = false;
9
22
 
10
23
  @property({ type: String }) value = '';
11
24
 
12
- @property({ type: Boolean }) selected = false;
25
+ @property({ type: Boolean, reflect: true }) selected = false;
26
+
27
+ @property({ type: Boolean, attribute: 'keep-open' }) keepOpen = false;
28
+
29
+ @property({ type: Boolean, attribute: 'has-submenu' }) hasSubmenu = false;
30
+
31
+ @property({ type: Boolean, attribute: 'submenu-open' }) submenuOpen = false;
13
32
 
14
33
  /*
15
34
  * Hyperlink to navigate to on click.
16
35
  */
17
36
  @property({ reflect: true }) href?: string;
18
37
 
19
- /**
38
+ /**
20
39
  * Sets or retrieves the window or frame at which to target content.
21
40
  */
22
41
  @property() target: string = '_self';
23
42
 
24
-
25
43
  @property({ type: String, reflect: true }) variant: 'standard' | 'vibrant' =
26
44
  'standard';
27
45
 
@@ -33,76 +51,149 @@ export class MenuItem extends LitElement {
33
51
  if (!this.hasAttribute('role')) {
34
52
  this.setAttribute('role', 'menuitem');
35
53
  }
54
+
55
+ if (!this.hasAttribute('tabindex')) {
56
+ this.tabIndex = -1;
57
+ }
58
+
59
+ this.addEventListener('click', this._handleClick);
60
+ this.addEventListener('keydown', this._handleKeyDown);
61
+ }
62
+
63
+ disconnectedCallback() {
64
+ this.removeEventListener('click', this._handleClick);
65
+ this.removeEventListener('keydown', this._handleKeyDown);
66
+ super.disconnectedCallback();
67
+ }
68
+
69
+ private emitActivate(source: 'click' | 'keydown', key?: string) {
70
+ this.dispatchEvent(
71
+ new CustomEvent('menu-item-activate', {
72
+ bubbles: true,
73
+ composed: true,
74
+ detail: { item: this, source, key },
75
+ }),
76
+ );
77
+ }
78
+
79
+ private requestClose(source: 'click' | 'keydown', key?: string) {
80
+ this.dispatchEvent(
81
+ new CustomEvent('menu-item-request-close', {
82
+ bubbles: true,
83
+ composed: true,
84
+ detail: {
85
+ item: this,
86
+ source,
87
+ key,
88
+ reason: source === 'click' ? 'click-selection' : 'keydown',
89
+ },
90
+ }),
91
+ );
92
+ }
93
+
94
+ private requestSubmenuKey(key: string) {
95
+ this.dispatchEvent(
96
+ new CustomEvent('menu-item-submenu-keydown', {
97
+ bubbles: true,
98
+ composed: true,
99
+ detail: { item: this, key },
100
+ }),
101
+ );
36
102
  }
37
103
 
38
- // Handle keyboard activation (Enter/Space)
39
104
  private _handleKeyDown(e: KeyboardEvent) {
105
+ if (this.disabled) {
106
+ e.preventDefault();
107
+ return;
108
+ }
109
+
110
+ if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
111
+ this.requestSubmenuKey(e.key);
112
+ return;
113
+ }
114
+
40
115
  if (e.key === 'Enter' || e.key === ' ') {
41
116
  e.preventDefault();
42
- this.click();
117
+ this.emitActivate('keydown', e.key);
118
+ if (!this.keepOpen) {
119
+ this.requestClose('keydown', e.key);
120
+ }
121
+ }
122
+ }
123
+
124
+ private _handleClick(e: MouseEvent) {
125
+ if (this.disabled) {
126
+ e.preventDefault();
127
+ e.stopPropagation();
128
+ return;
129
+ }
130
+
131
+ this.emitActivate('click');
132
+ if (!this.keepOpen) {
133
+ this.requestClose('click');
43
134
  }
44
135
  }
45
136
 
46
- __isLink() {
137
+ __isLink() {
47
138
  return !!this.href;
48
139
  }
49
140
 
50
- @query('.menu-item') private readonly menuItemElement!: HTMLElement | null;
51
-
52
- override focus() {
53
- this.menuItemElement?.focus();
54
- }
55
-
56
- override blur() {
57
- this.menuItemElement?.blur();
58
- }
141
+ get focusTarget() {
142
+ return this;
143
+ }
59
144
 
60
145
  render() {
61
-
62
146
  const isLink = this.__isLink();
63
147
 
64
148
  const cssClasses = {
65
- 'menu-item': true,
66
- disabled: this.disabled,
67
- selected: this.selected,
68
- };
149
+ 'menu-item': true,
150
+ disabled: this.disabled,
151
+ selected: this.selected,
152
+ };
153
+
154
+ const controls = this.getAttribute('aria-controls');
69
155
 
70
156
  if (isLink) {
71
157
  return html`<a
72
158
  class=${classMap(cssClasses)}
73
159
  href=${this.href}
74
160
  target=${this.target}
161
+ aria-disabled=${String(this.disabled)}
162
+ aria-haspopup=${this.hasSubmenu ? 'menu' : nothing}
163
+ aria-controls=${this.hasSubmenu && controls ? controls : nothing}
164
+ aria-expanded=${this.hasSubmenu ? String(this.submenuOpen) : nothing}
75
165
  >
76
166
  ${this.renderContent()}
77
- </a>
78
- `;
167
+ </a> `;
79
168
  }
80
169
 
81
-
82
170
  return html`<div
83
- class=${classMap(cssClasses)}
84
- tabindex=${!this.disabled ? 0 : -1}
85
- @keydown="${this._handleKeyDown}"
86
- >
87
- ${this.renderContent()}
88
- </div>
89
- `;
171
+ class=${classMap(cssClasses)}
172
+ aria-disabled=${String(this.disabled)}
173
+ aria-haspopup=${this.hasSubmenu ? 'menu' : nothing}
174
+ aria-controls=${this.hasSubmenu && controls ? controls : nothing}
175
+ aria-expanded=${this.hasSubmenu ? String(this.submenuOpen) : nothing}
176
+ >
177
+ ${this.renderContent()}
178
+ </div>`;
90
179
  }
91
180
 
92
181
  renderContent() {
93
182
  return html`
94
- <focus-ring class="focus-ring" .control=${this} element="menuItemElement"></focus-ring>
183
+ <wc-focus-ring
184
+ class="focus-ring"
185
+ .control=${this}
186
+ element="focusTarget"
187
+ ></wc-focus-ring>
95
188
  <div class="background"></div>
96
- <base-ripple class="ripple"></base-ripple>
189
+ <wc-ripple class="ripple"></wc-ripple>
97
190
 
98
191
  <div class="menu-item-content">
99
192
  <slot name="leading-icon"></slot>
100
193
  <div class="slot-container">
101
194
  <slot></slot>
102
195
  </div>
103
- <slot
104
- name="trailing-supporting-text"
105
- ></slot>
196
+ <slot name="trailing-supporting-text"></slot>
106
197
  </div>
107
198
  `;
108
199
  }
@@ -0,0 +1,7 @@
1
+ @use "../../../scss/mixin";
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: contents;
7
+ }
@@ -0,0 +1,243 @@
1
+ import { html, LitElement } from 'lit';
2
+ import { property, queryAssignedElements } from 'lit/decorators.js';
3
+ import styles from './sub-menu.scss';
4
+ import { MenuItem } from '../menu-item/menu-item.js';
5
+ import { Menu } from '../menu/menu.js';
6
+
7
+ let subMenuIdCounter = 0;
8
+
9
+ /**
10
+ * @label Sub Menu
11
+ * @tag wc-sub-menu
12
+ * @rawTag sub-menu
13
+ * @summary Connects a menu item to a nested menu.
14
+ */
15
+ export class SubMenu extends LitElement {
16
+ static styles = [styles];
17
+
18
+ @property({ type: Number, attribute: 'hover-open-delay' })
19
+ hoverOpenDelay = 120;
20
+
21
+ @property({ type: Number, attribute: 'hover-close-delay' })
22
+ hoverCloseDelay = 180;
23
+
24
+ @property({ type: String, attribute: 'anchor-corner' })
25
+ anchorCorner = 'start-end';
26
+
27
+ @property({ type: String, attribute: 'menu-corner' })
28
+ menuCorner = 'start-start';
29
+
30
+ @queryAssignedElements({ slot: 'item' })
31
+ private readonly _items!: Element[];
32
+
33
+ @queryAssignedElements({ slot: 'menu' })
34
+ private readonly _menus!: Element[];
35
+
36
+ private _openTimeout?: number;
37
+
38
+ private _closeTimeout?: number;
39
+
40
+ private readonly _onChildMenuOpened = () => {
41
+ const { item } = this;
42
+ if (!item) {
43
+ return;
44
+ }
45
+
46
+ item.submenuOpen = true;
47
+ item.setAttribute('aria-expanded', 'true');
48
+ };
49
+
50
+ private readonly _onChildMenuClosed = () => {
51
+ const { item } = this;
52
+ if (!item) {
53
+ return;
54
+ }
55
+
56
+ item.submenuOpen = false;
57
+ item.setAttribute('aria-expanded', 'false');
58
+ };
59
+
60
+ get item(): MenuItem | null {
61
+ const [candidate] = this._items ?? [];
62
+ return candidate instanceof MenuItem ? candidate : null;
63
+ }
64
+
65
+ get menu(): Menu | null {
66
+ const [candidate] = this._menus ?? [];
67
+ return candidate instanceof Menu ? candidate : null;
68
+ }
69
+
70
+ connectedCallback() {
71
+ super.connectedCallback();
72
+ this.addEventListener('mouseenter', this._onMouseEnter);
73
+ this.addEventListener('mouseleave', this._onMouseLeave);
74
+ }
75
+
76
+ disconnectedCallback() {
77
+ const { menu } = this;
78
+ menu?.removeEventListener('opened', this._onChildMenuOpened);
79
+ menu?.removeEventListener('closed', this._onChildMenuClosed);
80
+ this.removeEventListener('mouseenter', this._onMouseEnter);
81
+ this.removeEventListener('mouseleave', this._onMouseLeave);
82
+ window.clearTimeout(this._openTimeout);
83
+ window.clearTimeout(this._closeTimeout);
84
+ super.disconnectedCallback();
85
+ }
86
+
87
+ async show() {
88
+ const { item, menu } = this;
89
+ if (!item || !menu) {
90
+ return;
91
+ }
92
+
93
+ menu.anchorElement = item;
94
+ menu.isSubmenu = true;
95
+ menu.show();
96
+
97
+ item.hasSubmenu = true;
98
+ item.submenuOpen = true;
99
+ item.setAttribute('aria-expanded', 'true');
100
+ }
101
+
102
+ async close() {
103
+ const { item, menu } = this;
104
+ if (!item || !menu) {
105
+ return;
106
+ }
107
+
108
+ menu.close({ kind: 'programmatic' });
109
+ item.submenuOpen = false;
110
+ item.setAttribute('aria-expanded', 'false');
111
+ }
112
+
113
+ render() {
114
+ return html`
115
+ <slot
116
+ name="item"
117
+ @slotchange=${this._onSlotChange}
118
+ @click=${this._onItemClick}
119
+ @keydown=${this._onItemKeyDown}
120
+ ></slot>
121
+ <slot
122
+ name="menu"
123
+ @slotchange=${this._onSlotChange}
124
+ @close-menu=${this._onCloseMenu}
125
+ @keydown=${this._onMenuKeyDown}
126
+ ></slot>
127
+ `;
128
+ }
129
+
130
+ private _onSlotChange = () => {
131
+ const { item, menu } = this;
132
+ if (!item || !menu) {
133
+ return;
134
+ }
135
+
136
+ if (!menu.id) {
137
+ subMenuIdCounter += 1;
138
+ menu.id = `wc-sub-menu-${subMenuIdCounter}`;
139
+ }
140
+
141
+ item.keepOpen = true;
142
+ item.hasSubmenu = true;
143
+ item.submenuOpen = menu.open;
144
+ item.setAttribute('aria-haspopup', 'menu');
145
+ item.setAttribute('aria-expanded', String(menu.open));
146
+ item.setAttribute('aria-controls', menu.id);
147
+
148
+ menu.removeEventListener('opened', this._onChildMenuOpened);
149
+ menu.removeEventListener('closed', this._onChildMenuClosed);
150
+ menu.addEventListener('opened', this._onChildMenuOpened);
151
+ menu.addEventListener('closed', this._onChildMenuClosed);
152
+
153
+ menu.isSubmenu = true;
154
+ menu.anchorElement = item;
155
+ menu.placement =
156
+ getComputedStyle(this).direction === 'rtl' ? 'left-start' : 'right-start';
157
+ menu.offset = 4;
158
+ };
159
+
160
+ private _onItemClick = () => {
161
+ if (this.menu?.open) {
162
+ this.close();
163
+ return;
164
+ }
165
+
166
+ this.show();
167
+ };
168
+
169
+ private _onItemKeyDown = async (event: KeyboardEvent) => {
170
+ const isRtl = getComputedStyle(this).direction === 'rtl';
171
+ const arrowEnter = isRtl ? 'ArrowLeft' : 'ArrowRight';
172
+
173
+ const shouldOpen =
174
+ event.key === arrowEnter || event.key === 'Enter' || event.key === ' ';
175
+
176
+ if (!shouldOpen) {
177
+ return;
178
+ }
179
+
180
+ event.preventDefault();
181
+ if (event.key === arrowEnter) {
182
+ event.stopPropagation();
183
+ }
184
+
185
+ await this.show();
186
+ const firstItem = this.menu?.items.find(menuItem => !menuItem.disabled);
187
+ if (firstItem) {
188
+ firstItem.tabIndex = 0;
189
+ firstItem.focus();
190
+ }
191
+ };
192
+
193
+ private _onMenuKeyDown = async (event: KeyboardEvent) => {
194
+ const isRtl = getComputedStyle(this).direction === 'rtl';
195
+ const arrowExit = isRtl ? 'ArrowRight' : 'ArrowLeft';
196
+
197
+ if (event.key !== 'Escape' && event.key !== arrowExit) {
198
+ return;
199
+ }
200
+
201
+ event.preventDefault();
202
+ event.stopPropagation();
203
+
204
+ await this.close();
205
+
206
+ const { item } = this;
207
+ if (item) {
208
+ item.tabIndex = 0;
209
+ item.focus();
210
+ }
211
+ };
212
+
213
+ private _onCloseMenu = async (
214
+ event: CustomEvent<{ reason?: { kind?: string; key?: string } }>,
215
+ ) => {
216
+ const { reason } = event.detail ?? {};
217
+ const { key } = reason ?? {};
218
+ if (reason?.kind === 'keydown' && key === 'Escape') {
219
+ event.stopPropagation();
220
+ await this.close();
221
+ this.item?.focus();
222
+ }
223
+ };
224
+
225
+ private _onMouseEnter = () => {
226
+ window.clearTimeout(this._closeTimeout);
227
+ this._openTimeout = window.setTimeout(() => {
228
+ this.show();
229
+ }, this.hoverOpenDelay);
230
+ };
231
+
232
+ private _onMouseLeave = (event: MouseEvent) => {
233
+ const { relatedTarget: related } = event;
234
+ if (related instanceof Node && this.contains(related)) {
235
+ return;
236
+ }
237
+
238
+ window.clearTimeout(this._openTimeout);
239
+ this._closeTimeout = window.setTimeout(() => {
240
+ this.close();
241
+ }, this.hoverCloseDelay);
242
+ };
243
+ }
@@ -20,7 +20,7 @@
20
20
 
21
21
 
22
22
  <p class='text-body'>
23
- <number-counter value='400'></number-counter>
23
+ <wc-number-counter value='400'></wc-number-counter>
24
24
  </p>
25
25
 
26
26
 
@@ -1,29 +1,31 @@
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 PeacockComponent from 'src/PeacockComponent.js';
4
+ import IndividualComponent from 'src/IndividualComponent.js';
5
5
  import styles from './number-counter.scss';
6
6
 
7
7
  /**
8
8
  * @label Number Counter
9
- * @tag number-counter
9
+ * @tag wc-number-counter
10
10
  * @rawTag number-counter
11
11
  * @summary Displays a number with commas for thousands.
12
12
  *
13
13
  * @example
14
14
  * ```html
15
- * <number-counter value="123456789"></number-counter>
15
+ * <wc-number-counter id="number-counter" value="123456789"></wc-number-counter>
16
16
  * <script>
17
- * const $counter = document.querySelector('number-counter');
18
- *
19
- * setInterval(() => {
20
- * $counter.value = $counter.value + parseInt(Math.floor(Math.random() * 1000));
21
- * }, 1000);
17
+ * customElements.whenDefined('wc-number-counter').then(() => {
18
+ const $counter = document.querySelector('#number-counter');
19
+
20
+ setInterval(() => {
21
+ $counter.value = $counter.value + Math.floor(Math.random() * 1000);
22
+ }, 1000);
23
+ });
22
24
  * </script>
23
25
  * ```
24
26
  * @tags display
25
27
  */
26
- @PeacockComponent
28
+ @IndividualComponent
27
29
  export class NumberCounter extends LitElement {
28
30
  static styles = [styles];
29
31
 
@@ -15,7 +15,7 @@ import { spread } from '../spread.js';
15
15
  *
16
16
  * @example
17
17
  * ```html
18
- * <number-field label="Age" placeholder="Enter your age"></number-field>
18
+ * <wc-number-field label="Age" placeholder="Enter your age"></wc-number-field>
19
19
  * ```
20
20
  */
21
21
  export class NumberField extends BaseInput {
@@ -150,7 +150,7 @@ export class NumberField extends BaseInput {
150
150
  };
151
151
 
152
152
  return html`
153
- <base-field
153
+ <wc-field
154
154
  ?required=${this.required}
155
155
  ?disabled=${this.disabled}
156
156
  ?readonly=${this.readonly}
@@ -166,13 +166,13 @@ export class NumberField extends BaseInput {
166
166
  class=${classMap(classes)}
167
167
  >
168
168
  ${this.stepper && !this.disabled
169
- ? html`<icon-button
169
+ ? html`<wc-icon-button
170
170
  class="stepper"
171
171
  name="remove"
172
172
  variant="text"
173
173
  slot="field-start"
174
174
  @click=${this.stepDown}
175
- ></icon-button>`
175
+ ></wc-icon-button>`
176
176
  : nothing}
177
177
 
178
178
  <slot name="start" slot="field-start"></slot>
@@ -201,15 +201,15 @@ export class NumberField extends BaseInput {
201
201
  <slot name="end" slot="field-end"></slot>
202
202
 
203
203
  ${this.stepper && !this.disabled
204
- ? html`<icon-button
204
+ ? html`<wc-icon-button
205
205
  class="stepper"
206
206
  variant="text"
207
207
  name="add"
208
208
  slot="field-end"
209
209
  @click=${this.stepUp}
210
- ></icon-button>`
210
+ ></wc-icon-button>`
211
211
  : nothing}
212
- </base-field>
212
+ </wc-field>
213
213
  `;
214
214
  }
215
215
  }
@@ -0,0 +1 @@
1
+ export { Pagination } from './pagination.js';
@@ -0,0 +1,59 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ }
8
+
9
+ .pagination {
10
+ background: var(--color-surface, #fff);
11
+ display: flex;
12
+ align-items: center;
13
+
14
+ .page-sizes-select {
15
+ margin-inline-start: var(--spacing-100, 0.5rem);
16
+ }
17
+
18
+ .page-size-label {
19
+ display: flex;
20
+ align-items: center;
21
+ gap: var(--spacing-100, 0.5rem);
22
+ @include mixin.get-typography-not-important('body-medium');
23
+ color: var(--color-on-surface-variant);
24
+ white-space: nowrap;
25
+ }
26
+
27
+ .page-size-select {
28
+ border: 1px solid var(--color-outline-variant);
29
+ background: var(--color-surface, #fff);
30
+ color: var(--color-on-surface);
31
+ padding: var(--spacing-050, 0.25rem) var(--spacing-100, 0.5rem);
32
+ cursor: pointer;
33
+ outline: none;
34
+ height: 2.5rem;
35
+
36
+ @include mixin.get-typography-not-important('body-medium');
37
+
38
+ &:focus {
39
+ outline: 2px solid var(--color-primary);
40
+ }
41
+ }
42
+
43
+ .pagination-item-count {
44
+ margin-inline-start: var(--spacing-150, 0.75rem);
45
+ flex: 1;
46
+ display: flex;
47
+ align-items: center;
48
+ }
49
+
50
+ .pagination-text {
51
+ @include mixin.get-typography-not-important('body-medium');
52
+ color: var(--color-on-surface-variant);
53
+ }
54
+
55
+ .arrows {
56
+ --border-radius: 0;
57
+ --button-height: calc(2.5rem - 2px);
58
+ }
59
+ }