@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
package/core/css.js CHANGED
@@ -1,19 +1,84 @@
1
+ /** @type {Map<string, CSSStyleSheet>} */
2
+ const cssStyleSheetsCache = new Map();
3
+
4
+ /**
5
+ * @param {string} content
6
+ * @param {boolean} [useCache=true]
7
+ * @return {CSSStyleSheet}
8
+ */
9
+ export function createCSSStyleSheet(content, useCache = true) {
10
+ if (useCache && cssStyleSheetsCache.has(content)) {
11
+ return cssStyleSheetsCache.get(content);
12
+ }
13
+ const sheet = new CSSStyleSheet();
14
+ sheet.replaceSync(content);
15
+ if (useCache) {
16
+ cssStyleSheetsCache.set(content, sheet);
17
+ }
18
+ return sheet;
19
+ }
20
+
21
+ /** @type {Map<string, HTMLStyleElement>} */
22
+ const styleElementCache = new Map();
23
+
24
+ /** @type {Document} */
25
+ let _inactiveDocument;
26
+
27
+ /**
28
+ * @param {string} content
29
+ * @param {boolean} [useCache=true]
30
+ * @return {HTMLStyleElement}
31
+ */
32
+ export function createHTMLStyleElement(content, useCache = true) {
33
+ let style;
34
+ if (useCache && styleElementCache.has(content)) {
35
+ style = styleElementCache.get(content);
36
+ } else {
37
+ _inactiveDocument ??= document.implementation.createHTMLDocument();
38
+ style = _inactiveDocument.createElement('style');
39
+ style.textContent = content;
40
+ if (useCache) {
41
+ styleElementCache.set(content, style);
42
+ }
43
+ }
44
+ return /** @type {HTMLStyleElement} */ (style.cloneNode(true));
45
+ }
46
+
47
+ /** @type {boolean} */
48
+ let _cssStyleSheetConstructable;
49
+
50
+ /**
51
+ * @param {string} content
52
+ * @param {boolean} [useCache=true]
53
+ */
54
+ export function createCSS(content, useCache = true) {
55
+ if (_cssStyleSheetConstructable == null) {
56
+ try {
57
+ const sheet = createCSSStyleSheet(content, useCache);
58
+ _cssStyleSheetConstructable = true;
59
+ return sheet;
60
+ } catch {
61
+ _cssStyleSheetConstructable = false;
62
+ }
63
+ }
64
+ return _cssStyleSheetConstructable
65
+ ? createCSSStyleSheet(content, useCache)
66
+ : createHTMLStyleElement(content, useCache);
67
+ }
68
+
1
69
  /**
2
70
  * @param {Iterable<HTMLStyleElement|CSSStyleSheet>} styles
71
+ * @param {boolean} [useCache=true]
3
72
  * @yields composed CSSStyleSheet
4
73
  * @return {Generator<CSSStyleSheet>} composed CSSStyleSheet
5
74
  */
6
- export function* generateCSSStyleSheets(styles) {
75
+ export function* generateCSSStyleSheets(styles, useCache = true) {
7
76
  for (const style of styles) {
8
77
  if (style instanceof HTMLStyleElement) {
9
- const sheet = new CSSStyleSheet();
10
- sheet.replaceSync(style.textContent);
11
- yield sheet;
78
+ yield createCSSStyleSheet(style.textContent, useCache);
12
79
  } else if (style.ownerNode) {
13
80
  console.warn('Stylesheet is part of style');
14
- const sheet = new CSSStyleSheet();
15
- sheet.replaceSync([...style.cssRules].map((r) => r.cssText).join(''));
16
- yield sheet;
81
+ yield createCSSStyleSheet([...style.cssRules].map((r) => r.cssText).join(''), useCache);
17
82
  } else {
18
83
  yield style;
19
84
  }
@@ -21,14 +86,15 @@ export function* generateCSSStyleSheets(styles) {
21
86
  }
22
87
 
23
88
  /** @type {WeakMap<CSSStyleSheet, HTMLStyleElement>} */
24
- const styleElementWrappers = new WeakMap();
89
+ const styleElementFromStyleSheetCache = new WeakMap();
25
90
 
26
91
  /**
27
92
  * @param {Iterable<HTMLStyleElement|CSSStyleSheet>} styles
93
+ * @param {boolean} [useCache=true]
28
94
  * @yields composed HTMLStyleElement
29
95
  * @return {Generator<HTMLStyleElement>} composed CSSStyleSheet
30
96
  */
31
- export function* generateHTMLStyleElements(styles) {
97
+ export function* generateHTMLStyleElements(styles, useCache = true) {
32
98
  for (const style of styles) {
33
99
  if (style instanceof HTMLStyleElement) {
34
100
  yield style;
@@ -36,17 +102,56 @@ export function* generateHTMLStyleElements(styles) {
36
102
  // console.log('Cloning parent HTMLStyleElement instead');
37
103
  // @ts-ignore Skip cast
38
104
  yield style.ownerNode.cloneNode(true);
39
- } else if (styleElementWrappers.has(style)) {
105
+ } else if (useCache && styleElementFromStyleSheetCache.has(style)) {
40
106
  // @ts-ignore Skip cast
41
- yield styleElementWrappers.get(style).cloneNode(true);
107
+ yield styleElementFromStyleSheetCache.get(style).cloneNode(true);
42
108
  } else {
43
109
  console.warn('Manually constructing HTMLStyleElement', [...style.cssRules].map((r) => r.cssText).join('\n'));
44
110
  const styleElement = document.createElement('style');
45
111
  styleElement.textContent = [...style.cssRules].map((r) => r.cssText).join('');
46
- styleElementWrappers.set(style, styleElement);
112
+ if (useCache) {
113
+ styleElementFromStyleSheetCache.set(style, styleElement);
114
+ }
47
115
 
48
116
  // @ts-ignore Skip cast
49
117
  yield styleElement.cloneNode(true);
50
118
  }
51
119
  }
52
120
  }
121
+
122
+ /**
123
+ * @param {TemplateStringsArray|string} array
124
+ * @param {...any} substitutions
125
+ * @return {HTMLStyleElement|CSSStyleSheet}
126
+ */
127
+ export function css(array, ...substitutions) {
128
+ if (typeof array === 'string') return createCSS(array);
129
+ return createCSS(String.raw({ raw: array }, ...substitutions));
130
+ }
131
+
132
+ /**
133
+ * @param {TemplateStringsArray|string|HTMLStyleElement|CSSStyleSheet} styles
134
+ * @param {...any} substitutions
135
+ * @return {HTMLStyleElement|CSSStyleSheet}
136
+ */
137
+ export function addGlobalCss(styles, ...substitutions) {
138
+ /** @type {HTMLStyleElement|CSSStyleSheet} */
139
+ let compiled;
140
+ if (typeof styles === 'string') {
141
+ compiled = css(styles);
142
+ } else if (Array.isArray(styles)) {
143
+ compiled = css(/** @type {TemplateStringsArray} */ (styles), ...substitutions);
144
+ } else {
145
+ compiled = /** @type {HTMLStyleElement|CSSStyleSheet} */ (styles);
146
+ }
147
+
148
+ if (compiled instanceof HTMLStyleElement) {
149
+ document.head.append(compiled);
150
+ } else {
151
+ document.adoptedStyleSheets = [
152
+ ...document.adoptedStyleSheets,
153
+ compiled,
154
+ ];
155
+ }
156
+ return compiled;
157
+ }
@@ -1,8 +1,10 @@
1
1
  /** @typedef {import('./CustomElement').default} CustomElement */
2
2
 
3
+ import { attrNameFromPropName } from './dom.js';
4
+
3
5
  /**
4
6
  * @see https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes
5
- * @type {import('./typings.js').ObserverOptions<'function',EventListener, unknown>}
7
+ * @type {import('./observe.js').ObserverOptions<'function',EventListener, unknown>}
6
8
  */
7
9
  export const EVENT_HANDLER_TYPE = {
8
10
  type: 'function',
@@ -39,7 +41,7 @@ export const EVENT_HANDLER_TYPE = {
39
41
  const weakRefValues = new WeakMap();
40
42
 
41
43
  /**
42
- * @type {import('./typings.js').ObserverOptions<'object',HTMLElement>}
44
+ * @type {import('./observe.js').ObserverOptions<'object',HTMLElement>}
43
45
  */
44
46
  export const WEAKREF_TYPE = {
45
47
  type: 'object',
@@ -61,7 +63,12 @@ export const WEAKREF_TYPE = {
61
63
  * @prop {EffectTiming} [timing]
62
64
  */
63
65
 
64
- /** @type {WeakMap<CustomElement, Set<string>} */
66
+ /**
67
+ * @typedef {Object} QueuedPropsMetadata
68
+ * @prop {boolean} initial
69
+ */
70
+
71
+ /** @type {WeakMap<CustomElement, Map<string, QueuedPropsMetadata>>} */
65
72
  const queuedPropsByElement = new WeakMap();
66
73
 
67
74
  /** @type {WeakMap<CustomElement, Map<string, Animation>>} */
@@ -78,6 +85,9 @@ function elementStylerMicrotaskCallback(name) {
78
85
  if (previousAnimations?.has(name)) {
79
86
  previousAnimation = previousAnimations.get(name);
80
87
  }
88
+ const queuedProps = queuedPropsByElement.get(this);
89
+ const { initial } = queuedProps.get(name);
90
+ queuedProps.delete(name);
81
91
  const value = this[name];
82
92
  if (!value) {
83
93
  previousAnimation?.cancel();
@@ -90,6 +100,7 @@ function elementStylerMicrotaskCallback(name) {
90
100
  : this;
91
101
  const currentAnimation = el.animate(styles, {
92
102
  ...timing,
103
+ ...(initial ? { duration: 0 } : null),
93
104
  fill: 'forwards',
94
105
  });
95
106
  currentAnimation.onremove = () => {
@@ -106,42 +117,126 @@ function elementStylerMicrotaskCallback(name) {
106
117
  } else {
107
118
  previousAnimationsByElement.set(this, new Map([[name, currentAnimation]]));
108
119
  }
109
- queuedPropsByElement.get(this).delete(name);
110
120
  }
111
121
 
112
- /** @type {import('./typings.js').ObserverOptions<'object',ElementStylerOptions, CustomElement>} */
113
- export const ELEMENT_STYLER_TYPE = {
122
+ /** @type {WeakMap<Element, Function[]>} */
123
+ const pendingResizeCallbacks = new WeakMap();
124
+ const pendingConnections = new ResizeObserver((entries) => {
125
+ for (const { target } of entries) {
126
+ if (pendingResizeCallbacks.has(target)) {
127
+ const callbacks = pendingResizeCallbacks.get(target);
128
+ pendingResizeCallbacks.delete(target);
129
+ pendingConnections.unobserve(target);
130
+ for (const callback of callbacks) {
131
+ callback();
132
+ }
133
+ }
134
+ }
135
+ });
136
+
137
+ /** @type {import('./observe.js').ObserverOptions<'object',ElementStylerOptions, CustomElement>} */
138
+ export const ELEMENT_ANIMATION_TYPE = {
114
139
  type: 'object',
115
140
  reflect: false,
116
141
  diff: null, // Skip computing entire change
117
142
  propChangedCallback(name, oldValue, newValue) {
118
- if (!this.isConnected) return;
119
- const queuedProps = queuedPropsByElement.get(this);
120
- let hasQueue = false;
121
- if (queuedProps?.has(name)) {
122
- hasQueue = true;
123
- }
124
143
  if (!newValue) {
125
- if (!hasQueue) return;
126
- console.warn('debug of cancel needed');
127
- if (queuedProps) {
128
- queuedProps.delete(name);
144
+ const previousAnimations = previousAnimationsByElement.get(this);
145
+ if (!previousAnimations?.has(name)) {
146
+ // Fast abort
147
+ return;
129
148
  }
130
- return;
131
- }
132
-
133
- if (hasQueue) {
134
- // Already scheduled
135
- return;
136
149
  }
150
+ const queuedProps = queuedPropsByElement.get(this);
137
151
 
152
+ const initial = !this.isConnected;
138
153
  if (queuedProps) {
139
- queuedProps.add(name);
154
+ if (queuedProps.has(name)) return;
155
+ queuedProps.set(name, { initial });
140
156
  } else {
141
- queuedPropsByElement.set(this, new Set([name]));
157
+ queuedPropsByElement.set(this, new Map([[name, { initial }]]));
142
158
  }
159
+ // TODO: Reuse callback instead constructing each tick
143
160
  // Animation styles may trickle in steps, so queue a microtask before doing any work.
144
161
  // Using requestAnimationFrame would fire one frame too late for CSS animations already scheduled
145
- queueMicrotask(elementStylerMicrotaskCallback.bind(this, name));
162
+ const callback = elementStylerMicrotaskCallback.bind(this, name);
163
+ if (this.isConnected) {
164
+ queueMicrotask(callback);
165
+ } else if (pendingResizeCallbacks.has(this)) {
166
+ pendingResizeCallbacks.get(this).push(callback);
167
+ } else {
168
+ pendingResizeCallbacks.set(this, [callback]);
169
+ pendingConnections.observe(this);
170
+ }
171
+ },
172
+ };
173
+
174
+ /**
175
+ * @type {WeakMap<CustomElement, Map<string, HTMLStyleElement|CSSStyleSheet>>}
176
+ */
177
+ const styleReferences = new WeakMap();
178
+
179
+ /** @type {boolean} */
180
+ let useAdoptedStyleSheets = null;
181
+
182
+ /** @type {import('./observe.js').ObserverOptions<'string',string, CustomElement>} */
183
+ export const ELEMENT_STYLE_TYPE = {
184
+ type: 'string',
185
+ reflect: false,
186
+ /**
187
+ * @param {string|Record<keyof CSSStyleDeclaration & string, string|number>} value
188
+ * @return {string}
189
+ */
190
+ parser(value) {
191
+ if (!value || typeof value === 'string') {
192
+ return /** @type {string} */ (value);
193
+ }
194
+ return `:host{${
195
+ Object.entries(value).map(([key, rule]) => `${attrNameFromPropName(key)}:${rule}`)
196
+ .join(';')
197
+ }}`;
198
+ },
199
+ propChangedCallback(name, oldValue, newValue) {
200
+ let mapOfStyles;
201
+
202
+ /** @type {HTMLStyleElement|CSSStyleSheet} */
203
+ let styles;
204
+ if (styleReferences.has(this)) {
205
+ mapOfStyles = styleReferences.get(this);
206
+ if (mapOfStyles.has(name)) {
207
+ styles = mapOfStyles.get(name);
208
+ }
209
+ } else {
210
+ // Skip build if blank
211
+ if (!newValue) return;
212
+ mapOfStyles = new Map();
213
+ styleReferences.set(this, mapOfStyles);
214
+ }
215
+
216
+ useAdoptedStyleSheets ??= 'adoptedStyleSheets' in ShadowRoot.prototype;
217
+ if (!styles) {
218
+ if (useAdoptedStyleSheets) {
219
+ styles = new CSSStyleSheet();
220
+ this.shadowRoot.adoptedStyleSheets = [
221
+ ...this.shadowRoot.adoptedStyleSheets,
222
+ styles,
223
+ ];
224
+ } else {
225
+ const styleElement = this.ownerDocument.createElement('style');
226
+ this.shadowRoot.prepend(styleElement);
227
+ styles = styleElement;
228
+ }
229
+ mapOfStyles.set(name, styles);
230
+ }
231
+ if (newValue) {
232
+ if (useAdoptedStyleSheets) {
233
+ /** @type {CSSStyleSheet} */(styles).replaceSync(newValue);
234
+ } else if (newValue) {
235
+ /** @type {HTMLStyleElement} */(styles).textContent = newValue;
236
+ }
237
+ styles.disabled = false;
238
+ } else {
239
+ styles.disabled = true;
240
+ }
146
241
  },
147
242
  };
package/core/dom.js CHANGED
@@ -17,6 +17,9 @@ export function attrValueFromDataValue(value) {
17
17
  }
18
18
  }
19
19
 
20
+ /** @type {Map<string, string>} */
21
+ let attrNameFromPropNameCache;
22
+
20
23
  /**
21
24
  * Converts property name to attribute name
22
25
  * (Similar to DOMStringMap)
@@ -24,18 +27,21 @@ export function attrValueFromDataValue(value) {
24
27
  * @return {string}
25
28
  */
26
29
  export function attrNameFromPropName(name) {
27
- const attrNameWords = name.split(/([A-Z])/);
28
- if (attrNameWords.length === 1) return name;
29
- return attrNameWords.reduce((prev, curr) => {
30
- if (prev == null) return curr;
31
- if (curr.length === 1 && curr.toUpperCase() === curr) {
32
- return `${prev}-${curr.toLowerCase()}`;
33
- }
34
- return prev + curr;
35
- });
30
+ attrNameFromPropNameCache ??= new Map();
31
+ if (attrNameFromPropNameCache.has(name)) {
32
+ return attrNameFromPropNameCache.get(name);
33
+ }
34
+ // eslint-disable-next-line unicorn/prefer-string-replace-all
35
+ const value = name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
36
+ attrNameFromPropNameCache.set(name, value);
37
+ return value;
36
38
  }
37
39
 
38
- const IS_FIREFOX = globalThis?.navigator?.userAgent.includes('Firefox');
40
+ export const CHROME_VERSION = Number.parseFloat(navigator.userAgent.match(/Chrome\/([\d.]+)/)?.[1]);
41
+ export const FIREFOX_VERSION = Number.parseFloat(navigator.userAgent.match(/Firefox\/([\d.]+)/)?.[1]);
42
+ export const SAFARI_VERSION = CHROME_VERSION || !navigator.userAgent.includes('AppleWebKit')
43
+ ? Number.NaN
44
+ : Number.parseFloat(navigator.userAgent.match(/Version\/([\d.]+)/)?.[1]);
39
45
 
40
46
  /**
41
47
  * @param {Element} element
@@ -43,7 +49,7 @@ const IS_FIREFOX = globalThis?.navigator?.userAgent.includes('Firefox');
43
49
  */
44
50
  export function isFocused(element) {
45
51
  if (!element) return false;
46
- if (IS_FIREFOX && element.constructor.formAssociated && element.hasAttribute('disabled')) {
52
+ if (FIREFOX_VERSION < 113 && element.constructor.formAssociated && element.hasAttribute('disabled')) {
47
53
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1818287
48
54
  console.warn('Firefox bug 1818287: Disabled form associated custom element cannot receive focus.');
49
55
  return false;
@@ -54,14 +54,15 @@ export function buildMergePatch(previous, current, arrayStrategy = 'reference')
54
54
  return structuredClone(current);
55
55
  }
56
56
  for (const [index, value] of current.entries()) {
57
- if (value == null) {
58
- console.warn('Nullish value found at', index);
57
+ if (value === null) {
58
+ patch[index] = null;
59
59
  continue;
60
60
  }
61
+ if (value == null) {
62
+ continue; // Skip undefined
63
+ }
61
64
  const changes = buildMergePatch(previous[index], value, arrayStrategy);
62
- if (changes === null) {
63
- continue;
64
- } else {
65
+ if (changes !== null) {
65
66
  patch[index] = changes;
66
67
  }
67
68
  }
@@ -77,14 +78,15 @@ export function buildMergePatch(previous, current, arrayStrategy = 'reference')
77
78
  const previousKeys = new Set(Object.keys(previous));
78
79
  for (const [key, value] of Object.entries(current)) {
79
80
  previousKeys.delete(key);
80
- if (value == null) {
81
- console.warn('Nullish value found at', key);
81
+ if (value === null) {
82
+ patch[key] = null;
82
83
  continue;
83
84
  }
85
+ if (value == null) {
86
+ continue; // Skip undefined
87
+ }
84
88
  const changes = buildMergePatch(previous[key], value, arrayStrategy);
85
- if (changes === null) {
86
- // console.log('keeping', key);
87
- } else {
89
+ if (changes !== null) {
88
90
  patch[key] = changes;
89
91
  }
90
92
  }