@shortfuse/materialdesignweb 0.7.6 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (412) hide show
  1. package/README.md +87 -90
  2. package/bin/mdw-css.js +1 -1
  3. package/components/Badge.js +14 -7
  4. package/components/Body.js +3 -0
  5. package/components/BottomAppBar.js +4 -13
  6. package/components/BottomSheet.js +424 -0
  7. package/components/Box.js +20 -28
  8. package/components/Button.js +85 -79
  9. package/components/Button.md +9 -9
  10. package/components/Card.js +60 -72
  11. package/components/Checkbox.js +33 -42
  12. package/components/CheckboxIcon.js +11 -29
  13. package/components/Chip.js +13 -11
  14. package/components/Dialog.js +214 -394
  15. package/components/DialogActions.js +2 -2
  16. package/components/Display.js +55 -0
  17. package/components/Divider.js +3 -3
  18. package/components/Fab.js +83 -18
  19. package/components/FabContainer.js +48 -0
  20. package/components/FilterChip.js +35 -33
  21. package/components/Grid.js +176 -0
  22. package/components/Headline.js +5 -28
  23. package/components/Icon.js +61 -76
  24. package/components/IconButton.js +72 -126
  25. package/components/Input.js +859 -1
  26. package/components/InputChip.js +161 -0
  27. package/components/Label.js +3 -0
  28. package/components/List.js +4 -6
  29. package/components/ListItem.js +46 -30
  30. package/components/ListOption.js +86 -53
  31. package/components/Listbox.js +248 -0
  32. package/components/Menu.js +69 -528
  33. package/components/MenuItem.js +33 -36
  34. package/components/NavBar.js +49 -86
  35. package/components/NavDrawer.js +16 -15
  36. package/components/NavDrawerItem.js +4 -5
  37. package/components/NavItem.js +58 -41
  38. package/components/NavRail.js +30 -20
  39. package/components/NavRailItem.js +8 -3
  40. package/components/Page.js +105 -0
  41. package/components/Pane.js +11 -274
  42. package/components/Popup.js +29 -0
  43. package/components/Progress.js +24 -23
  44. package/components/Radio.js +40 -36
  45. package/components/RadioIcon.js +12 -16
  46. package/components/Ripple.js +13 -10
  47. package/components/Root.js +209 -0
  48. package/components/Scrim.js +87 -0
  49. package/components/Search.js +77 -0
  50. package/components/SegmentedButton.js +33 -45
  51. package/components/SegmentedButtonGroup.js +25 -13
  52. package/components/Select.js +10 -11
  53. package/components/Shape.js +5 -65
  54. package/components/SideSheet.js +308 -0
  55. package/components/Slider.js +108 -78
  56. package/components/Snackbar.js +26 -21
  57. package/components/SnackbarContainer.js +42 -0
  58. package/components/Surface.js +17 -12
  59. package/components/Switch.js +45 -24
  60. package/components/SwitchIcon.js +49 -39
  61. package/components/Tab.js +64 -43
  62. package/components/TabContent.js +5 -3
  63. package/components/TabList.js +62 -34
  64. package/components/TabPanel.js +11 -8
  65. package/components/Table.js +116 -0
  66. package/components/TextArea.js +54 -50
  67. package/components/Title.js +4 -9
  68. package/components/Tooltip.js +44 -22
  69. package/components/TopAppBar.js +68 -172
  70. package/constants/shapes.js +36 -0
  71. package/constants/typography.js +127 -0
  72. package/core/Composition.js +1164 -645
  73. package/core/CompositionAdapter.js +314 -0
  74. package/core/CustomElement.js +701 -286
  75. package/core/css.js +121 -15
  76. package/core/customTypes.js +157 -40
  77. package/core/dom.js +17 -11
  78. package/{utils → core}/jsonMergePatch.js +42 -18
  79. package/core/observe.js +343 -244
  80. package/core/optimizations.js +23 -0
  81. package/core/template.js +19 -56
  82. package/core/uid.js +13 -0
  83. package/dist/index.min.js +85 -184
  84. package/dist/index.min.js.map +4 -4
  85. package/dist/meta.json +1 -1
  86. package/dom/HTMLOptionsCollectionProxy.js +106 -0
  87. package/loaders/palette.js +13 -0
  88. package/loaders/theme.js +12 -0
  89. package/mixins/AriaReflectorMixin.js +53 -14
  90. package/mixins/AriaToolbarMixin.js +5 -3
  91. package/mixins/ControlMixin.js +92 -41
  92. package/mixins/DelegatesFocusMixin.js +54 -0
  93. package/mixins/DensityMixin.js +2 -3
  94. package/mixins/ElevationMixin.js +62 -0
  95. package/mixins/FlexableMixin.js +67 -39
  96. package/mixins/FormAssociatedMixin.js +71 -16
  97. package/mixins/HyperlinkMixin.js +66 -0
  98. package/mixins/InputMixin.js +205 -39
  99. package/mixins/KeyboardNavMixin.js +22 -7
  100. package/mixins/NavigationListenerMixin.js +33 -0
  101. package/mixins/PopupMixin.js +725 -0
  102. package/mixins/RTLObserverMixin.js +0 -1
  103. package/mixins/ResizeObserverMixin.js +16 -5
  104. package/mixins/RippleMixin.js +11 -10
  105. package/mixins/ScrollListenerMixin.js +42 -33
  106. package/mixins/SemiStickyMixin.js +97 -0
  107. package/mixins/ShapeMaskedMixin.js +117 -0
  108. package/mixins/ShapeMixin.js +17 -194
  109. package/mixins/StateMixin.js +80 -39
  110. package/mixins/TextFieldMixin.js +139 -183
  111. package/mixins/ThemableMixin.js +71 -161
  112. package/mixins/TooltipTriggerMixin.js +292 -366
  113. package/mixins/TouchTargetMixin.js +5 -4
  114. package/mixins/TypographyMixin.js +121 -0
  115. package/package.json +111 -71
  116. package/services/rtl.js +10 -0
  117. package/services/svgAlias.js +17 -0
  118. package/{theming/index.js → services/theme.js} +25 -175
  119. package/types/bin/mdw-css.d.ts +3 -0
  120. package/types/bin/mdw-css.d.ts.map +1 -0
  121. package/types/components/Badge.d.ts +39 -0
  122. package/types/components/Badge.d.ts.map +1 -0
  123. package/types/components/Body.d.ts +29 -0
  124. package/types/components/Body.d.ts.map +1 -0
  125. package/types/components/BottomAppBar.d.ts +73 -0
  126. package/types/components/BottomAppBar.d.ts.map +1 -0
  127. package/types/components/BottomSheet.d.ts +109 -0
  128. package/types/components/BottomSheet.d.ts.map +1 -0
  129. package/types/components/Box.d.ts +16 -0
  130. package/types/components/Box.d.ts.map +1 -0
  131. package/types/components/Button.d.ts +714 -0
  132. package/types/components/Button.d.ts.map +1 -0
  133. package/types/components/Card.d.ts +412 -0
  134. package/types/components/Card.d.ts.map +1 -0
  135. package/types/components/Checkbox.d.ts +205 -0
  136. package/types/components/Checkbox.d.ts.map +1 -0
  137. package/types/components/CheckboxIcon.d.ts +44 -0
  138. package/types/components/CheckboxIcon.d.ts.map +1 -0
  139. package/types/components/Chip.d.ts +1425 -0
  140. package/types/components/Chip.d.ts.map +1 -0
  141. package/types/components/Dialog.d.ts +286 -0
  142. package/types/components/Dialog.d.ts.map +1 -0
  143. package/types/components/DialogActions.d.ts +4 -0
  144. package/types/components/DialogActions.d.ts.map +1 -0
  145. package/types/components/Display.d.ts +45 -0
  146. package/types/components/Display.d.ts.map +1 -0
  147. package/types/components/Divider.d.ts +10 -0
  148. package/types/components/Divider.d.ts.map +1 -0
  149. package/types/components/Fab.d.ts +741 -0
  150. package/types/components/Fab.d.ts.map +1 -0
  151. package/types/components/FabContainer.d.ts +10 -0
  152. package/types/components/FabContainer.d.ts.map +1 -0
  153. package/types/components/FilterChip.d.ts +4283 -0
  154. package/types/components/FilterChip.d.ts.map +1 -0
  155. package/types/components/Grid.d.ts +37 -0
  156. package/types/components/Grid.d.ts.map +1 -0
  157. package/types/components/Headline.d.ts +47 -0
  158. package/types/components/Headline.d.ts.map +1 -0
  159. package/types/components/Icon.d.ts +103 -0
  160. package/types/components/Icon.d.ts.map +1 -0
  161. package/types/components/IconButton.d.ts +1486 -0
  162. package/types/components/IconButton.d.ts.map +1 -0
  163. package/types/components/Input.d.ts +51288 -0
  164. package/types/components/Input.d.ts.map +1 -0
  165. package/types/components/InputChip.d.ts +243 -0
  166. package/types/components/InputChip.d.ts.map +1 -0
  167. package/types/components/Label.d.ts +29 -0
  168. package/types/components/Label.d.ts.map +1 -0
  169. package/types/components/List.d.ts +31 -0
  170. package/types/components/List.d.ts.map +1 -0
  171. package/types/components/ListItem.d.ts +349 -0
  172. package/types/components/ListItem.d.ts.map +1 -0
  173. package/types/components/ListOption.d.ts +1493 -0
  174. package/types/components/ListOption.d.ts.map +1 -0
  175. package/types/components/Listbox.d.ts +12012 -0
  176. package/types/components/Listbox.d.ts.map +1 -0
  177. package/types/components/Menu.d.ts +119 -0
  178. package/types/components/Menu.d.ts.map +1 -0
  179. package/types/components/MenuItem.d.ts +3109 -0
  180. package/types/components/MenuItem.d.ts.map +1 -0
  181. package/types/components/NavBar.d.ts +18 -0
  182. package/types/components/NavBar.d.ts.map +1 -0
  183. package/types/components/NavBarItem.d.ts +186 -0
  184. package/types/components/NavBarItem.d.ts.map +1 -0
  185. package/types/components/NavDrawer.d.ts +108 -0
  186. package/types/components/NavDrawer.d.ts.map +1 -0
  187. package/types/components/NavDrawerItem.d.ts +186 -0
  188. package/types/components/NavDrawerItem.d.ts.map +1 -0
  189. package/types/components/NavItem.d.ts +190 -0
  190. package/types/components/NavItem.d.ts.map +1 -0
  191. package/types/components/NavRail.d.ts +109 -0
  192. package/types/components/NavRail.d.ts.map +1 -0
  193. package/types/components/NavRailItem.d.ts +186 -0
  194. package/types/components/NavRailItem.d.ts.map +1 -0
  195. package/types/components/Page.d.ts +24 -0
  196. package/types/components/Page.d.ts.map +1 -0
  197. package/types/components/Pane.d.ts +44 -0
  198. package/types/components/Pane.d.ts.map +1 -0
  199. package/types/components/Popup.d.ts +76 -0
  200. package/types/components/Popup.d.ts.map +1 -0
  201. package/types/components/Progress.d.ts +19 -0
  202. package/types/components/Progress.d.ts.map +1 -0
  203. package/types/components/Radio.d.ts +199 -0
  204. package/types/components/Radio.d.ts.map +1 -0
  205. package/types/components/RadioIcon.d.ts +46 -0
  206. package/types/components/RadioIcon.d.ts.map +1 -0
  207. package/types/components/Ripple.d.ts +34 -0
  208. package/types/components/Ripple.d.ts.map +1 -0
  209. package/types/components/Root.d.ts +68 -0
  210. package/types/components/Root.d.ts.map +1 -0
  211. package/types/components/Scrim.d.ts +6 -0
  212. package/types/components/Scrim.d.ts.map +1 -0
  213. package/types/components/Search.d.ts +16 -0
  214. package/types/components/Search.d.ts.map +1 -0
  215. package/types/components/SegmentedButton.d.ts +718 -0
  216. package/types/components/SegmentedButton.d.ts.map +1 -0
  217. package/types/components/SegmentedButtonGroup.d.ts +44 -0
  218. package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
  219. package/types/components/Select.d.ts +1361 -0
  220. package/types/components/Select.d.ts.map +1 -0
  221. package/types/components/Shape.d.ts +10 -0
  222. package/types/components/Shape.d.ts.map +1 -0
  223. package/types/components/SideSheet.d.ts +106 -0
  224. package/types/components/SideSheet.d.ts.map +1 -0
  225. package/types/components/Slider.d.ts +382 -0
  226. package/types/components/Slider.d.ts.map +1 -0
  227. package/types/components/Snackbar.d.ts +65 -0
  228. package/types/components/Snackbar.d.ts.map +1 -0
  229. package/types/components/SnackbarContainer.d.ts +6 -0
  230. package/types/components/SnackbarContainer.d.ts.map +1 -0
  231. package/types/components/Surface.d.ts +45 -0
  232. package/types/components/Surface.d.ts.map +1 -0
  233. package/types/components/Switch.d.ts +183 -0
  234. package/types/components/Switch.d.ts.map +1 -0
  235. package/types/components/SwitchIcon.d.ts +169 -0
  236. package/types/components/SwitchIcon.d.ts.map +1 -0
  237. package/types/components/Tab.d.ts +879 -0
  238. package/types/components/Tab.d.ts.map +1 -0
  239. package/types/components/TabContent.d.ts +122 -0
  240. package/types/components/TabContent.d.ts.map +1 -0
  241. package/types/components/TabList.d.ts +6266 -0
  242. package/types/components/TabList.d.ts.map +1 -0
  243. package/types/components/TabPanel.d.ts +28 -0
  244. package/types/components/TabPanel.d.ts.map +1 -0
  245. package/types/components/Table.d.ts +2 -0
  246. package/types/components/Table.d.ts.map +1 -0
  247. package/types/components/TextArea.d.ts +1394 -0
  248. package/types/components/TextArea.d.ts.map +1 -0
  249. package/types/components/Title.d.ts +47 -0
  250. package/types/components/Title.d.ts.map +1 -0
  251. package/types/components/Tooltip.d.ts +49 -0
  252. package/types/components/Tooltip.d.ts.map +1 -0
  253. package/types/components/TopAppBar.d.ts +130 -0
  254. package/types/components/TopAppBar.d.ts.map +1 -0
  255. package/types/constants/colorKeywords.d.ts +2 -0
  256. package/types/constants/colorKeywords.d.ts.map +1 -0
  257. package/types/constants/shapes.d.ts +38 -0
  258. package/types/constants/shapes.d.ts.map +1 -0
  259. package/types/constants/typography.d.ts +212 -0
  260. package/types/constants/typography.d.ts.map +1 -0
  261. package/types/core/Composition.d.ts +252 -0
  262. package/types/core/Composition.d.ts.map +1 -0
  263. package/types/core/CompositionAdapter.d.ts +92 -0
  264. package/types/core/CompositionAdapter.d.ts.map +1 -0
  265. package/types/core/CustomElement.d.ts +302 -0
  266. package/types/core/CustomElement.d.ts.map +1 -0
  267. package/types/core/css.d.ts +44 -0
  268. package/types/core/css.d.ts.map +1 -0
  269. package/types/core/customTypes.d.ts +26 -0
  270. package/types/core/customTypes.d.ts.map +1 -0
  271. package/types/core/dom.d.ts +32 -0
  272. package/types/core/dom.d.ts.map +1 -0
  273. package/types/core/jsonMergePatch.d.ts +31 -0
  274. package/types/core/jsonMergePatch.d.ts.map +1 -0
  275. package/types/core/observe.d.ts +113 -0
  276. package/types/core/observe.d.ts.map +1 -0
  277. package/types/core/optimizations.d.ts +7 -0
  278. package/types/core/optimizations.d.ts.map +1 -0
  279. package/types/core/template.d.ts +47 -0
  280. package/types/core/template.d.ts.map +1 -0
  281. package/types/core/uid.d.ts +6 -0
  282. package/types/core/uid.d.ts.map +1 -0
  283. package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
  284. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
  285. package/types/index.d.ts +88 -0
  286. package/types/index.d.ts.map +1 -0
  287. package/types/loaders/palette.d.ts +2 -0
  288. package/types/loaders/palette.d.ts.map +1 -0
  289. package/types/loaders/theme.d.ts +2 -0
  290. package/types/loaders/theme.d.ts.map +1 -0
  291. package/types/mixins/AriaReflectorMixin.d.ts +23 -0
  292. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
  293. package/types/mixins/AriaToolbarMixin.d.ts +32 -0
  294. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
  295. package/types/mixins/ControlMixin.d.ts +124 -0
  296. package/types/mixins/ControlMixin.d.ts.map +1 -0
  297. package/types/mixins/DelegatesFocusMixin.d.ts +5 -0
  298. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
  299. package/types/mixins/DensityMixin.d.ts +5 -0
  300. package/types/mixins/DensityMixin.d.ts.map +1 -0
  301. package/types/mixins/ElevationMixin.d.ts +33 -0
  302. package/types/mixins/ElevationMixin.d.ts.map +1 -0
  303. package/types/mixins/FlexableMixin.d.ts +13 -0
  304. package/types/mixins/FlexableMixin.d.ts.map +1 -0
  305. package/types/mixins/FormAssociatedMixin.d.ts +122 -0
  306. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
  307. package/types/mixins/HyperlinkMixin.d.ts +22 -0
  308. package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
  309. package/types/mixins/InputMixin.d.ts +179 -0
  310. package/types/mixins/InputMixin.d.ts.map +1 -0
  311. package/types/mixins/KeyboardNavMixin.d.ts +47 -0
  312. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
  313. package/types/mixins/NavigationListenerMixin.d.ts +8 -0
  314. package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
  315. package/types/mixins/PopupMixin.d.ts +82 -0
  316. package/types/mixins/PopupMixin.d.ts.map +1 -0
  317. package/types/mixins/RTLObserverMixin.d.ts +7 -0
  318. package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
  319. package/types/mixins/ResizeObserverMixin.d.ts +12 -0
  320. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
  321. package/types/mixins/RippleMixin.d.ts +92 -0
  322. package/types/mixins/RippleMixin.d.ts.map +1 -0
  323. package/types/mixins/ScrollListenerMixin.d.ts +41 -0
  324. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
  325. package/types/mixins/SemiStickyMixin.d.ts +50 -0
  326. package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
  327. package/types/mixins/ShapeMaskedMixin.d.ts +9 -0
  328. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
  329. package/types/mixins/ShapeMixin.d.ts +38 -0
  330. package/types/mixins/ShapeMixin.d.ts.map +1 -0
  331. package/types/mixins/StateMixin.d.ts +27 -0
  332. package/types/mixins/StateMixin.d.ts.map +1 -0
  333. package/types/mixins/TextFieldMixin.d.ts +1354 -0
  334. package/types/mixins/TextFieldMixin.d.ts.map +1 -0
  335. package/types/mixins/ThemableMixin.d.ts +9 -0
  336. package/types/mixins/ThemableMixin.d.ts.map +1 -0
  337. package/types/mixins/TooltipTriggerMixin.d.ts +106 -0
  338. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
  339. package/types/mixins/TouchTargetMixin.d.ts +3 -0
  340. package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
  341. package/types/mixins/TypographyMixin.d.ts +17 -0
  342. package/types/mixins/TypographyMixin.d.ts.map +1 -0
  343. package/types/services/rtl.d.ts +3 -0
  344. package/types/services/rtl.d.ts.map +1 -0
  345. package/types/services/svgAlias.d.ts +13 -0
  346. package/types/services/svgAlias.d.ts.map +1 -0
  347. package/types/services/theme.d.ts +45 -0
  348. package/types/services/theme.d.ts.map +1 -0
  349. package/types/utils/cli.d.ts +3 -0
  350. package/types/utils/cli.d.ts.map +1 -0
  351. package/types/utils/function.d.ts +3 -0
  352. package/types/utils/function.d.ts.map +1 -0
  353. package/types/utils/jsx-runtime.d.ts +20 -0
  354. package/types/utils/jsx-runtime.d.ts.map +1 -0
  355. package/types/utils/material-color/blend.d.ts +34 -0
  356. package/types/utils/material-color/blend.d.ts.map +1 -0
  357. package/types/utils/material-color/hct/Cam16.d.ts +142 -0
  358. package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
  359. package/types/utils/material-color/hct/Hct.d.ts +93 -0
  360. package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
  361. package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
  362. package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
  363. package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
  364. package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
  365. package/types/utils/material-color/helper.d.ts +8 -0
  366. package/types/utils/material-color/helper.d.ts.map +1 -0
  367. package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
  368. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
  369. package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
  370. package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
  371. package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
  372. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
  373. package/types/utils/material-color/utils/color.d.ts +172 -0
  374. package/types/utils/material-color/utils/color.d.ts.map +1 -0
  375. package/types/utils/material-color/utils/math.d.ts +94 -0
  376. package/types/utils/material-color/utils/math.d.ts.map +1 -0
  377. package/types/utils/pixelmatch.d.ts +22 -0
  378. package/types/utils/pixelmatch.d.ts.map +1 -0
  379. package/types/utils/popup.d.ts +106 -0
  380. package/types/utils/popup.d.ts.map +1 -0
  381. package/types/utils/searchParams.d.ts +3 -0
  382. package/types/utils/searchParams.d.ts.map +1 -0
  383. package/types/utils/svg.d.ts +7 -0
  384. package/types/utils/svg.d.ts.map +1 -0
  385. package/utils/{hct → material-color}/blend.js +8 -10
  386. package/utils/{hct → material-color/hct}/Cam16.js +196 -69
  387. package/utils/{hct → material-color/hct}/Hct.js +61 -19
  388. package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
  389. package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
  390. package/utils/{hct → material-color}/helper.js +11 -18
  391. package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
  392. package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
  393. package/utils/material-color/scheme/Scheme.js +376 -0
  394. package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
  395. package/utils/pixelmatch.js +360 -0
  396. package/utils/popup.js +127 -30
  397. package/utils/searchParams.js +19 -0
  398. package/components/ExtendedFab.js +0 -36
  399. package/components/Layout.js +0 -35
  400. package/components/ListSelect.js +0 -220
  401. package/components/Nav.js +0 -40
  402. package/components/Option.js +0 -91
  403. package/core/ICustomElement.d.ts +0 -291
  404. package/core/ICustomElement.js +0 -1
  405. package/core/identify.js +0 -40
  406. package/core/typings.d.ts +0 -136
  407. package/core/typings.js +0 -1
  408. package/mixins/SurfaceMixin.js +0 -181
  409. package/theming/loader.js +0 -22
  410. package/utils/hct/Scheme.js +0 -587
  411. /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
  412. /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
@@ -1,5 +1,7 @@
1
1
  /* https://html.spec.whatwg.org/multipage/form-control-infrastructure.html */
2
2
 
3
+ import { CHROME_VERSION } from '../core/dom.js';
4
+
3
5
  /** @typedef {HTMLElement & {value:string}} HTMLControlElement */
4
6
 
5
7
  /** @typedef {import('../core/CustomElement.js').default} CustomElement */
@@ -13,7 +15,6 @@ const DOMString = { nullParser: String, value: '' };
13
15
  */
14
16
  export default function FormAssociatedMixin(Base) {
15
17
  return Base
16
- .extend()
17
18
  .setStatic({
18
19
  formAssociated: true,
19
20
  })
@@ -22,12 +23,15 @@ export default function FormAssociatedMixin(Base) {
22
23
  _ipcListener: null,
23
24
  /** @type {EventTarget} */
24
25
  _ipcTarget: null,
26
+ /** @type {FileList} */
27
+ _files: null,
25
28
  })
26
29
  .observe({
27
30
  ariaControls: 'string',
28
31
  autocomplete: DOMString,
29
32
  name: DOMString,
30
33
  readOnly: { attr: 'readonly', type: 'boolean' },
34
+ formNoValidate: { attr: 'formnovalidate', type: 'boolean' },
31
35
  defaultChecked: { attr: 'checked', type: 'boolean' },
32
36
  _checkedDirty: 'boolean',
33
37
  /* "Checkedness" */
@@ -38,6 +42,7 @@ export default function FormAssociatedMixin(Base) {
38
42
  _defaultValue: { reflect: true, attr: 'value' },
39
43
  _value: { empty: '' },
40
44
  _valueDirty: 'boolean',
45
+ _userInteracted: 'boolean',
41
46
  _invalid: 'boolean',
42
47
  _badInput: 'boolean',
43
48
  _validationMessage: 'string',
@@ -45,7 +50,7 @@ export default function FormAssociatedMixin(Base) {
45
50
  _formReset: 'boolean',
46
51
  })
47
52
  .observe({
48
- erroredState({ _invalid }) { return _invalid; },
53
+ erroredState({ _invalid, _userInteracted }) { return _userInteracted && _invalid; },
49
54
  defaultValue: {
50
55
  reflect: false,
51
56
  get({ _defaultValue }) {
@@ -92,14 +97,13 @@ export default function FormAssociatedMixin(Base) {
92
97
  reflect: false,
93
98
  get({ _valueBehavior, _defaultValue, _value }) {
94
99
  switch (_valueBehavior) {
100
+ case 'filename':
95
101
  default:
96
102
  return _value;
97
103
  case 'default':
98
104
  return _defaultValue ?? '';
99
105
  case 'default/on':
100
106
  return _defaultValue ?? 'on';
101
- case 'filename':
102
- throw new Error('Not supported!');
103
107
  }
104
108
  },
105
109
  /** @param {string} v */
@@ -109,6 +113,14 @@ export default function FormAssociatedMixin(Base) {
109
113
  this._valueDirty = true;
110
114
  this._onSetValue(v);
111
115
  break;
116
+ case 'filename':
117
+ if (v == null || v === '') {
118
+ this._files = null;
119
+ // Presume overriding class will interpet null as empty
120
+ } else {
121
+ throw new DOMException('InvalidStateError');
122
+ }
123
+ break;
112
124
  default:
113
125
  this.defaultValue = v;
114
126
  }
@@ -121,8 +133,9 @@ export default function FormAssociatedMixin(Base) {
121
133
  checked: {
122
134
  reflect: false,
123
135
  type: 'boolean',
124
- get({ _checked }) {
125
- return _checked;
136
+ get({ _checkedDirty, defaultChecked, _checked }) {
137
+ if (_checkedDirty) return _checked;
138
+ return defaultChecked;
126
139
  },
127
140
  /** @param {boolean} checked */
128
141
  set(checked) {
@@ -135,7 +148,11 @@ export default function FormAssociatedMixin(Base) {
135
148
  form() { return this.elementInternals.form; },
136
149
  validity() { return this.elementInternals.validity; },
137
150
  validationMessage() { return this.elementInternals.validationMessage; },
138
- willValidate() { return this.elementInternals.willValidate; },
151
+ willValidate() {
152
+ if (this.type === 'submit') return !this.formNoValidate;
153
+ if (this.type === 'button' || this.type === 'reset') return false;
154
+ return this.elementInternals.willValidate;
155
+ },
139
156
  labels() { return this.elementInternals.labels; },
140
157
  })
141
158
  .observe({
@@ -195,8 +212,7 @@ export default function FormAssociatedMixin(Base) {
195
212
  */
196
213
  formAssociatedCallback(form) {
197
214
  this.refreshFormAssociation();
198
- console.debug('FormAssociatedMixin: formAssociatedCallback', this);
199
- // Set value on association (not done by default?)
215
+ this.checkValidity();
200
216
  },
201
217
 
202
218
  /**
@@ -231,6 +247,7 @@ export default function FormAssociatedMixin(Base) {
231
247
  this._formReset = true; // Fires Change Event
232
248
  this._valueDirty = false;
233
249
  this.checkValidity();
250
+ this._userInteracted = false; // Reset error states
234
251
  this._formReset = false;
235
252
  },
236
253
 
@@ -239,9 +256,8 @@ export default function FormAssociatedMixin(Base) {
239
256
  * @param {'autocomplete'|'restore'} mode
240
257
  */
241
258
  formStateRestoreCallback(state, mode) {
242
- if (navigator.userAgent.includes('Edg/')) {
243
- console.warn('Chromium Bug: 1429585 - Ignoring formStateRestoreCallback on Edge', { state, mode });
244
- // formStateRestoreCallback is broken on Edge
259
+ if (CHROME_VERSION < 115) {
260
+ // formStateRestoreCallback is broken on Chromium
245
261
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1429585
246
262
  return;
247
263
  }
@@ -275,21 +291,52 @@ export default function FormAssociatedMixin(Base) {
275
291
  // Fallthrough
276
292
  case 'checkbox':
277
293
  if (this.checked) {
278
- console.log('FormAssociatedMixin: setFormValue', this.name, `(${this.value}, 'checked')`, this);
294
+ // console.debug('FormAssociatedMixin: setFormValue', this.name, `(${this.value}, 'checked')`, this);
279
295
  this.elementInternals.setFormValue(this.value, 'checked');
280
296
  } else {
281
- console.log('FormAssociatedMixin: setFormValue', this.name, "(null, 'unchecked')", this);
297
+ // console.debug('FormAssociatedMixin: setFormValue', this.name, "(null, 'unchecked')", this);
282
298
  this.elementInternals.setFormValue(null, 'unchecked');
283
299
  }
284
300
  break;
301
+ case 'button':
302
+ case 'reset':
303
+ this.elementInternals.setFormValue(null);
304
+ break;
305
+ case 'file': {
306
+ const { elementInternals, _files, name } = this;
307
+ if (!_files || _files.length) {
308
+ elementInternals.setFormValue(null);
309
+ } else {
310
+ const fd = new FormData();
311
+ for (const entry of _files) {
312
+ fd.append(name, entry);
313
+ }
314
+ elementInternals.setFormValue(fd);
315
+ }
316
+ break;
317
+ }
318
+ case 'select-multiple': {
319
+ const formData = new FormData();
320
+ if (this.name) {
321
+ for (const option of this.selectedOptions) {
322
+ formData.append(this.name, option.value);
323
+ }
324
+ }
325
+ this.elementInternals.setFormValue(formData);
326
+ break;
327
+ }
328
+ // case 'select-one':
285
329
  default:
286
- console.log('FormAssociatedMixin: updating form value', this.name, this.value);
330
+ // console.debug('FormAssociatedMixin: setFormValue', this.name, this.value, this);
287
331
  this.elementInternals.setFormValue(this.value);
288
332
  }
289
333
  },
290
334
  })
291
335
  .events({
292
- blur() { this.checkValidity(); },
336
+ blur() {
337
+ this._userInteracted = true;
338
+ this.checkValidity();
339
+ },
293
340
  })
294
341
  .on({
295
342
  connected() {
@@ -302,5 +349,13 @@ export default function FormAssociatedMixin(Base) {
302
349
  valueChanged() {
303
350
  this._updateFormAssociatedValue();
304
351
  },
352
+ _valueBehaviorChanged(previous, current) {
353
+ if (previous !== 'filename' && current === 'filename') {
354
+ this.value = '';
355
+ }
356
+ },
357
+ typeChanged() {
358
+ this._updateFormAssociatedValue();
359
+ },
305
360
  });
306
361
  }
@@ -0,0 +1,66 @@
1
+ import NavigationListenerMixin from './NavigationListenerMixin.js';
2
+
3
+ // https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-protocol-dev
4
+
5
+ /**
6
+ * @template {keyof URL} T
7
+ * @param {T} name
8
+ * @return {ThisType<URL> & TypedPropertyDescriptor<URL[T]>}
9
+ */
10
+ function buildHyperlinkDefinition(name) {
11
+ return {
12
+ get() {
13
+ return new URL(this.href, window.location.href)[name];
14
+ },
15
+ set(value) {
16
+ const { href } = this;
17
+ if (!href) return;
18
+ const url = new URL(href, window.location.href);
19
+ url[name] = value;
20
+ this.href = url.href;
21
+ },
22
+ };
23
+ }
24
+
25
+ /** @param {typeof import('../core/CustomElement.js').default} Base */
26
+ export default function HyperlinkMixin(Base) {
27
+ return Base
28
+ .mixin(NavigationListenerMixin)
29
+ .observe({
30
+ href: 'string',
31
+ target: 'string',
32
+ download: 'string',
33
+ ping: 'string',
34
+ rel: 'string',
35
+ hreflang: 'string',
36
+ referrerPolicy: { type: 'string', attr: 'referrerpolicy' },
37
+ })
38
+ .define({
39
+ origin() { return new URL(this.href).origin; },
40
+ protocol: buildHyperlinkDefinition('protocol'),
41
+ username: buildHyperlinkDefinition('username'),
42
+ password: buildHyperlinkDefinition('password'),
43
+ host: buildHyperlinkDefinition('host'),
44
+ hostname: buildHyperlinkDefinition('hostname'),
45
+ port: buildHyperlinkDefinition('port'),
46
+ pathname: buildHyperlinkDefinition('pathname'),
47
+ search: buildHyperlinkDefinition('search'),
48
+ hash: buildHyperlinkDefinition('hash'),
49
+ })
50
+ .html`
51
+ <a id=anchor
52
+ href={href}
53
+ target={target}
54
+ download={download}
55
+ ping={ping}
56
+ rel={rel}
57
+ hreflang={hreflang}
58
+ referrerpolicy={referrerPolicy}
59
+ ></a>
60
+ `
61
+ .methods({
62
+ toString() {
63
+ return this.href;
64
+ },
65
+ });
66
+ }
@@ -23,6 +23,11 @@ const IMPLICIT_SUBMISSION_BLOCKING_TYPES = new Set([
23
23
 
24
24
  const DOMString = { nullParser: String, empty: '' };
25
25
 
26
+ /** Flag redispatched click events to know not to block them */
27
+ const redispatchedClickEvents = new WeakSet();
28
+ /** Flag root click events to know not to block them */
29
+ const rootClickEvents = new WeakSet();
30
+
26
31
  /**
27
32
  * @see https://html.spec.whatwg.org/multipage/input.html#htmlinputelement
28
33
  * @param {ReturnType<import('./StateMixin.js').default>} Base
@@ -30,7 +35,6 @@ const DOMString = { nullParser: String, empty: '' };
30
35
  export default function InputMixin(Base) {
31
36
  return Base
32
37
  .mixin(ControlMixin)
33
- .extend()
34
38
  .observe({
35
39
  accept: DOMString,
36
40
  alt: DOMString,
@@ -38,10 +42,9 @@ export default function InputMixin(Base) {
38
42
  _formAction: { attr: 'formaction' },
39
43
  formEnctype: { attr: 'formenctype', ...DOMString },
40
44
  formMethod: { attr: 'formmethod', ...DOMString },
41
- formNoValidate: { attr: 'formNoValidate', type: 'boolean' },
42
45
  formTarget: { attr: 'formtarget', ...DOMString },
43
46
  _height: { attr: 'height', type: 'integer' },
44
- indeterminate: { type: 'boolean', reflect: false },
47
+ _indeterminate: 'boolean',
45
48
  max: DOMString,
46
49
  maxLength: { attr: 'maxlength', type: 'integer', empty: -1 },
47
50
  min: DOMString,
@@ -55,31 +58,44 @@ export default function InputMixin(Base) {
55
58
  // [CEReactions] attribute [LegacyNullToEmptyString] DOMString value;
56
59
  _width: { attr: 'width', type: 'integer' },
57
60
  })
61
+ .set({
62
+ _useFormImplicitSubmission: true,
63
+ })
58
64
  .define({
59
65
  // Alias for typescript
60
66
  _input() { return /** @type {HTMLInputElement} */ (this.refs.control); },
61
67
  })
68
+ .observe({
69
+ indeterminate: {
70
+ type: 'boolean',
71
+ get({ _indeterminate }) {
72
+ return _indeterminate;
73
+ },
74
+ /** @param {boolean} value */
75
+ set(value) {
76
+ this._input.indeterminate = value;
77
+ this._indeterminate = this._input.indeterminate;
78
+ },
79
+ },
80
+ })
62
81
  .overrides({
63
82
  controlTagName: 'input',
64
83
  })
84
+ .recompose(({ refs: { control } }) => {
85
+ control.setAttribute('checked', '{defaultChecked}');
86
+ control.setAttribute('height', '{_height}');
87
+ control.setAttribute('width', '{_width}');
88
+ control.setAttribute('value', '{_defaultValue}');
89
+ })
65
90
  .on({
66
- composed({ inline }) {
67
- const { label, control } = this.refs;
68
- // Expose [selected] to .checked
69
- label.setAttribute('selected', '{checked}');
70
- label.setAttribute('invalid', '{_invalid}');
71
- label.setAttribute('indeterminate', '{indeterminate}');
72
-
73
- control.setAttribute('checked', '{defaultChecked}');
74
- control.setAttribute('height', '{_height}');
75
- control.setAttribute('width', '{_width}');
76
- control.setAttribute('value', '{_defaultValue}');
77
- },
78
-
79
91
  // TODO: Bind multiple
80
92
  typeChanged() { this.onValueChangingContentAttribute(); },
81
- defaultCheckedChanged() {
82
- this._checked = this._input.checked;
93
+ checkedChanged() {
94
+ this._input.checked = this.checked;
95
+ this._input.indeterminate = this._indeterminate;
96
+ },
97
+ _indeterminateChanged(previous, current) {
98
+ this._input.indeterminate = current;
83
99
  },
84
100
  minChanged() { this.onValueChangingContentAttribute(); },
85
101
  minLengthChanged() { this.onValueChangingContentAttribute(); },
@@ -91,11 +107,9 @@ export default function InputMixin(Base) {
91
107
  defaultValueChanged() { this.onValueChangingContentAttribute(); },
92
108
  _formResetChanged(oldValue, newValue) {
93
109
  if (!newValue) return;
94
- console.log('form reset');
110
+ this._onSetValue(this.defaultValue);
95
111
  const input = this._input;
96
- input.value = this.defaultValue;
97
112
  input.checked = this.defaultChecked;
98
- this._value = input.value;
99
113
  this._checked = input.checked;
100
114
  this._checkedDirty = false;
101
115
  },
@@ -124,6 +138,7 @@ export default function InputMixin(Base) {
124
138
  // Apply user value to input and read back result to apply control to parse
125
139
  this._input.checked = checked;
126
140
  this._checked = this._input.checked;
141
+ this.indeterminate = false;
127
142
  },
128
143
  _onSetValue(value) {
129
144
  // Apply user value to input and read back result to apply control to parse
@@ -138,6 +153,7 @@ export default function InputMixin(Base) {
138
153
  * @return {void}
139
154
  */
140
155
  performImplicitSubmission(event) {
156
+ if (!this._useFormImplicitSubmission) return;
141
157
  const form = this.form;
142
158
  if (!form) return;
143
159
  /** @type {HTMLInputElement} */
@@ -154,13 +170,123 @@ export default function InputMixin(Base) {
154
170
  }
155
171
  }
156
172
  if (defaultButton) {
157
- defaultButton.click();
173
+ defaultButton.dispatchEvent(new PointerEvent(
174
+ 'click',
175
+ { bubbles: true, cancelable: true, composed: true },
176
+ ));
158
177
  return;
159
178
  }
160
179
  if (submissionBlockers.size > 1) return;
161
180
  this.form.submit();
162
181
  },
182
+ /** @param {Event} event */
183
+ _redispatchControlClickEvent(event) {
184
+ event.stopPropagation();
185
+ // Use constructor to match mouse/pointer properties
186
+ /** @type {Event} */
187
+ // @ts-ignore skip-cast
188
+ const newEvent = (new event.constructor(event.type, event));
189
+ redispatchedClickEvents.add(newEvent);
190
+ return this.dispatchEvent(newEvent);
191
+ },
192
+ /** @param {MouseEvent} event */
193
+ _handleInputClick(event) {
194
+ if (this.disabledState) return;
195
+ const input = this._input;
196
+ switch (input.type) {
197
+ case 'checkbox':
198
+ case 'radio': {
199
+ const { _checkedDirty, _checked, _indeterminate } = this;
200
+ this.checked = input.checked;
201
+ // Event needs to be rethrown and preventDefault inspected
202
+ if (this._redispatchControlClickEvent(event)) return;
203
+ event.preventDefault();
204
+ this._checkedDirty = _checkedDirty;
205
+ this._checked = _checked;
206
+ this._indeterminate = _indeterminate;
207
+ break;
208
+ }
209
+ case 'button':
210
+ case 'submit':
211
+ case 'reset': {
212
+ if (!this._redispatchControlClickEvent(event)) {
213
+ event.preventDefault();
214
+ return;
215
+ }
216
+ const { type } = input;
217
+ if (type !== 'submit' && type !== 'reset') return;
218
+ // If in the composed path is another submit/reset button,
219
+ // Let that button take preference and ignore click.
220
+
221
+ for (const target of event.composedPath()) {
222
+ if (target === input || target === this) break;
223
+ if ((target instanceof HTMLInputElement || target instanceof HTMLButtonElement)
224
+ && (target.type === 'submit' || target.type === 'reset')) {
225
+ // Inner Native Button
226
+ return;
227
+ }
228
+ if ((target instanceof HTMLElement && target.form instanceof HTMLFormElement
229
+ && (target.type === 'submit' || target.type === 'reset'))) {
230
+ // Inner FACE Button
231
+ return;
232
+ }
233
+ if ((target instanceof HTMLAnchorElement && target.href)) {
234
+ // Inner Anchor Button
235
+ return;
236
+ }
237
+ }
163
238
 
239
+ const form = this.elementInternals?.form;
240
+ if (!form) return;
241
+
242
+ if (type === 'submit') {
243
+ const duplicatedButton = /** @type {HTMLInputElement} */ (input.cloneNode());
244
+ duplicatedButton.hidden = true;
245
+ form.append(duplicatedButton);
246
+ if ('requestSubmit' in form) {
247
+ form.requestSubmit(duplicatedButton);
248
+ } else {
249
+ duplicatedButton.click();
250
+ }
251
+ duplicatedButton.remove();
252
+ } else if (type === 'reset') {
253
+ form.reset();
254
+ }
255
+ }
256
+ break;
257
+ default:
258
+ }
259
+ },
260
+ })
261
+ .rootEvents({
262
+ click(event) {
263
+ rootClickEvents.add(event);
264
+ const { control } = this.refs;
265
+ if (event.target === control) return;
266
+ // Label-like click
267
+ if (!event.bubbles) return;
268
+ const { disabledState, type } = this;
269
+ if (disabledState) return;
270
+ if (type === 'checkbox' || type === 'radio') {
271
+ event.stopPropagation();
272
+ control.click();
273
+ } else {
274
+ this._handleInputClick(event);
275
+ }
276
+ },
277
+ })
278
+ .events({
279
+ click(event) {
280
+ // If click event came from own shadowRoot, let it through
281
+ if (rootClickEvents.has(event)) return;
282
+ // If click event is a redispatch, let it through
283
+ if (redispatchedClickEvents.has(event)) return;
284
+ if (event.target === this) {
285
+ // Support custom host.dispatchEvent(new Event('click'))
286
+ event.stopImmediatePropagation();
287
+ this.refs.control.click();
288
+ }
289
+ },
164
290
  })
165
291
  .childEvents({
166
292
  control: {
@@ -170,6 +296,16 @@ export default function InputMixin(Base) {
170
296
  if (/** @type {HTMLInputElement} */ (event.currentTarget).type === 'submit') return;
171
297
  this.performImplicitSubmission(event);
172
298
  },
299
+ click: '_handleInputClick',
300
+ input(event) {
301
+ if (this.disabledState) {
302
+ event.preventDefault();
303
+ event.stopImmediatePropagation();
304
+ return;
305
+ }
306
+ const input = /** @type {HTMLInputElement} */ (event.currentTarget);
307
+ this.checked = input.checked;
308
+ },
173
309
  change(event) {
174
310
  if (this.disabledState) {
175
311
  event.preventDefault();
@@ -177,16 +313,51 @@ export default function InputMixin(Base) {
177
313
  return;
178
314
  }
179
315
  const input = /** @type {HTMLInputElement} */ (event.currentTarget);
180
- console.debug('InputMixin: Will fire checked via change event');
181
- this._checkedDirty = true;
182
- this._checked = input.checked;
316
+ this.checked = input.checked;
183
317
  },
184
318
  },
185
319
  })
186
- .define({
187
- files() { return this._input.files; },
320
+ .methods({
321
+ /** @type {HTMLInputElement['setRangeText']} */
322
+ // @ts-ignore Can't cast?
323
+ setRangeText(...args) { this._input.setRangeText(...args); },
324
+
325
+ /** @type {HTMLInputElement['setSelectionRange']} */
326
+ setSelectionRange(...args) { this._input.setSelectionRange(...args); },
327
+
328
+ /** @type {HTMLInputElement['showPicker']} */
329
+ showPicker(...args) { this._input.showPicker(...args); },
330
+
331
+ /** @type {HTMLInputElement['stepDown']} */
332
+ stepDown(...args) {
333
+ this._input.stepDown(...args);
334
+ this._value = this._input.value;
335
+ },
336
+
337
+ /** @type {HTMLInputElement['stepUp']} */
338
+ stepUp(...args) {
339
+ this._input.stepUp(...args);
340
+ this._value = this._input.value;
341
+ },
188
342
 
189
- select() { return this._input.select; },
343
+ /** @type {HTMLInputElement['select']} */
344
+ select(...args) {
345
+ this._input.select(...args);
346
+ },
347
+ })
348
+ .define({
349
+ files: {
350
+ get() { return this._input.files; },
351
+ set(value) {
352
+ if (value == null && this.type === 'file') {
353
+ // TODO: Clean up single-loop recursion
354
+ this._input.value = ''; // Clears files
355
+ this.value = '';
356
+ } else {
357
+ this._input.files = value;
358
+ }
359
+ },
360
+ },
190
361
 
191
362
  selectionDirection: {
192
363
  get() { return this._input.selectionDirection; },
@@ -203,16 +374,6 @@ export default function InputMixin(Base) {
203
374
  set(value) { this._input.selectionStart = value; },
204
375
  },
205
376
 
206
- setRangeText() { return this._input.setRangeText; },
207
-
208
- setSelectionRange() { return this._input.setSelectionRange; },
209
-
210
- showPicker() { return this._input.showPicker; },
211
-
212
- stepDown() { return this._input.stepDown; },
213
-
214
- stepUp() { return this._input.stepUp; },
215
-
216
377
  valueAsDate: {
217
378
  get() { return this._input.valueAsDate; },
218
379
  set(value) {
@@ -252,5 +413,10 @@ export default function InputMixin(Base) {
252
413
  this._width = value;
253
414
  },
254
415
  },
255
- });
416
+ })
417
+ .css`
418
+ #control::-webkit-file-upload-button {
419
+ display: none;
420
+ }
421
+ `;
256
422
  }
@@ -1,4 +1,6 @@
1
- import { attemptFocus, isRtl } from '../core/dom.js';
1
+ import { attemptFocus, isFocused, isRtl } from '../core/dom.js';
2
+
3
+ import AriaReflectorMixin from './AriaReflectorMixin.js';
2
4
 
3
5
  const DEFAULT_ELEMENT_QUERY = [
4
6
  'button',
@@ -14,7 +16,7 @@ const DEFAULT_ELEMENT_QUERY = [
14
16
  */
15
17
  export default function KeyboardNavMixin(Base) {
16
18
  return Base
17
- .extend()
19
+ .mixin(AriaReflectorMixin)
18
20
  .observe({
19
21
  /** Keyboard navigation attribute */
20
22
  kbdNav: { empty: 'true' },
@@ -47,10 +49,23 @@ export default function KeyboardNavMixin(Base) {
47
49
  })
48
50
  .methods({
49
51
  _ariaOrientationIsVertical() {
50
- return (this.ariaOrientation
51
- ?? this.getAttribute('aria-orientation')
52
+ return (this.readAriaProperty('ariaOrientation')
52
53
  ?? this.ariaOrientationDefault) === 'vertical';
53
54
  },
55
+ focusCurrentOrFirst() {
56
+ let current;
57
+ let first;
58
+ for (const candidate of this.kbdNavChildren) {
59
+ first = candidate;
60
+ if (candidate.tabIndex === 0) {
61
+ current = candidate;
62
+ break;
63
+ }
64
+ }
65
+ if (attemptFocus(current)) return current;
66
+ if (attemptFocus(first)) return first;
67
+ return null;
68
+ },
54
69
  /**
55
70
  * Focuses next element participating in roving tab index list
56
71
  * @param {HTMLElement} [current]
@@ -81,7 +96,7 @@ export default function KeyboardNavMixin(Base) {
81
96
  }
82
97
 
83
98
  if (!loop) {
84
- if (document.activeElement !== current && current instanceof HTMLElement) {
99
+ if (!isFocused(current) && current instanceof HTMLElement) {
85
100
  current.focus();
86
101
  }
87
102
  return current;
@@ -145,7 +160,7 @@ export default function KeyboardNavMixin(Base) {
145
160
  /** @type {HTMLElement} */
146
161
  let firstFocusableChild = null;
147
162
  for (const child of this.kbdNavChildren) {
148
- if (!currentlyFocusedChild && document.activeElement === child) {
163
+ if (!currentlyFocusedChild && isFocused(child)) {
149
164
  currentlyFocusedChild = child;
150
165
  } else if (!currentTabIndexChild && child.getAttribute('tabindex') === '0') {
151
166
  currentTabIndexChild = child;
@@ -159,7 +174,7 @@ export default function KeyboardNavMixin(Base) {
159
174
  }
160
175
  // Bind
161
176
  if (!child.hasAttribute('tabindex')) {
162
- child.tabIndex = (document.activeElement === child) ? 0 : -1;
177
+ child.tabIndex = isFocused(child) ? 0 : -1;
163
178
  }
164
179
  // this.rtiBindChild(child);
165
180
  }