@shortfuse/materialdesignweb 0.8.0 → 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 (394) hide show
  1. package/README.md +32 -24
  2. package/bin/mdw-css.js +1 -1
  3. package/components/Badge.js +12 -5
  4. package/components/Body.js +3 -0
  5. package/components/BottomAppBar.js +1 -8
  6. package/components/BottomSheet.js +424 -0
  7. package/components/Box.js +11 -49
  8. package/components/Button.js +61 -82
  9. package/components/Card.js +56 -61
  10. package/components/Checkbox.js +7 -25
  11. package/components/CheckboxIcon.js +10 -28
  12. package/components/Chip.js +13 -11
  13. package/components/Dialog.js +49 -98
  14. package/components/Display.js +55 -0
  15. package/components/Fab.js +83 -17
  16. package/components/FabContainer.js +48 -0
  17. package/components/FilterChip.js +34 -32
  18. package/components/Grid.js +176 -0
  19. package/components/Headline.js +5 -28
  20. package/components/Icon.js +54 -69
  21. package/components/IconButton.js +71 -120
  22. package/components/Input.js +669 -83
  23. package/components/InputChip.js +161 -0
  24. package/components/Label.js +3 -0
  25. package/components/List.js +1 -5
  26. package/components/ListItem.js +39 -23
  27. package/components/ListOption.js +79 -62
  28. package/components/Listbox.js +19 -10
  29. package/components/Menu.js +8 -18
  30. package/components/MenuItem.js +25 -26
  31. package/components/NavBar.js +53 -19
  32. package/components/NavDrawer.js +15 -15
  33. package/components/NavDrawerItem.js +2 -4
  34. package/components/NavItem.js +40 -33
  35. package/components/NavRail.js +23 -21
  36. package/components/NavRailItem.js +5 -2
  37. package/components/Page.js +105 -0
  38. package/components/Pane.js +18 -0
  39. package/components/Popup.js +17 -8
  40. package/components/Radio.js +2 -5
  41. package/components/RadioIcon.js +10 -14
  42. package/components/Ripple.js +11 -7
  43. package/components/Root.js +209 -0
  44. package/components/Scrim.js +87 -0
  45. package/components/Search.js +12 -20
  46. package/components/SegmentedButton.js +33 -36
  47. package/components/SegmentedButtonGroup.js +9 -3
  48. package/components/Select.js +6 -7
  49. package/components/Shape.js +5 -65
  50. package/components/SideSheet.js +308 -0
  51. package/components/Slider.js +71 -34
  52. package/components/Snackbar.js +22 -16
  53. package/components/SnackbarContainer.js +42 -0
  54. package/components/Surface.js +15 -10
  55. package/components/Switch.js +3 -16
  56. package/components/SwitchIcon.js +40 -32
  57. package/components/Tab.js +57 -38
  58. package/components/TabContent.js +1 -0
  59. package/components/TabList.js +60 -32
  60. package/components/TabPanel.js +1 -1
  61. package/components/Table.js +116 -0
  62. package/components/TextArea.js +16 -15
  63. package/components/Title.js +4 -9
  64. package/components/Tooltip.js +43 -21
  65. package/components/TopAppBar.js +56 -78
  66. package/constants/shapes.js +36 -0
  67. package/constants/typography.js +127 -0
  68. package/core/Composition.js +354 -192
  69. package/core/CompositionAdapter.js +11 -12
  70. package/core/CustomElement.js +588 -236
  71. package/core/css.js +117 -12
  72. package/core/customTypes.js +120 -25
  73. package/core/dom.js +17 -11
  74. package/core/jsonMergePatch.js +12 -10
  75. package/core/observe.js +298 -253
  76. package/core/optimizations.js +9 -9
  77. package/core/template.js +14 -57
  78. package/dist/index.min.js +85 -115
  79. package/dist/index.min.js.map +4 -4
  80. package/dist/meta.json +1 -1
  81. package/dom/HTMLOptionsCollectionProxy.js +106 -0
  82. package/{theming/themableMixinLoader.js → loaders/palette.js} +4 -3
  83. package/loaders/theme.js +12 -0
  84. package/mixins/AriaReflectorMixin.js +53 -13
  85. package/mixins/AriaToolbarMixin.js +3 -0
  86. package/mixins/ControlMixin.js +76 -33
  87. package/mixins/DelegatesFocusMixin.js +54 -0
  88. package/mixins/DensityMixin.js +2 -2
  89. package/mixins/ElevationMixin.js +62 -0
  90. package/mixins/FlexableMixin.js +66 -37
  91. package/mixins/FormAssociatedMixin.js +60 -8
  92. package/mixins/HyperlinkMixin.js +66 -0
  93. package/mixins/InputMixin.js +205 -32
  94. package/mixins/KeyboardNavMixin.js +8 -6
  95. package/mixins/NavigationListenerMixin.js +33 -0
  96. package/mixins/PopupMixin.js +176 -208
  97. package/mixins/ResizeObserverMixin.js +16 -4
  98. package/mixins/RippleMixin.js +8 -6
  99. package/mixins/ScrollListenerMixin.js +1 -1
  100. package/mixins/SemiStickyMixin.js +44 -98
  101. package/mixins/ShapeMaskedMixin.js +117 -0
  102. package/mixins/ShapeMixin.js +22 -204
  103. package/mixins/StateMixin.js +70 -34
  104. package/mixins/TextFieldMixin.js +107 -143
  105. package/mixins/ThemableMixin.js +44 -56
  106. package/mixins/TooltipTriggerMixin.js +291 -359
  107. package/mixins/TouchTargetMixin.js +1 -1
  108. package/mixins/TypographyMixin.js +121 -0
  109. package/package.json +110 -74
  110. package/services/rtl.js +10 -0
  111. package/services/svgAlias.js +17 -0
  112. package/{theming/index.js → services/theme.js} +24 -174
  113. package/types/bin/mdw-css.d.ts +3 -0
  114. package/types/bin/mdw-css.d.ts.map +1 -0
  115. package/types/components/Badge.d.ts +39 -0
  116. package/types/components/Badge.d.ts.map +1 -0
  117. package/types/components/Body.d.ts +29 -0
  118. package/types/components/Body.d.ts.map +1 -0
  119. package/types/components/BottomAppBar.d.ts +73 -0
  120. package/types/components/BottomAppBar.d.ts.map +1 -0
  121. package/types/components/BottomSheet.d.ts +109 -0
  122. package/types/components/BottomSheet.d.ts.map +1 -0
  123. package/types/components/Box.d.ts +16 -0
  124. package/types/components/Box.d.ts.map +1 -0
  125. package/types/components/Button.d.ts +714 -0
  126. package/types/components/Button.d.ts.map +1 -0
  127. package/types/components/Card.d.ts +412 -0
  128. package/types/components/Card.d.ts.map +1 -0
  129. package/types/components/Checkbox.d.ts +205 -0
  130. package/types/components/Checkbox.d.ts.map +1 -0
  131. package/types/components/CheckboxIcon.d.ts +44 -0
  132. package/types/components/CheckboxIcon.d.ts.map +1 -0
  133. package/types/components/Chip.d.ts +1425 -0
  134. package/types/components/Chip.d.ts.map +1 -0
  135. package/types/components/Dialog.d.ts +286 -0
  136. package/types/components/Dialog.d.ts.map +1 -0
  137. package/types/components/DialogActions.d.ts +4 -0
  138. package/types/components/DialogActions.d.ts.map +1 -0
  139. package/types/components/Display.d.ts +45 -0
  140. package/types/components/Display.d.ts.map +1 -0
  141. package/types/components/Divider.d.ts +10 -0
  142. package/types/components/Divider.d.ts.map +1 -0
  143. package/types/components/Fab.d.ts +741 -0
  144. package/types/components/Fab.d.ts.map +1 -0
  145. package/types/components/FabContainer.d.ts +10 -0
  146. package/types/components/FabContainer.d.ts.map +1 -0
  147. package/types/components/FilterChip.d.ts +4283 -0
  148. package/types/components/FilterChip.d.ts.map +1 -0
  149. package/types/components/Grid.d.ts +37 -0
  150. package/types/components/Grid.d.ts.map +1 -0
  151. package/types/components/Headline.d.ts +47 -0
  152. package/types/components/Headline.d.ts.map +1 -0
  153. package/types/components/Icon.d.ts +103 -0
  154. package/types/components/Icon.d.ts.map +1 -0
  155. package/types/components/IconButton.d.ts +1486 -0
  156. package/types/components/IconButton.d.ts.map +1 -0
  157. package/types/components/Input.d.ts +51288 -0
  158. package/types/components/Input.d.ts.map +1 -0
  159. package/types/components/InputChip.d.ts +243 -0
  160. package/types/components/InputChip.d.ts.map +1 -0
  161. package/types/components/Label.d.ts +29 -0
  162. package/types/components/Label.d.ts.map +1 -0
  163. package/types/components/List.d.ts +31 -0
  164. package/types/components/List.d.ts.map +1 -0
  165. package/types/components/ListItem.d.ts +349 -0
  166. package/types/components/ListItem.d.ts.map +1 -0
  167. package/types/components/ListOption.d.ts +1493 -0
  168. package/types/components/ListOption.d.ts.map +1 -0
  169. package/types/components/Listbox.d.ts +12012 -0
  170. package/types/components/Listbox.d.ts.map +1 -0
  171. package/types/components/Menu.d.ts +119 -0
  172. package/types/components/Menu.d.ts.map +1 -0
  173. package/types/components/MenuItem.d.ts +3109 -0
  174. package/types/components/MenuItem.d.ts.map +1 -0
  175. package/types/components/NavBar.d.ts +18 -0
  176. package/types/components/NavBar.d.ts.map +1 -0
  177. package/types/components/NavBarItem.d.ts +186 -0
  178. package/types/components/NavBarItem.d.ts.map +1 -0
  179. package/types/components/NavDrawer.d.ts +108 -0
  180. package/types/components/NavDrawer.d.ts.map +1 -0
  181. package/types/components/NavDrawerItem.d.ts +186 -0
  182. package/types/components/NavDrawerItem.d.ts.map +1 -0
  183. package/types/components/NavItem.d.ts +190 -0
  184. package/types/components/NavItem.d.ts.map +1 -0
  185. package/types/components/NavRail.d.ts +109 -0
  186. package/types/components/NavRail.d.ts.map +1 -0
  187. package/types/components/NavRailItem.d.ts +186 -0
  188. package/types/components/NavRailItem.d.ts.map +1 -0
  189. package/types/components/Page.d.ts +24 -0
  190. package/types/components/Page.d.ts.map +1 -0
  191. package/types/components/Pane.d.ts +44 -0
  192. package/types/components/Pane.d.ts.map +1 -0
  193. package/types/components/Popup.d.ts +76 -0
  194. package/types/components/Popup.d.ts.map +1 -0
  195. package/types/components/Progress.d.ts +19 -0
  196. package/types/components/Progress.d.ts.map +1 -0
  197. package/types/components/Radio.d.ts +199 -0
  198. package/types/components/Radio.d.ts.map +1 -0
  199. package/types/components/RadioIcon.d.ts +46 -0
  200. package/types/components/RadioIcon.d.ts.map +1 -0
  201. package/types/components/Ripple.d.ts +34 -0
  202. package/types/components/Ripple.d.ts.map +1 -0
  203. package/types/components/Root.d.ts +68 -0
  204. package/types/components/Root.d.ts.map +1 -0
  205. package/types/components/Scrim.d.ts +6 -0
  206. package/types/components/Scrim.d.ts.map +1 -0
  207. package/types/components/Search.d.ts +16 -0
  208. package/types/components/Search.d.ts.map +1 -0
  209. package/types/components/SegmentedButton.d.ts +718 -0
  210. package/types/components/SegmentedButton.d.ts.map +1 -0
  211. package/types/components/SegmentedButtonGroup.d.ts +44 -0
  212. package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
  213. package/types/components/Select.d.ts +1361 -0
  214. package/types/components/Select.d.ts.map +1 -0
  215. package/types/components/Shape.d.ts +10 -0
  216. package/types/components/Shape.d.ts.map +1 -0
  217. package/types/components/SideSheet.d.ts +106 -0
  218. package/types/components/SideSheet.d.ts.map +1 -0
  219. package/types/components/Slider.d.ts +382 -0
  220. package/types/components/Slider.d.ts.map +1 -0
  221. package/types/components/Snackbar.d.ts +65 -0
  222. package/types/components/Snackbar.d.ts.map +1 -0
  223. package/types/components/SnackbarContainer.d.ts +6 -0
  224. package/types/components/SnackbarContainer.d.ts.map +1 -0
  225. package/types/components/Surface.d.ts +45 -0
  226. package/types/components/Surface.d.ts.map +1 -0
  227. package/types/components/Switch.d.ts +183 -0
  228. package/types/components/Switch.d.ts.map +1 -0
  229. package/types/components/SwitchIcon.d.ts +169 -0
  230. package/types/components/SwitchIcon.d.ts.map +1 -0
  231. package/types/components/Tab.d.ts +879 -0
  232. package/types/components/Tab.d.ts.map +1 -0
  233. package/types/components/TabContent.d.ts +122 -0
  234. package/types/components/TabContent.d.ts.map +1 -0
  235. package/types/components/TabList.d.ts +6266 -0
  236. package/types/components/TabList.d.ts.map +1 -0
  237. package/types/components/TabPanel.d.ts +28 -0
  238. package/types/components/TabPanel.d.ts.map +1 -0
  239. package/types/components/Table.d.ts +2 -0
  240. package/types/components/Table.d.ts.map +1 -0
  241. package/types/components/TextArea.d.ts +1394 -0
  242. package/types/components/TextArea.d.ts.map +1 -0
  243. package/types/components/Title.d.ts +47 -0
  244. package/types/components/Title.d.ts.map +1 -0
  245. package/types/components/Tooltip.d.ts +49 -0
  246. package/types/components/Tooltip.d.ts.map +1 -0
  247. package/types/components/TopAppBar.d.ts +130 -0
  248. package/types/components/TopAppBar.d.ts.map +1 -0
  249. package/types/constants/colorKeywords.d.ts +2 -0
  250. package/types/constants/colorKeywords.d.ts.map +1 -0
  251. package/types/constants/shapes.d.ts +38 -0
  252. package/types/constants/shapes.d.ts.map +1 -0
  253. package/types/constants/typography.d.ts +212 -0
  254. package/types/constants/typography.d.ts.map +1 -0
  255. package/types/core/Composition.d.ts +252 -0
  256. package/types/core/Composition.d.ts.map +1 -0
  257. package/types/core/CompositionAdapter.d.ts +92 -0
  258. package/types/core/CompositionAdapter.d.ts.map +1 -0
  259. package/types/core/CustomElement.d.ts +302 -0
  260. package/types/core/CustomElement.d.ts.map +1 -0
  261. package/types/core/css.d.ts +44 -0
  262. package/types/core/css.d.ts.map +1 -0
  263. package/types/core/customTypes.d.ts +26 -0
  264. package/types/core/customTypes.d.ts.map +1 -0
  265. package/types/core/dom.d.ts +32 -0
  266. package/types/core/dom.d.ts.map +1 -0
  267. package/types/core/jsonMergePatch.d.ts +31 -0
  268. package/types/core/jsonMergePatch.d.ts.map +1 -0
  269. package/types/core/observe.d.ts +113 -0
  270. package/types/core/observe.d.ts.map +1 -0
  271. package/types/core/optimizations.d.ts +7 -0
  272. package/types/core/optimizations.d.ts.map +1 -0
  273. package/types/core/template.d.ts +47 -0
  274. package/types/core/template.d.ts.map +1 -0
  275. package/types/core/uid.d.ts +6 -0
  276. package/types/core/uid.d.ts.map +1 -0
  277. package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
  278. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
  279. package/types/index.d.ts +88 -0
  280. package/types/index.d.ts.map +1 -0
  281. package/types/loaders/palette.d.ts +2 -0
  282. package/types/loaders/palette.d.ts.map +1 -0
  283. package/types/loaders/theme.d.ts +2 -0
  284. package/types/loaders/theme.d.ts.map +1 -0
  285. package/types/mixins/AriaReflectorMixin.d.ts +23 -0
  286. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
  287. package/types/mixins/AriaToolbarMixin.d.ts +32 -0
  288. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
  289. package/types/mixins/ControlMixin.d.ts +124 -0
  290. package/types/mixins/ControlMixin.d.ts.map +1 -0
  291. package/types/mixins/DelegatesFocusMixin.d.ts +5 -0
  292. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
  293. package/types/mixins/DensityMixin.d.ts +5 -0
  294. package/types/mixins/DensityMixin.d.ts.map +1 -0
  295. package/types/mixins/ElevationMixin.d.ts +33 -0
  296. package/types/mixins/ElevationMixin.d.ts.map +1 -0
  297. package/types/mixins/FlexableMixin.d.ts +13 -0
  298. package/types/mixins/FlexableMixin.d.ts.map +1 -0
  299. package/types/mixins/FormAssociatedMixin.d.ts +122 -0
  300. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
  301. package/types/mixins/HyperlinkMixin.d.ts +22 -0
  302. package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
  303. package/types/mixins/InputMixin.d.ts +179 -0
  304. package/types/mixins/InputMixin.d.ts.map +1 -0
  305. package/types/mixins/KeyboardNavMixin.d.ts +47 -0
  306. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
  307. package/types/mixins/NavigationListenerMixin.d.ts +8 -0
  308. package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
  309. package/types/mixins/PopupMixin.d.ts +82 -0
  310. package/types/mixins/PopupMixin.d.ts.map +1 -0
  311. package/types/mixins/RTLObserverMixin.d.ts +7 -0
  312. package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
  313. package/types/mixins/ResizeObserverMixin.d.ts +12 -0
  314. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
  315. package/types/mixins/RippleMixin.d.ts +92 -0
  316. package/types/mixins/RippleMixin.d.ts.map +1 -0
  317. package/types/mixins/ScrollListenerMixin.d.ts +41 -0
  318. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
  319. package/types/mixins/SemiStickyMixin.d.ts +50 -0
  320. package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
  321. package/types/mixins/ShapeMaskedMixin.d.ts +9 -0
  322. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
  323. package/types/mixins/ShapeMixin.d.ts +38 -0
  324. package/types/mixins/ShapeMixin.d.ts.map +1 -0
  325. package/types/mixins/StateMixin.d.ts +27 -0
  326. package/types/mixins/StateMixin.d.ts.map +1 -0
  327. package/types/mixins/TextFieldMixin.d.ts +1354 -0
  328. package/types/mixins/TextFieldMixin.d.ts.map +1 -0
  329. package/types/mixins/ThemableMixin.d.ts +9 -0
  330. package/types/mixins/ThemableMixin.d.ts.map +1 -0
  331. package/types/mixins/TooltipTriggerMixin.d.ts +106 -0
  332. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
  333. package/types/mixins/TouchTargetMixin.d.ts +3 -0
  334. package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
  335. package/types/mixins/TypographyMixin.d.ts +17 -0
  336. package/types/mixins/TypographyMixin.d.ts.map +1 -0
  337. package/types/services/rtl.d.ts +3 -0
  338. package/types/services/rtl.d.ts.map +1 -0
  339. package/types/services/svgAlias.d.ts +13 -0
  340. package/types/services/svgAlias.d.ts.map +1 -0
  341. package/types/services/theme.d.ts +45 -0
  342. package/types/services/theme.d.ts.map +1 -0
  343. package/types/utils/cli.d.ts +3 -0
  344. package/types/utils/cli.d.ts.map +1 -0
  345. package/types/utils/function.d.ts +3 -0
  346. package/types/utils/function.d.ts.map +1 -0
  347. package/types/utils/jsx-runtime.d.ts +20 -0
  348. package/types/utils/jsx-runtime.d.ts.map +1 -0
  349. package/types/utils/material-color/blend.d.ts +34 -0
  350. package/types/utils/material-color/blend.d.ts.map +1 -0
  351. package/types/utils/material-color/hct/Cam16.d.ts +142 -0
  352. package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
  353. package/types/utils/material-color/hct/Hct.d.ts +93 -0
  354. package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
  355. package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
  356. package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
  357. package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
  358. package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
  359. package/types/utils/material-color/helper.d.ts +8 -0
  360. package/types/utils/material-color/helper.d.ts.map +1 -0
  361. package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
  362. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
  363. package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
  364. package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
  365. package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
  366. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
  367. package/types/utils/material-color/utils/color.d.ts +172 -0
  368. package/types/utils/material-color/utils/color.d.ts.map +1 -0
  369. package/types/utils/material-color/utils/math.d.ts +94 -0
  370. package/types/utils/material-color/utils/math.d.ts.map +1 -0
  371. package/types/utils/pixelmatch.d.ts +22 -0
  372. package/types/utils/pixelmatch.d.ts.map +1 -0
  373. package/types/utils/popup.d.ts +106 -0
  374. package/types/utils/popup.d.ts.map +1 -0
  375. package/types/utils/searchParams.d.ts +3 -0
  376. package/types/utils/searchParams.d.ts.map +1 -0
  377. package/types/utils/svg.d.ts +7 -0
  378. package/types/utils/svg.d.ts.map +1 -0
  379. package/utils/material-color/scheme/Scheme.js +1 -1
  380. package/utils/pixelmatch.js +360 -0
  381. package/utils/popup.js +86 -10
  382. package/utils/searchParams.js +19 -0
  383. package/components/ExtendedFab.js +0 -32
  384. package/components/Layout.js +0 -504
  385. package/components/Nav.js +0 -38
  386. package/core/DomAdapter.js +0 -586
  387. package/core/ICustomElement.d.ts +0 -291
  388. package/core/ICustomElement.js +0 -1
  389. package/core/test.js +0 -126
  390. package/core/typings.d.ts +0 -142
  391. package/core/typings.js +0 -1
  392. package/mixins/SurfaceMixin.js +0 -127
  393. package/theming/loader.js +0 -22
  394. /package/{utils/color_keywords.js → constants/colorKeywords.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 */
@@ -21,12 +23,15 @@ export default function FormAssociatedMixin(Base) {
21
23
  _ipcListener: null,
22
24
  /** @type {EventTarget} */
23
25
  _ipcTarget: null,
26
+ /** @type {FileList} */
27
+ _files: null,
24
28
  })
25
29
  .observe({
26
30
  ariaControls: 'string',
27
31
  autocomplete: DOMString,
28
32
  name: DOMString,
29
33
  readOnly: { attr: 'readonly', type: 'boolean' },
34
+ formNoValidate: { attr: 'formnovalidate', type: 'boolean' },
30
35
  defaultChecked: { attr: 'checked', type: 'boolean' },
31
36
  _checkedDirty: 'boolean',
32
37
  /* "Checkedness" */
@@ -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,7 +212,6 @@ export default function FormAssociatedMixin(Base) {
195
212
  */
196
213
  formAssociatedCallback(form) {
197
214
  this.refreshFormAssociation();
198
- console.debug('FormAssociatedMixin: formAssociatedCallback', this);
199
215
  this.checkValidity();
200
216
  },
201
217
 
@@ -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,8 +256,7 @@ export default function FormAssociatedMixin(Base) {
239
256
  * @param {'autocomplete'|'restore'} mode
240
257
  */
241
258
  formStateRestoreCallback(state, mode) {
242
- if (navigator.userAgent.includes('Chrome/')) {
243
- // console.warn('Chromium Bug: 1429585 - Ignoring formStateRestoreCallback on Chromium', { state, mode });
259
+ if (CHROME_VERSION < 115) {
244
260
  // formStateRestoreCallback is broken on Chromium
245
261
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1429585
246
262
  return;
@@ -282,6 +298,34 @@ export default function FormAssociatedMixin(Base) {
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
330
  // console.debug('FormAssociatedMixin: setFormValue', this.name, this.value, this);
287
331
  this.elementInternals.setFormValue(this.value);
@@ -305,5 +349,13 @@ export default function FormAssociatedMixin(Base) {
305
349
  valueChanged() {
306
350
  this._updateFormAssociatedValue();
307
351
  },
352
+ _valueBehaviorChanged(previous, current) {
353
+ if (previous !== 'filename' && current === 'filename') {
354
+ this.value = '';
355
+ }
356
+ },
357
+ typeChanged() {
358
+ this._updateFormAssociatedValue();
359
+ },
308
360
  });
309
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
@@ -37,10 +42,9 @@ export default function InputMixin(Base) {
37
42
  _formAction: { attr: 'formaction' },
38
43
  formEnctype: { attr: 'formenctype', ...DOMString },
39
44
  formMethod: { attr: 'formmethod', ...DOMString },
40
- formNoValidate: { attr: 'formNoValidate', type: 'boolean' },
41
45
  formTarget: { attr: 'formtarget', ...DOMString },
42
46
  _height: { attr: 'height', type: 'integer' },
43
- indeterminate: { type: 'boolean', reflect: false },
47
+ _indeterminate: 'boolean',
44
48
  max: DOMString,
45
49
  maxLength: { attr: 'maxlength', type: 'integer', empty: -1 },
46
50
  min: DOMString,
@@ -54,26 +58,44 @@ export default function InputMixin(Base) {
54
58
  // [CEReactions] attribute [LegacyNullToEmptyString] DOMString value;
55
59
  _width: { attr: 'width', type: 'integer' },
56
60
  })
61
+ .set({
62
+ _useFormImplicitSubmission: true,
63
+ })
57
64
  .define({
58
65
  // Alias for typescript
59
66
  _input() { return /** @type {HTMLInputElement} */ (this.refs.control); },
60
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
+ })
61
81
  .overrides({
62
82
  controlTagName: 'input',
63
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
+ })
64
90
  .on({
65
- composed() {
66
- const { control } = this.refs;
67
- control.setAttribute('checked', '{defaultChecked}');
68
- control.setAttribute('height', '{_height}');
69
- control.setAttribute('width', '{_width}');
70
- control.setAttribute('value', '{_defaultValue}');
71
- },
72
-
73
91
  // TODO: Bind multiple
74
92
  typeChanged() { this.onValueChangingContentAttribute(); },
75
- defaultCheckedChanged() {
76
- 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;
77
99
  },
78
100
  minChanged() { this.onValueChangingContentAttribute(); },
79
101
  minLengthChanged() { this.onValueChangingContentAttribute(); },
@@ -85,11 +107,9 @@ export default function InputMixin(Base) {
85
107
  defaultValueChanged() { this.onValueChangingContentAttribute(); },
86
108
  _formResetChanged(oldValue, newValue) {
87
109
  if (!newValue) return;
88
- console.log('form reset');
110
+ this._onSetValue(this.defaultValue);
89
111
  const input = this._input;
90
- input.value = this.defaultValue;
91
112
  input.checked = this.defaultChecked;
92
- this._value = input.value;
93
113
  this._checked = input.checked;
94
114
  this._checkedDirty = false;
95
115
  },
@@ -118,6 +138,7 @@ export default function InputMixin(Base) {
118
138
  // Apply user value to input and read back result to apply control to parse
119
139
  this._input.checked = checked;
120
140
  this._checked = this._input.checked;
141
+ this.indeterminate = false;
121
142
  },
122
143
  _onSetValue(value) {
123
144
  // Apply user value to input and read back result to apply control to parse
@@ -132,6 +153,7 @@ export default function InputMixin(Base) {
132
153
  * @return {void}
133
154
  */
134
155
  performImplicitSubmission(event) {
156
+ if (!this._useFormImplicitSubmission) return;
135
157
  const form = this.form;
136
158
  if (!form) return;
137
159
  /** @type {HTMLInputElement} */
@@ -148,13 +170,123 @@ export default function InputMixin(Base) {
148
170
  }
149
171
  }
150
172
  if (defaultButton) {
151
- defaultButton.click();
173
+ defaultButton.dispatchEvent(new PointerEvent(
174
+ 'click',
175
+ { bubbles: true, cancelable: true, composed: true },
176
+ ));
152
177
  return;
153
178
  }
154
179
  if (submissionBlockers.size > 1) return;
155
180
  this.form.submit();
156
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
+ }
157
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
+ },
158
290
  })
159
291
  .childEvents({
160
292
  control: {
@@ -164,6 +296,16 @@ export default function InputMixin(Base) {
164
296
  if (/** @type {HTMLInputElement} */ (event.currentTarget).type === 'submit') return;
165
297
  this.performImplicitSubmission(event);
166
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
+ },
167
309
  change(event) {
168
310
  if (this.disabledState) {
169
311
  event.preventDefault();
@@ -171,15 +313,51 @@ export default function InputMixin(Base) {
171
313
  return;
172
314
  }
173
315
  const input = /** @type {HTMLInputElement} */ (event.currentTarget);
174
- this._checkedDirty = true;
175
- this._checked = input.checked;
316
+ this.checked = input.checked;
176
317
  },
177
318
  },
178
319
  })
179
- .define({
180
- 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); },
181
330
 
182
- select() { return this._input.select; },
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
+ },
342
+
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
+ },
183
361
 
184
362
  selectionDirection: {
185
363
  get() { return this._input.selectionDirection; },
@@ -196,16 +374,6 @@ export default function InputMixin(Base) {
196
374
  set(value) { this._input.selectionStart = value; },
197
375
  },
198
376
 
199
- setRangeText() { return this._input.setRangeText; },
200
-
201
- setSelectionRange() { return this._input.setSelectionRange; },
202
-
203
- showPicker() { return this._input.showPicker; },
204
-
205
- stepDown() { return this._input.stepDown; },
206
-
207
- stepUp() { return this._input.stepUp; },
208
-
209
377
  valueAsDate: {
210
378
  get() { return this._input.valueAsDate; },
211
379
  set(value) {
@@ -245,5 +413,10 @@ export default function InputMixin(Base) {
245
413
  this._width = value;
246
414
  },
247
415
  },
248
- });
416
+ })
417
+ .css`
418
+ #control::-webkit-file-upload-button {
419
+ display: none;
420
+ }
421
+ `;
249
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,6 +16,7 @@ const DEFAULT_ELEMENT_QUERY = [
14
16
  */
15
17
  export default function KeyboardNavMixin(Base) {
16
18
  return Base
19
+ .mixin(AriaReflectorMixin)
17
20
  .observe({
18
21
  /** Keyboard navigation attribute */
19
22
  kbdNav: { empty: 'true' },
@@ -46,8 +49,7 @@ export default function KeyboardNavMixin(Base) {
46
49
  })
47
50
  .methods({
48
51
  _ariaOrientationIsVertical() {
49
- return (this.ariaOrientation
50
- ?? this.getAttribute('aria-orientation')
52
+ return (this.readAriaProperty('ariaOrientation')
51
53
  ?? this.ariaOrientationDefault) === 'vertical';
52
54
  },
53
55
  focusCurrentOrFirst() {
@@ -94,7 +96,7 @@ export default function KeyboardNavMixin(Base) {
94
96
  }
95
97
 
96
98
  if (!loop) {
97
- if (document.activeElement !== current && current instanceof HTMLElement) {
99
+ if (!isFocused(current) && current instanceof HTMLElement) {
98
100
  current.focus();
99
101
  }
100
102
  return current;
@@ -158,7 +160,7 @@ export default function KeyboardNavMixin(Base) {
158
160
  /** @type {HTMLElement} */
159
161
  let firstFocusableChild = null;
160
162
  for (const child of this.kbdNavChildren) {
161
- if (!currentlyFocusedChild && document.activeElement === child) {
163
+ if (!currentlyFocusedChild && isFocused(child)) {
162
164
  currentlyFocusedChild = child;
163
165
  } else if (!currentTabIndexChild && child.getAttribute('tabindex') === '0') {
164
166
  currentTabIndexChild = child;
@@ -172,7 +174,7 @@ export default function KeyboardNavMixin(Base) {
172
174
  }
173
175
  // Bind
174
176
  if (!child.hasAttribute('tabindex')) {
175
- child.tabIndex = (document.activeElement === child) ? 0 : -1;
177
+ child.tabIndex = isFocused(child) ? 0 : -1;
176
178
  }
177
179
  // this.rtiBindChild(child);
178
180
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Listens for HTMLAnchorElement click events that will trigger navigation
3
+ * and throws a cancelable `mdw:hyperlink` event before firing.
4
+ * Will be supported until Navigation API is widely available
5
+ * @param {typeof import('../core/CustomElement.js').default} Base
6
+ */
7
+ export default function NavigationListenerMixin(Base) {
8
+ return Base
9
+ .rootEvents({
10
+ click(event) {
11
+ const { target } = event;
12
+ if (!(target instanceof HTMLAnchorElement)) return;
13
+ if (!target.href) return;
14
+ const actionAllowed = target.dispatchEvent(new CustomEvent('mdw:hyperlink', {
15
+ bubbles: true,
16
+ composed: true,
17
+ cancelable: true,
18
+ detail: {
19
+ download: target.download,
20
+ href: target.href,
21
+ hreflang: target.hreflang,
22
+ target: target.target,
23
+ },
24
+ }));
25
+ if (!actionAllowed) {
26
+ // Allow the click event to propagate
27
+ // event.stopPropagation();
28
+ // Don't perform native hyperlink action
29
+ event.preventDefault();
30
+ }
31
+ },
32
+ });
33
+ }