@shortfuse/materialdesignweb 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/README.md +50 -198
  2. package/bin/mdw-css.js +1 -1
  3. package/components/Badge.js +15 -5
  4. package/components/Body.js +7 -0
  5. package/components/BottomAppBar.js +7 -10
  6. package/components/BottomSheet.js +472 -0
  7. package/components/Box.js +11 -49
  8. package/components/Button.js +81 -82
  9. package/components/Card.js +74 -62
  10. package/components/Checkbox.js +15 -25
  11. package/components/CheckboxIcon.js +19 -31
  12. package/components/Chip.js +18 -13
  13. package/components/Dialog.js +70 -100
  14. package/components/DialogActions.js +4 -0
  15. package/components/Display.js +64 -0
  16. package/components/Divider.js +5 -0
  17. package/components/Fab.js +94 -17
  18. package/components/FabContainer.js +57 -0
  19. package/components/FilterChip.js +43 -32
  20. package/components/Grid.js +187 -0
  21. package/components/Headline.js +9 -28
  22. package/components/Icon.js +80 -71
  23. package/components/IconButton.js +77 -120
  24. package/components/Input.js +745 -86
  25. package/components/InputChip.js +193 -0
  26. package/components/Label.js +7 -0
  27. package/components/List.js +11 -5
  28. package/components/ListItem.js +92 -23
  29. package/components/ListOption.js +143 -65
  30. package/components/Listbox.js +57 -17
  31. package/components/Menu.js +39 -27
  32. package/components/MenuItem.js +49 -36
  33. package/components/NavBar.js +66 -21
  34. package/components/NavBarItem.js +5 -0
  35. package/components/NavDrawer.js +33 -16
  36. package/components/NavDrawerItem.js +7 -4
  37. package/components/NavItem.js +61 -34
  38. package/components/NavRail.js +32 -21
  39. package/components/NavRailItem.js +10 -2
  40. package/components/Page.js +119 -0
  41. package/components/Pane.js +24 -0
  42. package/components/Popup.js +23 -8
  43. package/components/Progress.js +25 -5
  44. package/components/Radio.js +8 -7
  45. package/components/RadioIcon.js +24 -15
  46. package/components/Ripple.js +25 -7
  47. package/components/Root.js +225 -0
  48. package/components/Scrim.js +95 -0
  49. package/components/Search.js +30 -25
  50. package/components/SegmentedButton.js +53 -40
  51. package/components/SegmentedButtonGroup.js +15 -12
  52. package/components/Select.js +19 -10
  53. package/components/Shape.js +10 -66
  54. package/components/SideSheet.js +337 -0
  55. package/components/Slider.js +93 -36
  56. package/components/Snackbar.js +52 -20
  57. package/components/SnackbarContainer.js +51 -0
  58. package/components/Surface.js +20 -10
  59. package/components/Switch.js +21 -18
  60. package/components/SwitchIcon.js +62 -33
  61. package/components/Tab.js +78 -38
  62. package/components/TabContent.js +33 -12
  63. package/components/TabList.js +95 -34
  64. package/components/TabPanel.js +10 -1
  65. package/components/Table.js +151 -0
  66. package/components/TextArea.js +48 -16
  67. package/components/Title.js +8 -9
  68. package/components/Tooltip.js +51 -22
  69. package/components/TopAppBar.js +71 -78
  70. package/constants/shapes.js +36 -0
  71. package/constants/typography.js +127 -0
  72. package/core/Composition.js +391 -201
  73. package/core/CompositionAdapter.js +35 -18
  74. package/core/CustomElement.js +634 -254
  75. package/core/css.js +117 -12
  76. package/core/customTypes.js +161 -49
  77. package/core/dom.js +18 -11
  78. package/core/jsonMergePatch.js +27 -11
  79. package/core/observe.js +308 -256
  80. package/core/optimizations.js +9 -9
  81. package/core/template.js +14 -57
  82. package/dist/CustomElement.min.js +2 -0
  83. package/dist/CustomElement.min.js.map +7 -0
  84. package/dist/core/CustomElement.min.js +2 -0
  85. package/dist/core/CustomElement.min.js.map +7 -0
  86. package/dist/index.min.js +85 -115
  87. package/dist/index.min.js.map +4 -4
  88. package/dist/meta.json +1 -1
  89. package/dom/HTMLOptionsCollectionProxy.js +108 -0
  90. package/{theming/themableMixinLoader.js → loaders/palette.js} +4 -3
  91. package/loaders/theme.js +12 -0
  92. package/mixins/AriaReflectorMixin.js +64 -15
  93. package/mixins/AriaToolbarMixin.js +6 -0
  94. package/mixins/ControlMixin.js +79 -33
  95. package/mixins/DelegatesFocusMixin.js +62 -0
  96. package/mixins/DensityMixin.js +7 -3
  97. package/mixins/ElevationMixin.js +61 -0
  98. package/mixins/FlexableMixin.js +87 -39
  99. package/mixins/FormAssociatedMixin.js +76 -10
  100. package/mixins/HyperlinkMixin.js +76 -0
  101. package/mixins/InputMixin.js +227 -32
  102. package/mixins/KeyboardNavMixin.js +11 -7
  103. package/mixins/NavigationListenerMixin.js +33 -0
  104. package/mixins/PopupMixin.js +216 -219
  105. package/mixins/RTLObserverMixin.js +2 -0
  106. package/mixins/ResizeObserverMixin.js +18 -4
  107. package/mixins/RippleMixin.js +11 -7
  108. package/mixins/ScrollListenerMixin.js +14 -2
  109. package/mixins/SemiStickyMixin.js +51 -98
  110. package/mixins/ShapeMaskedMixin.js +125 -0
  111. package/mixins/ShapeMixin.js +30 -203
  112. package/mixins/StateMixin.js +74 -34
  113. package/mixins/TextFieldMixin.js +128 -145
  114. package/mixins/ThemableMixin.js +57 -56
  115. package/mixins/TooltipTriggerMixin.js +305 -359
  116. package/mixins/TouchTargetMixin.js +5 -2
  117. package/mixins/TypographyMixin.js +128 -0
  118. package/package.json +125 -81
  119. package/services/rtl.js +10 -0
  120. package/services/svgAlias.js +17 -0
  121. package/{theming/index.js → services/theme.js} +25 -176
  122. package/types/bin/mdw-css.d.ts +3 -0
  123. package/types/bin/mdw-css.d.ts.map +1 -0
  124. package/types/components/Badge.d.ts +39 -0
  125. package/types/components/Badge.d.ts.map +1 -0
  126. package/types/components/Body.d.ts +29 -0
  127. package/types/components/Body.d.ts.map +1 -0
  128. package/types/components/BottomAppBar.d.ts +72 -0
  129. package/types/components/BottomAppBar.d.ts.map +1 -0
  130. package/types/components/BottomSheet.d.ts +135 -0
  131. package/types/components/BottomSheet.d.ts.map +1 -0
  132. package/types/components/Box.d.ts +16 -0
  133. package/types/components/Box.d.ts.map +1 -0
  134. package/types/components/Button.d.ts +245 -0
  135. package/types/components/Button.d.ts.map +1 -0
  136. package/types/components/Card.d.ts +147 -0
  137. package/types/components/Card.d.ts.map +1 -0
  138. package/types/components/Checkbox.d.ts +207 -0
  139. package/types/components/Checkbox.d.ts.map +1 -0
  140. package/types/components/CheckboxIcon.d.ts +44 -0
  141. package/types/components/CheckboxIcon.d.ts.map +1 -0
  142. package/types/components/Chip.d.ts +248 -0
  143. package/types/components/Chip.d.ts.map +1 -0
  144. package/types/components/Dialog.d.ts +103 -0
  145. package/types/components/Dialog.d.ts.map +1 -0
  146. package/types/components/DialogActions.d.ts +4 -0
  147. package/types/components/DialogActions.d.ts.map +1 -0
  148. package/types/components/Display.d.ts +46 -0
  149. package/types/components/Display.d.ts.map +1 -0
  150. package/types/components/Divider.d.ts +10 -0
  151. package/types/components/Divider.d.ts.map +1 -0
  152. package/types/components/Fab.d.ts +273 -0
  153. package/types/components/Fab.d.ts.map +1 -0
  154. package/types/components/FabContainer.d.ts +10 -0
  155. package/types/components/FabContainer.d.ts.map +1 -0
  156. package/types/components/FilterChip.d.ts +256 -0
  157. package/types/components/FilterChip.d.ts.map +1 -0
  158. package/types/components/Grid.d.ts +38 -0
  159. package/types/components/Grid.d.ts.map +1 -0
  160. package/types/components/Headline.d.ts +46 -0
  161. package/types/components/Headline.d.ts.map +1 -0
  162. package/types/components/Icon.d.ts +55 -0
  163. package/types/components/Icon.d.ts.map +1 -0
  164. package/types/components/IconButton.d.ts +284 -0
  165. package/types/components/IconButton.d.ts.map +1 -0
  166. package/types/components/Input.d.ts +2528 -0
  167. package/types/components/Input.d.ts.map +1 -0
  168. package/types/components/InputChip.d.ts +85 -0
  169. package/types/components/InputChip.d.ts.map +1 -0
  170. package/types/components/Label.d.ts +29 -0
  171. package/types/components/Label.d.ts.map +1 -0
  172. package/types/components/List.d.ts +35 -0
  173. package/types/components/List.d.ts.map +1 -0
  174. package/types/components/ListItem.d.ts +124 -0
  175. package/types/components/ListItem.d.ts.map +1 -0
  176. package/types/components/ListOption.d.ts +158 -0
  177. package/types/components/ListOption.d.ts.map +1 -0
  178. package/types/components/Listbox.d.ts +763 -0
  179. package/types/components/Listbox.d.ts.map +1 -0
  180. package/types/components/Menu.d.ts +130 -0
  181. package/types/components/Menu.d.ts.map +1 -0
  182. package/types/components/MenuItem.d.ts +232 -0
  183. package/types/components/MenuItem.d.ts.map +1 -0
  184. package/types/components/NavBar.d.ts +20 -0
  185. package/types/components/NavBar.d.ts.map +1 -0
  186. package/types/components/NavBarItem.d.ts +97 -0
  187. package/types/components/NavBarItem.d.ts.map +1 -0
  188. package/types/components/NavDrawer.d.ts +107 -0
  189. package/types/components/NavDrawer.d.ts.map +1 -0
  190. package/types/components/NavDrawerItem.d.ts +97 -0
  191. package/types/components/NavDrawerItem.d.ts.map +1 -0
  192. package/types/components/NavItem.d.ts +99 -0
  193. package/types/components/NavItem.d.ts.map +1 -0
  194. package/types/components/NavRail.d.ts +108 -0
  195. package/types/components/NavRail.d.ts.map +1 -0
  196. package/types/components/NavRailItem.d.ts +97 -0
  197. package/types/components/NavRailItem.d.ts.map +1 -0
  198. package/types/components/Page.d.ts +25 -0
  199. package/types/components/Page.d.ts.map +1 -0
  200. package/types/components/Pane.d.ts +44 -0
  201. package/types/components/Pane.d.ts.map +1 -0
  202. package/types/components/Popup.d.ts +78 -0
  203. package/types/components/Popup.d.ts.map +1 -0
  204. package/types/components/Progress.d.ts +21 -0
  205. package/types/components/Progress.d.ts.map +1 -0
  206. package/types/components/Radio.d.ts +201 -0
  207. package/types/components/Radio.d.ts.map +1 -0
  208. package/types/components/RadioIcon.d.ts +46 -0
  209. package/types/components/RadioIcon.d.ts.map +1 -0
  210. package/types/components/Ripple.d.ts +35 -0
  211. package/types/components/Ripple.d.ts.map +1 -0
  212. package/types/components/Root.d.ts +68 -0
  213. package/types/components/Root.d.ts.map +1 -0
  214. package/types/components/Scrim.d.ts +6 -0
  215. package/types/components/Scrim.d.ts.map +1 -0
  216. package/types/components/Search.d.ts +516 -0
  217. package/types/components/Search.d.ts.map +1 -0
  218. package/types/components/SegmentedButton.d.ts +252 -0
  219. package/types/components/SegmentedButton.d.ts.map +1 -0
  220. package/types/components/SegmentedButtonGroup.d.ts +43 -0
  221. package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
  222. package/types/components/Select.d.ts +158 -0
  223. package/types/components/Select.d.ts.map +1 -0
  224. package/types/components/Shape.d.ts +10 -0
  225. package/types/components/Shape.d.ts.map +1 -0
  226. package/types/components/SideSheet.d.ts +111 -0
  227. package/types/components/SideSheet.d.ts.map +1 -0
  228. package/types/components/Slider.d.ts +203 -0
  229. package/types/components/Slider.d.ts.map +1 -0
  230. package/types/components/Snackbar.d.ts +73 -0
  231. package/types/components/Snackbar.d.ts.map +1 -0
  232. package/types/components/SnackbarContainer.d.ts +6 -0
  233. package/types/components/SnackbarContainer.d.ts.map +1 -0
  234. package/types/components/Surface.d.ts +45 -0
  235. package/types/components/Surface.d.ts.map +1 -0
  236. package/types/components/Switch.d.ts +187 -0
  237. package/types/components/Switch.d.ts.map +1 -0
  238. package/types/components/SwitchIcon.d.ts +61 -0
  239. package/types/components/SwitchIcon.d.ts.map +1 -0
  240. package/types/components/Tab.d.ts +139 -0
  241. package/types/components/Tab.d.ts.map +1 -0
  242. package/types/components/TabContent.d.ts +124 -0
  243. package/types/components/TabContent.d.ts.map +1 -0
  244. package/types/components/TabList.d.ts +1111 -0
  245. package/types/components/TabList.d.ts.map +1 -0
  246. package/types/components/TabPanel.d.ts +28 -0
  247. package/types/components/TabPanel.d.ts.map +1 -0
  248. package/types/components/Table.d.ts +25 -0
  249. package/types/components/Table.d.ts.map +1 -0
  250. package/types/components/TextArea.d.ts +201 -0
  251. package/types/components/TextArea.d.ts.map +1 -0
  252. package/types/components/Title.d.ts +46 -0
  253. package/types/components/Title.d.ts.map +1 -0
  254. package/types/components/Tooltip.d.ts +49 -0
  255. package/types/components/Tooltip.d.ts.map +1 -0
  256. package/types/components/TopAppBar.d.ts +129 -0
  257. package/types/components/TopAppBar.d.ts.map +1 -0
  258. package/types/constants/colorKeywords.d.ts +2 -0
  259. package/types/constants/colorKeywords.d.ts.map +1 -0
  260. package/types/constants/shapes.d.ts +38 -0
  261. package/types/constants/shapes.d.ts.map +1 -0
  262. package/types/constants/typography.d.ts +212 -0
  263. package/types/constants/typography.d.ts.map +1 -0
  264. package/types/core/Composition.d.ts +260 -0
  265. package/types/core/Composition.d.ts.map +1 -0
  266. package/types/core/CompositionAdapter.d.ts +114 -0
  267. package/types/core/CompositionAdapter.d.ts.map +1 -0
  268. package/types/core/CustomElement.d.ts +304 -0
  269. package/types/core/CustomElement.d.ts.map +1 -0
  270. package/types/core/css.d.ts +44 -0
  271. package/types/core/css.d.ts.map +1 -0
  272. package/types/core/customTypes.d.ts +22 -0
  273. package/types/core/customTypes.d.ts.map +1 -0
  274. package/types/core/dom.d.ts +32 -0
  275. package/types/core/dom.d.ts.map +1 -0
  276. package/types/core/jsonMergePatch.d.ts +31 -0
  277. package/types/core/jsonMergePatch.d.ts.map +1 -0
  278. package/types/core/observe.d.ts +114 -0
  279. package/types/core/observe.d.ts.map +1 -0
  280. package/types/core/optimizations.d.ts +7 -0
  281. package/types/core/optimizations.d.ts.map +1 -0
  282. package/types/core/template.d.ts +47 -0
  283. package/types/core/template.d.ts.map +1 -0
  284. package/types/core/uid.d.ts +6 -0
  285. package/types/core/uid.d.ts.map +1 -0
  286. package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
  287. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
  288. package/types/index.d.ts +88 -0
  289. package/types/index.d.ts.map +1 -0
  290. package/types/loaders/palette.d.ts +2 -0
  291. package/types/loaders/palette.d.ts.map +1 -0
  292. package/types/loaders/theme.d.ts +2 -0
  293. package/types/loaders/theme.d.ts.map +1 -0
  294. package/types/mixins/AriaReflectorMixin.d.ts +31 -0
  295. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
  296. package/types/mixins/AriaToolbarMixin.d.ts +34 -0
  297. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
  298. package/types/mixins/ControlMixin.d.ts +124 -0
  299. package/types/mixins/ControlMixin.d.ts.map +1 -0
  300. package/types/mixins/DelegatesFocusMixin.d.ts +13 -0
  301. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
  302. package/types/mixins/DensityMixin.d.ts +8 -0
  303. package/types/mixins/DensityMixin.d.ts.map +1 -0
  304. package/types/mixins/ElevationMixin.d.ts +32 -0
  305. package/types/mixins/ElevationMixin.d.ts.map +1 -0
  306. package/types/mixins/FlexableMixin.d.ts +14 -0
  307. package/types/mixins/FlexableMixin.d.ts.map +1 -0
  308. package/types/mixins/FormAssociatedMixin.d.ts +123 -0
  309. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
  310. package/types/mixins/HyperlinkMixin.d.ts +25 -0
  311. package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
  312. package/types/mixins/InputMixin.d.ts +173 -0
  313. package/types/mixins/InputMixin.d.ts.map +1 -0
  314. package/types/mixins/KeyboardNavMixin.d.ts +46 -0
  315. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
  316. package/types/mixins/NavigationListenerMixin.d.ts +8 -0
  317. package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
  318. package/types/mixins/PopupMixin.d.ts +98 -0
  319. package/types/mixins/PopupMixin.d.ts.map +1 -0
  320. package/types/mixins/RTLObserverMixin.d.ts +8 -0
  321. package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
  322. package/types/mixins/ResizeObserverMixin.d.ts +13 -0
  323. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
  324. package/types/mixins/RippleMixin.d.ts +94 -0
  325. package/types/mixins/RippleMixin.d.ts.map +1 -0
  326. package/types/mixins/ScrollListenerMixin.d.ts +46 -0
  327. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
  328. package/types/mixins/SemiStickyMixin.d.ts +50 -0
  329. package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
  330. package/types/mixins/ShapeMaskedMixin.d.ts +12 -0
  331. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
  332. package/types/mixins/ShapeMixin.d.ts +39 -0
  333. package/types/mixins/ShapeMixin.d.ts.map +1 -0
  334. package/types/mixins/StateMixin.d.ts +29 -0
  335. package/types/mixins/StateMixin.d.ts.map +1 -0
  336. package/types/mixins/TextFieldMixin.d.ts +153 -0
  337. package/types/mixins/TextFieldMixin.d.ts.map +1 -0
  338. package/types/mixins/ThemableMixin.d.ts +10 -0
  339. package/types/mixins/ThemableMixin.d.ts.map +1 -0
  340. package/types/mixins/TooltipTriggerMixin.d.ts +114 -0
  341. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
  342. package/types/mixins/TouchTargetMixin.d.ts +6 -0
  343. package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
  344. package/types/mixins/TypographyMixin.d.ts +20 -0
  345. package/types/mixins/TypographyMixin.d.ts.map +1 -0
  346. package/types/services/rtl.d.ts +3 -0
  347. package/types/services/rtl.d.ts.map +1 -0
  348. package/types/services/svgAlias.d.ts +13 -0
  349. package/types/services/svgAlias.d.ts.map +1 -0
  350. package/types/services/theme.d.ts +45 -0
  351. package/types/services/theme.d.ts.map +1 -0
  352. package/types/utils/cli.d.ts +3 -0
  353. package/types/utils/cli.d.ts.map +1 -0
  354. package/types/utils/function.d.ts +3 -0
  355. package/types/utils/function.d.ts.map +1 -0
  356. package/types/utils/jsx-runtime.d.ts +20 -0
  357. package/types/utils/jsx-runtime.d.ts.map +1 -0
  358. package/types/utils/material-color/blend.d.ts +34 -0
  359. package/types/utils/material-color/blend.d.ts.map +1 -0
  360. package/types/utils/material-color/hct/Cam16.d.ts +142 -0
  361. package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
  362. package/types/utils/material-color/hct/Hct.d.ts +93 -0
  363. package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
  364. package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
  365. package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
  366. package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
  367. package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
  368. package/types/utils/material-color/helper.d.ts +8 -0
  369. package/types/utils/material-color/helper.d.ts.map +1 -0
  370. package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
  371. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
  372. package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
  373. package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
  374. package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
  375. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
  376. package/types/utils/material-color/utils/color.d.ts +172 -0
  377. package/types/utils/material-color/utils/color.d.ts.map +1 -0
  378. package/types/utils/material-color/utils/math.d.ts +94 -0
  379. package/types/utils/material-color/utils/math.d.ts.map +1 -0
  380. package/types/utils/pixelmatch.d.ts +22 -0
  381. package/types/utils/pixelmatch.d.ts.map +1 -0
  382. package/types/utils/popup.d.ts +106 -0
  383. package/types/utils/popup.d.ts.map +1 -0
  384. package/types/utils/searchParams.d.ts +3 -0
  385. package/types/utils/searchParams.d.ts.map +1 -0
  386. package/types/utils/svg.d.ts +7 -0
  387. package/types/utils/svg.d.ts.map +1 -0
  388. package/utils/jsx-runtime.js +9 -4
  389. package/utils/material-color/scheme/Scheme.js +1 -1
  390. package/utils/pixelmatch.js +363 -0
  391. package/utils/popup.js +86 -10
  392. package/utils/searchParams.js +22 -0
  393. package/components/Button.md +0 -61
  394. package/components/ExtendedFab.js +0 -32
  395. package/components/Layout.js +0 -504
  396. package/components/Nav.js +0 -38
  397. package/core/DomAdapter.js +0 -586
  398. package/core/ICustomElement.d.ts +0 -291
  399. package/core/ICustomElement.js +0 -1
  400. package/core/test.js +0 -126
  401. package/core/typings.d.ts +0 -142
  402. package/core/typings.js +0 -1
  403. package/mixins/SurfaceMixin.js +0 -127
  404. package/theming/loader.js +0 -22
  405. /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
@@ -1,27 +1,64 @@
1
1
  // https://www.w3.org/WAI/ARIA/apg/patterns/listbox/
2
2
 
3
+ import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
4
+
3
5
  import ListItem from './ListItem.js';
4
6
 
5
7
  // https://html.spec.whatwg.org/multipage/form-elements.html#htmloptionelement
6
8
 
7
- export default class ListOption extends ListItem
9
+ /**
10
+ * List options represent selectable choices within a `mdw-listbox` or list.
11
+ * @see https://m3.material.io/components/lists/specs
12
+ */
13
+ export default ListItem
8
14
  .extend()
15
+ .mixin(DelegatesFocusMixin)
9
16
  .setStatic({
10
17
  formAssociated: true,
11
18
  })
12
19
  .set({
20
+ /** ARIA role applied to the option container (anchor receives role 'option'). */
13
21
  _ariaRole: 'none',
14
- delegatesFocus: true,
22
+
23
+ /** Index of this option within its list/listbox (managed externally). */
15
24
  _index: -1,
25
+
26
+ /** Internal flag indicating selection was modified via API rather than default. */
16
27
  _selectedDirty: false,
28
+
29
+ /** Whether this option behaves as an interactive selectable item. */
17
30
  isInteractive: true,
18
31
  })
19
32
  .observe({
20
33
  // ListOption.prototype._form = ListOption.prop('_form');
34
+
35
+ /**
36
+ * Explicit label for accessibility. Reflected to attribute `label`.
37
+ * Falls back to `textContent` when not provided.
38
+ */
21
39
  _label: { attr: 'label', reflect: true, nullParser: String },
40
+
41
+ /**
42
+ * Explicit text content for the option. Reflected to attribute `text`.
43
+ */
44
+ _text: { attr: 'text', reflect: true, nullParser: String },
45
+
46
+ /**
47
+ * Initial/default selection state (reflected to `selected` attribute).
48
+ * Use `selected` property to control runtime selection.
49
+ */
22
50
  defaultSelected: { attr: 'selected', reflect: true, type: 'boolean' },
51
+
52
+ /** Internal boolean representing the current selected state. */
23
53
  _selected: 'boolean',
54
+
55
+ /**
56
+ * Underlying option value (reflected to `value` attribute). Defaults to
57
+ * the option's text content when not provided.
58
+ */
24
59
  _value: { attr: 'value', reflect: true },
60
+
61
+ /** Set when form association disables the option. */
25
62
  _formDisabled: 'boolean',
26
63
  })
27
64
  .observe({
@@ -44,19 +81,45 @@ export default class ListOption extends ListItem
44
81
  },
45
82
  })
46
83
  .define({
84
+ /** Numeric index of the option inside the parent listbox. */
47
85
  index() { return this._index; },
48
- form() { return (this.parentElement)?.form; },
86
+
87
+ /** Associated form owner (if any) for form-associated behavior. */
88
+ form() { return /** @type {HTMLInputElement} */ (this.parentElement)?.form; },
89
+
90
+ /**
91
+ * Text content for the option; setting updates the internal `_text` field.
92
+ * If not provided, the getter falls back to element textContent.
93
+ */
94
+ text: {
95
+ // Incomplete
96
+ get() { return this._text ?? this.textContent; },
97
+ /** @param {string} value */
98
+ set(value) {
99
+ this._text = value;
100
+ },
101
+ },
102
+
103
+ /**
104
+ * Accessible label for the option. Falls back to `text` or the element
105
+ * content when not explicitly set.
106
+ */
49
107
  label: {
50
- get() { return this._label ?? this.textContent; },
108
+ get() { return this._label ?? this._text ?? this.textContent; },
51
109
  /** @param {string} value */
52
110
  set(value) {
53
111
  this._label = value;
54
112
  },
55
113
  },
114
+
115
+ /**
116
+ * Option `value` used when the option is selected in a form. Defaults to
117
+ * the option's text when not explicitly defined.
118
+ */
56
119
  value: {
57
120
  get() { return this._value ?? this.textContent; },
58
121
  /** @param {string} value */
59
- set(value) { this._label = value; },
122
+ set(value) { this._value = value; },
60
123
  },
61
124
  })
62
125
  .methods({
@@ -69,38 +132,48 @@ export default class ListOption extends ListItem
69
132
  this.refs.anchor.focus(...options);
70
133
  },
71
134
  })
72
- .on({
73
- composed({ inline }) {
74
- const { anchor, state, content } = this.refs;
75
-
76
- // Form Associated elements cannot receive focus unless using delegatesFocus
77
- // Workaround by redirecting focus to an inner element
78
- // Reuse HTMLAnchorElement with no HREF
79
- // Issues: Siblings (images) are not contained within tree
80
-
81
- anchor.setAttribute('disabled', '{disabledState}');
82
- anchor.setAttribute('role', 'option');
83
- anchor.setAttribute('aria-disabled', inline(({ disabledState }) => `${disabledState}`));
84
- anchor.setAttribute('tabindex', '0');
85
- anchor.setAttribute('aria-selected', inline(({ selected }) => `${selected}`));
86
- anchor.setAttribute('selected', '{selected}');
87
- anchor.removeAttribute('href');
88
- anchor.removeAttribute('mdw-if');
89
-
90
- content.setAttribute('selected', '{selected}');
91
-
92
- state.setAttribute('state-disabled', 'focus');
135
+ .expressions({
136
+ anchorAriaLabelledBy({ _label }) {
137
+ return _label ? null : 'content';
93
138
  },
94
- _labelChanged(previous, current) {
95
- const { anchor } = this.refs;
96
- if (current == null) {
97
- anchor.setAttribute('aria-labelledby', 'content');
98
- anchor.removeAttribute('aria-label');
99
- } else {
100
- anchor.setAttribute('aria-label', current);
101
- anchor.removeAttribute('aria-labelledby');
102
- }
139
+ anchorAriaDescribedBy({ _label }) {
140
+ return _label ? 'content' : null;
103
141
  },
142
+ computedIconVariation({ iconVariation, selected }) {
143
+ if (iconVariation != null) return iconVariation;
144
+ return selected ? 'filled' : null;
145
+ },
146
+ })
147
+ .recompose(({ inline, refs: { checkbox, radio, anchor, state, content } }) => {
148
+ // Form Associated elements cannot receive focus unless using delegatesFocus
149
+ // Workaround by redirecting focus to an inner element
150
+ // Reuse HTMLAnchorElement with no HREF
151
+ // Issues: Siblings (images) are not contained within tree
152
+
153
+ anchor.setAttribute('disabled', '{disabledState}');
154
+ anchor.setAttribute('role', 'option');
155
+ anchor.setAttribute('aria-disabled', inline(({ disabledState }) => `${disabledState}`));
156
+ anchor.setAttribute('tabindex', '0');
157
+ anchor.setAttribute('aria-selected', inline(({ selected }) => `${selected}`));
158
+ anchor.setAttribute('selected', '{selected}');
159
+ anchor.setAttribute('aria-labelledby', '{anchorAriaLabelledBy}');
160
+ anchor.setAttribute('aria-describedby', '{anchorAriaDescribedBy}');
161
+ anchor.setAttribute('aria-label', '{_label}');
162
+ anchor.removeAttribute('href');
163
+ anchor.removeAttribute('mdw-if');
164
+
165
+ // eslint-disable-next-line no-shadow
166
+ checkbox.setAttribute('mdw-if', inline(({ checkbox, icon }) => !icon && checkbox));
167
+
168
+ // eslint-disable-next-line no-shadow
169
+ radio.setAttribute('mdw-if', inline(({ radio, icon }) => !icon && radio));
170
+
171
+ content.setAttribute('aria-hidden', 'true');
172
+ content.setAttribute('selected', '{selected}');
173
+
174
+ state.setAttribute('state-disabled', 'focus');
175
+ })
176
+ .on({
104
177
  selectedChanged(previous, current) {
105
178
  // Used by HTMLCollection
106
179
  this.classList.toggle('mdw-list-option__selected', current);
@@ -115,7 +188,11 @@ export default class ListOption extends ListItem
115
188
 
116
189
  z-index: 0;
117
190
  }
118
-
191
+
192
+ :host([hidden]) {
193
+ display: none;
194
+ }
195
+
119
196
  :host([href]) {
120
197
  cursor: pointer;
121
198
  }
@@ -128,6 +205,7 @@ export default class ListOption extends ListItem
128
205
  #content {
129
206
  -webkit-user-select: none;
130
207
  user-select: none;
208
+ pointer-events: none;
131
209
  }
132
210
 
133
211
  #content[selected] {
@@ -142,35 +220,35 @@ export default class ListOption extends ListItem
142
220
  background-color: rgb(var(--mdw-bg));
143
221
  color: rgb(var(--mdw-ink));
144
222
  }
145
- ` {
146
- static { this.autoRegister('mdw-list-option'); }
147
-
148
- /**
149
- * @param {string} [text]
150
- * @param {string} [value]
151
- * @param {boolean} [defaultSelected]
152
- * @param {boolean} [selected]
153
- */
154
- constructor(text, value, defaultSelected, selected) {
155
- super();
156
- if (text !== undefined) {
157
- this.text = text;
158
- }
159
- if (value !== undefined) {
160
- this._value = value;
161
- }
162
- if (defaultSelected !== undefined) {
163
- this.defaultSelected = defaultSelected;
164
- }
165
- if (selected !== undefined) {
166
- this._selected = selected;
223
+ `
224
+ .extend((BaseClass) => class extends BaseClass {
225
+ /**
226
+ * @param {string} [text]
227
+ * @param {string} [value]
228
+ * @param {boolean} [defaultSelected]
229
+ * @param {boolean} [selected]
230
+ */
231
+ constructor(text, value, defaultSelected, selected) {
232
+ super();
233
+ if (text !== undefined) {
234
+ this.text = text;
235
+ }
236
+ if (value !== undefined) {
237
+ this._value = value;
238
+ }
239
+ if (defaultSelected !== undefined) {
240
+ this.defaultSelected = defaultSelected;
241
+ }
242
+ if (selected !== undefined) {
243
+ this._selected = selected;
244
+ }
167
245
  }
168
- }
169
246
 
170
- connectedCallback() {
171
- super.connectedCallback();
172
- if (!this.hasAttribute('tabindex')) {
173
- this.tabIndex = 0;
247
+ connectedCallback() {
248
+ super.connectedCallback();
249
+ if (!this.hasAttribute('tabindex')) {
250
+ this.tabIndex = 0;
251
+ }
174
252
  }
175
- }
176
- }
253
+ })
254
+ .autoRegister('mdw-list-option');
@@ -1,4 +1,5 @@
1
1
  import { constructHTMLOptionsCollectionProxy } from '../dom/HTMLOptionsCollectionProxy.js';
2
+ import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
2
3
  import FormAssociatedMixin from '../mixins/FormAssociatedMixin.js';
3
4
  import KeyboardNavMixin from '../mixins/KeyboardNavMixin.js';
4
5
  import StateMixin from '../mixins/StateMixin.js';
@@ -6,32 +7,53 @@ import StateMixin from '../mixins/StateMixin.js';
6
7
  import List from './List.js';
7
8
  import ListOption from './ListOption.js';
8
9
 
9
- /** @implements {HTMLSelectElement} */
10
- // @ts-expect-error Can't implement index signatures (use `item()`)
10
+ /**
11
+ * Listbox: a selectable list of options, used for autocompletes and selects.
12
+ * implements {HTMLSelectElement}
13
+ * @see https://m3.material.io/components/lists/specs
14
+ */
11
15
  export default List
12
16
  .extend()
13
17
  .mixin(StateMixin)
14
18
  .mixin(FormAssociatedMixin)
15
19
  .mixin(KeyboardNavMixin)
20
+ .mixin(DelegatesFocusMixin)
16
21
  .observe({
22
+ /** When true, multiple options may be selected (select-multiple semantics). */
17
23
  multiple: 'boolean',
24
+
25
+ /** Visible size (number of rows) for the listbox; 0 means auto. */
18
26
  size: { type: 'integer', empty: 0 },
19
27
  })
20
28
  .set({
29
+ /** ARIA role applied to the host element (default: 'listbox'). */
21
30
  _ariaRole: 'listbox',
22
- delegatesFocus: true,
23
- /** @type {HTMLCollectionOf<ListOption> & HTMLOptionsCollection} */
31
+
32
+ /**
33
+ * Lazily-constructed options collection proxy exposing `add`, indexed
34
+ * access, and other `HTMLOptionsCollection` semantics.
35
+ * @type {HTMLCollectionOf<InstanceType<typeof ListOption>> & HTMLOptionsCollection}
36
+ */
24
37
  _optionsCollection: null,
25
- /** @type {HTMLCollectionOf<ListOption>} */
38
+
39
+ /** Cached collection of selected options (HTMLCollection). */
26
40
  _selectedOptionsCollection: null,
41
+
42
+ /** Internal guard to avoid reentrant selectedness updates. */
27
43
  _handlingSelectedness: false,
44
+
45
+ /** When true, form resets are honored; toggled when form association changes. */
46
+ _handleFormReset: true,
28
47
  })
29
48
  .define({
30
49
  options() {
31
50
  if (!this._optionsCollection) {
51
+ // eslint-disable-next-line operator-linebreak
52
+ const collection = /** @type {HTMLCollectionOf<InstanceType<typeof ListOption>>} */
53
+ (this.getElementsByTagName(ListOption.elementName));
32
54
  this._optionsCollection = constructHTMLOptionsCollectionProxy({
33
55
  host: this,
34
- collection: this.getElementsByTagName(ListOption.elementName),
56
+ collection,
35
57
  OptionConstructor: ListOption,
36
58
  GroupConstructor: ListOption,
37
59
  });
@@ -39,36 +61,46 @@ export default List
39
61
  return this._optionsCollection;
40
62
  },
41
63
 
42
- /** @return {HTMLCollectionOf<ListOption>} */
64
+ /**
65
+ * Returns a live HTMLCollection of selected `mdw-list-option` elements.
66
+ * @return {HTMLCollectionOf<InstanceType<typeof ListOption>>}
67
+ */
43
68
  selectedOptions() {
44
69
  // eslint-disable-next-line no-return-assign
45
70
  return (this._selectedOptionsCollection
46
71
  ??= (
47
- /** @type {HTMLCollectionOf<ListOption>} */
72
+ /** @type {HTMLCollectionOf<InstanceType<typeof ListOption>>} */
48
73
  (this.getElementsByClassName('mdw-list-option__selected')))
49
74
  );
50
75
  },
51
76
 
52
- type() { return 'select'; },
77
+ /** Returns the control type string compatible with `input`/`select` semantics. */
78
+ type() { return this.multiple ? 'select-multiple' : 'select-one'; },
53
79
 
80
+ /** Query selector used by keyboard navigation mixin to find focusable options. */
54
81
  kbdNavQuery() { return ListOption.elementName; },
55
82
 
83
+ /** Allow keyboard navigation to focus disabled options in some patterns. */
56
84
  kbdNavFocusableWhenDisabled() { return true; },
57
85
  })
58
86
  .define({
59
87
  length() { return this.options.length; },
60
88
 
61
89
  selectedIndex: {
90
+ /** @return {number} */
62
91
  get() {
63
92
  const [selectedItem] = this.selectedOptions;
64
93
  if (!selectedItem) return -1;
65
94
  return Array.prototype.indexOf.call(this.options, selectedItem);
66
95
  },
96
+ /** @param {number} value */
67
97
  set(value) {
68
98
  const itemToSelect = this.options[value];
99
+ this._handlingSelectedness = true;
69
100
  for (const option of this.options) {
70
101
  option.selected = (option === itemToSelect);
71
102
  }
103
+ this._handlingSelectedness = false;
72
104
  this._value = this.value;
73
105
  },
74
106
  },
@@ -80,11 +112,13 @@ export default List
80
112
  set(v) {
81
113
  let newValue = '';
82
114
  const vString = `${v}`;
115
+ this._handlingSelectedness = true;
83
116
  for (const option of this.options) {
84
117
  if ((option.selected = (option.value === vString))) {
85
118
  newValue = vString;
86
119
  }
87
120
  }
121
+ this._handlingSelectedness = false;
88
122
  this._value = newValue;
89
123
  },
90
124
  },
@@ -99,7 +133,9 @@ export default List
99
133
  this.updateAriaProperty('ariaMultiSelectable', newValue ? 'true' : 'false');
100
134
  },
101
135
  _formResetChanged(oldValue, newValue) {
102
- // TODO: Unset dirty
136
+ if (!newValue) return;
137
+ if (!this._handleFormReset) return;
138
+ this.value = this.defaultValue;
103
139
  },
104
140
  connected() {
105
141
  if (!this.hasAttribute('tabindex')) {
@@ -124,12 +160,12 @@ export default List
124
160
  },
125
161
  /**
126
162
  * @param {number} index
127
- * @return {ListOption|null}
163
+ * @return {InstanceType<typeof ListOption>|null}
128
164
  */
129
165
  item(index) { return this.options[index]; },
130
166
  /**
131
167
  * @param {string} name ID of ListOption
132
- * @return {ListOption|null}
168
+ * @return {InstanceType<typeof ListOption>|null}
133
169
  */
134
170
  namedItem(name) {
135
171
  for (const option of this.options) {
@@ -143,18 +179,21 @@ export default List
143
179
  onListboxClick(event) {
144
180
  const target = event.target;
145
181
  if (!(target instanceof ListOption)) return;
182
+ event.stopImmediatePropagation();
146
183
  event.stopPropagation();
147
- if (target.disabledState) return;
184
+
185
+ const listOption = /** @type {InstanceType<ListOption>} */ (target);
186
+ if (listOption.disabledState) return;
148
187
 
149
188
  let sendUpdateNotifications = false;
150
189
  this._handlingSelectedness = true;
151
190
 
152
191
  // Perform unselect
153
- if (target.selected) {
192
+ if (listOption.selected) {
154
193
  // Unselect condition
155
194
  if (!this.required || (this.multiple && this.selectedOptions.length > 1)) {
156
195
  sendUpdateNotifications = true;
157
- target.selected = false;
196
+ listOption.selected = false;
158
197
  }
159
198
  } else {
160
199
  if (!this.multiple) {
@@ -164,12 +203,13 @@ export default List
164
203
  }
165
204
  }
166
205
 
167
- target.selected = true;
206
+ listOption.selected = true;
168
207
  sendUpdateNotifications = true;
169
208
  }
170
209
 
171
210
  this._value = this.value;
172
211
  this._handlingSelectedness = false;
212
+ this._updateFormAssociatedValue();
173
213
 
174
214
  if (sendUpdateNotifications) {
175
215
  this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
@@ -194,7 +234,7 @@ export default List
194
234
  if (this.multiple) return;
195
235
  if (this._handlingSelectedness) return;
196
236
 
197
- const target = /** @type {ListOption} */ (/** @type {unknown} */ (event.target));
237
+ const target = /** @type {InstanceType<typeof ListOption>} */ (event.target);
198
238
  if (target.selected) return;
199
239
  this._handlingSelectedness = true;
200
240
 
@@ -1,30 +1,43 @@
1
- // https://www.w3.org/TR/wai-aria-practices/#menu
2
-
3
- import './Surface.js';
4
1
  import CustomElement from '../core/CustomElement.js';
5
2
  import { attemptFocus } from '../core/dom.js';
6
3
  import DensityMixin from '../mixins/DensityMixin.js';
4
+ import ElevationMixin from '../mixins/ElevationMixin.js';
7
5
  import KeyboardNavMixin from '../mixins/KeyboardNavMixin.js';
8
6
  import PopupMixin from '../mixins/PopupMixin.js';
9
7
  import ShapeMixin from '../mixins/ShapeMixin.js';
10
- import SurfaceMixin from '../mixins/SurfaceMixin.js';
11
8
  import ThemableMixin from '../mixins/ThemableMixin.js';
12
9
 
10
+ /**
11
+ * Menus provide a list of choices or actions in a temporary surface.
12
+ * @see https://m3.material.io/components/menus/specs
13
+ * @see https://www.w3.org/TR/wai-aria-practices/#menu
14
+ */
13
15
  export default CustomElement
14
16
  .extend()
15
17
  .mixin(ThemableMixin)
16
- .mixin(SurfaceMixin)
18
+ .mixin(ElevationMixin)
17
19
  .mixin(ShapeMixin)
18
20
  .mixin(PopupMixin)
19
21
  .mixin(DensityMixin)
20
22
  .mixin(KeyboardNavMixin)
21
23
  .set({
22
- scrollable: true,
24
+ /** Placement strategy for the popup ('corner'). */
23
25
  flow: 'corner',
26
+
27
+ /** When true, show a scrim behind the menu (used by `showModal`). */
24
28
  _useScrim: false,
25
- /** @type {WeakRef<HTMLElement>} */
29
+
30
+ /**
31
+ * Weak reference to the element that requested a submenu cascade. Stored
32
+ * as a WeakRef to avoid retaining DOM nodes.
33
+ * @type {WeakRef<HTMLElement>}
34
+ */
26
35
  _cascader: null,
27
- /** @type {WeakRef<HTMLElement>} */
36
+
37
+ /**
38
+ * Weak reference to the currently opened submenu (if any).
39
+ * @type {WeakRef<HTMLElement>}
40
+ */
28
41
  _submenu: null,
29
42
  })
30
43
  .define({
@@ -34,9 +47,11 @@ export default CustomElement
34
47
  const submenuItems = [...this.querySelectorAll(':scope mdw-menu mdw-menu-item')];
35
48
  return items.filter((el) => !submenuItems.includes(el));
36
49
  },
50
+ /** Return the internal dialog element used for popup rendering (if any). */
37
51
  _dialog() {
38
52
  return /** @type {HTMLDialogElement} */ (this.refs.dialog);
39
53
  },
54
+ /** Element that cascaded this submenu (if present). */
40
55
  cascader: {
41
56
  get() {
42
57
  return this._cascader?.deref();
@@ -48,6 +63,7 @@ export default CustomElement
48
63
  this._cascader = value ? new WeakRef(value) : null;
49
64
  },
50
65
  },
66
+ /** Currently opened submenu element (if any). */
51
67
  submenu: {
52
68
  get() {
53
69
  return this._submenu?.deref();
@@ -60,15 +76,9 @@ export default CustomElement
60
76
  },
61
77
  },
62
78
  })
63
- .on({
64
- composed() {
65
- const { shape, surface, dialog, scrim } = this.refs;
66
- surface.append(shape);
67
- dialog.prepend(surface);
68
- scrim.setAttribute('invisible', '');
69
-
70
- // Wrap slot in scroller
71
- },
79
+ .recompose(({ refs: { scrim } }) => {
80
+ scrim.setAttribute('invisible', '');
81
+ // Wrap slot in scroller
72
82
  })
73
83
  .css`
74
84
  /* https://m3.material.io/components/menus/specs */
@@ -77,17 +87,14 @@ export default CustomElement
77
87
  --mdw-shape__size: var(--mdw-shape__extra-small);
78
88
  --mdw-bg: var(--mdw-color__surface-container);
79
89
  --mdw-ink: var(--mdw-color__on-surface);
80
-
81
- --mdw-surface__shadow__resting: var(--mdw-surface__shadow__2);
82
- --mdw-surface__shadow__raised: var(--mdw-surface__shadow__resting);
83
90
  display: block;
84
91
 
85
92
  inline-size: auto;
86
93
  min-inline-size: calc(var(--mdw-menu__inline-base) * 2);
87
94
  max-inline-size: 100vw;
88
- }
89
95
 
90
- #shape {
96
+ filter: var(--mdw-elevation__drop-shadow__2);
97
+
91
98
  background-color: rgb(var(--mdw-bg));
92
99
  }
93
100
 
@@ -96,6 +103,7 @@ export default CustomElement
96
103
  }
97
104
  `
98
105
  .methods({
106
+ /** @param {Parameters<InstanceType<ReturnType<PopupMixin>>['showPopup']>} args */
99
107
  showModal(...args) {
100
108
  this._useScrim = true;
101
109
  const result = this.showPopup(...args);
@@ -118,16 +126,18 @@ export default CustomElement
118
126
  })
119
127
  .events({
120
128
  'mdw-menu-item:cascade'(event) {
121
- const menuItem = event.target;
122
- const subMenuId = event.detail;
129
+ const menuItem = /** @type {HTMLElement} */ (event.target);
130
+ const subMenuId = /** @type {CustomEvent<string>} */ (event).detail;
123
131
  event.stopPropagation();
124
132
 
125
- const submenu = this.getRootNode().getElementById(subMenuId);
133
+ const root = /** @type {DocumentFragment|Document} */ (this.getRootNode());
134
+ const submenu = /** @type {typeof this} */ (root.getElementById(subMenuId));
126
135
  this.submenu = submenu;
127
136
  submenu.cascade(menuItem);
128
137
  },
129
138
  'mdw-menu-item:cascader-blur'() {
130
- const submenu = this.submenu;
139
+ const submenu = /** @type {typeof this} */ (this.submenu);
140
+ if (!submenu) return;
131
141
  // Wait for focus event (if mouse focus on sub menu item)
132
142
  queueMicrotask(() => {
133
143
  // Stay open if submenu is focused
@@ -163,7 +173,9 @@ export default CustomElement
163
173
  // if (!this.submenu) break;
164
174
  if (getComputedStyle(this).direction === 'rtl') {
165
175
  if (event.key === 'ArrowLeft') break;
166
- } else if (event.key === 'ArrowRight') break;
176
+ } else if (event.key === 'ArrowRight') {
177
+ break;
178
+ }
167
179
  // Fallthrough;
168
180
  case 'Escape':
169
181
  case 'Esc':