@material/web 1.0.0-pre.6 → 1.0.0-pre.7

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 (334) hide show
  1. package/README.md +7 -7
  2. package/aria/aria.d.ts +43 -0
  3. package/aria/aria.js +56 -0
  4. package/aria/aria.js.map +1 -0
  5. package/aria/delegate.d.ts +37 -0
  6. package/aria/delegate.js +53 -0
  7. package/aria/delegate.js.map +1 -0
  8. package/badge/badge.d.ts +0 -1
  9. package/badge/badge.js +0 -1
  10. package/badge/badge.js.map +1 -1
  11. package/badge/lib/badge.d.ts +8 -7
  12. package/badge/lib/badge.js +5 -6
  13. package/badge/lib/badge.js.map +1 -1
  14. package/button/lib/_elevation.scss +13 -3
  15. package/button/lib/button.d.ts +1 -12
  16. package/button/lib/button.js +29 -60
  17. package/button/lib/button.js.map +1 -1
  18. package/button/lib/shared-elevation-styles.css.js +1 -1
  19. package/button/lib/shared-elevation-styles.css.js.map +1 -1
  20. package/checkbox/lib/checkbox.d.ts +0 -1
  21. package/checkbox/lib/checkbox.js +33 -43
  22. package/checkbox/lib/checkbox.js.map +1 -1
  23. package/chips/_filter-chip.scss +6 -0
  24. package/chips/filter-chip.d.ts +20 -0
  25. package/chips/filter-chip.js +24 -0
  26. package/chips/filter-chip.js.map +1 -0
  27. package/chips/lib/_filter-chip.scss +141 -0
  28. package/chips/lib/_shared.scss +18 -14
  29. package/chips/lib/assist-styles.css.js +1 -1
  30. package/chips/lib/assist-styles.css.js.map +1 -1
  31. package/chips/lib/chip.d.ts +8 -3
  32. package/chips/lib/chip.js +29 -30
  33. package/chips/lib/chip.js.map +1 -1
  34. package/chips/lib/filter-chip.d.ts +21 -0
  35. package/chips/lib/filter-chip.js +47 -0
  36. package/chips/lib/filter-chip.js.map +1 -0
  37. package/chips/lib/filter-styles.css.js +9 -0
  38. package/chips/lib/filter-styles.css.js.map +1 -0
  39. package/{fab/lib/fab-extended-styles.scss → chips/lib/filter-styles.scss} +3 -3
  40. package/chips/lib/shared-styles.css.js +1 -1
  41. package/chips/lib/shared-styles.css.js.map +1 -1
  42. package/chips/lib/suggestion-styles.css.js +1 -1
  43. package/chips/lib/suggestion-styles.css.js.map +1 -1
  44. package/circularprogress/harness.d.ts +1 -0
  45. package/circularprogress/harness.js +4 -0
  46. package/circularprogress/harness.js.map +1 -1
  47. package/circularprogress/lib/circular-progress.d.ts +0 -1
  48. package/circularprogress/lib/circular-progress.js +16 -19
  49. package/circularprogress/lib/circular-progress.js.map +1 -1
  50. package/dialog/lib/_dialog.scss +8 -8
  51. package/dialog/lib/dialog-styles.css.js +1 -1
  52. package/dialog/lib/dialog-styles.css.js.map +1 -1
  53. package/dialog/lib/dialog.js +25 -49
  54. package/dialog/lib/dialog.js.map +1 -1
  55. package/divider/lib/divider.js +4 -7
  56. package/divider/lib/divider.js.map +1 -1
  57. package/elevation/lib/_elevation.scss +5 -7
  58. package/elevation/lib/elevation-styles.css.js +1 -1
  59. package/elevation/lib/elevation-styles.css.js.map +1 -1
  60. package/fab/_fab.scss +1 -0
  61. package/fab/branded-fab.d.ts +53 -0
  62. package/fab/branded-fab.js +56 -0
  63. package/fab/branded-fab.js.map +1 -0
  64. package/fab/fab.d.ts +25 -5
  65. package/fab/fab.js +27 -10
  66. package/fab/fab.js.map +1 -1
  67. package/fab/harness.d.ts +1 -2
  68. package/fab/harness.js +1 -1
  69. package/fab/harness.js.map +1 -1
  70. package/fab/lib/_fab-branded.scss +27 -0
  71. package/fab/lib/_fab.scss +144 -16
  72. package/fab/lib/_shared.scss +155 -130
  73. package/fab/lib/fab-branded-styles.css.js +9 -0
  74. package/fab/lib/fab-branded-styles.css.js.map +1 -0
  75. package/fab/lib/fab-branded-styles.scss +10 -0
  76. package/fab/lib/fab-styles.css.js +1 -1
  77. package/fab/lib/fab-styles.css.js.map +1 -1
  78. package/fab/lib/fab.d.ts +14 -10
  79. package/fab/lib/fab.js +19 -12
  80. package/fab/lib/fab.js.map +1 -1
  81. package/fab/lib/forced-colors-styles.css.d.ts +1 -0
  82. package/fab/lib/forced-colors-styles.css.js +9 -0
  83. package/fab/lib/forced-colors-styles.css.js.map +1 -0
  84. package/fab/lib/forced-colors-styles.scss +26 -0
  85. package/fab/lib/shared-styles.css.d.ts +1 -0
  86. package/fab/lib/shared-styles.css.js +9 -0
  87. package/fab/lib/shared-styles.css.js.map +1 -0
  88. package/fab/lib/{fab-shared-styles.scss → shared-styles.scss} +1 -1
  89. package/fab/lib/{fab-shared.d.ts → shared.d.ts} +24 -16
  90. package/fab/lib/shared.js +137 -0
  91. package/fab/lib/shared.js.map +1 -0
  92. package/field/lib/field.js +14 -27
  93. package/field/lib/field.js.map +1 -1
  94. package/focus/focus-ring.d.ts +0 -1
  95. package/focus/focus-ring.js +0 -1
  96. package/focus/focus-ring.js.map +1 -1
  97. package/focus/lib/focus-ring.js +2 -3
  98. package/focus/lib/focus-ring.js.map +1 -1
  99. package/focus/strong-focus.js +5 -0
  100. package/focus/strong-focus.js.map +1 -1
  101. package/icon/icon.d.ts +0 -1
  102. package/icon/icon.js +0 -1
  103. package/icon/icon.js.map +1 -1
  104. package/icon/lib/_icon.scss +2 -0
  105. package/icon/lib/icon-styles.css.js +1 -1
  106. package/icon/lib/icon-styles.css.js.map +1 -1
  107. package/icon/lib/icon.d.ts +5 -4
  108. package/icon/lib/icon.js +3 -2
  109. package/icon/lib/icon.js.map +1 -1
  110. package/iconbutton/lib/icon-button.d.ts +0 -4
  111. package/iconbutton/lib/icon-button.js +28 -48
  112. package/iconbutton/lib/icon-button.js.map +1 -1
  113. package/linearprogress/_linear-progress.scss +6 -0
  114. package/linearprogress/harness.d.ts +13 -0
  115. package/linearprogress/harness.js +18 -0
  116. package/linearprogress/harness.js.map +1 -0
  117. package/linearprogress/lib/_linear-progress.scss +380 -0
  118. package/linearprogress/lib/linear-progress-styles.css.d.ts +1 -0
  119. package/linearprogress/lib/linear-progress-styles.css.js +9 -0
  120. package/linearprogress/lib/linear-progress-styles.css.js.map +1 -0
  121. package/linearprogress/lib/linear-progress-styles.scss +8 -0
  122. package/linearprogress/lib/linear-progress.d.ts +35 -0
  123. package/linearprogress/lib/linear-progress.js +127 -0
  124. package/linearprogress/lib/linear-progress.js.map +1 -0
  125. package/linearprogress/linear-progress.d.ts +23 -0
  126. package/linearprogress/linear-progress.js +26 -0
  127. package/linearprogress/linear-progress.js.map +1 -0
  128. package/list/lib/_list.scss +6 -49
  129. package/list/lib/list-styles.css.js +1 -1
  130. package/list/lib/list-styles.css.js.map +1 -1
  131. package/list/lib/list.d.ts +1 -3
  132. package/list/lib/list.js +18 -34
  133. package/list/lib/list.js.map +1 -1
  134. package/list/lib/listitem/_list-item.scss +10 -69
  135. package/list/lib/listitem/forced-colors-styles.css.js +1 -1
  136. package/list/lib/listitem/forced-colors-styles.css.js.map +1 -1
  137. package/list/lib/listitem/list-item-styles.css.js +1 -1
  138. package/list/lib/listitem/list-item-styles.css.js.map +1 -1
  139. package/list/lib/listitem/list-item.d.ts +2 -4
  140. package/list/lib/listitem/list-item.js +24 -53
  141. package/list/lib/listitem/list-item.js.map +1 -1
  142. package/list/lib/listitemlink/list-item-link.js +4 -6
  143. package/list/lib/listitemlink/list-item-link.js.map +1 -1
  144. package/menu/lib/_menu.scss +6 -28
  145. package/menu/lib/menu-styles.css.js +1 -1
  146. package/menu/lib/menu-styles.css.js.map +1 -1
  147. package/menu/lib/menu.d.ts +1 -2
  148. package/menu/lib/menu.js +38 -63
  149. package/menu/lib/menu.js.map +1 -1
  150. package/menu/lib/menuitem/_menu-item.scss +13 -32
  151. package/menu/lib/menuitem/menu-item-styles.css.js +1 -1
  152. package/menu/lib/menuitem/menu-item-styles.css.js.map +1 -1
  153. package/menu/lib/menuitem/menu-item.d.ts +1 -1
  154. package/menu/lib/menuitem/menu-item.js +4 -6
  155. package/menu/lib/menuitem/menu-item.js.map +1 -1
  156. package/menu/lib/menuitemlink/menu-item-link.d.ts +0 -2
  157. package/menu/lib/menuitemlink/menu-item-link.js +3 -6
  158. package/menu/lib/menuitemlink/menu-item-link.js.map +1 -1
  159. package/menu/lib/shared.d.ts +6 -2
  160. package/menu/lib/shared.js.map +1 -1
  161. package/menu/lib/submenuitem/sub-menu-item.d.ts +0 -2
  162. package/menu/lib/submenuitem/sub-menu-item.js +7 -15
  163. package/menu/lib/submenuitem/sub-menu-item.js.map +1 -1
  164. package/navigationbar/lib/_navigation-bar.scss +7 -1
  165. package/navigationbar/lib/navigation-bar-styles.css.js +1 -1
  166. package/navigationbar/lib/navigation-bar-styles.css.js.map +1 -1
  167. package/navigationbar/lib/navigation-bar.d.ts +5 -5
  168. package/navigationbar/lib/navigation-bar.js +17 -18
  169. package/navigationbar/lib/navigation-bar.js.map +1 -1
  170. package/navigationbar/navigation-bar.d.ts +0 -1
  171. package/navigationbar/navigation-bar.js +0 -1
  172. package/navigationbar/navigation-bar.js.map +1 -1
  173. package/navigationdrawer/lib/navigation-drawer-modal.d.ts +5 -10
  174. package/navigationdrawer/lib/navigation-drawer-modal.js +19 -41
  175. package/navigationdrawer/lib/navigation-drawer-modal.js.map +1 -1
  176. package/navigationdrawer/lib/navigation-drawer.d.ts +5 -9
  177. package/navigationdrawer/lib/navigation-drawer.js +17 -38
  178. package/navigationdrawer/lib/navigation-drawer.js.map +1 -1
  179. package/navigationdrawer/navigation-drawer-modal.d.ts +0 -1
  180. package/navigationdrawer/navigation-drawer-modal.js +0 -1
  181. package/navigationdrawer/navigation-drawer-modal.js.map +1 -1
  182. package/navigationdrawer/navigation-drawer.d.ts +0 -1
  183. package/navigationdrawer/navigation-drawer.js +0 -1
  184. package/navigationdrawer/navigation-drawer.js.map +1 -1
  185. package/navigationtab/lib/navigation-tab.d.ts +19 -24
  186. package/navigationtab/lib/navigation-tab.js +48 -68
  187. package/navigationtab/lib/navigation-tab.js.map +1 -1
  188. package/navigationtab/navigation-tab.d.ts +0 -1
  189. package/navigationtab/navigation-tab.js +0 -1
  190. package/navigationtab/navigation-tab.js.map +1 -1
  191. package/package.json +1 -1
  192. package/radio/lib/radio.d.ts +0 -1
  193. package/radio/lib/radio.js +30 -37
  194. package/radio/lib/radio.js.map +1 -1
  195. package/ripple/lib/ripple.js +7 -13
  196. package/ripple/lib/ripple.js.map +1 -1
  197. package/segmentedbutton/lib/outlined-segmented-button.d.ts +16 -7
  198. package/segmentedbutton/lib/outlined-segmented-button.js +3 -3
  199. package/segmentedbutton/lib/outlined-segmented-button.js.map +1 -1
  200. package/segmentedbutton/lib/segmented-button.d.ts +27 -33
  201. package/segmentedbutton/lib/segmented-button.js +42 -75
  202. package/segmentedbutton/lib/segmented-button.js.map +1 -1
  203. package/segmentedbutton/outlined-segmented-button.d.ts +0 -1
  204. package/segmentedbutton/outlined-segmented-button.js +0 -1
  205. package/segmentedbutton/outlined-segmented-button.js.map +1 -1
  206. package/segmentedbuttonset/lib/outlined-segmented-button-set.d.ts +6 -4
  207. package/segmentedbuttonset/lib/outlined-segmented-button-set.js +3 -2
  208. package/segmentedbuttonset/lib/outlined-segmented-button-set.js.map +1 -1
  209. package/segmentedbuttonset/lib/segmented-button-set.d.ts +3 -9
  210. package/segmentedbuttonset/lib/segmented-button-set.js +14 -20
  211. package/segmentedbuttonset/lib/segmented-button-set.js.map +1 -1
  212. package/segmentedbuttonset/outlined-segmented-button-set.d.ts +0 -1
  213. package/segmentedbuttonset/outlined-segmented-button-set.js +0 -1
  214. package/segmentedbuttonset/outlined-segmented-button-set.js.map +1 -1
  215. package/select/_filled-select.scss +6 -0
  216. package/select/_outlined-select.scss +6 -0
  217. package/select/filled-select.d.ts +41 -0
  218. package/select/filled-select.js +46 -0
  219. package/select/filled-select.js.map +1 -0
  220. package/select/harness.d.ts +24 -0
  221. package/select/harness.js +53 -0
  222. package/select/harness.js.map +1 -0
  223. package/select/lib/_filled-select.scss +163 -0
  224. package/select/lib/_outlined-select.scss +146 -0
  225. package/select/lib/_shared.scss +48 -0
  226. package/select/lib/filled-forced-colors-styles.css.d.ts +1 -0
  227. package/select/lib/filled-forced-colors-styles.css.js +9 -0
  228. package/select/lib/filled-forced-colors-styles.css.js.map +1 -0
  229. package/select/lib/filled-forced-colors-styles.scss +29 -0
  230. package/select/lib/filled-select-styles.css.d.ts +1 -0
  231. package/select/lib/filled-select-styles.css.js +9 -0
  232. package/select/lib/filled-select-styles.css.js.map +1 -0
  233. package/select/lib/filled-select-styles.scss +10 -0
  234. package/select/lib/filled-select.d.ts +10 -0
  235. package/select/lib/filled-select.js +16 -0
  236. package/select/lib/filled-select.js.map +1 -0
  237. package/select/lib/outlined-forced-colors-styles.css.d.ts +1 -0
  238. package/select/lib/outlined-forced-colors-styles.css.js +9 -0
  239. package/select/lib/outlined-forced-colors-styles.css.js.map +1 -0
  240. package/select/lib/outlined-forced-colors-styles.scss +29 -0
  241. package/select/lib/outlined-select-styles.css.d.ts +1 -0
  242. package/select/lib/outlined-select-styles.css.js +9 -0
  243. package/select/lib/outlined-select-styles.css.js.map +1 -0
  244. package/select/lib/outlined-select-styles.scss +10 -0
  245. package/select/lib/outlined-select.d.ts +10 -0
  246. package/select/lib/outlined-select.js +16 -0
  247. package/select/lib/outlined-select.js.map +1 -0
  248. package/select/lib/select.d.ts +218 -0
  249. package/select/lib/select.js +587 -0
  250. package/select/lib/select.js.map +1 -0
  251. package/select/lib/selectoption/harness.d.ts +11 -0
  252. package/select/lib/selectoption/harness.js +12 -0
  253. package/select/lib/selectoption/harness.js.map +1 -0
  254. package/select/lib/selectoption/select-option.d.ts +30 -0
  255. package/select/lib/selectoption/select-option.js +71 -0
  256. package/select/lib/selectoption/select-option.js.map +1 -0
  257. package/select/lib/shared-styles.css.d.ts +1 -0
  258. package/select/lib/shared-styles.css.js +9 -0
  259. package/select/lib/shared-styles.css.js.map +1 -0
  260. package/select/lib/shared-styles.scss +10 -0
  261. package/select/lib/shared.d.ts +52 -0
  262. package/select/lib/shared.js +41 -0
  263. package/select/lib/shared.js.map +1 -0
  264. package/select/outlined-select.d.ts +41 -0
  265. package/select/outlined-select.js +46 -0
  266. package/select/outlined-select.js.map +1 -0
  267. package/select/select-option.d.ts +44 -0
  268. package/select/select-option.js +51 -0
  269. package/select/select-option.js.map +1 -0
  270. package/slider/harness.d.ts +1 -0
  271. package/slider/harness.js +5 -0
  272. package/slider/harness.js.map +1 -1
  273. package/slider/lib/_slider.scss +146 -164
  274. package/slider/lib/forced-colors-styles.css.js +1 -1
  275. package/slider/lib/forced-colors-styles.css.js.map +1 -1
  276. package/slider/lib/forced-colors-styles.scss +2 -2
  277. package/slider/lib/slider-styles.css.js +1 -1
  278. package/slider/lib/slider-styles.css.js.map +1 -1
  279. package/slider/lib/slider.d.ts +2 -7
  280. package/slider/lib/slider.js +64 -118
  281. package/slider/lib/slider.js.map +1 -1
  282. package/switch/lib/switch.d.ts +0 -2
  283. package/switch/lib/switch.js +32 -54
  284. package/switch/lib/switch.js.map +1 -1
  285. package/textfield/lib/text-field.d.ts +0 -10
  286. package/textfield/lib/text-field.js +45 -115
  287. package/textfield/lib/text-field.js.map +1 -1
  288. package/tokens/_index.scss +3 -0
  289. package/tokens/_md-comp-assist-chip.scss +25 -20
  290. package/tokens/_md-comp-elevation.scss +0 -4
  291. package/tokens/_md-comp-fab-branded.scss +109 -1
  292. package/tokens/_md-comp-fab.scss +290 -0
  293. package/tokens/_md-comp-filled-select.scss +150 -1
  294. package/tokens/_md-comp-filter-chip.scss +103 -93
  295. package/tokens/_md-comp-input-chip.scss +77 -85
  296. package/tokens/_md-comp-linear-progress-indicator.scss +14 -1
  297. package/tokens/_md-comp-list-item.scss +201 -0
  298. package/tokens/_md-comp-list.scss +107 -26
  299. package/tokens/_md-comp-menu-item.scss +76 -0
  300. package/tokens/_md-comp-menu.scss +52 -2
  301. package/tokens/_md-comp-outlined-select.scss +150 -1
  302. package/tokens/_md-comp-slider.scss +13 -1
  303. package/tokens/_md-comp-suggestion-chip.scss +29 -21
  304. package/tokens/_values.scss +5 -2
  305. package/types/aria.d.ts +61 -1
  306. package/actionelement/action-element.d.ts +0 -79
  307. package/actionelement/action-element.js +0 -97
  308. package/actionelement/action-element.js.map +0 -1
  309. package/button/lib/state.d.ts +0 -10
  310. package/button/lib/state.js +0 -7
  311. package/button/lib/state.js.map +0 -1
  312. package/controller/action-controller.d.ts +0 -147
  313. package/controller/action-controller.js +0 -286
  314. package/controller/action-controller.js.map +0 -1
  315. package/decorators/aria-property.d.ts +0 -32
  316. package/decorators/aria-property.js +0 -99
  317. package/decorators/aria-property.js.map +0 -1
  318. package/fab/_fab-extended.scss +0 -6
  319. package/fab/fab-extended.d.ts +0 -23
  320. package/fab/fab-extended.js +0 -29
  321. package/fab/fab-extended.js.map +0 -1
  322. package/fab/lib/_fab-extended.scss +0 -73
  323. package/fab/lib/fab-extended-styles.css.js +0 -9
  324. package/fab/lib/fab-extended-styles.css.js.map +0 -1
  325. package/fab/lib/fab-extended.d.ts +0 -19
  326. package/fab/lib/fab-extended.js +0 -28
  327. package/fab/lib/fab-extended.js.map +0 -1
  328. package/fab/lib/fab-shared-styles.css.js +0 -9
  329. package/fab/lib/fab-shared-styles.css.js.map +0 -1
  330. package/fab/lib/fab-shared.js +0 -121
  331. package/fab/lib/fab-shared.js.map +0 -1
  332. package/slider/lib/_tokens.scss +0 -65
  333. /package/{fab/lib/fab-extended-styles.css.d.ts → chips/lib/filter-styles.css.d.ts} +0 -0
  334. /package/fab/lib/{fab-shared-styles.css.d.ts → fab-branded-styles.css.d.ts} +0 -0
@@ -0,0 +1,587 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { __decorate } from "tslib";
7
+ import '../../menu/menu.js';
8
+ import { html, LitElement, nothing } from 'lit';
9
+ import { property, query, queryAssignedElements, state } from 'lit/decorators.js';
10
+ import { classMap } from 'lit/directives/class-map.js';
11
+ import { html as staticHtml } from 'lit/static-html.js';
12
+ import { List } from '../../list/lib/list.js';
13
+ import { DEFAULT_TYPEAHEAD_BUFFER_TIME } from '../../menu/lib/menu.js';
14
+ import { isElementInSubtree, isSelectableKey } from '../../menu/lib/shared.js';
15
+ import { TYPEAHEAD_RECORD } from '../../menu/lib/typeaheadController.js';
16
+ import { getSelectedItems } from './shared.js';
17
+ /**
18
+ * @fires input Fired when a selection is made by the user via mouse or keyboard
19
+ * interaction.
20
+ * @fires change Fired when a selection is made by the user via mouse or
21
+ * keyboard interaction.
22
+ */
23
+ export class Select extends LitElement {
24
+ constructor() {
25
+ super(...arguments);
26
+ /**
27
+ * Opens the menu synchronously with no animation.
28
+ */
29
+ this.quick = false;
30
+ /**
31
+ * Whether or not the select is required.
32
+ */
33
+ this.required = false;
34
+ /**
35
+ * Disables the select.
36
+ */
37
+ this.disabled = false;
38
+ /**
39
+ * The error message that replaces supporting text when `error` is true. If
40
+ * `errorText` is an empty string, then the supporting text will continue to
41
+ * show.
42
+ *
43
+ * Calling `reportValidity()` will automatically update `errorText` to the
44
+ * native `validationMessage`.
45
+ */
46
+ this.errorText = '';
47
+ /**
48
+ * The floating label for the field.
49
+ */
50
+ this.label = '';
51
+ /**
52
+ * Conveys additional information below the text field, such as how it should
53
+ * be used.
54
+ */
55
+ this.supportingText = '';
56
+ /**
57
+ * Gets or sets whether or not the text field is in a visually invalid state.
58
+ *
59
+ * Calling `reportValidity()` will automatically update `error`.
60
+ */
61
+ this.error = false;
62
+ /**
63
+ * Whether or not the underlying md-menu should be position: fixed to display
64
+ * in a top-level manner.
65
+ */
66
+ this.menuFixed = false;
67
+ /**
68
+ * The max time between the keystrokes of the typeahead select / menu behavior
69
+ * before it clears the typeahead buffer.
70
+ */
71
+ this.typeaheadBufferTime = DEFAULT_TYPEAHEAD_BUFFER_TIME;
72
+ /**
73
+ * Whether or not the text field has a leading icon. Used for SSR.
74
+ */
75
+ this.hasLeadingIcon = false;
76
+ /**
77
+ * Whether or not the text field has a trailing icon. Used for SSR.
78
+ */
79
+ this.hasTrailingIcon = false;
80
+ /**
81
+ * Text to display in the field. Only set for SSR.
82
+ */
83
+ this.displayText = '';
84
+ /**
85
+ * When set to true, the error text's `role="alert"` will be removed, then
86
+ * re-added after an animation frame. This will re-announce an error message
87
+ * to screen readers.
88
+ */
89
+ this.refreshErrorAlert = false;
90
+ this.focused = false;
91
+ this.open = false;
92
+ // tslint:disable-next-line:enforce-name-casing
93
+ this._value = '';
94
+ /**
95
+ * Used for initializing select when the user sets the `value` directly.
96
+ */
97
+ this.lastUserSetValue = null;
98
+ /**
99
+ * Used for initializing select when the user sets the `selectedIndex`
100
+ * directly.
101
+ */
102
+ this.lastUserSetSelectedIndex = null;
103
+ /**
104
+ * Used for `input` and `change` event change detection.
105
+ */
106
+ this.lastSelectedOption = null;
107
+ // tslint:disable-next-line:enforce-name-casing
108
+ this._lastSelectedOptionRecords = [];
109
+ }
110
+ /**
111
+ * The value of the currently selected option.
112
+ *
113
+ * Note: For SSR, set `[selected]` on the requested option and `displayText`
114
+ * rather than setting `value` setting `value` will incur a DOM query.
115
+ */
116
+ get value() {
117
+ return this._value;
118
+ }
119
+ set value(value) {
120
+ this.lastUserSetValue = value;
121
+ this.select(value);
122
+ }
123
+ get options() {
124
+ // NOTE: this does a DOM query.
125
+ return (this.menu?.items ?? []);
126
+ }
127
+ /**
128
+ * The index of the currently selected option.
129
+ *
130
+ * Note: For SSR, set `[selected]` on the requested option and `displayText`
131
+ * rather than setting `selectedIndex` setting `selectedIndex` will incur a
132
+ * DOM query.
133
+ */
134
+ get selectedIndex() {
135
+ // tslint:disable-next-line:enforce-name-casing
136
+ const [_option, index] = (this.getSelectedOptions() ?? [])[0] ?? [];
137
+ return index ?? -1;
138
+ }
139
+ set selectedIndex(index) {
140
+ this.lastUserSetSelectedIndex = index;
141
+ this.selectIndex(index);
142
+ }
143
+ /**
144
+ * Returns an array of selected options.
145
+ *
146
+ * NOTE: md-select only suppoprts single selection.
147
+ */
148
+ get selectedOptions() {
149
+ return (this.getSelectedOptions() ?? []).map(([option]) => option);
150
+ }
151
+ render() {
152
+ return html `
153
+ <span
154
+ class="select ${classMap(this.getRenderClasses())}"
155
+ @focusout=${this.handleFocusout}>
156
+ ${this.renderField()}
157
+ ${this.renderMenu()}
158
+ </span>
159
+ `;
160
+ }
161
+ getRenderClasses() {
162
+ return {
163
+ 'disabled': this.disabled,
164
+ 'error': this.error,
165
+ };
166
+ }
167
+ renderField() {
168
+ return staticHtml `
169
+ <${this.fieldTag}
170
+ aria-haspopup="listbox"
171
+ role="combobox"
172
+ tabindex=${this.disabled ? '-1' : '0'}
173
+ aria-expanded=${this.open ? 'true' : 'false'}
174
+ class="field"
175
+ label=${this.label}
176
+ .focused=${this.focused || this.open}
177
+ .populated=${!!this.displayText}
178
+ .disabled=${this.disabled}
179
+ .required=${this.required}
180
+ .error=${this.error}
181
+ .hasStart=${this.hasLeadingIcon}
182
+ .hasEnd=${this.hasTrailingIcon}
183
+ @keydown =${this.handleKeydown}
184
+ @click=${this.handleClick}
185
+ @focus=${this.handleFocus}
186
+ @blur=${this.handleBlur}>
187
+ ${this.renderFieldContent()}
188
+ </${this.fieldTag}>`;
189
+ }
190
+ renderFieldContent() {
191
+ return [
192
+ this.renderLeadingIcon(),
193
+ this.renderLabel(),
194
+ this.renderTrailingIcon(),
195
+ this.renderSupportingText(),
196
+ ];
197
+ }
198
+ renderLeadingIcon() {
199
+ return html `
200
+ <span class="icon leading" slot="start">
201
+ <slot name="leadingicon" @slotchange=${this.handleIconChange}></slot>
202
+ </span>
203
+ `;
204
+ }
205
+ renderTrailingIcon() {
206
+ return html `
207
+ <span class="icon trailing" slot="end">
208
+ <slot name="trailingicon" @slotchange=${this.handleIconChange}></slot>
209
+ </span>
210
+ `;
211
+ }
212
+ renderLabel() {
213
+ // need to render &nbsp; so that line-height can apply and give it a
214
+ // non-zero height
215
+ return html `<div
216
+ id="label"
217
+ class="label">${this.displayText || html `&nbsp;`}</div>`;
218
+ }
219
+ renderSupportingText() {
220
+ const text = this.getSupportingText();
221
+ if (!text) {
222
+ return nothing;
223
+ }
224
+ return html `<span id="support"
225
+ slot="supporting-text"
226
+ role=${this.shouldErrorAnnounce() ? 'alert' : nothing}>${text}</span>`;
227
+ }
228
+ getSupportingText() {
229
+ return this.error && this.errorText ? this.errorText : this.supportingText;
230
+ }
231
+ shouldErrorAnnounce() {
232
+ // Announce if there is an error and error text visible.
233
+ // If refreshErrorAlert is true, do not announce. This will remove the
234
+ // role="alert" attribute. Another render cycle will happen after an
235
+ // animation frame to re-add the role.
236
+ return this.error && !!this.errorText && !this.refreshErrorAlert;
237
+ }
238
+ renderMenu() {
239
+ return html `
240
+ <md-menu
241
+ id="listbox"
242
+ default-focus="NONE"
243
+ listTabIndex="-1"
244
+ type="listbox"
245
+ stay-open-on-focusout
246
+ .anchor=${this.field}
247
+ .open=${this.open}
248
+ .quick=${this.quick}
249
+ .fixed=${this.menuFixed}
250
+ .typeaheadBufferTime=${this.typeaheadBufferTime}
251
+ @opening=${this.handleOpening}
252
+ @closing=${this.handleClosing}
253
+ @close-menu=${this.handleCloseMenu}
254
+ @request-selection=${this.handleRequestSelection}
255
+ @request-deselection=${this.handleRequestDeselection}>
256
+ ${this.renderMenuContent()}
257
+ </md-menu>`;
258
+ }
259
+ renderMenuContent() {
260
+ return html `<slot></slot>`;
261
+ }
262
+ /**
263
+ * Handles opening the select on keydown and typahead selection when the menu
264
+ * is closed.
265
+ */
266
+ handleKeydown(e) {
267
+ if (this.open || this.disabled) {
268
+ return;
269
+ }
270
+ const typeaheadController = this.menu?.typeaheadController;
271
+ const isOpenKey = e.code === 'Space' || e.code === 'ArrowDown' || e.code === 'Enter';
272
+ // Do not open if currently typing ahead because the user may be typing the
273
+ // spacebar to match a word with a space
274
+ if (!typeaheadController.isTypingAhead && isOpenKey) {
275
+ e.preventDefault();
276
+ this.open = true;
277
+ return;
278
+ }
279
+ const isPrintableKey = e.key.length === 1;
280
+ // Handles typing ahead when the menu is closed by delegating the event to
281
+ // the underlying menu's typeaheadController
282
+ if (isPrintableKey) {
283
+ typeaheadController.onKeydown(e);
284
+ e.preventDefault();
285
+ const { lastActiveRecord } = typeaheadController;
286
+ if (!lastActiveRecord) {
287
+ return;
288
+ }
289
+ const hasChanged = this.selectItem(lastActiveRecord[TYPEAHEAD_RECORD.ITEM]);
290
+ if (hasChanged) {
291
+ this.dispatchInteractionEvents();
292
+ }
293
+ }
294
+ }
295
+ handleClick() {
296
+ this.open = true;
297
+ }
298
+ handleFocus() {
299
+ this.focused = true;
300
+ }
301
+ handleBlur() {
302
+ this.focused = false;
303
+ }
304
+ /**
305
+ * Handles closing the menu when the focus leaves the select's subtree.
306
+ */
307
+ handleFocusout(e) {
308
+ // Don't close the menu if we are switching focus between menu,
309
+ // select-option, and field
310
+ if (e.relatedTarget && isElementInSubtree(e.relatedTarget, this)) {
311
+ return;
312
+ }
313
+ this.open = false;
314
+ }
315
+ /**
316
+ * Gets a list of all selected select options as a list item record array.
317
+ *
318
+ * @return An array of selected list option records.
319
+ */
320
+ getSelectedOptions() {
321
+ if (!this.menu) {
322
+ this._lastSelectedOptionRecords = [];
323
+ return null;
324
+ }
325
+ const items = this.menu.items;
326
+ this._lastSelectedOptionRecords = getSelectedItems(items);
327
+ return this._lastSelectedOptionRecords;
328
+ }
329
+ async getUpdateComplete() {
330
+ await this.menu?.updateComplete;
331
+ return super.getUpdateComplete();
332
+ }
333
+ /**
334
+ * Gets the selected options from the DOM, and updates the value and display
335
+ * text to the first selected option's value and headline respectively.
336
+ *
337
+ * @return Whether or not the selected option has changed since last update.
338
+ */
339
+ updateValueAndDisplayText() {
340
+ const selectedOptions = this.getSelectedOptions() ?? [];
341
+ // Used to determine whether or not we need to fire an input / change event
342
+ // which fire whenever the option element changes (value or selectedIndex)
343
+ // on user interaction.
344
+ let hasSelectedOptionChanged = false;
345
+ if (selectedOptions.length) {
346
+ const [firstSelectedOption] = selectedOptions[0];
347
+ hasSelectedOptionChanged =
348
+ this.lastSelectedOption !== firstSelectedOption;
349
+ this.lastSelectedOption = firstSelectedOption;
350
+ this._value = firstSelectedOption.value;
351
+ this.displayText = firstSelectedOption.headline;
352
+ }
353
+ else {
354
+ hasSelectedOptionChanged = this.lastSelectedOption !== null;
355
+ this.lastSelectedOption = null;
356
+ this._value = '';
357
+ this.displayText = '';
358
+ }
359
+ return hasSelectedOptionChanged;
360
+ }
361
+ update(changed) {
362
+ // In SSR the options will be ready to query, so try to figure out what
363
+ // the value and display text should be.
364
+ if (!this.hasUpdated) {
365
+ this.initUserSelection();
366
+ }
367
+ super.update(changed);
368
+ }
369
+ async firstUpdated(changed) {
370
+ await this.menu.updateComplete;
371
+ // If this has been handled on update already due to SSR, try again.
372
+ if (!this._lastSelectedOptionRecords.length) {
373
+ this.initUserSelection();
374
+ }
375
+ super.firstUpdated(changed);
376
+ }
377
+ updated(changedProperties) {
378
+ // Keep changedProperties arg so that subclasses may call it
379
+ if (this.refreshErrorAlert) {
380
+ // The past render cycle removed the role="alert" from the error message.
381
+ // Re-add it after an animation frame to re-announce the error.
382
+ requestAnimationFrame(() => {
383
+ this.refreshErrorAlert = false;
384
+ });
385
+ }
386
+ }
387
+ /**
388
+ * Focuses and activates the last selected item upon opening, and resets other
389
+ * active items.
390
+ */
391
+ async handleOpening() {
392
+ const items = this.menu.items;
393
+ const activeItem = List.getActiveItem(items)?.item;
394
+ const [selectedItem] = this._lastSelectedOptionRecords[0] ?? [null];
395
+ // This is true if the user keys through the list but clicks out of the menu
396
+ // thus no close-menu event is fired by an item and we can't clean up in
397
+ // handleCloseMenu.
398
+ if (activeItem && activeItem !== selectedItem) {
399
+ activeItem.active = false;
400
+ }
401
+ if (selectedItem) {
402
+ selectedItem.active = true;
403
+ selectedItem.focus();
404
+ }
405
+ }
406
+ handleClosing() {
407
+ this.open = false;
408
+ }
409
+ /**
410
+ * Determines the reason for closing, and updates the UI accordingly.
411
+ */
412
+ handleCloseMenu(e) {
413
+ const reason = e.reason;
414
+ const item = e.itemPath[0];
415
+ this.open = false;
416
+ let hasChanged = false;
417
+ if (reason.kind === 'CLICK_SELECTION') {
418
+ hasChanged = this.selectItem(item);
419
+ }
420
+ else if (reason.kind === 'KEYDOWN' && isSelectableKey(reason.key)) {
421
+ hasChanged = this.selectItem(item);
422
+ }
423
+ else {
424
+ // This can happen on ESC being pressed
425
+ item.active = false;
426
+ item.blur();
427
+ }
428
+ // Dispatch interaction events since selection has been made via keyboard
429
+ // or mouse.
430
+ if (hasChanged) {
431
+ this.dispatchInteractionEvents();
432
+ }
433
+ }
434
+ /**
435
+ * Selects a given option, deselects other options, and updates the UI.
436
+ *
437
+ * @return Whether the last selected option has changed.
438
+ */
439
+ selectItem(item) {
440
+ this._lastSelectedOptionRecords.forEach(([option]) => {
441
+ if (item !== option) {
442
+ option.selected = false;
443
+ }
444
+ });
445
+ item.selected = true;
446
+ return this.updateValueAndDisplayText();
447
+ }
448
+ /**
449
+ * Handles updating selection when an option element requests selection via
450
+ * property / attribute change.
451
+ */
452
+ handleRequestSelection(e) {
453
+ const requestingOptionEl = e.target;
454
+ // No-op if this item is already selected.
455
+ if (this._lastSelectedOptionRecords.some(([option]) => option === requestingOptionEl)) {
456
+ return;
457
+ }
458
+ this.selectItem(requestingOptionEl);
459
+ }
460
+ /**
461
+ * Handles updating selection when an option element requests deselection via
462
+ * property / attribute change.
463
+ */
464
+ handleRequestDeselection(e) {
465
+ const requestingOptionEl = e.target;
466
+ // No-op if this item is not even in the list of tracked selected items.
467
+ if (!this._lastSelectedOptionRecords.some(([option]) => option === requestingOptionEl)) {
468
+ return;
469
+ }
470
+ this.updateValueAndDisplayText();
471
+ }
472
+ /**
473
+ * Selects an option given the value of the option, and updates MdSelect's
474
+ * value.
475
+ */
476
+ select(value) {
477
+ const optionToSelect = this.options.find(option => option.value === value);
478
+ if (optionToSelect) {
479
+ this.selectItem(optionToSelect);
480
+ }
481
+ }
482
+ /**
483
+ * Selects an option given the index of the option, and updates MdSelect's
484
+ * value.
485
+ */
486
+ selectIndex(index) {
487
+ const optionToSelect = this.options[index];
488
+ if (optionToSelect) {
489
+ this.selectItem(optionToSelect);
490
+ }
491
+ }
492
+ /**
493
+ * Attempts to initialize the selected option from user-settable values like
494
+ * SSR, setting `value`, or `selectedIndex` at startup.
495
+ */
496
+ initUserSelection() {
497
+ // User has set `.value` directly, but internals have not yet booted up.
498
+ if (this.lastUserSetValue && !this._lastSelectedOptionRecords.length) {
499
+ this.select(this.lastUserSetValue);
500
+ // User has set `.selectedIndex` directly, but internals have not yet
501
+ // booted up.
502
+ }
503
+ else if (this.lastUserSetSelectedIndex !== null &&
504
+ !this._lastSelectedOptionRecords.length) {
505
+ this.selectIndex(this.lastUserSetSelectedIndex);
506
+ // Regular boot up!
507
+ }
508
+ else {
509
+ this.updateValueAndDisplayText();
510
+ }
511
+ }
512
+ handleIconChange() {
513
+ this.hasLeadingIcon = this.leadingIcons.length > 0;
514
+ this.hasTrailingIcon = this.trailingIcons.length > 0;
515
+ }
516
+ /**
517
+ * Dispatches the `input` and `change` events.
518
+ */
519
+ dispatchInteractionEvents() {
520
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
521
+ this.dispatchEvent(new Event('change', { bubbles: true }));
522
+ }
523
+ }
524
+ __decorate([
525
+ property({ type: Boolean })
526
+ ], Select.prototype, "quick", void 0);
527
+ __decorate([
528
+ property({ type: Boolean })
529
+ ], Select.prototype, "required", void 0);
530
+ __decorate([
531
+ property({ type: Boolean, reflect: true })
532
+ ], Select.prototype, "disabled", void 0);
533
+ __decorate([
534
+ property({ type: String })
535
+ ], Select.prototype, "errorText", void 0);
536
+ __decorate([
537
+ property()
538
+ ], Select.prototype, "label", void 0);
539
+ __decorate([
540
+ property({ type: String })
541
+ ], Select.prototype, "supportingText", void 0);
542
+ __decorate([
543
+ property({ type: Boolean, reflect: true })
544
+ ], Select.prototype, "error", void 0);
545
+ __decorate([
546
+ property({ type: Boolean })
547
+ ], Select.prototype, "menuFixed", void 0);
548
+ __decorate([
549
+ property({ type: Number })
550
+ ], Select.prototype, "typeaheadBufferTime", void 0);
551
+ __decorate([
552
+ property({ type: Boolean })
553
+ ], Select.prototype, "hasLeadingIcon", void 0);
554
+ __decorate([
555
+ property({ type: Boolean })
556
+ ], Select.prototype, "hasTrailingIcon", void 0);
557
+ __decorate([
558
+ property()
559
+ ], Select.prototype, "displayText", void 0);
560
+ __decorate([
561
+ state()
562
+ ], Select.prototype, "refreshErrorAlert", void 0);
563
+ __decorate([
564
+ state()
565
+ ], Select.prototype, "focused", void 0);
566
+ __decorate([
567
+ state()
568
+ ], Select.prototype, "open", void 0);
569
+ __decorate([
570
+ query('.field')
571
+ ], Select.prototype, "field", void 0);
572
+ __decorate([
573
+ query('md-menu')
574
+ ], Select.prototype, "menu", void 0);
575
+ __decorate([
576
+ queryAssignedElements({ slot: 'leadingicon', flatten: true })
577
+ ], Select.prototype, "leadingIcons", void 0);
578
+ __decorate([
579
+ queryAssignedElements({ slot: 'trailingicon', flatten: true })
580
+ ], Select.prototype, "trailingIcons", void 0);
581
+ __decorate([
582
+ property()
583
+ ], Select.prototype, "value", null);
584
+ __decorate([
585
+ property({ type: Number })
586
+ ], Select.prototype, "selectedIndex", null);
587
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../menu/menu.js';\n\nimport {html, LitElement, nothing, PropertyValues, TemplateResult} from 'lit';\nimport {property, query, queryAssignedElements, state} from 'lit/decorators.js';\nimport {ClassInfo, classMap} from 'lit/directives/class-map.js';\nimport {html as staticHtml, StaticValue} from 'lit/static-html.js';\n\nimport {Field} from '../../field/lib/field.js';\nimport {List} from '../../list/lib/list.js';\nimport {DEFAULT_TYPEAHEAD_BUFFER_TIME, Menu} from '../../menu/lib/menu.js';\nimport {DefaultCloseMenuEvent, isElementInSubtree, isSelectableKey} from '../../menu/lib/shared.js';\nimport {TYPEAHEAD_RECORD} from '../../menu/lib/typeaheadController.js';\n\nimport {getSelectedItems, RequestDeselectionEvent, RequestSelectionEvent, SelectOption, SelectOptionRecord} from './shared.js';\n\n/**\n * @fires input Fired when a selection is made by the user via mouse or keyboard\n * interaction.\n * @fires change Fired when a selection is made by the user via mouse or\n * keyboard interaction.\n */\nexport abstract class Select extends LitElement {\n /**\n * Opens the menu synchronously with no animation.\n */\n @property({type: Boolean}) quick = false;\n /**\n * Whether or not the select is required.\n */\n @property({type: Boolean}) required = false;\n /**\n * Disables the select.\n */\n @property({type: Boolean, reflect: true}) disabled = false;\n /**\n * The error message that replaces supporting text when `error` is true. If\n * `errorText` is an empty string, then the supporting text will continue to\n * show.\n *\n * Calling `reportValidity()` will automatically update `errorText` to the\n * native `validationMessage`.\n */\n @property({type: String}) errorText = '';\n /**\n * The floating label for the field.\n */\n @property() label = '';\n /**\n * Conveys additional information below the text field, such as how it should\n * be used.\n */\n @property({type: String}) supportingText = '';\n /**\n * Gets or sets whether or not the text field is in a visually invalid state.\n *\n * Calling `reportValidity()` will automatically update `error`.\n */\n @property({type: Boolean, reflect: true}) error = false;\n /**\n * Whether or not the underlying md-menu should be position: fixed to display\n * in a top-level manner.\n */\n @property({type: Boolean}) menuFixed = false;\n /**\n * The max time between the keystrokes of the typeahead select / menu behavior\n * before it clears the typeahead buffer.\n */\n @property({type: Number}) typeaheadBufferTime = DEFAULT_TYPEAHEAD_BUFFER_TIME;\n /**\n * Whether or not the text field has a leading icon. Used for SSR.\n */\n @property({type: Boolean}) hasLeadingIcon = false;\n /**\n * Whether or not the text field has a trailing icon. Used for SSR.\n */\n @property({type: Boolean}) hasTrailingIcon = false;\n /**\n * Text to display in the field. Only set for SSR.\n */\n @property() displayText = '';\n /**\n * When set to true, the error text's `role=\"alert\"` will be removed, then\n * re-added after an animation frame. This will re-announce an error message\n * to screen readers.\n */\n @state() protected refreshErrorAlert = false;\n @state() protected focused = false;\n @state() protected open = false;\n @query('.field') protected field!: Field;\n @query('md-menu') protected menu!: Menu;\n @queryAssignedElements({slot: 'leadingicon', flatten: true})\n protected readonly leadingIcons!: Element[];\n @queryAssignedElements({slot: 'trailingicon', flatten: true})\n protected readonly trailingIcons!: Element[];\n\n /**\n * The value of the currently selected option.\n *\n * Note: For SSR, set `[selected]` on the requested option and `displayText`\n * rather than setting `value` setting `value` will incur a DOM query.\n */\n @property()\n get value(): string {\n return this._value;\n }\n\n set value(value: string) {\n this.lastUserSetValue = value;\n this.select(value);\n }\n\n get options() {\n // NOTE: this does a DOM query.\n return (this.menu?.items ?? []) as SelectOption[];\n }\n\n /**\n * The index of the currently selected option.\n *\n * Note: For SSR, set `[selected]` on the requested option and `displayText`\n * rather than setting `selectedIndex` setting `selectedIndex` will incur a\n * DOM query.\n */\n @property({type: Number})\n get selectedIndex(): number {\n // tslint:disable-next-line:enforce-name-casing\n const [_option, index] = (this.getSelectedOptions() ?? [])[0] ?? [];\n return index ?? -1;\n }\n\n set selectedIndex(index: number) {\n this.lastUserSetSelectedIndex = index;\n this.selectIndex(index);\n }\n\n /**\n * Returns an array of selected options.\n *\n * NOTE: md-select only suppoprts single selection.\n */\n get selectedOptions() {\n return (this.getSelectedOptions() ?? []).map(([option]) => option);\n }\n\n protected abstract readonly fieldTag: StaticValue;\n // tslint:disable-next-line:enforce-name-casing\n protected _value = '';\n\n /**\n * Used for initializing select when the user sets the `value` directly.\n */\n protected lastUserSetValue: string|null = null;\n\n /**\n * Used for initializing select when the user sets the `selectedIndex`\n * directly.\n */\n protected lastUserSetSelectedIndex: number|null = null;\n\n /**\n * Used for `input` and `change` event change detection.\n */\n protected lastSelectedOption: SelectOption|null = null;\n\n // tslint:disable-next-line:enforce-name-casing\n protected _lastSelectedOptionRecords: SelectOptionRecord[] = [];\n\n override render(): TemplateResult {\n return html`\n <span\n class=\"select ${classMap(this.getRenderClasses())}\"\n @focusout=${this.handleFocusout}>\n ${this.renderField()}\n ${this.renderMenu()}\n </span>\n `;\n }\n\n protected getRenderClasses(): ClassInfo {\n return {\n 'disabled': this.disabled,\n 'error': this.error,\n };\n }\n\n protected renderField() {\n return staticHtml`\n <${this.fieldTag}\n aria-haspopup=\"listbox\"\n role=\"combobox\"\n tabindex=${this.disabled ? '-1' : '0'}\n aria-expanded=${this.open ? 'true' : 'false'}\n class=\"field\"\n label=${this.label}\n .focused=${this.focused || this.open}\n .populated=${!!this.displayText}\n .disabled=${this.disabled}\n .required=${this.required}\n .error=${this.error}\n .hasStart=${this.hasLeadingIcon}\n .hasEnd=${this.hasTrailingIcon}\n @keydown =${this.handleKeydown}\n @click=${this.handleClick}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}>\n ${this.renderFieldContent()}\n </${this.fieldTag}>`;\n }\n\n protected renderFieldContent() {\n return [\n this.renderLeadingIcon(),\n this.renderLabel(),\n this.renderTrailingIcon(),\n this.renderSupportingText(),\n ];\n }\n\n protected renderLeadingIcon() {\n return html`\n <span class=\"icon leading\" slot=\"start\">\n <slot name=\"leadingicon\" @slotchange=${this.handleIconChange}></slot>\n </span>\n `;\n }\n\n protected renderTrailingIcon() {\n return html`\n <span class=\"icon trailing\" slot=\"end\">\n <slot name=\"trailingicon\" @slotchange=${this.handleIconChange}></slot>\n </span>\n `;\n }\n\n protected renderLabel() {\n // need to render &nbsp; so that line-height can apply and give it a\n // non-zero height\n return html`<div\n id=\"label\"\n class=\"label\">${this.displayText || html`&nbsp;`}</div>`;\n }\n\n protected renderSupportingText() {\n const text = this.getSupportingText();\n if (!text) {\n return nothing;\n }\n\n return html`<span id=\"support\"\n slot=\"supporting-text\"\n role=${this.shouldErrorAnnounce() ? 'alert' : nothing}>${text}</span>`;\n }\n\n protected getSupportingText() {\n return this.error && this.errorText ? this.errorText : this.supportingText;\n }\n\n protected shouldErrorAnnounce() {\n // Announce if there is an error and error text visible.\n // If refreshErrorAlert is true, do not announce. This will remove the\n // role=\"alert\" attribute. Another render cycle will happen after an\n // animation frame to re-add the role.\n return this.error && !!this.errorText && !this.refreshErrorAlert;\n }\n\n protected renderMenu(): TemplateResult {\n return html`\n <md-menu\n id=\"listbox\"\n default-focus=\"NONE\"\n listTabIndex=\"-1\"\n type=\"listbox\"\n stay-open-on-focusout\n .anchor=${this.field}\n .open=${this.open}\n .quick=${this.quick}\n .fixed=${this.menuFixed}\n .typeaheadBufferTime=${this.typeaheadBufferTime}\n @opening=${this.handleOpening}\n @closing=${this.handleClosing}\n @close-menu=${this.handleCloseMenu}\n @request-selection=${this.handleRequestSelection}\n @request-deselection=${this.handleRequestDeselection}>\n ${this.renderMenuContent()}\n </md-menu>`;\n }\n\n protected renderMenuContent(): TemplateResult {\n return html`<slot></slot>`;\n }\n\n /**\n * Handles opening the select on keydown and typahead selection when the menu\n * is closed.\n */\n protected handleKeydown(e: KeyboardEvent) {\n if (this.open || this.disabled) {\n return;\n }\n\n const typeaheadController = this.menu?.typeaheadController;\n const isOpenKey =\n e.code === 'Space' || e.code === 'ArrowDown' || e.code === 'Enter';\n\n // Do not open if currently typing ahead because the user may be typing the\n // spacebar to match a word with a space\n if (!typeaheadController.isTypingAhead && isOpenKey) {\n e.preventDefault();\n this.open = true;\n return;\n }\n\n const isPrintableKey = e.key.length === 1;\n\n // Handles typing ahead when the menu is closed by delegating the event to\n // the underlying menu's typeaheadController\n if (isPrintableKey) {\n typeaheadController.onKeydown(e);\n e.preventDefault();\n\n const {lastActiveRecord} = typeaheadController;\n\n if (!lastActiveRecord) {\n return;\n }\n\n const hasChanged = this.selectItem(\n lastActiveRecord[TYPEAHEAD_RECORD.ITEM] as SelectOption);\n\n if (hasChanged) {\n this.dispatchInteractionEvents();\n }\n }\n }\n\n protected handleClick() {\n this.open = true;\n }\n\n protected handleFocus() {\n this.focused = true;\n }\n\n protected handleBlur() {\n this.focused = false;\n }\n\n /**\n * Handles closing the menu when the focus leaves the select's subtree.\n */\n protected handleFocusout(e: FocusEvent) {\n // Don't close the menu if we are switching focus between menu,\n // select-option, and field\n if (e.relatedTarget && isElementInSubtree(e.relatedTarget, this)) {\n return;\n }\n\n this.open = false;\n }\n\n /**\n * Gets a list of all selected select options as a list item record array.\n *\n * @return An array of selected list option records.\n */\n protected getSelectedOptions() {\n if (!this.menu) {\n this._lastSelectedOptionRecords = [];\n return null;\n }\n\n const items = this.menu.items as SelectOption[];\n this._lastSelectedOptionRecords = getSelectedItems(items);\n return this._lastSelectedOptionRecords;\n }\n\n override async getUpdateComplete() {\n await this.menu?.updateComplete;\n return super.getUpdateComplete();\n }\n\n /**\n * Gets the selected options from the DOM, and updates the value and display\n * text to the first selected option's value and headline respectively.\n *\n * @return Whether or not the selected option has changed since last update.\n */\n protected updateValueAndDisplayText() {\n const selectedOptions = this.getSelectedOptions() ?? [];\n // Used to determine whether or not we need to fire an input / change event\n // which fire whenever the option element changes (value or selectedIndex)\n // on user interaction.\n let hasSelectedOptionChanged = false;\n\n if (selectedOptions.length) {\n const [firstSelectedOption] = selectedOptions[0];\n hasSelectedOptionChanged =\n this.lastSelectedOption !== firstSelectedOption;\n this.lastSelectedOption = firstSelectedOption;\n this._value = firstSelectedOption.value;\n this.displayText = firstSelectedOption.headline;\n\n } else {\n hasSelectedOptionChanged = this.lastSelectedOption !== null;\n this.lastSelectedOption = null;\n this._value = '';\n this.displayText = '';\n }\n\n return hasSelectedOptionChanged;\n }\n\n override update(changed: PropertyValues<this>) {\n // In SSR the options will be ready to query, so try to figure out what\n // the value and display text should be.\n if (!this.hasUpdated) {\n this.initUserSelection();\n }\n\n super.update(changed);\n }\n\n override async firstUpdated(changed: PropertyValues<this>) {\n await this.menu.updateComplete;\n // If this has been handled on update already due to SSR, try again.\n if (!this._lastSelectedOptionRecords.length) {\n this.initUserSelection();\n }\n\n super.firstUpdated(changed);\n }\n\n protected override updated(changedProperties: PropertyValues) {\n // Keep changedProperties arg so that subclasses may call it\n\n if (this.refreshErrorAlert) {\n // The past render cycle removed the role=\"alert\" from the error message.\n // Re-add it after an animation frame to re-announce the error.\n requestAnimationFrame(() => {\n this.refreshErrorAlert = false;\n });\n }\n }\n\n /**\n * Focuses and activates the last selected item upon opening, and resets other\n * active items.\n */\n protected async handleOpening() {\n const items = this.menu.items;\n const activeItem = List.getActiveItem(items)?.item;\n const [selectedItem] = this._lastSelectedOptionRecords[0] ?? [null];\n\n // This is true if the user keys through the list but clicks out of the menu\n // thus no close-menu event is fired by an item and we can't clean up in\n // handleCloseMenu.\n if (activeItem && activeItem !== selectedItem) {\n activeItem.active = false;\n }\n\n if (selectedItem) {\n selectedItem.active = true;\n selectedItem.focus();\n }\n }\n\n protected handleClosing() {\n this.open = false;\n }\n\n /**\n * Determines the reason for closing, and updates the UI accordingly.\n */\n protected handleCloseMenu(e: InstanceType<typeof DefaultCloseMenuEvent>) {\n const reason = e.reason;\n const item = e.itemPath[0] as SelectOption;\n this.open = false;\n let hasChanged = false;\n\n if (reason.kind === 'CLICK_SELECTION') {\n hasChanged = this.selectItem(item);\n } else if (reason.kind === 'KEYDOWN' && isSelectableKey(reason.key)) {\n hasChanged = this.selectItem(item);\n } else {\n // This can happen on ESC being pressed\n item.active = false;\n item.blur();\n }\n\n // Dispatch interaction events since selection has been made via keyboard\n // or mouse.\n if (hasChanged) {\n this.dispatchInteractionEvents();\n }\n }\n\n /**\n * Selects a given option, deselects other options, and updates the UI.\n *\n * @return Whether the last selected option has changed.\n */\n protected selectItem(item: SelectOption) {\n this._lastSelectedOptionRecords.forEach(([option]) => {\n if (item !== option) {\n option.selected = false;\n }\n });\n item.selected = true;\n\n return this.updateValueAndDisplayText();\n }\n\n /**\n * Handles updating selection when an option element requests selection via\n * property / attribute change.\n */\n protected handleRequestSelection(e: RequestSelectionEvent) {\n const requestingOptionEl = e.target as SelectOption & HTMLElement;\n\n // No-op if this item is already selected.\n if (this._lastSelectedOptionRecords.some(\n ([option]) => option === requestingOptionEl)) {\n return;\n }\n\n this.selectItem(requestingOptionEl);\n }\n\n /**\n * Handles updating selection when an option element requests deselection via\n * property / attribute change.\n */\n protected handleRequestDeselection(e: RequestDeselectionEvent) {\n const requestingOptionEl = e.target as SelectOption & HTMLElement;\n\n // No-op if this item is not even in the list of tracked selected items.\n if (!this._lastSelectedOptionRecords.some(\n ([option]) => option === requestingOptionEl)) {\n return;\n }\n\n this.updateValueAndDisplayText();\n }\n\n /**\n * Selects an option given the value of the option, and updates MdSelect's\n * value.\n */\n select(value: string) {\n const optionToSelect = this.options.find(option => option.value === value);\n if (optionToSelect) {\n this.selectItem(optionToSelect);\n }\n }\n\n /**\n * Selects an option given the index of the option, and updates MdSelect's\n * value.\n */\n selectIndex(index: number) {\n const optionToSelect = this.options[index];\n if (optionToSelect) {\n this.selectItem(optionToSelect);\n }\n }\n\n /**\n * Attempts to initialize the selected option from user-settable values like\n * SSR, setting `value`, or `selectedIndex` at startup.\n */\n protected initUserSelection() {\n // User has set `.value` directly, but internals have not yet booted up.\n if (this.lastUserSetValue && !this._lastSelectedOptionRecords.length) {\n this.select(this.lastUserSetValue);\n\n // User has set `.selectedIndex` directly, but internals have not yet\n // booted up.\n } else if (\n this.lastUserSetSelectedIndex !== null &&\n !this._lastSelectedOptionRecords.length) {\n this.selectIndex(this.lastUserSetSelectedIndex);\n\n // Regular boot up!\n } else {\n this.updateValueAndDisplayText();\n }\n }\n\n protected handleIconChange() {\n this.hasLeadingIcon = this.leadingIcons.length > 0;\n this.hasTrailingIcon = this.trailingIcons.length > 0;\n }\n\n /**\n * Dispatches the `input` and `change` events.\n */\n protected dispatchInteractionEvents() {\n this.dispatchEvent(new Event('input', {bubbles: true, composed: true}));\n this.dispatchEvent(new Event('change', {bubbles: true}));\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { ListItemHarness } from '../../../list/lib/listitem/harness.js';
7
+ /**
8
+ * Test harness for menu item.
9
+ */
10
+ export declare class SelectOptionHarness extends ListItemHarness {
11
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { ListItemHarness } from '../../../list/lib/listitem/harness.js';
7
+ /**
8
+ * Test harness for menu item.
9
+ */
10
+ export class SelectOptionHarness extends ListItemHarness {
11
+ }
12
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["harness.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,eAAe,EAAC,MAAM,uCAAuC,CAAC;AAEtE;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;CAAG","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ListItemHarness} from '../../../list/lib/listitem/harness.js';\n\n/**\n * Test harness for menu item.\n */\nexport class SelectOptionHarness extends ListItemHarness {}\n"]}