@material/web 1.0.0-pre.16 → 1.0.0-pre.17

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 (291) hide show
  1. package/README.md +5 -5
  2. package/all.d.ts +4 -2
  3. package/all.js +4 -2
  4. package/all.js.map +1 -1
  5. package/button/internal/_elevation.scss +4 -0
  6. package/button/internal/_shared.scss +5 -1
  7. package/button/internal/elevated-styles.css.js +1 -1
  8. package/button/internal/elevated-styles.css.js.map +1 -1
  9. package/button/internal/filled-styles.css.js +1 -1
  10. package/button/internal/filled-styles.css.js.map +1 -1
  11. package/button/internal/filled-tonal-styles.css.js +1 -1
  12. package/button/internal/filled-tonal-styles.css.js.map +1 -1
  13. package/button/internal/outlined-styles.css.js +1 -1
  14. package/button/internal/outlined-styles.css.js.map +1 -1
  15. package/button/internal/shared-elevation-styles.css.js +1 -1
  16. package/button/internal/shared-elevation-styles.css.js.map +1 -1
  17. package/button/internal/shared-styles.css.js +1 -1
  18. package/button/internal/shared-styles.css.js.map +1 -1
  19. package/button/internal/text-styles.css.js +1 -1
  20. package/button/internal/text-styles.css.js.map +1 -1
  21. package/checkbox/internal/_checkbox.scss +1 -1
  22. package/checkbox/internal/checkbox-styles.css.js +1 -1
  23. package/checkbox/internal/checkbox-styles.css.js.map +1 -1
  24. package/chips/internal/_elevated.scss +0 -4
  25. package/chips/internal/_shared.scss +10 -1
  26. package/chips/internal/assist-chip.d.ts +3 -1
  27. package/chips/internal/assist-chip.js +11 -8
  28. package/chips/internal/assist-chip.js.map +1 -1
  29. package/chips/internal/assist-styles.css.js +1 -1
  30. package/chips/internal/assist-styles.css.js.map +1 -1
  31. package/chips/internal/chip.d.ts +18 -10
  32. package/chips/internal/chip.js +38 -33
  33. package/chips/internal/chip.js.map +1 -1
  34. package/chips/internal/elevated-styles.css.js +1 -1
  35. package/chips/internal/elevated-styles.css.js.map +1 -1
  36. package/chips/internal/filter-chip.d.ts +6 -7
  37. package/chips/internal/filter-chip.js +13 -14
  38. package/chips/internal/filter-chip.js.map +1 -1
  39. package/chips/internal/filter-styles.css.js +1 -1
  40. package/chips/internal/filter-styles.css.js.map +1 -1
  41. package/chips/internal/input-chip.d.ts +4 -2
  42. package/chips/internal/input-chip.js +16 -12
  43. package/chips/internal/input-chip.js.map +1 -1
  44. package/chips/internal/input-styles.css.js +1 -1
  45. package/chips/internal/input-styles.css.js.map +1 -1
  46. package/chips/internal/multi-action-chip.d.ts +2 -3
  47. package/chips/internal/multi-action-chip.js +3 -3
  48. package/chips/internal/multi-action-chip.js.map +1 -1
  49. package/chips/internal/shared-styles.css.js +1 -1
  50. package/chips/internal/shared-styles.css.js.map +1 -1
  51. package/chips/internal/suggestion-styles.css.js +1 -1
  52. package/chips/internal/suggestion-styles.css.js.map +1 -1
  53. package/color/_color.scss +193 -0
  54. package/common.d.ts +2 -2
  55. package/common.js +2 -2
  56. package/common.js.map +1 -1
  57. package/dialog/internal/_dialog.scss +19 -4
  58. package/dialog/internal/dialog-styles.css.js +1 -1
  59. package/dialog/internal/dialog-styles.css.js.map +1 -1
  60. package/dialog/internal/dialog.d.ts +6 -0
  61. package/dialog/internal/dialog.js +36 -4
  62. package/dialog/internal/dialog.js.map +1 -1
  63. package/elevation/internal/elevation.d.ts +1 -0
  64. package/elevation/internal/elevation.js +6 -0
  65. package/elevation/internal/elevation.js.map +1 -1
  66. package/fab/internal/_shared.scss +4 -1
  67. package/fab/internal/fab-branded-styles.css.js +1 -1
  68. package/fab/internal/fab-branded-styles.css.js.map +1 -1
  69. package/fab/internal/fab-styles.css.js +1 -1
  70. package/fab/internal/fab-styles.css.js.map +1 -1
  71. package/fab/internal/shared-styles.css.js +1 -1
  72. package/fab/internal/shared-styles.css.js.map +1 -1
  73. package/field/internal/_content.scss +9 -1
  74. package/field/internal/_filled-field.scss +12 -0
  75. package/field/internal/_label.scss +4 -1
  76. package/field/internal/_outlined-field.scss +33 -0
  77. package/field/internal/_shared.scss +14 -6
  78. package/field/internal/_supporting-text.scss +4 -1
  79. package/field/internal/field.d.ts +2 -0
  80. package/field/internal/field.js +19 -0
  81. package/field/internal/field.js.map +1 -1
  82. package/field/internal/filled-styles.css.js +1 -1
  83. package/field/internal/filled-styles.css.js.map +1 -1
  84. package/field/internal/outlined-styles.css.js +1 -1
  85. package/field/internal/outlined-styles.css.js.map +1 -1
  86. package/field/internal/shared-styles.css.js +1 -1
  87. package/field/internal/shared-styles.css.js.map +1 -1
  88. package/focus/internal/focus-ring.d.ts +3 -1
  89. package/focus/internal/focus-ring.js +9 -0
  90. package/focus/internal/focus-ring.js.map +1 -1
  91. package/icon/internal/icon.js +4 -0
  92. package/icon/internal/icon.js.map +1 -1
  93. package/iconbutton/internal/_icon-button.scss +8 -0
  94. package/iconbutton/internal/icon-button.d.ts +3 -3
  95. package/iconbutton/internal/icon-button.js +4 -4
  96. package/iconbutton/internal/icon-button.js.map +1 -1
  97. package/iconbutton/internal/standard-styles.css.js +1 -1
  98. package/iconbutton/internal/standard-styles.css.js.map +1 -1
  99. package/internal/aria/aria.d.ts +52 -1
  100. package/internal/aria/aria.js +146 -0
  101. package/internal/aria/aria.js.map +1 -1
  102. package/internal/controller/attachable-controller.d.ts +5 -4
  103. package/internal/controller/attachable-controller.js +8 -0
  104. package/internal/controller/attachable-controller.js.map +1 -1
  105. package/labs/badge/internal/_badge.scss +5 -1
  106. package/labs/badge/internal/badge-styles.css.js +1 -1
  107. package/labs/badge/internal/badge-styles.css.js.map +1 -1
  108. package/labs/navigationbar/internal/navigation-bar-styles.css.js +1 -1
  109. package/labs/navigationbar/internal/navigation-bar-styles.css.js.map +1 -1
  110. package/labs/navigationtab/internal/_navigation-tab.scss +4 -1
  111. package/labs/navigationtab/internal/navigation-tab-styles.css.js +1 -1
  112. package/labs/navigationtab/internal/navigation-tab-styles.css.js.map +1 -1
  113. package/labs/segmentedbutton/internal/_shared.scss +4 -1
  114. package/labs/segmentedbutton/internal/outlined-styles.css.js +1 -1
  115. package/labs/segmentedbutton/internal/outlined-styles.css.js.map +1 -1
  116. package/labs/segmentedbutton/internal/shared-styles.css.js +1 -1
  117. package/labs/segmentedbutton/internal/shared-styles.css.js.map +1 -1
  118. package/labs/segmentedbuttonset/internal/outlined-styles.css.js +1 -1
  119. package/labs/segmentedbuttonset/internal/outlined-styles.css.js.map +1 -1
  120. package/list/harness.js +1 -1
  121. package/list/harness.js.map +1 -1
  122. package/list/internal/_list.scss +1 -4
  123. package/list/internal/list-styles.css.js +1 -1
  124. package/list/internal/list-styles.css.js.map +1 -1
  125. package/list/internal/list.d.ts +1 -2
  126. package/list/internal/list.js +4 -6
  127. package/list/internal/list.js.map +1 -1
  128. package/list/internal/listitem/_list-item.scss +17 -5
  129. package/list/internal/listitem/list-item-styles.css.js +1 -1
  130. package/list/internal/listitem/list-item-styles.css.js.map +1 -1
  131. package/menu/harness.d.ts +1 -1
  132. package/menu/harness.js +3 -4
  133. package/menu/harness.js.map +1 -1
  134. package/menu/internal/_menu.scss +32 -26
  135. package/menu/internal/menu-styles.css.js +1 -1
  136. package/menu/internal/menu-styles.css.js.map +1 -1
  137. package/menu/internal/menu.d.ts +15 -4
  138. package/menu/internal/menu.js +27 -4
  139. package/menu/internal/menu.js.map +1 -1
  140. package/menu/internal/menuitem/menu-item.js +1 -1
  141. package/menu/internal/menuitem/menu-item.js.map +1 -1
  142. package/menu/internal/submenuitem/sub-menu-item.d.ts +3 -0
  143. package/menu/internal/submenuitem/sub-menu-item.js +42 -12
  144. package/menu/internal/submenuitem/sub-menu-item.js.map +1 -1
  145. package/menu/internal/typeaheadController.js +2 -1
  146. package/menu/internal/typeaheadController.js.map +1 -1
  147. package/menu/menu.d.ts +12 -5
  148. package/menu/menu.js +12 -5
  149. package/menu/menu.js.map +1 -1
  150. package/menu/sub-menu-item.d.ts +3 -4
  151. package/menu/sub-menu-item.js +3 -4
  152. package/menu/sub-menu-item.js.map +1 -1
  153. package/package.json +10 -2
  154. package/progress/internal/_circular-progress.scss +4 -2
  155. package/progress/internal/_linear-progress.scss +2 -2
  156. package/progress/internal/circular-progress-styles.css.js +1 -1
  157. package/progress/internal/circular-progress-styles.css.js.map +1 -1
  158. package/radio/harness.d.ts +1 -1
  159. package/radio/harness.js +1 -1
  160. package/radio/harness.js.map +1 -1
  161. package/radio/internal/_radio.scss +4 -4
  162. package/radio/internal/radio-styles.css.js +1 -1
  163. package/radio/internal/radio-styles.css.js.map +1 -1
  164. package/radio/internal/radio.d.ts +3 -5
  165. package/radio/internal/radio.js +37 -32
  166. package/radio/internal/radio.js.map +1 -1
  167. package/radio/internal/single-selection-controller.js +4 -3
  168. package/radio/internal/single-selection-controller.js.map +1 -1
  169. package/ripple/internal/ripple.d.ts +3 -1
  170. package/ripple/internal/ripple.js +9 -0
  171. package/ripple/internal/ripple.js.map +1 -1
  172. package/select/harness.d.ts +1 -1
  173. package/select/harness.js +1 -3
  174. package/select/harness.js.map +1 -1
  175. package/select/internal/_filled-select.scss +13 -3
  176. package/select/internal/_outlined-select.scss +13 -3
  177. package/select/internal/filled-select-styles.css.js +1 -1
  178. package/select/internal/filled-select-styles.css.js.map +1 -1
  179. package/select/internal/outlined-select-styles.css.js +1 -1
  180. package/select/internal/outlined-select-styles.css.js.map +1 -1
  181. package/select/internal/select.d.ts +8 -2
  182. package/select/internal/select.js +21 -8
  183. package/select/internal/select.js.map +1 -1
  184. package/slider/internal/_slider.scss +9 -4
  185. package/slider/internal/forced-colors-styles.css.js +1 -1
  186. package/slider/internal/forced-colors-styles.css.js.map +1 -1
  187. package/slider/internal/forced-colors-styles.scss +31 -4
  188. package/slider/internal/slider-styles.css.js +1 -1
  189. package/slider/internal/slider-styles.css.js.map +1 -1
  190. package/switch/harness.d.ts +1 -1
  191. package/switch/harness.js +1 -1
  192. package/switch/harness.js.map +1 -1
  193. package/switch/internal/_handle.scss +22 -21
  194. package/switch/internal/_icon.scss +12 -12
  195. package/switch/internal/_switch.scss +11 -19
  196. package/switch/internal/_track.scss +12 -12
  197. package/switch/internal/forced-colors-styles.css.js +1 -1
  198. package/switch/internal/forced-colors-styles.css.js.map +1 -1
  199. package/switch/internal/forced-colors-styles.scss +1 -0
  200. package/switch/internal/switch-styles.css.js +1 -1
  201. package/switch/internal/switch-styles.css.js.map +1 -1
  202. package/switch/internal/switch.d.ts +72 -2
  203. package/switch/internal/switch.js +144 -30
  204. package/switch/internal/switch.js.map +1 -1
  205. package/tabs/{_tab.scss → _primary-tab.scss} +1 -1
  206. package/tabs/_secondary-tab.scss +6 -0
  207. package/tabs/harness.d.ts +2 -2
  208. package/tabs/harness.js +1 -2
  209. package/tabs/harness.js.map +1 -1
  210. package/tabs/internal/_primary-tab.scss +70 -0
  211. package/tabs/internal/_secondary-tab.scss +61 -0
  212. package/tabs/internal/_tab.scss +8 -157
  213. package/tabs/internal/_tabs.scss +9 -10
  214. package/tabs/internal/primary-tab-styles.css.d.ts +1 -0
  215. package/tabs/internal/primary-tab-styles.css.js +9 -0
  216. package/tabs/internal/primary-tab-styles.css.js.map +1 -0
  217. package/tabs/internal/primary-tab-styles.scss +10 -0
  218. package/tabs/internal/primary-tab.d.ts +20 -0
  219. package/tabs/internal/primary-tab.js +30 -0
  220. package/tabs/internal/primary-tab.js.map +1 -0
  221. package/tabs/internal/secondary-tab-styles.css.d.ts +1 -0
  222. package/tabs/internal/secondary-tab-styles.css.js +9 -0
  223. package/tabs/internal/secondary-tab-styles.css.js.map +1 -0
  224. package/tabs/internal/secondary-tab-styles.scss +10 -0
  225. package/tabs/internal/secondary-tab.d.ts +12 -0
  226. package/tabs/internal/secondary-tab.js +16 -0
  227. package/tabs/internal/secondary-tab.js.map +1 -0
  228. package/tabs/internal/tab-styles.css.js +1 -1
  229. package/tabs/internal/tab-styles.css.js.map +1 -1
  230. package/tabs/internal/tab.d.ts +16 -34
  231. package/tabs/internal/tab.js +81 -80
  232. package/tabs/internal/tab.js.map +1 -1
  233. package/tabs/internal/tabs-styles.css.js +1 -1
  234. package/tabs/internal/tabs-styles.css.js.map +1 -1
  235. package/tabs/internal/tabs.d.ts +6 -20
  236. package/tabs/internal/tabs.js +33 -66
  237. package/tabs/internal/tabs.js.map +1 -1
  238. package/tabs/{tab.d.ts → primary-tab.d.ts} +3 -4
  239. package/tabs/primary-tab.js +23 -0
  240. package/tabs/primary-tab.js.map +1 -0
  241. package/tabs/secondary-tab.d.ts +18 -0
  242. package/tabs/secondary-tab.js +23 -0
  243. package/tabs/secondary-tab.js.map +1 -0
  244. package/tabs/tabs.d.ts +0 -2
  245. package/tabs/tabs.js +0 -2
  246. package/tabs/tabs.js.map +1 -1
  247. package/textfield/internal/_filled-text-field.scss +12 -3
  248. package/textfield/internal/_outlined-text-field.scss +12 -3
  249. package/textfield/internal/filled-styles.css.js +1 -1
  250. package/textfield/internal/filled-styles.css.js.map +1 -1
  251. package/textfield/internal/outlined-styles.css.js +1 -1
  252. package/textfield/internal/outlined-styles.css.js.map +1 -1
  253. package/textfield/internal/text-field.d.ts +19 -0
  254. package/textfield/internal/text-field.js +20 -0
  255. package/textfield/internal/text-field.js.map +1 -1
  256. package/tokens/_index.scss +5 -6
  257. package/tokens/_md-comp-assist-chip.scss +6 -14
  258. package/tokens/_md-comp-badge.scss +1 -14
  259. package/tokens/{_md-comp-circular-progress-indicator.scss → _md-comp-circular-progress.scss} +3 -1
  260. package/tokens/_md-comp-dialog.scss +10 -17
  261. package/tokens/_md-comp-elevated-button.scss +5 -13
  262. package/tokens/_md-comp-fab-branded.scss +9 -10
  263. package/tokens/_md-comp-fab.scss +9 -10
  264. package/tokens/_md-comp-filled-button.scss +5 -13
  265. package/tokens/_md-comp-filled-field.scss +25 -6
  266. package/tokens/_md-comp-filled-select.scss +15 -15
  267. package/tokens/_md-comp-filled-text-field.scss +15 -19
  268. package/tokens/_md-comp-filled-tonal-button.scss +5 -13
  269. package/tokens/_md-comp-filter-chip.scss +5 -13
  270. package/tokens/_md-comp-input-chip.scss +5 -13
  271. package/tokens/_md-comp-list-item.scss +18 -37
  272. package/tokens/_md-comp-outlined-button.scss +5 -13
  273. package/tokens/_md-comp-outlined-field.scss +25 -6
  274. package/tokens/_md-comp-outlined-segmented-button.scss +5 -13
  275. package/tokens/_md-comp-outlined-select.scss +15 -15
  276. package/tokens/_md-comp-outlined-text-field.scss +15 -19
  277. package/tokens/_md-comp-primary-tab.scss +132 -0
  278. package/tokens/_md-comp-secondary-tab.scss +139 -0
  279. package/tokens/_md-comp-slider.scss +16 -16
  280. package/tokens/_md-comp-suggestion-chip.scss +5 -13
  281. package/tokens/_md-comp-test-table.scss +13 -2
  282. package/tokens/_md-comp-text-button.scss +5 -13
  283. package/tokens/_md-ref-palette.scss +101 -1
  284. package/tokens/_md-ref-typeface.scss +3 -0
  285. package/tokens/_md-sys-color.scss +57 -2
  286. package/tokens/_md-sys-typescale.scss +66 -5
  287. package/tabs/tab.js +0 -22
  288. package/tabs/tab.js.map +0 -1
  289. package/tokens/_md-comp-tab.scss +0 -285
  290. /package/tokens/{_md-comp-linear-progress-indicator.scss → _md-comp-linear-progress.scss} +0 -0
  291. /package/tokens/{_md-comp-radio-button.scss → _md-comp-radio.scss} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sourceRoot":"","sources":["menu.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../list/list.js';\nimport '../../focus/md-focus-ring.js';\nimport '../../elevation/elevation.js';\n\nimport {html, isServer, LitElement, nothing} from 'lit';\nimport {eventOptions, property, query, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {styleMap} from 'lit/directives/style-map.js';\n\nimport {ARIAMixinStrict, ARIARole} from '../../internal/aria/aria.js';\nimport {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';\nimport {createAnimationSignal, EASING} from '../../internal/motion/animation.js';\nimport {List} from '../../list/internal/list.js';\n\nimport {ActivateTypeaheadEvent, DeactivateTypeaheadEvent, isClosableKey, isElementInSubtree, MenuItem} from './shared.js';\nimport {Corner, SurfacePositionController, SurfacePositionTarget} from './surfacePositionController.js';\nimport {TypeaheadController} from './typeaheadController.js';\n\nexport {Corner} from './surfacePositionController.js';\n\n/**\n * The default value for the typeahead buffer time in Milliseconds.\n */\nexport const DEFAULT_TYPEAHEAD_BUFFER_TIME = 200;\n\n/**\n * Element to focus on when menu is first opened.\n */\nexport type DefaultFocusState = 'NONE'|'LIST_ROOT'|'FIRST_ITEM'|'LAST_ITEM';\n\n/**\n * Gets the currently focused element on the page.\n *\n * @param activeDoc The document or shadowroot from which to start the search.\n * Defaults to `window.document`\n * @return Returns the currently deeply focused element or `null` if none.\n */\nfunction getFocusedElement(activeDoc: Document|ShadowRoot = document):\n HTMLElement|null {\n const activeEl = activeDoc.activeElement as HTMLElement | null;\n\n if (!activeEl) {\n return null;\n }\n\n if (activeEl.shadowRoot) {\n return getFocusedElement(activeEl.shadowRoot) ?? activeEl;\n }\n\n return activeEl;\n}\n\n/**\n * @fires opening Fired before the opening animation begins\n * @fires opened Fired once the menu is open, after any animations\n * @fires closing Fired before the closing animation begins\n * @fires closed Fired once the menu is closed, after any animations\n */\nexport abstract class Menu extends LitElement {\n static {\n requestUpdateOnAriaChange(Menu);\n }\n\n @query('md-list') private readonly listElement!: List|null;\n @query('.menu') private readonly surfaceEl!: HTMLElement|null;\n @query('slot') private readonly slotEl!: HTMLSlotElement|null;\n\n /**\n * The element in which the menu should align to.\n */\n @property({attribute: false})\n anchor: HTMLElement&Partial<SurfacePositionTarget>|null = null;\n /**\n * Makes the element use `position:fixed` instead of `position:absolute`. In\n * most cases, the menu should position itself above most other\n * `position:absolute` or `position:fixed` elements when placed inside of\n * them. e.g. using a menu inside of an `md-dialog`.\n *\n * __NOTE__: Fixed menus will not scroll with the page and will be fixed to\n * the window instead.\n */\n @property({type: Boolean}) fixed = false;\n /**\n * Skips the opening and closing animations.\n */\n @property({type: Boolean}) quick = false;\n /**\n * Displays overflow content like a submenu.\n *\n * __NOTE__: This may cause adverse effects if you set\n * `md-menu {max-height:...}`\n * and have items overflowing items in the \"y\" direction.\n */\n @property({type: Boolean, attribute: 'has-overflow'}) hasOverflow = false;\n /**\n * Opens the menu and makes it visible. Alternative to the `.show()` and\n * `.close()` methods\n */\n @property({type: Boolean, reflect: true}) open = false;\n /**\n * Offsets the menu's inline alignment from the anchor by the given number in\n * pixels. This value is direction aware and will follow the LTR / RTL\n * direction.\n *\n * e.g. LTR: positive -> right, negative -> left\n * RTL: positive -> left, negative -> right\n */\n @property({type: Number, attribute: 'x-offset'}) xOffset = 0;\n /**\n * Offsets the menu's block alignment from the anchor by the given number in\n * pixels.\n *\n * e.g. positive -> down, negative -> up\n */\n @property({type: Number, attribute: 'y-offset'}) yOffset = 0;\n /**\n * The tabindex of the underlying list element.\n */\n @property({type: Number, attribute: 'list-tabindex'}) listTabIndex = 0;\n /**\n * The role of the underlying list element.\n */\n @property() type: ARIARole = 'menu';\n /**\n * The max time between the keystrokes of the typeahead menu behavior before\n * it clears the typeahead buffer.\n */\n @property({type: Number, attribute: 'typeahead-delay'})\n typeaheadDelay = DEFAULT_TYPEAHEAD_BUFFER_TIME;\n /**\n * The corner of the anchor which to align the menu in the standard logical\n * property style of <block>_<inline>.\n */\n @property({attribute: 'anchor-corner'}) anchorCorner: Corner = 'END_START';\n /**\n * The corner of the menu which to align the anchor in the standard logical\n * property style of <block>_<inline>.\n */\n @property({attribute: 'menu-corner'}) menuCorner: Corner = 'START_START';\n /**\n * Keeps the user clicks outside the menu.\n *\n * NOTE: clicking outside may still cause focusout to close the menu so see\n * `stayOpenOnFocusout`.\n */\n @property({type: Boolean, attribute: 'stay-open-on-outside-click'})\n stayOpenOnOutsideClick = false;\n /**\n * Keeps the menu open when focus leaves the menu's composed subtree.\n *\n * NOTE: Focusout behavior will stop propagation of the focusout event. Set\n * this property to true to opt-out of menu's focuout handling altogether.\n */\n @property({type: Boolean, attribute: 'stay-open-on-focusout'})\n stayOpenOnFocusout = false;\n /**\n * After closing, does not restore focus to the last focused element before\n * the menu was opened.\n */\n @property({type: Boolean, attribute: 'skip-restore-focus'})\n skipRestoreFocus = false;\n /**\n * The element that should be focused by default once opened.\n */\n @property({attribute: 'default-focus'})\n defaultFocus: DefaultFocusState = 'LIST_ROOT';\n\n @state() private typeaheadActive = true;\n\n private readonly openCloseAnimationSignal = createAnimationSignal();\n\n /**\n * Whether the menu is animating upwards or downwards when opening. This is\n * helpful for calculating some animation calculations.\n */\n private get openDirection(): 'UP'|'DOWN' {\n const menuCornerBlock = this.menuCorner.split('_')[0];\n return menuCornerBlock === 'START' ? 'DOWN' : 'UP';\n }\n\n /**\n * The element that was focused before the menu opened.\n */\n private lastFocusedElement: HTMLElement|null = null;\n\n /**\n * Handles typeahead navigation through the menu.\n */\n typeaheadController = new TypeaheadController(() => {\n return {\n getItems: () => this.items,\n typeaheadBufferTime: this.typeaheadDelay,\n active: this.typeaheadActive\n };\n });\n\n /**\n * Handles positioning the surface and aligning it to the anchor.\n */\n private readonly menuPositionController =\n new SurfacePositionController(this, () => {\n return {\n anchorCorner: this.anchorCorner,\n surfaceCorner: this.menuCorner,\n surfaceEl: this.surfaceEl,\n anchorEl: this.anchor,\n isTopLayer: this.fixed,\n isOpen: this.open,\n xOffset: this.xOffset,\n yOffset: this.yOffset,\n onOpen: this.onOpened,\n beforeClose: this.beforeClose,\n onClose: this.onClosed,\n };\n });\n\n /**\n * The menu items associated with this menu. The items must be `MenuItem`s and\n * have both the `md-menu-item` and `md-list-item` attributes.\n */\n get items(): MenuItem[] {\n const listElement = this.listElement;\n\n if (listElement) {\n return listElement.items.filter(el => el.hasAttribute('md-menu-item')) as\n MenuItem[];\n }\n\n return [];\n }\n\n protected override render() {\n return this.renderSurface();\n }\n\n /**\n * Renders the positionable surface element and its contents.\n */\n private renderSurface() {\n // TODO(b/274140618): elevation should be an underlay, not an overlay that\n // tints content\n return html`\n <div\n class=\"menu ${classMap(this.getSurfaceClasses())}\"\n style=${styleMap(this.menuPositionController.surfaceStyles)}\n @focusout=${this.handleFocusout}>\n ${this.renderElevation()}\n ${this.renderList()}\n ${this.renderFocusRing()}\n </div>\n `;\n }\n\n /**\n * Renders the List element and its items\n */\n private renderList() {\n // Needed for closure conformance\n const {ariaLabel} = this as ARIAMixinStrict;\n return html`\n <md-list\n part=\"list\"\n id=\"list\"\n aria-label=${ariaLabel || nothing}\n type=${this.type}\n listTabIndex=${this.listTabIndex}\n @keydown=${this.handleListKeydown}>\n ${this.renderMenuItems()}\n </md-list>`;\n }\n\n /**\n * Renders the menu items' slot\n */\n private renderMenuItems() {\n return html`<slot\n @close-menu=${this.onCloseMenu}\n @deactivate-items=${this.onDeactivateItems}\n @deactivate-typeahead=${this.handleDeactivateTypeahead}\n @activate-typeahead=${this.handleActivateTypeahead}\n @stay-open-on-focusout=${this.handleStayOpenOnFocusout}\n @close-on-focusout=${this.handleCloseOnFocusout}></slot>`;\n }\n\n /**\n * Renders the elevation component.\n */\n private renderElevation() {\n return html`<md-elevation part=\"elevation\"></md-elevation>`;\n }\n\n /**\n * Renders the focus ring component.\n */\n private renderFocusRing() {\n return html`<md-focus-ring part=\"focus-ring\" for=\"list\"></md-focus-ring>`;\n }\n\n private getSurfaceClasses() {\n return {\n open: this.open,\n fixed: this.fixed,\n 'has-overflow': this.hasOverflow,\n };\n }\n\n private async handleFocusout(event: FocusEvent) {\n if (this.stayOpenOnFocusout) {\n return;\n }\n\n // Stop propagation to prevent nested menus from interfering with each other\n event.stopPropagation();\n\n if (event.relatedTarget) {\n // Don't close the menu if we are switching focus between menu,\n // md-menu-item, and md-list\n if (isElementInSubtree(event.relatedTarget, this)) {\n return;\n }\n }\n\n const oldRestoreFocus = this.skipRestoreFocus;\n // allow focus to continue to the next focused object rather than returning\n this.skipRestoreFocus = true;\n this.close();\n // await for close\n await this.updateComplete;\n // return to previous behavior\n this.skipRestoreFocus = oldRestoreFocus;\n }\n\n // Capture so that we can grab the event before it reaches the list item\n // istelf. Specifically useful for the case where typeahead encounters a space\n // and we don't want the menu item to close the menu.\n @eventOptions({capture: true})\n private handleListKeydown(event: KeyboardEvent) {\n if (event.target === this.listElement && !event.defaultPrevented &&\n isClosableKey(event.code)) {\n event.preventDefault();\n this.close();\n }\n\n this.typeaheadController.onKeydown(event);\n }\n\n /**\n * Saves the last focused element focuses the new element based on\n * `defaultFocus`, and animates open.\n */\n private readonly onOpened = () => {\n this.lastFocusedElement = getFocusedElement();\n\n if (!this.listElement) return;\n\n const items = this.listElement.items;\n const activeItemRecord = List.getActiveItem(items);\n\n if (activeItemRecord && this.defaultFocus !== 'NONE') {\n activeItemRecord.item.active = false;\n }\n\n switch (this.defaultFocus) {\n case 'FIRST_ITEM':\n const first = List.getFirstActivatableItem(items);\n if (first) {\n first.active = true;\n }\n break;\n case 'LAST_ITEM':\n const last = List.getLastActivatableItem(items);\n if (last) {\n last.active = true;\n }\n break;\n case 'LIST_ROOT':\n this.listElement?.focus();\n break;\n default:\n case 'NONE':\n // Do nothing.\n break;\n }\n\n if (this.quick) {\n this.dispatchEvent(new Event('opening'));\n this.dispatchEvent(new Event('opened'));\n } else {\n this.animateOpen();\n }\n };\n\n /**\n * Animates closed.\n */\n private readonly beforeClose = async () => {\n this.open = false;\n\n if (!this.skipRestoreFocus) {\n this.lastFocusedElement?.focus?.();\n }\n\n if (!this.quick) {\n await this.animateClose();\n }\n };\n\n /**\n * Focuses the last focused element.\n */\n private readonly onClosed = () => {\n if (this.quick) {\n this.dispatchEvent(new Event('closing'));\n this.dispatchEvent(new Event('closed'));\n }\n };\n\n /**\n * Performs the opening animation:\n *\n * https://direct.googleplex.com/#/spec/295000003+271060003\n */\n private animateOpen() {\n const surfaceEl = this.surfaceEl;\n const slotEl = this.slotEl;\n\n if (!surfaceEl || !slotEl) return;\n\n const openDirection = this.openDirection;\n this.dispatchEvent(new Event('opening'));\n // needs to be imperative because we don't want to mix animation and Lit\n // render timing\n surfaceEl.classList.toggle('animating', true);\n\n const signal = this.openCloseAnimationSignal.start();\n const height = surfaceEl.offsetHeight;\n const openingUpwards = openDirection === 'UP';\n const children = this.items;\n const FULL_DURATION = 500;\n const SURFACE_OPACITY_DURATION = 50;\n const ITEM_OPACITY_DURATION = 250;\n // We want to fit every child fade-in animation within the full duration of\n // the animation.\n const DELAY_BETWEEN_ITEMS =\n (FULL_DURATION - ITEM_OPACITY_DURATION) / children.length;\n\n const surfaceHeightAnimation =\n surfaceEl.animate([{height: '0px'}, {height: `${height}px`}], {\n duration: FULL_DURATION,\n easing: EASING.EMPHASIZED,\n });\n // When we are opening upwards, we want to make sure the last item is always\n // in view, so we need to translate it upwards the opposite direction of the\n // height animation\n const upPositionCorrectionAnimation = slotEl.animate(\n [\n {transform: openingUpwards ? `translateY(-${height}px)` : ''},\n {transform: ''}\n ],\n {duration: FULL_DURATION, easing: EASING.EMPHASIZED});\n\n const surfaceOpacityAnimation = surfaceEl.animate(\n [{opacity: 0}, {opacity: 1}], SURFACE_OPACITY_DURATION);\n\n const childrenAnimations: Array<[HTMLElement, Animation]> = [];\n\n for (let i = 0; i < children.length; i++) {\n // If we are animating upwards, then reverse the children list.\n const directionalIndex = openingUpwards ? children.length - 1 - i : i;\n const child = children[directionalIndex];\n const animation = child.animate([{opacity: 0}, {opacity: 1}], {\n duration: ITEM_OPACITY_DURATION,\n delay: DELAY_BETWEEN_ITEMS * i,\n });\n\n // Make them all initially hidden and then clean up at the end of each\n // animation.\n child.classList.toggle('md-menu-hidden', true);\n animation.addEventListener('finish', () => {\n child.classList.toggle('md-menu-hidden', false);\n });\n\n childrenAnimations.push([child, animation]);\n }\n\n signal.addEventListener('abort', () => {\n surfaceHeightAnimation.cancel();\n upPositionCorrectionAnimation.cancel();\n surfaceOpacityAnimation.cancel();\n childrenAnimations.forEach(([child, animation]) => {\n child.classList.toggle('md-menu-hidden', false);\n animation.cancel();\n });\n });\n\n surfaceHeightAnimation.addEventListener('finish', () => {\n surfaceEl.classList.toggle('animating', false);\n this.openCloseAnimationSignal.finish();\n this.dispatchEvent(new Event('opened'));\n });\n }\n\n /**\n * Performs the closing animation:\n *\n * https://direct.googleplex.com/#/spec/295000003+271060003\n */\n private animateClose() {\n let resolve!: (value: unknown) => void;\n let reject!: () => void;\n\n // This promise blocks the surface position controller from setting\n // display: none on the surface which will interfere with this animation.\n const animationEnded = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n const surfaceEl = this.surfaceEl;\n const slotEl = this.slotEl;\n\n if (!surfaceEl || !slotEl) {\n reject();\n return animationEnded;\n }\n\n const openDirection = this.openDirection;\n const closingDownwards = openDirection === 'UP';\n this.dispatchEvent(new Event('closing'));\n // needs to be imperative because we don't want to mix animation and Lit\n // render timing\n surfaceEl.classList.toggle('animating', true);\n const signal = this.openCloseAnimationSignal.start();\n const height = surfaceEl.offsetHeight;\n const children = this.items;\n const FULL_DURATION = 150;\n const SURFACE_OPACITY_DURATION = 50;\n // The surface fades away at the very end\n const SURFACE_OPACITY_DELAY = FULL_DURATION - SURFACE_OPACITY_DURATION;\n const ITEM_OPACITY_DURATION = 50;\n const ITEM_OPACITY_INITIAL_DELAY = 50;\n const END_HEIGHT_PERCENTAGE = .35;\n\n // We want to fit every child fade-out animation within the full duration of\n // the animation.\n const DELAY_BETWEEN_ITEMS =\n (FULL_DURATION - ITEM_OPACITY_INITIAL_DELAY - ITEM_OPACITY_DURATION) /\n children.length;\n\n // The mock has the animation shrink to 35%\n const surfaceHeightAnimation = surfaceEl.animate(\n [\n {height: `${height}px`},\n {height: `${height * END_HEIGHT_PERCENTAGE}px`}\n ],\n {\n duration: FULL_DURATION,\n easing: EASING.EMPHASIZED_ACCELERATE,\n });\n\n // When we are closing downwards, we want to make sure the last item is\n // always in view, so we need to translate it upwards the opposite direction\n // of the height animation\n const downPositionCorrectionAnimation = slotEl.animate(\n [\n {transform: ''}, {\n transform: closingDownwards ?\n `translateY(-${height * (1 - END_HEIGHT_PERCENTAGE)}px)` :\n ''\n }\n ],\n {duration: FULL_DURATION, easing: EASING.EMPHASIZED_ACCELERATE});\n\n const surfaceOpacityAnimation = surfaceEl.animate(\n [{opacity: 1}, {opacity: 0}],\n {duration: SURFACE_OPACITY_DURATION, delay: SURFACE_OPACITY_DELAY});\n\n const childrenAnimations: Array<[HTMLElement, Animation]> = [];\n\n for (let i = 0; i < children.length; i++) {\n // If the animation is closing upwards, then reverse the list of\n // children so that we animate in the opposite direction.\n const directionalIndex = closingDownwards ? i : children.length - 1 - i;\n const child = children[directionalIndex];\n const animation = child.animate([{opacity: 1}, {opacity: 0}], {\n duration: ITEM_OPACITY_DURATION,\n delay: ITEM_OPACITY_INITIAL_DELAY + DELAY_BETWEEN_ITEMS * i,\n });\n\n // Make sure the items stay hidden at the end of each child animation.\n // We clean this up at the end of the overall animation.\n animation.addEventListener('finish', () => {\n child.classList.toggle('md-menu-hidden', true);\n });\n childrenAnimations.push([child, animation]);\n }\n\n signal.addEventListener('abort', () => {\n surfaceHeightAnimation.cancel();\n downPositionCorrectionAnimation.cancel();\n surfaceOpacityAnimation.cancel();\n childrenAnimations.forEach(([child, animation]) => {\n animation.cancel();\n child.classList.toggle('md-menu-hidden', false);\n });\n reject();\n });\n\n surfaceHeightAnimation.addEventListener('finish', () => {\n surfaceEl.classList.toggle('animating', false);\n childrenAnimations.forEach(([child]) => {\n child.classList.toggle('md-menu-hidden', false);\n });\n this.openCloseAnimationSignal.finish();\n this.dispatchEvent(new Event('closed'));\n resolve(true);\n });\n\n return animationEnded;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (!isServer) {\n window.addEventListener('click', this.onWindowClick, {capture: true});\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (!isServer) {\n window.removeEventListener('click', this.onWindowClick, {capture: true});\n }\n }\n\n private readonly onWindowClick = (event: MouseEvent) => {\n if (!this.stayOpenOnOutsideClick && !event.composedPath().includes(this)) {\n this.open = false;\n }\n };\n\n private onCloseMenu() {\n this.close();\n }\n\n private onDeactivateItems(event: Event) {\n event.stopPropagation();\n const items = this.items;\n for (const item of items) {\n item.active = false;\n item.selected = false;\n }\n }\n\n private handleDeactivateTypeahead(event: DeactivateTypeaheadEvent) {\n // stopPropagation so that this does not deactivate any typeaheads in menus\n // nested above it e.g. md-sub-menu-item\n event.stopPropagation();\n this.typeaheadActive = false;\n }\n\n private handleActivateTypeahead(event: ActivateTypeaheadEvent) {\n // stopPropagation so that this does not activate any typeaheads in menus\n // nested above it e.g. md-sub-menu-item\n event.stopPropagation();\n this.typeaheadActive = true;\n }\n\n private handleStayOpenOnFocusout(event: Event) {\n event.stopPropagation();\n this.stayOpenOnFocusout = true;\n }\n\n private handleCloseOnFocusout(event: Event) {\n event.stopPropagation();\n this.stayOpenOnFocusout = false;\n }\n\n override focus() {\n this.listElement?.focus();\n }\n\n close() {\n this.open = false;\n this.items.forEach(item => {\n item.close?.();\n });\n }\n\n show() {\n this.open = true;\n }\n\n /**\n * Activates the next item in the menu. If at the end of the menu, the first\n * item will be activated.\n *\n * @return The activated menu item or `null` if there are no items.\n */\n activateNextItem() {\n return this.listElement?.activateNextItem() as MenuItem ?? null;\n }\n\n /**\n * Activates the previous item in the menu. If at the start of the menu, the\n * last item will be activated.\n *\n * @return The activated menu item or `null` if there are no items.\n */\n activatePreviousItem() {\n return this.listElement?.activatePreviousItem() as MenuItem ?? null;\n }\n}\n"]}
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["menu.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../list/list.js';\nimport '../../focus/md-focus-ring.js';\nimport '../../elevation/elevation.js';\n\nimport {html, isServer, LitElement, nothing} from 'lit';\nimport {eventOptions, property, query, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {styleMap} from 'lit/directives/style-map.js';\n\nimport {ARIAMixinStrict} from '../../internal/aria/aria.js';\nimport {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';\nimport {createAnimationSignal, EASING} from '../../internal/motion/animation.js';\nimport {List} from '../../list/internal/list.js';\n\nimport {ActivateTypeaheadEvent, DeactivateTypeaheadEvent, isClosableKey, isElementInSubtree, MenuItem} from './shared.js';\nimport {Corner, SurfacePositionController, SurfacePositionTarget} from './surfacePositionController.js';\nimport {TypeaheadController} from './typeaheadController.js';\n\nexport {Corner} from './surfacePositionController.js';\n\n/**\n * The default value for the typeahead buffer time in Milliseconds.\n */\nexport const DEFAULT_TYPEAHEAD_BUFFER_TIME = 200;\n\n/**\n * Element to focus on when menu is first opened.\n */\nexport type DefaultFocusState = 'NONE'|'LIST_ROOT'|'FIRST_ITEM'|'LAST_ITEM';\n\n/**\n * Gets the currently focused element on the page.\n *\n * @param activeDoc The document or shadowroot from which to start the search.\n * Defaults to `window.document`\n * @return Returns the currently deeply focused element or `null` if none.\n */\nfunction getFocusedElement(activeDoc: Document|ShadowRoot = document):\n HTMLElement|null {\n const activeEl = activeDoc.activeElement as HTMLElement | null;\n\n if (!activeEl) {\n return null;\n }\n\n if (activeEl.shadowRoot) {\n return getFocusedElement(activeEl.shadowRoot) ?? activeEl;\n }\n\n return activeEl;\n}\n\n/**\n * @fires opening Fired before the opening animation begins\n * @fires opened Fired once the menu is open, after any animations\n * @fires closing Fired before the closing animation begins\n * @fires closed Fired once the menu is closed, after any animations\n */\nexport abstract class Menu extends LitElement {\n static {\n requestUpdateOnAriaChange(Menu);\n }\n\n @query('md-list') private readonly listElement!: List|null;\n @query('.menu') private readonly surfaceEl!: HTMLElement|null;\n @query('slot') private readonly slotEl!: HTMLSlotElement|null;\n\n /**\n * The ID of the element in the same root node in which the menu should align\n * to. Overrides setting `anchorElement = elementReference`.\n *\n * __NOTE__: anchor or anchorElement must either be an HTMLElement or resolve\n * to an HTMLElement in order for menu to open.\n */\n @property() anchor = '';\n /**\n * Makes the element use `position:fixed` instead of `position:absolute`. In\n * most cases, the menu should position itself above most other\n * `position:absolute` or `position:fixed` elements when placed inside of\n * them. e.g. using a menu inside of an `md-dialog`.\n *\n * __NOTE__: Fixed menus will not scroll with the page and will be fixed to\n * the window instead.\n */\n @property({type: Boolean}) fixed = false;\n /**\n * Skips the opening and closing animations.\n */\n @property({type: Boolean}) quick = false;\n /**\n * Displays overflow content like a submenu.\n *\n * __NOTE__: This may cause adverse effects if you set\n * `md-menu {max-height:...}`\n * and have items overflowing items in the \"y\" direction.\n */\n @property({type: Boolean, attribute: 'has-overflow'}) hasOverflow = false;\n /**\n * Opens the menu and makes it visible. Alternative to the `.show()` and\n * `.close()` methods\n */\n @property({type: Boolean, reflect: true}) open = false;\n /**\n * Offsets the menu's inline alignment from the anchor by the given number in\n * pixels. This value is direction aware and will follow the LTR / RTL\n * direction.\n *\n * e.g. LTR: positive -> right, negative -> left\n * RTL: positive -> left, negative -> right\n */\n @property({type: Number, attribute: 'x-offset'}) xOffset = 0;\n /**\n * Offsets the menu's block alignment from the anchor by the given number in\n * pixels.\n *\n * e.g. positive -> down, negative -> up\n */\n @property({type: Number, attribute: 'y-offset'}) yOffset = 0;\n /**\n * The tabindex of the underlying list element.\n */\n @property({type: Number, attribute: 'list-tabindex'}) listTabIndex = 0;\n /**\n * The role of the underlying list element.\n */\n @property() type: 'menu'|'menubar'|'listbox'|'list' = 'menu';\n /**\n * The max time between the keystrokes of the typeahead menu behavior before\n * it clears the typeahead buffer.\n */\n @property({type: Number, attribute: 'typeahead-delay'})\n typeaheadDelay = DEFAULT_TYPEAHEAD_BUFFER_TIME;\n /**\n * The corner of the anchor which to align the menu in the standard logical\n * property style of <block>_<inline>.\n */\n @property({attribute: 'anchor-corner'}) anchorCorner: Corner = 'END_START';\n /**\n * The corner of the menu which to align the anchor in the standard logical\n * property style of <block>_<inline>.\n */\n @property({attribute: 'menu-corner'}) menuCorner: Corner = 'START_START';\n /**\n * Keeps the user clicks outside the menu.\n *\n * NOTE: clicking outside may still cause focusout to close the menu so see\n * `stayOpenOnFocusout`.\n */\n @property({type: Boolean, attribute: 'stay-open-on-outside-click'})\n stayOpenOnOutsideClick = false;\n /**\n * Keeps the menu open when focus leaves the menu's composed subtree.\n *\n * NOTE: Focusout behavior will stop propagation of the focusout event. Set\n * this property to true to opt-out of menu's focuout handling altogether.\n */\n @property({type: Boolean, attribute: 'stay-open-on-focusout'})\n stayOpenOnFocusout = false;\n /**\n * After closing, does not restore focus to the last focused element before\n * the menu was opened.\n */\n @property({type: Boolean, attribute: 'skip-restore-focus'})\n skipRestoreFocus = false;\n /**\n * The element that should be focused by default once opened.\n */\n @property({attribute: 'default-focus'})\n defaultFocus: DefaultFocusState = 'LIST_ROOT';\n\n @state() private typeaheadActive = true;\n\n private readonly openCloseAnimationSignal = createAnimationSignal();\n\n /**\n * Whether the menu is animating upwards or downwards when opening. This is\n * helpful for calculating some animation calculations.\n */\n private get openDirection(): 'UP'|'DOWN' {\n const menuCornerBlock = this.menuCorner.split('_')[0];\n return menuCornerBlock === 'START' ? 'DOWN' : 'UP';\n }\n\n /**\n * The element that was focused before the menu opened.\n */\n private lastFocusedElement: HTMLElement|null = null;\n\n /**\n * Handles typeahead navigation through the menu.\n */\n typeaheadController = new TypeaheadController(() => {\n return {\n getItems: () => this.items,\n typeaheadBufferTime: this.typeaheadDelay,\n active: this.typeaheadActive\n };\n });\n\n private currentAnchorElement: HTMLElement|null = null;\n\n /**\n * The element which the menu should align to. If `anchor` is set to a\n * non-empty idref string, then `anchorEl` will resolve to the element with\n * the given id in the same root node. Otherwise, `null`.\n */\n get anchorElement(): HTMLElement&Partial<SurfacePositionTarget>|null {\n if (this.anchor) {\n return (this.getRootNode() as Document | ShadowRoot)\n .querySelector(`#${this.anchor}`);\n }\n\n return this.currentAnchorElement;\n }\n\n set anchorElement(element: HTMLElement&Partial<SurfacePositionTarget>|null) {\n this.currentAnchorElement = element;\n this.requestUpdate('anchorElement');\n }\n\n /**\n * Handles positioning the surface and aligning it to the anchor.\n */\n private readonly menuPositionController =\n new SurfacePositionController(this, () => {\n return {\n anchorCorner: this.anchorCorner,\n surfaceCorner: this.menuCorner,\n surfaceEl: this.surfaceEl,\n anchorEl: this.anchorElement,\n isTopLayer: this.fixed,\n isOpen: this.open,\n xOffset: this.xOffset,\n yOffset: this.yOffset,\n onOpen: this.onOpened,\n beforeClose: this.beforeClose,\n onClose: this.onClosed,\n };\n });\n\n /**\n * The menu items associated with this menu. The items must be `MenuItem`s and\n * have both the `md-menu-item` and `md-list-item` attributes.\n */\n get items(): MenuItem[] {\n const listElement = this.listElement;\n\n if (listElement) {\n return listElement.items.filter(el => el.hasAttribute('md-menu-item')) as\n MenuItem[];\n }\n\n return [];\n }\n\n protected override render() {\n return this.renderSurface();\n }\n\n /**\n * Renders the positionable surface element and its contents.\n */\n private renderSurface() {\n // TODO(b/274140618): elevation should be an underlay, not an overlay that\n // tints content\n return html`\n <div\n class=\"menu ${classMap(this.getSurfaceClasses())}\"\n style=${styleMap(this.menuPositionController.surfaceStyles)}\n @focusout=${this.handleFocusout}>\n ${this.renderElevation()}\n ${this.renderList()}\n ${this.renderFocusRing()}\n </div>\n `;\n }\n\n /**\n * Renders the List element and its items\n */\n private renderList() {\n // Needed for closure conformance\n const {ariaLabel} = this as ARIAMixinStrict;\n return html`\n <md-list\n part=\"list\"\n id=\"list\"\n aria-label=${ariaLabel || nothing}\n type=${this.type}\n listTabIndex=${this.listTabIndex}\n @keydown=${this.handleListKeydown}>\n ${this.renderMenuItems()}\n </md-list>`;\n }\n\n /**\n * Renders the menu items' slot\n */\n private renderMenuItems() {\n return html`<slot\n @close-menu=${this.onCloseMenu}\n @deactivate-items=${this.onDeactivateItems}\n @deactivate-typeahead=${this.handleDeactivateTypeahead}\n @activate-typeahead=${this.handleActivateTypeahead}\n @stay-open-on-focusout=${this.handleStayOpenOnFocusout}\n @close-on-focusout=${this.handleCloseOnFocusout}></slot>`;\n }\n\n /**\n * Renders the elevation component.\n */\n private renderElevation() {\n return html`<md-elevation part=\"elevation\"></md-elevation>`;\n }\n\n /**\n * Renders the focus ring component.\n */\n private renderFocusRing() {\n return html`<md-focus-ring part=\"focus-ring\" for=\"list\"></md-focus-ring>`;\n }\n\n private getSurfaceClasses() {\n return {\n open: this.open,\n fixed: this.fixed,\n 'has-overflow': this.hasOverflow,\n };\n }\n\n private async handleFocusout(event: FocusEvent) {\n if (this.stayOpenOnFocusout) {\n return;\n }\n\n // Stop propagation to prevent nested menus from interfering with each other\n event.stopPropagation();\n\n if (event.relatedTarget) {\n // Don't close the menu if we are switching focus between menu,\n // md-menu-item, and md-list\n if (isElementInSubtree(event.relatedTarget, this)) {\n return;\n }\n }\n\n const oldRestoreFocus = this.skipRestoreFocus;\n // allow focus to continue to the next focused object rather than returning\n this.skipRestoreFocus = true;\n this.close();\n // await for close\n await this.updateComplete;\n // return to previous behavior\n this.skipRestoreFocus = oldRestoreFocus;\n }\n\n // Capture so that we can grab the event before it reaches the list item\n // istelf. Specifically useful for the case where typeahead encounters a space\n // and we don't want the menu item to close the menu.\n @eventOptions({capture: true})\n private handleListKeydown(event: KeyboardEvent) {\n if (event.target === this.listElement && !event.defaultPrevented &&\n isClosableKey(event.code)) {\n event.preventDefault();\n this.close();\n }\n\n this.typeaheadController.onKeydown(event);\n }\n\n /**\n * Saves the last focused element focuses the new element based on\n * `defaultFocus`, and animates open.\n */\n private readonly onOpened = () => {\n this.lastFocusedElement = getFocusedElement();\n\n if (!this.listElement) return;\n\n const items = this.listElement.items;\n const activeItemRecord = List.getActiveItem(items);\n\n if (activeItemRecord && this.defaultFocus !== 'NONE') {\n activeItemRecord.item.active = false;\n }\n\n switch (this.defaultFocus) {\n case 'FIRST_ITEM':\n const first = List.getFirstActivatableItem(items);\n if (first) {\n first.active = true;\n }\n break;\n case 'LAST_ITEM':\n const last = List.getLastActivatableItem(items);\n if (last) {\n last.active = true;\n }\n break;\n case 'LIST_ROOT':\n this.listElement?.focus();\n break;\n default:\n case 'NONE':\n // Do nothing.\n break;\n }\n\n if (this.quick) {\n this.dispatchEvent(new Event('opening'));\n this.dispatchEvent(new Event('opened'));\n } else {\n this.animateOpen();\n }\n };\n\n /**\n * Animates closed.\n */\n private readonly beforeClose = async () => {\n this.open = false;\n\n if (!this.skipRestoreFocus) {\n this.lastFocusedElement?.focus?.();\n }\n\n if (!this.quick) {\n await this.animateClose();\n }\n };\n\n /**\n * Focuses the last focused element.\n */\n private readonly onClosed = () => {\n if (this.quick) {\n this.dispatchEvent(new Event('closing'));\n this.dispatchEvent(new Event('closed'));\n }\n };\n\n /**\n * Performs the opening animation:\n *\n * https://direct.googleplex.com/#/spec/295000003+271060003\n */\n private animateOpen() {\n const surfaceEl = this.surfaceEl;\n const slotEl = this.slotEl;\n\n if (!surfaceEl || !slotEl) return;\n\n const openDirection = this.openDirection;\n this.dispatchEvent(new Event('opening'));\n // needs to be imperative because we don't want to mix animation and Lit\n // render timing\n surfaceEl.classList.toggle('animating', true);\n\n const signal = this.openCloseAnimationSignal.start();\n const height = surfaceEl.offsetHeight;\n const openingUpwards = openDirection === 'UP';\n const children = this.items;\n const FULL_DURATION = 500;\n const SURFACE_OPACITY_DURATION = 50;\n const ITEM_OPACITY_DURATION = 250;\n // We want to fit every child fade-in animation within the full duration of\n // the animation.\n const DELAY_BETWEEN_ITEMS =\n (FULL_DURATION - ITEM_OPACITY_DURATION) / children.length;\n\n const surfaceHeightAnimation =\n surfaceEl.animate([{height: '0px'}, {height: `${height}px`}], {\n duration: FULL_DURATION,\n easing: EASING.EMPHASIZED,\n });\n // When we are opening upwards, we want to make sure the last item is always\n // in view, so we need to translate it upwards the opposite direction of the\n // height animation\n const upPositionCorrectionAnimation = slotEl.animate(\n [\n {transform: openingUpwards ? `translateY(-${height}px)` : ''},\n {transform: ''}\n ],\n {duration: FULL_DURATION, easing: EASING.EMPHASIZED});\n\n const surfaceOpacityAnimation = surfaceEl.animate(\n [{opacity: 0}, {opacity: 1}], SURFACE_OPACITY_DURATION);\n\n const childrenAnimations: Array<[HTMLElement, Animation]> = [];\n\n for (let i = 0; i < children.length; i++) {\n // If we are animating upwards, then reverse the children list.\n const directionalIndex = openingUpwards ? children.length - 1 - i : i;\n const child = children[directionalIndex];\n const animation = child.animate([{opacity: 0}, {opacity: 1}], {\n duration: ITEM_OPACITY_DURATION,\n delay: DELAY_BETWEEN_ITEMS * i,\n });\n\n // Make them all initially hidden and then clean up at the end of each\n // animation.\n child.classList.toggle('md-menu-hidden', true);\n animation.addEventListener('finish', () => {\n child.classList.toggle('md-menu-hidden', false);\n });\n\n childrenAnimations.push([child, animation]);\n }\n\n signal.addEventListener('abort', () => {\n surfaceHeightAnimation.cancel();\n upPositionCorrectionAnimation.cancel();\n surfaceOpacityAnimation.cancel();\n childrenAnimations.forEach(([child, animation]) => {\n child.classList.toggle('md-menu-hidden', false);\n animation.cancel();\n });\n });\n\n surfaceHeightAnimation.addEventListener('finish', () => {\n surfaceEl.classList.toggle('animating', false);\n this.openCloseAnimationSignal.finish();\n this.dispatchEvent(new Event('opened'));\n });\n }\n\n /**\n * Performs the closing animation:\n *\n * https://direct.googleplex.com/#/spec/295000003+271060003\n */\n private animateClose() {\n let resolve!: (value: unknown) => void;\n let reject!: () => void;\n\n // This promise blocks the surface position controller from setting\n // display: none on the surface which will interfere with this animation.\n const animationEnded = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n const surfaceEl = this.surfaceEl;\n const slotEl = this.slotEl;\n\n if (!surfaceEl || !slotEl) {\n reject();\n return animationEnded;\n }\n\n const openDirection = this.openDirection;\n const closingDownwards = openDirection === 'UP';\n this.dispatchEvent(new Event('closing'));\n // needs to be imperative because we don't want to mix animation and Lit\n // render timing\n surfaceEl.classList.toggle('animating', true);\n const signal = this.openCloseAnimationSignal.start();\n const height = surfaceEl.offsetHeight;\n const children = this.items;\n const FULL_DURATION = 150;\n const SURFACE_OPACITY_DURATION = 50;\n // The surface fades away at the very end\n const SURFACE_OPACITY_DELAY = FULL_DURATION - SURFACE_OPACITY_DURATION;\n const ITEM_OPACITY_DURATION = 50;\n const ITEM_OPACITY_INITIAL_DELAY = 50;\n const END_HEIGHT_PERCENTAGE = .35;\n\n // We want to fit every child fade-out animation within the full duration of\n // the animation.\n const DELAY_BETWEEN_ITEMS =\n (FULL_DURATION - ITEM_OPACITY_INITIAL_DELAY - ITEM_OPACITY_DURATION) /\n children.length;\n\n // The mock has the animation shrink to 35%\n const surfaceHeightAnimation = surfaceEl.animate(\n [\n {height: `${height}px`},\n {height: `${height * END_HEIGHT_PERCENTAGE}px`}\n ],\n {\n duration: FULL_DURATION,\n easing: EASING.EMPHASIZED_ACCELERATE,\n });\n\n // When we are closing downwards, we want to make sure the last item is\n // always in view, so we need to translate it upwards the opposite direction\n // of the height animation\n const downPositionCorrectionAnimation = slotEl.animate(\n [\n {transform: ''}, {\n transform: closingDownwards ?\n `translateY(-${height * (1 - END_HEIGHT_PERCENTAGE)}px)` :\n ''\n }\n ],\n {duration: FULL_DURATION, easing: EASING.EMPHASIZED_ACCELERATE});\n\n const surfaceOpacityAnimation = surfaceEl.animate(\n [{opacity: 1}, {opacity: 0}],\n {duration: SURFACE_OPACITY_DURATION, delay: SURFACE_OPACITY_DELAY});\n\n const childrenAnimations: Array<[HTMLElement, Animation]> = [];\n\n for (let i = 0; i < children.length; i++) {\n // If the animation is closing upwards, then reverse the list of\n // children so that we animate in the opposite direction.\n const directionalIndex = closingDownwards ? i : children.length - 1 - i;\n const child = children[directionalIndex];\n const animation = child.animate([{opacity: 1}, {opacity: 0}], {\n duration: ITEM_OPACITY_DURATION,\n delay: ITEM_OPACITY_INITIAL_DELAY + DELAY_BETWEEN_ITEMS * i,\n });\n\n // Make sure the items stay hidden at the end of each child animation.\n // We clean this up at the end of the overall animation.\n animation.addEventListener('finish', () => {\n child.classList.toggle('md-menu-hidden', true);\n });\n childrenAnimations.push([child, animation]);\n }\n\n signal.addEventListener('abort', () => {\n surfaceHeightAnimation.cancel();\n downPositionCorrectionAnimation.cancel();\n surfaceOpacityAnimation.cancel();\n childrenAnimations.forEach(([child, animation]) => {\n animation.cancel();\n child.classList.toggle('md-menu-hidden', false);\n });\n reject();\n });\n\n surfaceHeightAnimation.addEventListener('finish', () => {\n surfaceEl.classList.toggle('animating', false);\n childrenAnimations.forEach(([child]) => {\n child.classList.toggle('md-menu-hidden', false);\n });\n this.openCloseAnimationSignal.finish();\n this.dispatchEvent(new Event('closed'));\n resolve(true);\n });\n\n return animationEnded;\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (!isServer) {\n window.addEventListener('click', this.onWindowClick, {capture: true});\n }\n\n // need to self-identify as an md-menu for submenu ripple identification.\n this.toggleAttribute('md-menu', true);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (!isServer) {\n window.removeEventListener('click', this.onWindowClick, {capture: true});\n }\n }\n\n private readonly onWindowClick = (event: MouseEvent) => {\n if (!this.stayOpenOnOutsideClick && !event.composedPath().includes(this)) {\n this.open = false;\n }\n };\n\n private onCloseMenu() {\n this.close();\n }\n\n private onDeactivateItems(event: Event) {\n event.stopPropagation();\n const items = this.items;\n for (const item of items) {\n item.active = false;\n item.selected = false;\n }\n }\n\n private handleDeactivateTypeahead(event: DeactivateTypeaheadEvent) {\n // stopPropagation so that this does not deactivate any typeaheads in menus\n // nested above it e.g. md-sub-menu-item\n event.stopPropagation();\n this.typeaheadActive = false;\n }\n\n private handleActivateTypeahead(event: ActivateTypeaheadEvent) {\n // stopPropagation so that this does not activate any typeaheads in menus\n // nested above it e.g. md-sub-menu-item\n event.stopPropagation();\n this.typeaheadActive = true;\n }\n\n private handleStayOpenOnFocusout(event: Event) {\n event.stopPropagation();\n this.stayOpenOnFocusout = true;\n }\n\n private handleCloseOnFocusout(event: Event) {\n event.stopPropagation();\n this.stayOpenOnFocusout = false;\n }\n\n override focus() {\n this.listElement?.focus();\n }\n\n close() {\n this.open = false;\n this.items.forEach(item => {\n item.close?.();\n });\n }\n\n show() {\n this.open = true;\n }\n\n /**\n * Activates the next item in the menu. If at the end of the menu, the first\n * item will be activated.\n *\n * @return The activated menu item or `null` if there are no items.\n */\n activateNextItem() {\n return this.listElement?.activateNextItem() as MenuItem ?? null;\n }\n\n /**\n * Activates the previous item in the menu. If at the start of the menu, the\n * last item will be activated.\n *\n * @return The activated menu item or `null` if there are no items.\n */\n activatePreviousItem() {\n return this.listElement?.activatePreviousItem() as MenuItem ?? null;\n }\n}\n"]}
@@ -44,7 +44,7 @@ export class MenuItemEl extends ListItemEl {
44
44
  this.hasFocusRing = focusRing.visible;
45
45
  }
46
46
  onKeydown(event) {
47
- if (this.keepOpen)
47
+ if (this.keepOpen || event.defaultPrevented)
48
48
  return;
49
49
  const keyCode = event.code;
50
50
  if (!event.defaultPrevented && isClosableKey(keyCode)) {
@@ -1 +1 @@
1
- {"version":3,"file":"menu-item.js","sourceRoot":"","sources":["menu-item.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAC,UAAU,EAAe,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAC,YAAY,EAAE,2BAA2B,EAAE,aAAa,EAAW,MAAM,cAAc,CAAC;AAIhG;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IAA1C;;QACE;;WAEG;QAEH,eAAU,GAAG,IAAI,CAAC;QAElB;;WAEG;QACgD,aAAQ,GAAG,KAAK,CAAC;QAEjD,iBAAY,GAAG,KAAK,CAAC;QAExC;;WAEG;QACO,oBAAe,GAAG,KAAK,CAAC;QAEhB,SAAI,GAAiB,UAAU,CAAC;IA+BpD,CAAC;IA7BoB,OAAO;QACxB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QAElD,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAC1C,IAAI,EAAE,EAAC,IAAI,EAAE,YAAY,CAAC,eAAe,EAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAEkB,gBAAgB;QACjC,OAAO;YACL,GAAG,KAAK,CAAC,gBAAgB,EAAE;YAC3B,gBAAgB,EAAE,IAAI,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAEkB,4BAA4B,CAAC,CAAQ;QACtD,MAAM,SAAS,GAAG,CAAC,CAAC,MAAqB,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC;IACxC,CAAC;IAEkB,SAAS,CAAC,KAAoB;QAC/C,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QAE3B,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE;YACrD,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAC1C,IAAI,EAAE,EAAC,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAC,CAAC,CAAC,CAAC;SACxD;IACH,CAAC;CACF;AA7CC;IADC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;8CAClD;AAKiC;IAAlD,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAC,CAAC;4CAAkB;AAE3D;IAAR,KAAK,EAAE;gDAAgC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {property, state} from 'lit/decorators.js';\n\nimport type {MdFocusRing} from '../../../focus/md-focus-ring.js';\nimport {ListItemEl, ListItemRole} from '../../../list/internal/listitem/list-item.js';\nimport {CLOSE_REASON, createDefaultCloseMenuEvent, isClosableKey, MenuItem} from '../shared.js';\n\nexport {ListItemRole} from '../../../list/internal/listitem/list-item.js';\n\n/**\n * @fires close-menu {CloseMenuEvent}\n */\nexport class MenuItemEl extends ListItemEl implements MenuItem {\n /**\n * READONLY: self-identifies as a menu item and sets its identifying attribute\n */\n @property({type: Boolean, attribute: 'md-menu-item', reflect: true})\n isMenuItem = true;\n\n /**\n * Keeps the menu open if clicked or keyboard selected.\n */\n @property({type: Boolean, attribute: 'keep-open'}) keepOpen = false;\n\n @state() protected hasFocusRing = false;\n\n /**\n * Used for overriding e.g. sub-menu-item.\n */\n protected keepOpenOnClick = false;\n\n override readonly type: ListItemRole = 'menuitem';\n\n protected override onClick() {\n if (this.keepOpen || this.keepOpenOnClick) return;\n\n this.dispatchEvent(createDefaultCloseMenuEvent(\n this, {kind: CLOSE_REASON.CLICK_SELECTION}));\n }\n\n protected override getRenderClasses() {\n return {\n ...super.getRenderClasses(),\n 'has-focus-ring': this.hasFocusRing,\n };\n }\n\n protected override onFocusRingVisibilityChanged(e: Event) {\n const focusRing = e.target as MdFocusRing;\n this.hasFocusRing = focusRing.visible;\n }\n\n protected override onKeydown(event: KeyboardEvent) {\n if (this.keepOpen) return;\n const keyCode = event.code;\n\n if (!event.defaultPrevented && isClosableKey(keyCode)) {\n event.preventDefault();\n this.dispatchEvent(createDefaultCloseMenuEvent(\n this, {kind: CLOSE_REASON.KEYDOWN, key: keyCode}));\n }\n }\n}\n"]}
1
+ {"version":3,"file":"menu-item.js","sourceRoot":"","sources":["menu-item.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAGlD,OAAO,EAAC,UAAU,EAAe,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAC,YAAY,EAAE,2BAA2B,EAAE,aAAa,EAAW,MAAM,cAAc,CAAC;AAIhG;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IAA1C;;QACE;;WAEG;QAEH,eAAU,GAAG,IAAI,CAAC;QAElB;;WAEG;QACgD,aAAQ,GAAG,KAAK,CAAC;QAEjD,iBAAY,GAAG,KAAK,CAAC;QAExC;;WAEG;QACO,oBAAe,GAAG,KAAK,CAAC;QAEhB,SAAI,GAAiB,UAAU,CAAC;IA+BpD,CAAC;IA7BoB,OAAO;QACxB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO;QAElD,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAC1C,IAAI,EAAE,EAAC,IAAI,EAAE,YAAY,CAAC,eAAe,EAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAEkB,gBAAgB;QACjC,OAAO;YACL,GAAG,KAAK,CAAC,gBAAgB,EAAE;YAC3B,gBAAgB,EAAE,IAAI,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAEkB,4BAA4B,CAAC,CAAQ;QACtD,MAAM,SAAS,GAAG,CAAC,CAAC,MAAqB,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC;IACxC,CAAC;IAEkB,SAAS,CAAC,KAAoB;QAC/C,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,gBAAgB;YAAE,OAAO;QACpD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QAE3B,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE;YACrD,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,2BAA2B,CAC1C,IAAI,EAAE,EAAC,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAC,CAAC,CAAC,CAAC;SACxD;IACH,CAAC;CACF;AA7CC;IADC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;8CAClD;AAKiC;IAAlD,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAC,CAAC;4CAAkB;AAE3D;IAAR,KAAK,EAAE;gDAAgC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {property, state} from 'lit/decorators.js';\n\nimport type {MdFocusRing} from '../../../focus/md-focus-ring.js';\nimport {ListItemEl, ListItemRole} from '../../../list/internal/listitem/list-item.js';\nimport {CLOSE_REASON, createDefaultCloseMenuEvent, isClosableKey, MenuItem} from '../shared.js';\n\nexport {ListItemRole} from '../../../list/internal/listitem/list-item.js';\n\n/**\n * @fires close-menu {CloseMenuEvent}\n */\nexport class MenuItemEl extends ListItemEl implements MenuItem {\n /**\n * READONLY: self-identifies as a menu item and sets its identifying attribute\n */\n @property({type: Boolean, attribute: 'md-menu-item', reflect: true})\n isMenuItem = true;\n\n /**\n * Keeps the menu open if clicked or keyboard selected.\n */\n @property({type: Boolean, attribute: 'keep-open'}) keepOpen = false;\n\n @state() protected hasFocusRing = false;\n\n /**\n * Used for overriding e.g. sub-menu-item.\n */\n protected keepOpenOnClick = false;\n\n override readonly type: ListItemRole = 'menuitem';\n\n protected override onClick() {\n if (this.keepOpen || this.keepOpenOnClick) return;\n\n this.dispatchEvent(createDefaultCloseMenuEvent(\n this, {kind: CLOSE_REASON.CLICK_SELECTION}));\n }\n\n protected override getRenderClasses() {\n return {\n ...super.getRenderClasses(),\n 'has-focus-ring': this.hasFocusRing,\n };\n }\n\n protected override onFocusRingVisibilityChanged(e: Event) {\n const focusRing = e.target as MdFocusRing;\n this.hasFocusRing = focusRing.visible;\n }\n\n protected override onKeydown(event: KeyboardEvent) {\n if (this.keepOpen || event.defaultPrevented) return;\n const keyCode = event.code;\n\n if (!event.defaultPrevented && isClosableKey(keyCode)) {\n event.preventDefault();\n this.dispatchEvent(createDefaultCloseMenuEvent(\n this, {kind: CLOSE_REASON.KEYDOWN, key: keyCode}));\n }\n }\n}\n"]}
@@ -3,6 +3,7 @@
3
3
  * Copyright 2023 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import { PropertyValues } from 'lit';
6
7
  import { Corner } from '../menu.js';
7
8
  import { MenuItemEl } from '../menuitem/menu-item.js';
8
9
  /**
@@ -40,6 +41,7 @@ export declare class SubMenuItem extends MenuItemEl {
40
41
  */
41
42
  selected: boolean;
42
43
  protected submenuHover: boolean;
44
+ private readonly rippleEl;
43
45
  private readonly menus;
44
46
  protected keepOpenOnClick: boolean;
45
47
  private previousOpenTimeout;
@@ -74,6 +76,7 @@ export declare class SubMenuItem extends MenuItemEl {
74
76
  * Renders the slot for the submenu.
75
77
  */
76
78
  private renderSubMenu;
79
+ firstUpdated(changed: PropertyValues<this>): void;
77
80
  private onCloseSubmenu;
78
81
  private onSubMenuKeydown;
79
82
  /**
@@ -5,13 +5,10 @@
5
5
  */
6
6
  import { __decorate } from "tslib";
7
7
  import { html } from 'lit';
8
- import { property, queryAssignedElements, state } from 'lit/decorators.js';
8
+ import { property, query, queryAssignedElements, state } from 'lit/decorators.js';
9
9
  import { List } from '../../../list/internal/list.js';
10
10
  import { MenuItemEl } from '../menuitem/menu-item.js';
11
11
  import { CLOSE_REASON, createActivateTypeaheadEvent, createCloseOnFocusoutEvent, createDeactivateItemsEvent, createDeactivateTypeaheadEvent, createStayOpenOnFocusoutEvent, KEYDOWN_CLOSE_KEYS, NAVIGABLE_KEY, SELECTION_KEY } from '../shared.js';
12
- function stopPropagation(event) {
13
- event.stopPropagation();
14
- }
15
12
  /**
16
13
  * @fires deactivate-items Requests the parent menu to deselect other items when
17
14
  * a submenu opens
@@ -103,6 +100,8 @@ export class SubMenuItem extends MenuItemEl {
103
100
  */
104
101
  onKeydown(event) {
105
102
  const shouldOpenSubmenu = this.isSubmenuOpenKey(event.code);
103
+ if (event.defaultPrevented)
104
+ return;
106
105
  if (event.code === SELECTION_KEY.SPACE) {
107
106
  // prevent space from scrolling. Only open the submenu.
108
107
  event.preventDefault();
@@ -137,12 +136,17 @@ export class SubMenuItem extends MenuItemEl {
137
136
  name="submenu"
138
137
  @pointerenter=${this.onSubmenuPointerEnter}
139
138
  @pointerleave=${this.onSubmenuPointerLeave}
140
- @pointerdown=${stopPropagation}
141
- @click=${stopPropagation}
142
139
  @keydown=${this.onSubMenuKeydown}
143
140
  @close-menu=${this.onCloseSubmenu}
144
141
  ></slot></span>`;
145
142
  }
143
+ firstUpdated(changed) {
144
+ super.firstUpdated(changed);
145
+ const { handleEvent } = this.rippleEl;
146
+ // TODO(b/298476971): remove once ripple has a better solution
147
+ this.rippleEl.handleEvent =
148
+ callIfEventNotBubbledThroughMenu(this, handleEvent.bind(this.rippleEl));
149
+ }
146
150
  onCloseSubmenu(event) {
147
151
  const { itemPath, reason } = event.detail;
148
152
  itemPath.push(this);
@@ -164,13 +168,15 @@ export class SubMenuItem extends MenuItemEl {
164
168
  this.selected = false;
165
169
  }
166
170
  async onSubMenuKeydown(event) {
167
- // Stop propagation so that we don't accidentally close every parent menu.
168
- // Additionally, we want to isolate things like the typeahead keydowns
169
- // from bubbling up to the parent menu and confounding things.
170
- event.stopPropagation();
171
+ if (event.defaultPrevented)
172
+ return;
171
173
  const shouldClose = this.isSubmenuCloseKey(event.code);
172
174
  if (!shouldClose)
173
175
  return;
176
+ // Communicate that it's handled so that we don't accidentally close every
177
+ // parent menu. Additionally, we want to isolate things like the typeahead
178
+ // keydowns from bubbling up to the parent menu and confounding things.
179
+ event.preventDefault();
174
180
  this.close(() => {
175
181
  List.deactivateActiveItem(this.submenuEl.items);
176
182
  this.listItemRoot?.focus();
@@ -184,7 +190,7 @@ export class SubMenuItem extends MenuItemEl {
184
190
  */
185
191
  show(onOpened = () => { }) {
186
192
  const menu = this.submenuEl;
187
- if (!menu)
193
+ if (!menu || menu.open)
188
194
  return;
189
195
  menu.quick = true;
190
196
  // Submenus are in overflow when not fixed. Can remove once we have native
@@ -192,7 +198,7 @@ export class SubMenuItem extends MenuItemEl {
192
198
  menu.hasOverflow = true;
193
199
  menu.anchorCorner = this.anchorCorner;
194
200
  menu.menuCorner = this.menuCorner;
195
- menu.anchor = this;
201
+ menu.anchorElement = this;
196
202
  // We manually set focus with `active` on keyboard navigation. And we
197
203
  // want to focus the root on hover, so the user can pick up navigation with
198
204
  // keyboard after hover.
@@ -302,7 +308,31 @@ __decorate([
302
308
  __decorate([
303
309
  state()
304
310
  ], SubMenuItem.prototype, "submenuHover", void 0);
311
+ __decorate([
312
+ query('md-ripple')
313
+ ], SubMenuItem.prototype, "rippleEl", void 0);
305
314
  __decorate([
306
315
  queryAssignedElements({ slot: 'submenu', flatten: true })
307
316
  ], SubMenuItem.prototype, "menus", void 0);
317
+ /**
318
+ * Calls the given callback if the event has not bubbled through an md-menu.
319
+ */
320
+ function callIfEventNotBubbledThroughMenu(menuItem, callback) {
321
+ return async (event) => {
322
+ const path = event.composedPath();
323
+ for (const element of path) {
324
+ const isMenu = !!element?.hasAttribute?.('md-menu');
325
+ // The path has a submenu, do not invoke callback;
326
+ if (isMenu)
327
+ return;
328
+ // We have reached the target submenu. Any other menus in path are
329
+ // ancestors.
330
+ if (element === menuItem) {
331
+ break;
332
+ }
333
+ }
334
+ // invoke the callback because we have not run into a submenu.
335
+ await callback(event);
336
+ };
337
+ }
308
338
  //# sourceMappingURL=sub-menu-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sub-menu-item.js","sourceRoot":"","sources":["sub-menu-item.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 {html} from 'lit';\nimport {property, queryAssignedElements, state} from 'lit/decorators.js';\n\nimport {List} from '../../../list/internal/list.js';\nimport {Corner, Menu} from '../menu.js';\nimport {MenuItemEl} from '../menuitem/menu-item.js';\nimport {CLOSE_REASON, CloseMenuEvent, createActivateTypeaheadEvent, createCloseOnFocusoutEvent, createDeactivateItemsEvent, createDeactivateTypeaheadEvent, createStayOpenOnFocusoutEvent, KEYDOWN_CLOSE_KEYS, NAVIGABLE_KEY, SELECTION_KEY} from '../shared.js';\n\nfunction stopPropagation(event: Event) {\n event.stopPropagation();\n}\n\n/**\n * @fires deactivate-items Requests the parent menu to deselect other items when\n * a submenu opens\n * @fires deactivate-typeahead Requests the parent menu to deactivate the\n * typeahead functionality when a submenu opens\n * @fires activate-typeahead Requests the parent menu to activate the typeahead\n * functionality when a submenu closes\n * @fires stay-open-on-focusout Requests the parent menu to stay open when\n * focusout event is fired or has a `null` `relatedTarget` when submenu is\n * opened.\n * @fires close-on-focusout Requests the parent menu to close when focusout\n * event is fired or has a `null` `relatedTarget` When submenu is closed.\n */\nexport class SubMenuItem extends MenuItemEl {\n /**\n * The anchorCorner to set on the submenu.\n */\n @property({attribute: 'anchor-corner'}) anchorCorner: Corner = 'START_END';\n /**\n * The menuCorner to set on the submenu.\n */\n @property({attribute: 'menu-corner'}) menuCorner: Corner = 'START_START';\n /**\n * The delay between pointerenter and submenu opening.\n */\n @property({type: Number, attribute: 'hover-open-delay'}) hoverOpenDelay = 400;\n /**\n * The delay between ponterleave and the submenu closing.\n */\n @property({type: Number, attribute: 'hover-close-delay'})\n hoverCloseDelay = 400;\n /**\n * Sets the item in the selected visual state when a submenu is opened.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n @state() protected submenuHover = false;\n\n @queryAssignedElements({slot: 'submenu', flatten: true})\n private readonly menus!: Menu[];\n\n protected override keepOpenOnClick = true;\n private previousOpenTimeout = 0;\n private previousCloseTimeout = 0;\n\n private get submenuEl(): Menu|undefined {\n return this.menus[0];\n }\n\n /**\n * Starts the default 400ms countdown to open the submenu.\n */\n protected override onPointerenter = () => {\n clearTimeout(this.previousOpenTimeout);\n clearTimeout(this.previousCloseTimeout);\n if (this.submenuEl?.open) return;\n\n // Open synchronously if delay is 0. (screenshot tests infra\n // would never resolve otherwise)\n if (!this.hoverOpenDelay) {\n this.show();\n } else {\n this.previousOpenTimeout = setTimeout(() => {\n this.show();\n }, this.hoverOpenDelay);\n }\n };\n\n /**\n * Starts the default 400ms countdown to close the submenu.\n */\n protected override onPointerleave = () => {\n clearTimeout(this.previousCloseTimeout);\n clearTimeout(this.previousOpenTimeout);\n\n // Close synchronously if delay is 0. (screenshot tests infra\n // would never resolve otherwise)\n if (!this.hoverCloseDelay) {\n this.close();\n } else {\n this.previousCloseTimeout = setTimeout(() => {\n this.close();\n }, this.hoverCloseDelay);\n }\n };\n\n protected override onClick() {\n this.show();\n }\n\n protected override getRenderClasses() {\n return {...super.getRenderClasses(), 'submenu-hover': this.submenuHover};\n }\n\n /**\n * On item keydown handles opening the submenu.\n */\n protected override onKeydown(event: KeyboardEvent) {\n const shouldOpenSubmenu = this.isSubmenuOpenKey(event.code);\n\n if (event.code === SELECTION_KEY.SPACE) {\n // prevent space from scrolling. Only open the submenu.\n event.preventDefault();\n }\n\n if (!shouldOpenSubmenu) {\n super.onKeydown(event);\n return;\n }\n\n const submenu = this.submenuEl;\n if (!submenu) return;\n\n const submenuItems = submenu.items;\n const firstActivatableItem = List.getFirstActivatableItem(submenuItems);\n\n if (firstActivatableItem) {\n this.show(() => {\n firstActivatableItem.active = true;\n });\n\n return;\n }\n }\n\n /**\n * Render the submenu at the end\n */\n protected override renderEnd() {\n return html`${super.renderEnd()}${this.renderSubMenu()}`;\n }\n\n /**\n * Renders the slot for the submenu.\n */\n private renderSubMenu() {\n return html`<span class=\"submenu\"><slot\n name=\"submenu\"\n @pointerenter=${this.onSubmenuPointerEnter}\n @pointerleave=${this.onSubmenuPointerLeave}\n @pointerdown=${stopPropagation}\n @click=${stopPropagation}\n @keydown=${this.onSubMenuKeydown}\n @close-menu=${this.onCloseSubmenu}\n ></slot></span>`;\n }\n\n private onCloseSubmenu(event: CloseMenuEvent) {\n const {itemPath, reason} = event.detail;\n itemPath.push(this);\n // Restore focusout behavior\n this.dispatchEvent(createCloseOnFocusoutEvent());\n this.dispatchEvent(createActivateTypeaheadEvent());\n // Escape should only close one menu not all of the menus unlike space or\n // click selection which should close all menus.\n if (reason.kind === CLOSE_REASON.KEYDOWN &&\n reason.key === KEYDOWN_CLOSE_KEYS.ESCAPE) {\n event.stopPropagation();\n this.active = true;\n this.selected = false;\n // It might already be active so manually focus\n this.listItemRoot?.focus();\n return;\n }\n\n this.active = false;\n this.selected = false;\n }\n\n private async onSubMenuKeydown(event: KeyboardEvent) {\n // Stop propagation so that we don't accidentally close every parent menu.\n // Additionally, we want to isolate things like the typeahead keydowns\n // from bubbling up to the parent menu and confounding things.\n event.stopPropagation();\n const shouldClose = this.isSubmenuCloseKey(event.code);\n\n if (!shouldClose) return;\n\n this.close(() => {\n List.deactivateActiveItem(this.submenuEl!.items);\n this.listItemRoot?.focus();\n this.active = true;\n });\n }\n\n /**\n * Shows the submenu.\n *\n * @param onOpened A function to call after the menu is opened.\n */\n show(onOpened = () => {}) {\n const menu = this.submenuEl;\n if (!menu) return;\n\n menu.quick = true;\n // Submenus are in overflow when not fixed. Can remove once we have native\n // popup support\n menu.hasOverflow = true;\n menu.anchorCorner = this.anchorCorner;\n menu.menuCorner = this.menuCorner;\n menu.anchor = this;\n // We manually set focus with `active` on keyboard navigation. And we\n // want to focus the root on hover, so the user can pick up navigation with\n // keyboard after hover.\n menu.defaultFocus = 'LIST_ROOT';\n menu.skipRestoreFocus = true;\n menu.stayOpenOnOutsideClick = true;\n menu.stayOpenOnFocusout = true;\n\n // Menu could already be opened because of mouse interaction\n const menuAlreadyOpen = menu.open;\n // We want the parent to stay open in the case such that a middle submenu\n // has a submenuitem hovered which opens a third submenut. Then if you hover\n // on yet another middle menu-item (not submenuitem) then focusout Event's\n // relatedTarget will be `null` thus, causing all the menus to close\n this.dispatchEvent(createStayOpenOnFocusoutEvent());\n menu.show();\n\n // Deactivate other items. This can be the case if the user has tabbed\n // around the menu and then mouses over an md-sub-menu.\n this.dispatchEvent(createDeactivateItemsEvent());\n this.dispatchEvent(createDeactivateTypeaheadEvent());\n this.selected = true;\n\n // This is the case of mouse hovering when already opened via keyboard or\n // vice versa\n if (menuAlreadyOpen) {\n onOpened();\n } else {\n menu.addEventListener('opened', onOpened, {once: true});\n }\n }\n\n /**\n * Closes the submenu.\n *\n * @param onClosed A function to call after the menu is closed.\n */\n close(onClosed = () => {}) {\n const menu = this.submenuEl;\n if (!menu || !menu.open) return;\n\n this.dispatchEvent(createActivateTypeaheadEvent());\n menu.quick = true;\n menu.close();\n // Restore focusout behavior.\n this.dispatchEvent(createCloseOnFocusoutEvent());\n this.active = false;\n this.selected = false;\n menu.addEventListener('closed', onClosed, {once: true});\n }\n\n /**\n * Determines whether the given KeyboardEvent code is one that should open\n * the submenu. This is RTL-aware. By default, left, right, space, or enter.\n *\n * @param code The native KeyboardEvent code.\n * @return Whether or not the key code should open the submenu.\n */\n private isSubmenuOpenKey(code: string) {\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const arrowEnterKey = isRtl ? NAVIGABLE_KEY.LEFT : NAVIGABLE_KEY.RIGHT;\n switch (code) {\n case arrowEnterKey:\n case SELECTION_KEY.SPACE:\n case SELECTION_KEY.ENTER:\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Determines whether the given KeyboardEvent code is one that should close\n * the submenu. This is RTL-aware. By default right, left, or escape.\n *\n * @param code The native KeyboardEvent code.\n * @return Whether or not the key code should close the submenu.\n */\n private isSubmenuCloseKey(code: string) {\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const arrowEnterKey = isRtl ? NAVIGABLE_KEY.RIGHT : NAVIGABLE_KEY.LEFT;\n switch (code) {\n case arrowEnterKey:\n case KEYDOWN_CLOSE_KEYS.ESCAPE:\n return true;\n default:\n return false;\n }\n }\n\n private onSubmenuPointerEnter() {\n this.submenuHover = true;\n }\n\n private onSubmenuPointerLeave() {\n this.submenuHover = false;\n }\n}\n"]}
1
+ {"version":3,"file":"sub-menu-item.js","sourceRoot":"","sources":["sub-menu-item.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 {html, PropertyValues} from 'lit';\nimport {property, query, queryAssignedElements, state} from 'lit/decorators.js';\n\nimport {List} from '../../../list/internal/list.js';\nimport {MdRipple} from '../../../ripple/ripple.js';\nimport {Corner, Menu} from '../menu.js';\nimport {MenuItemEl} from '../menuitem/menu-item.js';\nimport {CLOSE_REASON, CloseMenuEvent, createActivateTypeaheadEvent, createCloseOnFocusoutEvent, createDeactivateItemsEvent, createDeactivateTypeaheadEvent, createStayOpenOnFocusoutEvent, KEYDOWN_CLOSE_KEYS, NAVIGABLE_KEY, SELECTION_KEY} from '../shared.js';\n\n/**\n * @fires deactivate-items Requests the parent menu to deselect other items when\n * a submenu opens\n * @fires deactivate-typeahead Requests the parent menu to deactivate the\n * typeahead functionality when a submenu opens\n * @fires activate-typeahead Requests the parent menu to activate the typeahead\n * functionality when a submenu closes\n * @fires stay-open-on-focusout Requests the parent menu to stay open when\n * focusout event is fired or has a `null` `relatedTarget` when submenu is\n * opened.\n * @fires close-on-focusout Requests the parent menu to close when focusout\n * event is fired or has a `null` `relatedTarget` When submenu is closed.\n */\nexport class SubMenuItem extends MenuItemEl {\n /**\n * The anchorCorner to set on the submenu.\n */\n @property({attribute: 'anchor-corner'}) anchorCorner: Corner = 'START_END';\n /**\n * The menuCorner to set on the submenu.\n */\n @property({attribute: 'menu-corner'}) menuCorner: Corner = 'START_START';\n /**\n * The delay between pointerenter and submenu opening.\n */\n @property({type: Number, attribute: 'hover-open-delay'}) hoverOpenDelay = 400;\n /**\n * The delay between ponterleave and the submenu closing.\n */\n @property({type: Number, attribute: 'hover-close-delay'})\n hoverCloseDelay = 400;\n /**\n * Sets the item in the selected visual state when a submenu is opened.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n @state() protected submenuHover = false;\n\n @query('md-ripple') private readonly rippleEl!: MdRipple;\n\n @queryAssignedElements({slot: 'submenu', flatten: true})\n private readonly menus!: Menu[];\n\n protected override keepOpenOnClick = true;\n private previousOpenTimeout = 0;\n private previousCloseTimeout = 0;\n\n private get submenuEl(): Menu|undefined {\n return this.menus[0];\n }\n\n /**\n * Starts the default 400ms countdown to open the submenu.\n */\n protected override onPointerenter = () => {\n clearTimeout(this.previousOpenTimeout);\n clearTimeout(this.previousCloseTimeout);\n if (this.submenuEl?.open) return;\n\n // Open synchronously if delay is 0. (screenshot tests infra\n // would never resolve otherwise)\n if (!this.hoverOpenDelay) {\n this.show();\n } else {\n this.previousOpenTimeout = setTimeout(() => {\n this.show();\n }, this.hoverOpenDelay);\n }\n };\n\n /**\n * Starts the default 400ms countdown to close the submenu.\n */\n protected override onPointerleave = () => {\n clearTimeout(this.previousCloseTimeout);\n clearTimeout(this.previousOpenTimeout);\n\n // Close synchronously if delay is 0. (screenshot tests infra\n // would never resolve otherwise)\n if (!this.hoverCloseDelay) {\n this.close();\n } else {\n this.previousCloseTimeout = setTimeout(() => {\n this.close();\n }, this.hoverCloseDelay);\n }\n };\n\n protected override onClick() {\n this.show();\n }\n\n protected override getRenderClasses() {\n return {...super.getRenderClasses(), 'submenu-hover': this.submenuHover};\n }\n\n /**\n * On item keydown handles opening the submenu.\n */\n protected override onKeydown(event: KeyboardEvent) {\n const shouldOpenSubmenu = this.isSubmenuOpenKey(event.code);\n\n if (event.defaultPrevented) return;\n\n if (event.code === SELECTION_KEY.SPACE) {\n // prevent space from scrolling. Only open the submenu.\n event.preventDefault();\n }\n\n if (!shouldOpenSubmenu) {\n super.onKeydown(event);\n return;\n }\n\n const submenu = this.submenuEl;\n if (!submenu) return;\n\n const submenuItems = submenu.items;\n const firstActivatableItem = List.getFirstActivatableItem(submenuItems);\n\n if (firstActivatableItem) {\n this.show(() => {\n firstActivatableItem.active = true;\n });\n\n return;\n }\n }\n\n /**\n * Render the submenu at the end\n */\n protected override renderEnd() {\n return html`${super.renderEnd()}${this.renderSubMenu()}`;\n }\n\n /**\n * Renders the slot for the submenu.\n */\n private renderSubMenu() {\n return html`<span class=\"submenu\"><slot\n name=\"submenu\"\n @pointerenter=${this.onSubmenuPointerEnter}\n @pointerleave=${this.onSubmenuPointerLeave}\n @keydown=${this.onSubMenuKeydown}\n @close-menu=${this.onCloseSubmenu}\n ></slot></span>`;\n }\n\n override firstUpdated(changed: PropertyValues<this>) {\n super.firstUpdated(changed);\n\n const {handleEvent} = this.rippleEl;\n\n // TODO(b/298476971): remove once ripple has a better solution\n this.rippleEl.handleEvent =\n callIfEventNotBubbledThroughMenu(this, handleEvent.bind(this.rippleEl));\n }\n\n private onCloseSubmenu(event: CloseMenuEvent) {\n const {itemPath, reason} = event.detail;\n itemPath.push(this);\n // Restore focusout behavior\n this.dispatchEvent(createCloseOnFocusoutEvent());\n this.dispatchEvent(createActivateTypeaheadEvent());\n // Escape should only close one menu not all of the menus unlike space or\n // click selection which should close all menus.\n if (reason.kind === CLOSE_REASON.KEYDOWN &&\n reason.key === KEYDOWN_CLOSE_KEYS.ESCAPE) {\n event.stopPropagation();\n this.active = true;\n this.selected = false;\n // It might already be active so manually focus\n this.listItemRoot?.focus();\n return;\n }\n\n this.active = false;\n this.selected = false;\n }\n\n private async onSubMenuKeydown(event: KeyboardEvent) {\n if (event.defaultPrevented) return;\n const shouldClose = this.isSubmenuCloseKey(event.code);\n\n if (!shouldClose) return;\n\n // Communicate that it's handled so that we don't accidentally close every\n // parent menu. Additionally, we want to isolate things like the typeahead\n // keydowns from bubbling up to the parent menu and confounding things.\n event.preventDefault();\n\n this.close(() => {\n List.deactivateActiveItem(this.submenuEl!.items);\n this.listItemRoot?.focus();\n this.active = true;\n });\n }\n\n /**\n * Shows the submenu.\n *\n * @param onOpened A function to call after the menu is opened.\n */\n show(onOpened = () => {}) {\n const menu = this.submenuEl;\n if (!menu || menu.open) return;\n\n menu.quick = true;\n // Submenus are in overflow when not fixed. Can remove once we have native\n // popup support\n menu.hasOverflow = true;\n menu.anchorCorner = this.anchorCorner;\n menu.menuCorner = this.menuCorner;\n menu.anchorElement = this;\n // We manually set focus with `active` on keyboard navigation. And we\n // want to focus the root on hover, so the user can pick up navigation with\n // keyboard after hover.\n menu.defaultFocus = 'LIST_ROOT';\n menu.skipRestoreFocus = true;\n menu.stayOpenOnOutsideClick = true;\n menu.stayOpenOnFocusout = true;\n\n // Menu could already be opened because of mouse interaction\n const menuAlreadyOpen = menu.open;\n // We want the parent to stay open in the case such that a middle submenu\n // has a submenuitem hovered which opens a third submenut. Then if you hover\n // on yet another middle menu-item (not submenuitem) then focusout Event's\n // relatedTarget will be `null` thus, causing all the menus to close\n this.dispatchEvent(createStayOpenOnFocusoutEvent());\n menu.show();\n\n // Deactivate other items. This can be the case if the user has tabbed\n // around the menu and then mouses over an md-sub-menu.\n this.dispatchEvent(createDeactivateItemsEvent());\n this.dispatchEvent(createDeactivateTypeaheadEvent());\n this.selected = true;\n\n // This is the case of mouse hovering when already opened via keyboard or\n // vice versa\n if (menuAlreadyOpen) {\n onOpened();\n } else {\n menu.addEventListener('opened', onOpened, {once: true});\n }\n }\n\n /**\n * Closes the submenu.\n *\n * @param onClosed A function to call after the menu is closed.\n */\n close(onClosed = () => {}) {\n const menu = this.submenuEl;\n if (!menu || !menu.open) return;\n\n this.dispatchEvent(createActivateTypeaheadEvent());\n menu.quick = true;\n menu.close();\n // Restore focusout behavior.\n this.dispatchEvent(createCloseOnFocusoutEvent());\n this.active = false;\n this.selected = false;\n menu.addEventListener('closed', onClosed, {once: true});\n }\n\n /**\n * Determines whether the given KeyboardEvent code is one that should open\n * the submenu. This is RTL-aware. By default, left, right, space, or enter.\n *\n * @param code The native KeyboardEvent code.\n * @return Whether or not the key code should open the submenu.\n */\n private isSubmenuOpenKey(code: string) {\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const arrowEnterKey = isRtl ? NAVIGABLE_KEY.LEFT : NAVIGABLE_KEY.RIGHT;\n switch (code) {\n case arrowEnterKey:\n case SELECTION_KEY.SPACE:\n case SELECTION_KEY.ENTER:\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Determines whether the given KeyboardEvent code is one that should close\n * the submenu. This is RTL-aware. By default right, left, or escape.\n *\n * @param code The native KeyboardEvent code.\n * @return Whether or not the key code should close the submenu.\n */\n private isSubmenuCloseKey(code: string) {\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const arrowEnterKey = isRtl ? NAVIGABLE_KEY.RIGHT : NAVIGABLE_KEY.LEFT;\n switch (code) {\n case arrowEnterKey:\n case KEYDOWN_CLOSE_KEYS.ESCAPE:\n return true;\n default:\n return false;\n }\n }\n\n private onSubmenuPointerEnter() {\n this.submenuHover = true;\n }\n\n private onSubmenuPointerLeave() {\n this.submenuHover = false;\n }\n}\n\n/**\n * Calls the given callback if the event has not bubbled through an md-menu.\n */\nfunction callIfEventNotBubbledThroughMenu(\n menuItem: HTMLElement, callback: (event: Event) => Promise<void>) {\n return async (event: Event) => {\n const path = event.composedPath();\n\n for (const element of path) {\n const isMenu =\n !!(element as Element | HTMLElement)?.hasAttribute?.('md-menu');\n\n // The path has a submenu, do not invoke callback;\n if (isMenu) return;\n\n // We have reached the target submenu. Any other menus in path are\n // ancestors.\n if (element === menuItem) {\n break;\n }\n }\n\n // invoke the callback because we have not run into a submenu.\n await callback(event);\n };\n}"]}
@@ -165,6 +165,8 @@ export class TypeaheadController {
165
165
  * activates Olive
166
166
  */
167
167
  typeahead(event) {
168
+ if (event.defaultPrevented)
169
+ return;
168
170
  clearTimeout(this.cancelTypeaheadTimeout);
169
171
  // Stop typingahead if one of the navigation or selection keys (except for
170
172
  // Space) are pressed
@@ -178,7 +180,6 @@ export class TypeaheadController {
178
180
  }
179
181
  // If Space is pressed, prevent it from selecting and closing the menu
180
182
  if (event.code === 'Space') {
181
- event.stopPropagation();
182
183
  event.preventDefault();
183
184
  }
184
185
  // Start up a new keystroke buffer timeout
@@ -1 +1 @@
1
- {"version":3,"file":"typeaheadController.js","sourceRoot":"","sources":["typeaheadController.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8BH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;CACC,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAO,mBAAmB;IAsB9B;;;;;;;;;OASG;IACH,YACqB,aAAkD;QAAlD,kBAAa,GAAb,aAAa,CAAqC;QAhCvE;;WAEG;QACK,qBAAgB,GAAsB,EAAE,CAAC;QACjD;;WAEG;QACK,mBAAc,GAAG,EAAE,CAAC;QAC5B;;WAEG;QACK,2BAAsB,GAAG,CAAC,CAAC;QACnC;;WAEG;QACH,kBAAa,GAAG,KAAK,CAAC;QACtB;;WAEG;QACH,qBAAgB,GAAyB,IAAI,CAAC;QAwB9C;;;;;WAKG;QACM,cAAS,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC5C,IAAI,IAAI,CAAC,aAAa,EAAE;gBACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;aACvB;iBAAM;gBACL,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;aAC5B;QACH,CAAC,CAAC;QAuKF;;WAEG;QACc,iBAAY,GAAG,GAAG,EAAE;YACnC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC7B,CAAC,CAAC;IApMC,CAAC;IAEJ,IAAY,KAAK;QACf,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC;IAED,IAAY,MAAM;QAChB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC;IACrC,CAAC;IAgBD;;OAEG;IACK,cAAc,CAAC,KAAoB;QACzC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO;SACR;QAED,2EAA2E;QAC3E,yEAAyE;QACzE,wBAAwB;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;YAChD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;YAC7D,OAAO;SACR;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,4EAA4E;QAC5E,2BAA2B;QAC3B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAClC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,gBAAgB;YACjB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CACtB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;gBACnD,IAAI,CAAC;QACT,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;SAC7D;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACK,SAAS,CAAC,KAAoB;QACpC,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC1C,0EAA0E;QAC1E,qBAAqB;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YACxD,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;YAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,gBAAgB,EAAE;gBACzB,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;aAC7D;YACD,OAAO;SACR;QAED,sEAAsE;QACtE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE;YAC1B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,KAAK,CAAC,cAAc,EAAE,CAAC;SACxB;QAED,0CAA0C;QAC1C,IAAI,CAAC,sBAAsB;YACvB,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,mBAAmB,CAAC,CAAC;QAE5E,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QAE/C,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC3C,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACP,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAEhD;;;;;;;;;;;;;;;;;;;;;WAqBG;QACH,MAAM,mBAAmB,GAAG,CAAC,MAAuB,EAAE,EAAE;YACtD,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,eAAe,CAAC;gBAClE,UAAU,CAAC;QACjB,CAAC,CAAC;QAEF,qEAAqE;QACrE,MAAM,eAAe,GACjB,IAAI,CAAC,gBAAgB;aAChB,MAAM,CACH,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ;YAC7C,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,UAAU,CACpC,IAAI,CAAC,cAAc,CAAC,CAAC;aAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzE,sEAAsE;QACtE,0EAA0E;QAC1E,+CAA+C;QAC/C,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;YAChC,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC1C,IAAI,IAAI,CAAC,gBAAgB,EAAE;gBACzB,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;aAC7D;YACD,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,OAAO;SACR;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC;QACpD,IAAI,UAA2B,CAAC;QAEhC,4EAA4E;QAC5E,0CAA0C;QAC1C,IAAI,IAAI,CAAC,gBAAgB,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE;YAC9D,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;SACvD;aAAM;YACL,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;SACjC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;SAC7D;QAED,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC;QACnC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAChD,OAAO;IACT,CAAC;CAUF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {MenuItem} from './shared.js';\n\n/**\n * The options that are passed to the typeahead controller.\n */\nexport interface TypeaheadControllerProperties {\n /**\n * A function that returns an array of menu items to be searched.\n * @return An array of menu items to be searched by typing.\n */\n getItems: () => MenuItem[];\n /**\n * The maximum time between each keystroke to keep the current type buffer\n * alive.\n */\n typeaheadBufferTime: number;\n /**\n * Whether or not the typeahead should listen for keystrokes or not.\n */\n active: boolean;\n}\n\n/**\n * Data structure tuple that helps with indexing.\n *\n * [index, item, normalized header text]\n */\ntype TypeaheadRecord = [number, MenuItem, string];\n/**\n * Indicies to access the TypeaheadRecord tuple type.\n */\nexport const TYPEAHEAD_RECORD = {\n INDEX: 0,\n ITEM: 1,\n TEXT: 2,\n} as const;\n\n/**\n * This controller listens to `keydown` events and searches the header text of\n * an array of `MenuItem`s with the corresponding entered keys within the buffer\n * time and activates the item.\n *\n * @example\n * ```ts\n * const typeaheadController = new TypeaheadController(() => ({\n * typeaheadBufferTime: 50,\n * getItems: () => Array.from(document.querySelectorAll('md-menu-item'))\n * }));\n * html`\n * <div\n * @keydown=${typeaheadController.onKeydown}\n * tabindex=\"0\"\n * class=\"activeItemText\">\n * <!-- focusable element that will receive keydown events -->\n * Apple\n * </div>\n * <div>\n * <md-menu-item active header=\"Apple\"></md-menu-item>\n * <md-menu-item header=\"Apricot\"></md-menu-item>\n * <md-menu-item header=\"Banana\"></md-menu-item>\n * <md-menu-item header=\"Olive\"></md-menu-item>\n * <md-menu-item header=\"Orange\"></md-menu-item>\n * </div>\n * `;\n * ```\n */\nexport class TypeaheadController {\n /**\n * Array of tuples that helps with indexing.\n */\n private typeaheadRecords: TypeaheadRecord[] = [];\n /**\n * Currently-typed text since last buffer timeout\n */\n private typaheadBuffer = '';\n /**\n * The timeout id from the current buffer's setTimeout\n */\n private cancelTypeaheadTimeout = 0;\n /**\n * If we are currently \"typing\"\n */\n isTypingAhead = false;\n /**\n * The record of the last active item.\n */\n lastActiveRecord: TypeaheadRecord|null = null;\n\n /**\n * @param getProperties A function that returns the options of the typeahead\n * controller:\n *\n * {\n * getItems: A function that returns an array of menu items to be searched.\n * typeaheadBufferTime: The maximum time between each keystroke to keep the\n * current type buffer alive.\n * }\n */\n constructor(\n private readonly getProperties: () => TypeaheadControllerProperties,\n ) {}\n\n private get items() {\n return this.getProperties().getItems();\n }\n\n private get active() {\n return this.getProperties().active;\n }\n\n /**\n * Apply this listener to the element that will receive `keydown` events that\n * should trigger this controller.\n *\n * @param event The native browser `KeyboardEvent` from the `keydown` event.\n */\n readonly onKeydown = (event: KeyboardEvent) => {\n if (this.isTypingAhead) {\n this.typeahead(event);\n } else {\n this.beginTypeahead(event);\n }\n };\n\n /**\n * Sets up typingahead\n */\n private beginTypeahead(event: KeyboardEvent) {\n if (!this.active) {\n return;\n }\n\n // We don't want to typeahead if the _beginning_ of the typeahead is a menu\n // navigation, or a selection. We will handle \"Space\" only if it's in the\n // middle of a typeahead\n if (event.code === 'Space' || event.code === 'Enter' ||\n event.code.startsWith('Arrow') || event.code === 'Escape') {\n return;\n }\n\n this.isTypingAhead = true;\n // Generates the record array data structure which is the index, the element\n // and a normalized header.\n this.typeaheadRecords = this.items.map(\n (el, index) => [index, el, el.headline.trim().toLowerCase()]);\n this.lastActiveRecord =\n this.typeaheadRecords.find(\n record => record[TYPEAHEAD_RECORD.ITEM].active) ??\n null;\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n this.typeahead(event);\n }\n\n /**\n * Performs the typeahead. Based on the normalized items and the current text\n * buffer, finds the _next_ item with matching text and activates it.\n *\n * @example\n *\n * items: Apple, Banana, Olive, Orange, Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Olive\n *\n * @example\n *\n * items: Apple, Banana, Olive (active), Orange, Cucumber\n * buffer: 'o'\n * user types: l\n *\n * activates Olive\n *\n * @example\n *\n * items: Apple, Banana, Olive (active), Orange, Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Orange\n *\n * @example\n *\n * items: Apple, Banana, Olive, Orange (active), Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Olive\n */\n private typeahead(event: KeyboardEvent) {\n clearTimeout(this.cancelTypeaheadTimeout);\n // Stop typingahead if one of the navigation or selection keys (except for\n // Space) are pressed\n if (event.code === 'Enter' || event.code.startsWith('Arrow') ||\n event.code === 'Escape') {\n this.endTypeahead();\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n return;\n }\n\n // If Space is pressed, prevent it from selecting and closing the menu\n if (event.code === 'Space') {\n event.stopPropagation();\n event.preventDefault();\n }\n\n // Start up a new keystroke buffer timeout\n this.cancelTypeaheadTimeout =\n setTimeout(this.endTypeahead, this.getProperties().typeaheadBufferTime);\n\n this.typaheadBuffer += event.key.toLowerCase();\n\n const lastActiveIndex = this.lastActiveRecord ?\n this.lastActiveRecord[TYPEAHEAD_RECORD.INDEX] :\n -1;\n const numRecords = this.typeaheadRecords.length;\n\n /**\n * Sorting function that will resort the items starting with the given index\n *\n * @example\n *\n * this.typeaheadRecords =\n * 0: [0, <reference>, 'apple']\n * 1: [1, <reference>, 'apricot']\n * 2: [2, <reference>, 'banana']\n * 3: [3, <reference>, 'olive'] <-- lastActiveIndex\n * 4: [4, <reference>, 'orange']\n * 5: [5, <reference>, 'strawberry']\n *\n * this.typeaheadRecords.sort((a,b) => rebaseIndexOnActive(a)\n * - rebaseIndexOnActive(b)) ===\n * 0: [3, <reference>, 'olive'] <-- lastActiveIndex\n * 1: [4, <reference>, 'orange']\n * 2: [5, <reference>, 'strawberry']\n * 3: [0, <reference>, 'apple']\n * 4: [1, <reference>, 'apricot']\n * 5: [2, <reference>, 'banana']\n */\n const rebaseIndexOnActive = (record: TypeaheadRecord) => {\n return (record[TYPEAHEAD_RECORD.INDEX] + numRecords - lastActiveIndex) %\n numRecords;\n };\n\n // records filtered and sorted / rebased around the last active index\n const matchingRecords =\n this.typeaheadRecords\n .filter(\n record => !record[TYPEAHEAD_RECORD.ITEM].disabled &&\n record[TYPEAHEAD_RECORD.TEXT].startsWith(\n this.typaheadBuffer))\n .sort((a, b) => rebaseIndexOnActive(a) - rebaseIndexOnActive(b));\n\n // Just leave if there's nothing that matches. Native select will just\n // choose the first thing that starts with the next letter in the alphabet\n // but that's out of scope and hard to localize\n if (matchingRecords.length === 0) {\n clearTimeout(this.cancelTypeaheadTimeout);\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n this.endTypeahead();\n return;\n }\n\n const isNewQuery = this.typaheadBuffer.length === 1;\n let nextRecord: TypeaheadRecord;\n\n // This is likely the case that someone is trying to \"tab\" through different\n // entries that start with the same letter\n if (this.lastActiveRecord === matchingRecords[0] && isNewQuery) {\n nextRecord = matchingRecords[1] ?? matchingRecords[0];\n } else {\n nextRecord = matchingRecords[0];\n }\n\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n\n this.lastActiveRecord = nextRecord;\n nextRecord[TYPEAHEAD_RECORD.ITEM].active = true;\n return;\n }\n\n /**\n * Ends the current typeahead and clears the buffer.\n */\n private readonly endTypeahead = () => {\n this.isTypingAhead = false;\n this.typaheadBuffer = '';\n this.typeaheadRecords = [];\n };\n}\n"]}
1
+ {"version":3,"file":"typeaheadController.js","sourceRoot":"","sources":["typeaheadController.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 {MenuItem} from './shared.js';\n\n/**\n * The options that are passed to the typeahead controller.\n */\nexport interface TypeaheadControllerProperties {\n /**\n * A function that returns an array of menu items to be searched.\n * @return An array of menu items to be searched by typing.\n */\n getItems: () => MenuItem[];\n /**\n * The maximum time between each keystroke to keep the current type buffer\n * alive.\n */\n typeaheadBufferTime: number;\n /**\n * Whether or not the typeahead should listen for keystrokes or not.\n */\n active: boolean;\n}\n\n/**\n * Data structure tuple that helps with indexing.\n *\n * [index, item, normalized header text]\n */\ntype TypeaheadRecord = [number, MenuItem, string];\n/**\n * Indicies to access the TypeaheadRecord tuple type.\n */\nexport const TYPEAHEAD_RECORD = {\n INDEX: 0,\n ITEM: 1,\n TEXT: 2,\n} as const;\n\n/**\n * This controller listens to `keydown` events and searches the header text of\n * an array of `MenuItem`s with the corresponding entered keys within the buffer\n * time and activates the item.\n *\n * @example\n * ```ts\n * const typeaheadController = new TypeaheadController(() => ({\n * typeaheadBufferTime: 50,\n * getItems: () => Array.from(document.querySelectorAll('md-menu-item'))\n * }));\n * html`\n * <div\n * @keydown=${typeaheadController.onKeydown}\n * tabindex=\"0\"\n * class=\"activeItemText\">\n * <!-- focusable element that will receive keydown events -->\n * Apple\n * </div>\n * <div>\n * <md-menu-item active header=\"Apple\"></md-menu-item>\n * <md-menu-item header=\"Apricot\"></md-menu-item>\n * <md-menu-item header=\"Banana\"></md-menu-item>\n * <md-menu-item header=\"Olive\"></md-menu-item>\n * <md-menu-item header=\"Orange\"></md-menu-item>\n * </div>\n * `;\n * ```\n */\nexport class TypeaheadController {\n /**\n * Array of tuples that helps with indexing.\n */\n private typeaheadRecords: TypeaheadRecord[] = [];\n /**\n * Currently-typed text since last buffer timeout\n */\n private typaheadBuffer = '';\n /**\n * The timeout id from the current buffer's setTimeout\n */\n private cancelTypeaheadTimeout = 0;\n /**\n * If we are currently \"typing\"\n */\n isTypingAhead = false;\n /**\n * The record of the last active item.\n */\n lastActiveRecord: TypeaheadRecord|null = null;\n\n /**\n * @param getProperties A function that returns the options of the typeahead\n * controller:\n *\n * {\n * getItems: A function that returns an array of menu items to be searched.\n * typeaheadBufferTime: The maximum time between each keystroke to keep the\n * current type buffer alive.\n * }\n */\n constructor(\n private readonly getProperties: () => TypeaheadControllerProperties,\n ) {}\n\n private get items() {\n return this.getProperties().getItems();\n }\n\n private get active() {\n return this.getProperties().active;\n }\n\n /**\n * Apply this listener to the element that will receive `keydown` events that\n * should trigger this controller.\n *\n * @param event The native browser `KeyboardEvent` from the `keydown` event.\n */\n readonly onKeydown = (event: KeyboardEvent) => {\n if (this.isTypingAhead) {\n this.typeahead(event);\n } else {\n this.beginTypeahead(event);\n }\n };\n\n /**\n * Sets up typingahead\n */\n private beginTypeahead(event: KeyboardEvent) {\n if (!this.active) {\n return;\n }\n\n // We don't want to typeahead if the _beginning_ of the typeahead is a menu\n // navigation, or a selection. We will handle \"Space\" only if it's in the\n // middle of a typeahead\n if (event.code === 'Space' || event.code === 'Enter' ||\n event.code.startsWith('Arrow') || event.code === 'Escape') {\n return;\n }\n\n this.isTypingAhead = true;\n // Generates the record array data structure which is the index, the element\n // and a normalized header.\n this.typeaheadRecords = this.items.map(\n (el, index) => [index, el, el.headline.trim().toLowerCase()]);\n this.lastActiveRecord =\n this.typeaheadRecords.find(\n record => record[TYPEAHEAD_RECORD.ITEM].active) ??\n null;\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n this.typeahead(event);\n }\n\n /**\n * Performs the typeahead. Based on the normalized items and the current text\n * buffer, finds the _next_ item with matching text and activates it.\n *\n * @example\n *\n * items: Apple, Banana, Olive, Orange, Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Olive\n *\n * @example\n *\n * items: Apple, Banana, Olive (active), Orange, Cucumber\n * buffer: 'o'\n * user types: l\n *\n * activates Olive\n *\n * @example\n *\n * items: Apple, Banana, Olive (active), Orange, Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Orange\n *\n * @example\n *\n * items: Apple, Banana, Olive, Orange (active), Cucumber\n * buffer: ''\n * user types: o\n *\n * activates Olive\n */\n private typeahead(event: KeyboardEvent) {\n if (event.defaultPrevented) return;\n clearTimeout(this.cancelTypeaheadTimeout);\n // Stop typingahead if one of the navigation or selection keys (except for\n // Space) are pressed\n if (event.code === 'Enter' || event.code.startsWith('Arrow') ||\n event.code === 'Escape') {\n this.endTypeahead();\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n return;\n }\n\n // If Space is pressed, prevent it from selecting and closing the menu\n if (event.code === 'Space') {\n event.preventDefault();\n }\n\n // Start up a new keystroke buffer timeout\n this.cancelTypeaheadTimeout =\n setTimeout(this.endTypeahead, this.getProperties().typeaheadBufferTime);\n\n this.typaheadBuffer += event.key.toLowerCase();\n\n const lastActiveIndex = this.lastActiveRecord ?\n this.lastActiveRecord[TYPEAHEAD_RECORD.INDEX] :\n -1;\n const numRecords = this.typeaheadRecords.length;\n\n /**\n * Sorting function that will resort the items starting with the given index\n *\n * @example\n *\n * this.typeaheadRecords =\n * 0: [0, <reference>, 'apple']\n * 1: [1, <reference>, 'apricot']\n * 2: [2, <reference>, 'banana']\n * 3: [3, <reference>, 'olive'] <-- lastActiveIndex\n * 4: [4, <reference>, 'orange']\n * 5: [5, <reference>, 'strawberry']\n *\n * this.typeaheadRecords.sort((a,b) => rebaseIndexOnActive(a)\n * - rebaseIndexOnActive(b)) ===\n * 0: [3, <reference>, 'olive'] <-- lastActiveIndex\n * 1: [4, <reference>, 'orange']\n * 2: [5, <reference>, 'strawberry']\n * 3: [0, <reference>, 'apple']\n * 4: [1, <reference>, 'apricot']\n * 5: [2, <reference>, 'banana']\n */\n const rebaseIndexOnActive = (record: TypeaheadRecord) => {\n return (record[TYPEAHEAD_RECORD.INDEX] + numRecords - lastActiveIndex) %\n numRecords;\n };\n\n // records filtered and sorted / rebased around the last active index\n const matchingRecords =\n this.typeaheadRecords\n .filter(\n record => !record[TYPEAHEAD_RECORD.ITEM].disabled &&\n record[TYPEAHEAD_RECORD.TEXT].startsWith(\n this.typaheadBuffer))\n .sort((a, b) => rebaseIndexOnActive(a) - rebaseIndexOnActive(b));\n\n // Just leave if there's nothing that matches. Native select will just\n // choose the first thing that starts with the next letter in the alphabet\n // but that's out of scope and hard to localize\n if (matchingRecords.length === 0) {\n clearTimeout(this.cancelTypeaheadTimeout);\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n this.endTypeahead();\n return;\n }\n\n const isNewQuery = this.typaheadBuffer.length === 1;\n let nextRecord: TypeaheadRecord;\n\n // This is likely the case that someone is trying to \"tab\" through different\n // entries that start with the same letter\n if (this.lastActiveRecord === matchingRecords[0] && isNewQuery) {\n nextRecord = matchingRecords[1] ?? matchingRecords[0];\n } else {\n nextRecord = matchingRecords[0];\n }\n\n if (this.lastActiveRecord) {\n this.lastActiveRecord[TYPEAHEAD_RECORD.ITEM].active = false;\n }\n\n this.lastActiveRecord = nextRecord;\n nextRecord[TYPEAHEAD_RECORD.ITEM].active = true;\n return;\n }\n\n /**\n * Ends the current typeahead and clears the buffer.\n */\n private readonly endTypeahead = () => {\n this.isTypingAhead = false;\n this.typaheadBuffer = '';\n this.typeaheadRecords = [];\n };\n}\n"]}
package/menu/menu.d.ts CHANGED
@@ -29,18 +29,25 @@ declare global {
29
29
  * @example
30
30
  * ```html
31
31
  * <div style="position:relative;">
32
+ * <!--
33
+ * The menu ref in this example can be achieved by any method such as the
34
+ * preferred `@query` decorator in Lit or a ref in React.
35
+ * -->
32
36
  * <button
33
- * class="anchor"
34
- * ${ref(anchorRef)}
37
+ * id="anchor"
35
38
  * @click=${() => this.menuRef.value.show()}>
36
39
  * Click to open menu
37
40
  * </button>
38
41
  * <!--
39
42
  * `has-overflow` is required when using a submenu which overflows the
40
- * menu's contents
43
+ * menu's contents.
44
+ *
45
+ * Additionally, `anchor` ingests an idref which do not pass through shadow
46
+ * roots. You can also set `.anchorElement` to an element reference if
47
+ * necessary.
41
48
  * -->
42
- * <md-menu has-overflow ${ref(menuRef)} ${(el) => el.anchor =
43
- * anchorRef.value}> <md-menu-item header="This is a header"></md-menu-item>
49
+ * <md-menu anchor="anchor" has-overflow ${ref(menuRef)}>
50
+ * <md-menu-item header="This is a header"></md-menu-item>
44
51
  * <md-sub-menu-item header="this is a submenu item">
45
52
  * <md-menu slot="submenu">
46
53
  * <md-menu-item
package/menu/menu.js CHANGED
@@ -25,18 +25,25 @@ import { styles } from './internal/menu-styles.css.js';
25
25
  * @example
26
26
  * ```html
27
27
  * <div style="position:relative;">
28
+ * <!--
29
+ * The menu ref in this example can be achieved by any method such as the
30
+ * preferred `@query` decorator in Lit or a ref in React.
31
+ * -->
28
32
  * <button
29
- * class="anchor"
30
- * ${ref(anchorRef)}
33
+ * id="anchor"
31
34
  * @click=${() => this.menuRef.value.show()}>
32
35
  * Click to open menu
33
36
  * </button>
34
37
  * <!--
35
38
  * `has-overflow` is required when using a submenu which overflows the
36
- * menu's contents
39
+ * menu's contents.
40
+ *
41
+ * Additionally, `anchor` ingests an idref which do not pass through shadow
42
+ * roots. You can also set `.anchorElement` to an element reference if
43
+ * necessary.
37
44
  * -->
38
- * <md-menu has-overflow ${ref(menuRef)} ${(el) => el.anchor =
39
- * anchorRef.value}> <md-menu-item header="This is a header"></md-menu-item>
45
+ * <md-menu anchor="anchor" has-overflow ${ref(menuRef)}>
46
+ * <md-menu-item header="This is a header"></md-menu-item>
40
47
  * <md-sub-menu-item header="this is a submenu item">
41
48
  * <md-menu slot="submenu">
42
49
  * <md-menu-item