@shortfuse/materialdesignweb 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/README.md +50 -198
  2. package/bin/mdw-css.js +1 -1
  3. package/components/Badge.js +15 -5
  4. package/components/Body.js +7 -0
  5. package/components/BottomAppBar.js +7 -10
  6. package/components/BottomSheet.js +472 -0
  7. package/components/Box.js +11 -49
  8. package/components/Button.js +81 -82
  9. package/components/Card.js +74 -62
  10. package/components/Checkbox.js +15 -25
  11. package/components/CheckboxIcon.js +19 -31
  12. package/components/Chip.js +18 -13
  13. package/components/Dialog.js +70 -100
  14. package/components/DialogActions.js +4 -0
  15. package/components/Display.js +64 -0
  16. package/components/Divider.js +5 -0
  17. package/components/Fab.js +94 -17
  18. package/components/FabContainer.js +57 -0
  19. package/components/FilterChip.js +43 -32
  20. package/components/Grid.js +187 -0
  21. package/components/Headline.js +9 -28
  22. package/components/Icon.js +80 -71
  23. package/components/IconButton.js +77 -120
  24. package/components/Input.js +745 -86
  25. package/components/InputChip.js +193 -0
  26. package/components/Label.js +7 -0
  27. package/components/List.js +11 -5
  28. package/components/ListItem.js +92 -23
  29. package/components/ListOption.js +143 -65
  30. package/components/Listbox.js +57 -17
  31. package/components/Menu.js +39 -27
  32. package/components/MenuItem.js +49 -36
  33. package/components/NavBar.js +66 -21
  34. package/components/NavBarItem.js +5 -0
  35. package/components/NavDrawer.js +33 -16
  36. package/components/NavDrawerItem.js +7 -4
  37. package/components/NavItem.js +61 -34
  38. package/components/NavRail.js +32 -21
  39. package/components/NavRailItem.js +10 -2
  40. package/components/Page.js +119 -0
  41. package/components/Pane.js +24 -0
  42. package/components/Popup.js +23 -8
  43. package/components/Progress.js +25 -5
  44. package/components/Radio.js +8 -7
  45. package/components/RadioIcon.js +24 -15
  46. package/components/Ripple.js +25 -7
  47. package/components/Root.js +225 -0
  48. package/components/Scrim.js +95 -0
  49. package/components/Search.js +30 -25
  50. package/components/SegmentedButton.js +53 -40
  51. package/components/SegmentedButtonGroup.js +15 -12
  52. package/components/Select.js +19 -10
  53. package/components/Shape.js +10 -66
  54. package/components/SideSheet.js +337 -0
  55. package/components/Slider.js +93 -36
  56. package/components/Snackbar.js +52 -20
  57. package/components/SnackbarContainer.js +51 -0
  58. package/components/Surface.js +20 -10
  59. package/components/Switch.js +21 -18
  60. package/components/SwitchIcon.js +62 -33
  61. package/components/Tab.js +78 -38
  62. package/components/TabContent.js +33 -12
  63. package/components/TabList.js +95 -34
  64. package/components/TabPanel.js +10 -1
  65. package/components/Table.js +151 -0
  66. package/components/TextArea.js +48 -16
  67. package/components/Title.js +8 -9
  68. package/components/Tooltip.js +51 -22
  69. package/components/TopAppBar.js +71 -78
  70. package/constants/shapes.js +36 -0
  71. package/constants/typography.js +127 -0
  72. package/core/Composition.js +391 -201
  73. package/core/CompositionAdapter.js +35 -18
  74. package/core/CustomElement.js +634 -254
  75. package/core/css.js +117 -12
  76. package/core/customTypes.js +161 -49
  77. package/core/dom.js +18 -11
  78. package/core/jsonMergePatch.js +27 -11
  79. package/core/observe.js +308 -256
  80. package/core/optimizations.js +9 -9
  81. package/core/template.js +14 -57
  82. package/dist/CustomElement.min.js +2 -0
  83. package/dist/CustomElement.min.js.map +7 -0
  84. package/dist/core/CustomElement.min.js +2 -0
  85. package/dist/core/CustomElement.min.js.map +7 -0
  86. package/dist/index.min.js +85 -115
  87. package/dist/index.min.js.map +4 -4
  88. package/dist/meta.json +1 -1
  89. package/dom/HTMLOptionsCollectionProxy.js +108 -0
  90. package/{theming/themableMixinLoader.js → loaders/palette.js} +4 -3
  91. package/loaders/theme.js +12 -0
  92. package/mixins/AriaReflectorMixin.js +64 -15
  93. package/mixins/AriaToolbarMixin.js +6 -0
  94. package/mixins/ControlMixin.js +79 -33
  95. package/mixins/DelegatesFocusMixin.js +62 -0
  96. package/mixins/DensityMixin.js +7 -3
  97. package/mixins/ElevationMixin.js +61 -0
  98. package/mixins/FlexableMixin.js +87 -39
  99. package/mixins/FormAssociatedMixin.js +76 -10
  100. package/mixins/HyperlinkMixin.js +76 -0
  101. package/mixins/InputMixin.js +227 -32
  102. package/mixins/KeyboardNavMixin.js +11 -7
  103. package/mixins/NavigationListenerMixin.js +33 -0
  104. package/mixins/PopupMixin.js +216 -219
  105. package/mixins/RTLObserverMixin.js +2 -0
  106. package/mixins/ResizeObserverMixin.js +18 -4
  107. package/mixins/RippleMixin.js +11 -7
  108. package/mixins/ScrollListenerMixin.js +14 -2
  109. package/mixins/SemiStickyMixin.js +51 -98
  110. package/mixins/ShapeMaskedMixin.js +125 -0
  111. package/mixins/ShapeMixin.js +30 -203
  112. package/mixins/StateMixin.js +74 -34
  113. package/mixins/TextFieldMixin.js +128 -145
  114. package/mixins/ThemableMixin.js +57 -56
  115. package/mixins/TooltipTriggerMixin.js +305 -359
  116. package/mixins/TouchTargetMixin.js +5 -2
  117. package/mixins/TypographyMixin.js +128 -0
  118. package/package.json +125 -81
  119. package/services/rtl.js +10 -0
  120. package/services/svgAlias.js +17 -0
  121. package/{theming/index.js → services/theme.js} +25 -176
  122. package/types/bin/mdw-css.d.ts +3 -0
  123. package/types/bin/mdw-css.d.ts.map +1 -0
  124. package/types/components/Badge.d.ts +39 -0
  125. package/types/components/Badge.d.ts.map +1 -0
  126. package/types/components/Body.d.ts +29 -0
  127. package/types/components/Body.d.ts.map +1 -0
  128. package/types/components/BottomAppBar.d.ts +72 -0
  129. package/types/components/BottomAppBar.d.ts.map +1 -0
  130. package/types/components/BottomSheet.d.ts +135 -0
  131. package/types/components/BottomSheet.d.ts.map +1 -0
  132. package/types/components/Box.d.ts +16 -0
  133. package/types/components/Box.d.ts.map +1 -0
  134. package/types/components/Button.d.ts +245 -0
  135. package/types/components/Button.d.ts.map +1 -0
  136. package/types/components/Card.d.ts +147 -0
  137. package/types/components/Card.d.ts.map +1 -0
  138. package/types/components/Checkbox.d.ts +207 -0
  139. package/types/components/Checkbox.d.ts.map +1 -0
  140. package/types/components/CheckboxIcon.d.ts +44 -0
  141. package/types/components/CheckboxIcon.d.ts.map +1 -0
  142. package/types/components/Chip.d.ts +248 -0
  143. package/types/components/Chip.d.ts.map +1 -0
  144. package/types/components/Dialog.d.ts +103 -0
  145. package/types/components/Dialog.d.ts.map +1 -0
  146. package/types/components/DialogActions.d.ts +4 -0
  147. package/types/components/DialogActions.d.ts.map +1 -0
  148. package/types/components/Display.d.ts +46 -0
  149. package/types/components/Display.d.ts.map +1 -0
  150. package/types/components/Divider.d.ts +10 -0
  151. package/types/components/Divider.d.ts.map +1 -0
  152. package/types/components/Fab.d.ts +273 -0
  153. package/types/components/Fab.d.ts.map +1 -0
  154. package/types/components/FabContainer.d.ts +10 -0
  155. package/types/components/FabContainer.d.ts.map +1 -0
  156. package/types/components/FilterChip.d.ts +256 -0
  157. package/types/components/FilterChip.d.ts.map +1 -0
  158. package/types/components/Grid.d.ts +38 -0
  159. package/types/components/Grid.d.ts.map +1 -0
  160. package/types/components/Headline.d.ts +46 -0
  161. package/types/components/Headline.d.ts.map +1 -0
  162. package/types/components/Icon.d.ts +55 -0
  163. package/types/components/Icon.d.ts.map +1 -0
  164. package/types/components/IconButton.d.ts +284 -0
  165. package/types/components/IconButton.d.ts.map +1 -0
  166. package/types/components/Input.d.ts +2528 -0
  167. package/types/components/Input.d.ts.map +1 -0
  168. package/types/components/InputChip.d.ts +85 -0
  169. package/types/components/InputChip.d.ts.map +1 -0
  170. package/types/components/Label.d.ts +29 -0
  171. package/types/components/Label.d.ts.map +1 -0
  172. package/types/components/List.d.ts +35 -0
  173. package/types/components/List.d.ts.map +1 -0
  174. package/types/components/ListItem.d.ts +124 -0
  175. package/types/components/ListItem.d.ts.map +1 -0
  176. package/types/components/ListOption.d.ts +158 -0
  177. package/types/components/ListOption.d.ts.map +1 -0
  178. package/types/components/Listbox.d.ts +763 -0
  179. package/types/components/Listbox.d.ts.map +1 -0
  180. package/types/components/Menu.d.ts +130 -0
  181. package/types/components/Menu.d.ts.map +1 -0
  182. package/types/components/MenuItem.d.ts +232 -0
  183. package/types/components/MenuItem.d.ts.map +1 -0
  184. package/types/components/NavBar.d.ts +20 -0
  185. package/types/components/NavBar.d.ts.map +1 -0
  186. package/types/components/NavBarItem.d.ts +97 -0
  187. package/types/components/NavBarItem.d.ts.map +1 -0
  188. package/types/components/NavDrawer.d.ts +107 -0
  189. package/types/components/NavDrawer.d.ts.map +1 -0
  190. package/types/components/NavDrawerItem.d.ts +97 -0
  191. package/types/components/NavDrawerItem.d.ts.map +1 -0
  192. package/types/components/NavItem.d.ts +99 -0
  193. package/types/components/NavItem.d.ts.map +1 -0
  194. package/types/components/NavRail.d.ts +108 -0
  195. package/types/components/NavRail.d.ts.map +1 -0
  196. package/types/components/NavRailItem.d.ts +97 -0
  197. package/types/components/NavRailItem.d.ts.map +1 -0
  198. package/types/components/Page.d.ts +25 -0
  199. package/types/components/Page.d.ts.map +1 -0
  200. package/types/components/Pane.d.ts +44 -0
  201. package/types/components/Pane.d.ts.map +1 -0
  202. package/types/components/Popup.d.ts +78 -0
  203. package/types/components/Popup.d.ts.map +1 -0
  204. package/types/components/Progress.d.ts +21 -0
  205. package/types/components/Progress.d.ts.map +1 -0
  206. package/types/components/Radio.d.ts +201 -0
  207. package/types/components/Radio.d.ts.map +1 -0
  208. package/types/components/RadioIcon.d.ts +46 -0
  209. package/types/components/RadioIcon.d.ts.map +1 -0
  210. package/types/components/Ripple.d.ts +35 -0
  211. package/types/components/Ripple.d.ts.map +1 -0
  212. package/types/components/Root.d.ts +68 -0
  213. package/types/components/Root.d.ts.map +1 -0
  214. package/types/components/Scrim.d.ts +6 -0
  215. package/types/components/Scrim.d.ts.map +1 -0
  216. package/types/components/Search.d.ts +516 -0
  217. package/types/components/Search.d.ts.map +1 -0
  218. package/types/components/SegmentedButton.d.ts +252 -0
  219. package/types/components/SegmentedButton.d.ts.map +1 -0
  220. package/types/components/SegmentedButtonGroup.d.ts +43 -0
  221. package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
  222. package/types/components/Select.d.ts +158 -0
  223. package/types/components/Select.d.ts.map +1 -0
  224. package/types/components/Shape.d.ts +10 -0
  225. package/types/components/Shape.d.ts.map +1 -0
  226. package/types/components/SideSheet.d.ts +111 -0
  227. package/types/components/SideSheet.d.ts.map +1 -0
  228. package/types/components/Slider.d.ts +203 -0
  229. package/types/components/Slider.d.ts.map +1 -0
  230. package/types/components/Snackbar.d.ts +73 -0
  231. package/types/components/Snackbar.d.ts.map +1 -0
  232. package/types/components/SnackbarContainer.d.ts +6 -0
  233. package/types/components/SnackbarContainer.d.ts.map +1 -0
  234. package/types/components/Surface.d.ts +45 -0
  235. package/types/components/Surface.d.ts.map +1 -0
  236. package/types/components/Switch.d.ts +187 -0
  237. package/types/components/Switch.d.ts.map +1 -0
  238. package/types/components/SwitchIcon.d.ts +61 -0
  239. package/types/components/SwitchIcon.d.ts.map +1 -0
  240. package/types/components/Tab.d.ts +139 -0
  241. package/types/components/Tab.d.ts.map +1 -0
  242. package/types/components/TabContent.d.ts +124 -0
  243. package/types/components/TabContent.d.ts.map +1 -0
  244. package/types/components/TabList.d.ts +1111 -0
  245. package/types/components/TabList.d.ts.map +1 -0
  246. package/types/components/TabPanel.d.ts +28 -0
  247. package/types/components/TabPanel.d.ts.map +1 -0
  248. package/types/components/Table.d.ts +25 -0
  249. package/types/components/Table.d.ts.map +1 -0
  250. package/types/components/TextArea.d.ts +201 -0
  251. package/types/components/TextArea.d.ts.map +1 -0
  252. package/types/components/Title.d.ts +46 -0
  253. package/types/components/Title.d.ts.map +1 -0
  254. package/types/components/Tooltip.d.ts +49 -0
  255. package/types/components/Tooltip.d.ts.map +1 -0
  256. package/types/components/TopAppBar.d.ts +129 -0
  257. package/types/components/TopAppBar.d.ts.map +1 -0
  258. package/types/constants/colorKeywords.d.ts +2 -0
  259. package/types/constants/colorKeywords.d.ts.map +1 -0
  260. package/types/constants/shapes.d.ts +38 -0
  261. package/types/constants/shapes.d.ts.map +1 -0
  262. package/types/constants/typography.d.ts +212 -0
  263. package/types/constants/typography.d.ts.map +1 -0
  264. package/types/core/Composition.d.ts +260 -0
  265. package/types/core/Composition.d.ts.map +1 -0
  266. package/types/core/CompositionAdapter.d.ts +114 -0
  267. package/types/core/CompositionAdapter.d.ts.map +1 -0
  268. package/types/core/CustomElement.d.ts +304 -0
  269. package/types/core/CustomElement.d.ts.map +1 -0
  270. package/types/core/css.d.ts +44 -0
  271. package/types/core/css.d.ts.map +1 -0
  272. package/types/core/customTypes.d.ts +22 -0
  273. package/types/core/customTypes.d.ts.map +1 -0
  274. package/types/core/dom.d.ts +32 -0
  275. package/types/core/dom.d.ts.map +1 -0
  276. package/types/core/jsonMergePatch.d.ts +31 -0
  277. package/types/core/jsonMergePatch.d.ts.map +1 -0
  278. package/types/core/observe.d.ts +114 -0
  279. package/types/core/observe.d.ts.map +1 -0
  280. package/types/core/optimizations.d.ts +7 -0
  281. package/types/core/optimizations.d.ts.map +1 -0
  282. package/types/core/template.d.ts +47 -0
  283. package/types/core/template.d.ts.map +1 -0
  284. package/types/core/uid.d.ts +6 -0
  285. package/types/core/uid.d.ts.map +1 -0
  286. package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
  287. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
  288. package/types/index.d.ts +88 -0
  289. package/types/index.d.ts.map +1 -0
  290. package/types/loaders/palette.d.ts +2 -0
  291. package/types/loaders/palette.d.ts.map +1 -0
  292. package/types/loaders/theme.d.ts +2 -0
  293. package/types/loaders/theme.d.ts.map +1 -0
  294. package/types/mixins/AriaReflectorMixin.d.ts +31 -0
  295. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
  296. package/types/mixins/AriaToolbarMixin.d.ts +34 -0
  297. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
  298. package/types/mixins/ControlMixin.d.ts +124 -0
  299. package/types/mixins/ControlMixin.d.ts.map +1 -0
  300. package/types/mixins/DelegatesFocusMixin.d.ts +13 -0
  301. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
  302. package/types/mixins/DensityMixin.d.ts +8 -0
  303. package/types/mixins/DensityMixin.d.ts.map +1 -0
  304. package/types/mixins/ElevationMixin.d.ts +32 -0
  305. package/types/mixins/ElevationMixin.d.ts.map +1 -0
  306. package/types/mixins/FlexableMixin.d.ts +14 -0
  307. package/types/mixins/FlexableMixin.d.ts.map +1 -0
  308. package/types/mixins/FormAssociatedMixin.d.ts +123 -0
  309. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
  310. package/types/mixins/HyperlinkMixin.d.ts +25 -0
  311. package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
  312. package/types/mixins/InputMixin.d.ts +173 -0
  313. package/types/mixins/InputMixin.d.ts.map +1 -0
  314. package/types/mixins/KeyboardNavMixin.d.ts +46 -0
  315. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
  316. package/types/mixins/NavigationListenerMixin.d.ts +8 -0
  317. package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
  318. package/types/mixins/PopupMixin.d.ts +98 -0
  319. package/types/mixins/PopupMixin.d.ts.map +1 -0
  320. package/types/mixins/RTLObserverMixin.d.ts +8 -0
  321. package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
  322. package/types/mixins/ResizeObserverMixin.d.ts +13 -0
  323. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
  324. package/types/mixins/RippleMixin.d.ts +94 -0
  325. package/types/mixins/RippleMixin.d.ts.map +1 -0
  326. package/types/mixins/ScrollListenerMixin.d.ts +46 -0
  327. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
  328. package/types/mixins/SemiStickyMixin.d.ts +50 -0
  329. package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
  330. package/types/mixins/ShapeMaskedMixin.d.ts +12 -0
  331. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
  332. package/types/mixins/ShapeMixin.d.ts +39 -0
  333. package/types/mixins/ShapeMixin.d.ts.map +1 -0
  334. package/types/mixins/StateMixin.d.ts +29 -0
  335. package/types/mixins/StateMixin.d.ts.map +1 -0
  336. package/types/mixins/TextFieldMixin.d.ts +153 -0
  337. package/types/mixins/TextFieldMixin.d.ts.map +1 -0
  338. package/types/mixins/ThemableMixin.d.ts +10 -0
  339. package/types/mixins/ThemableMixin.d.ts.map +1 -0
  340. package/types/mixins/TooltipTriggerMixin.d.ts +114 -0
  341. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
  342. package/types/mixins/TouchTargetMixin.d.ts +6 -0
  343. package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
  344. package/types/mixins/TypographyMixin.d.ts +20 -0
  345. package/types/mixins/TypographyMixin.d.ts.map +1 -0
  346. package/types/services/rtl.d.ts +3 -0
  347. package/types/services/rtl.d.ts.map +1 -0
  348. package/types/services/svgAlias.d.ts +13 -0
  349. package/types/services/svgAlias.d.ts.map +1 -0
  350. package/types/services/theme.d.ts +45 -0
  351. package/types/services/theme.d.ts.map +1 -0
  352. package/types/utils/cli.d.ts +3 -0
  353. package/types/utils/cli.d.ts.map +1 -0
  354. package/types/utils/function.d.ts +3 -0
  355. package/types/utils/function.d.ts.map +1 -0
  356. package/types/utils/jsx-runtime.d.ts +20 -0
  357. package/types/utils/jsx-runtime.d.ts.map +1 -0
  358. package/types/utils/material-color/blend.d.ts +34 -0
  359. package/types/utils/material-color/blend.d.ts.map +1 -0
  360. package/types/utils/material-color/hct/Cam16.d.ts +142 -0
  361. package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
  362. package/types/utils/material-color/hct/Hct.d.ts +93 -0
  363. package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
  364. package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
  365. package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
  366. package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
  367. package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
  368. package/types/utils/material-color/helper.d.ts +8 -0
  369. package/types/utils/material-color/helper.d.ts.map +1 -0
  370. package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
  371. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
  372. package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
  373. package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
  374. package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
  375. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
  376. package/types/utils/material-color/utils/color.d.ts +172 -0
  377. package/types/utils/material-color/utils/color.d.ts.map +1 -0
  378. package/types/utils/material-color/utils/math.d.ts +94 -0
  379. package/types/utils/material-color/utils/math.d.ts.map +1 -0
  380. package/types/utils/pixelmatch.d.ts +22 -0
  381. package/types/utils/pixelmatch.d.ts.map +1 -0
  382. package/types/utils/popup.d.ts +106 -0
  383. package/types/utils/popup.d.ts.map +1 -0
  384. package/types/utils/searchParams.d.ts +3 -0
  385. package/types/utils/searchParams.d.ts.map +1 -0
  386. package/types/utils/svg.d.ts +7 -0
  387. package/types/utils/svg.d.ts.map +1 -0
  388. package/utils/jsx-runtime.js +9 -4
  389. package/utils/material-color/scheme/Scheme.js +1 -1
  390. package/utils/pixelmatch.js +363 -0
  391. package/utils/popup.js +86 -10
  392. package/utils/searchParams.js +22 -0
  393. package/components/Button.md +0 -61
  394. package/components/ExtendedFab.js +0 -32
  395. package/components/Layout.js +0 -504
  396. package/components/Nav.js +0 -38
  397. package/core/DomAdapter.js +0 -586
  398. package/core/ICustomElement.d.ts +0 -291
  399. package/core/ICustomElement.js +0 -1
  400. package/core/test.js +0 -126
  401. package/core/typings.d.ts +0 -142
  402. package/core/typings.js +0 -1
  403. package/mixins/SurfaceMixin.js +0 -127
  404. package/theming/loader.js +0 -22
  405. /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
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, CustomElement>}
6
8
  */
7
9
  export const EVENT_HANDLER_TYPE = {
8
10
  type: 'function',
@@ -13,16 +15,31 @@ export const EVENT_HANDLER_TYPE = {
13
15
  if (oldValue == null && newValue == null) return;
14
16
  // Must continue even if oldValue === newValue;
15
17
  if (newValue == null) {
18
+ // @ts-expect-error Can't verify key
16
19
  this[name] = null;
17
20
  return;
18
21
  }
19
- // Assign to temp element, allow it to parse and then copy result.
20
- // Let browser parse instead of using eval()
21
- // CSP Violations will be thrown by browser on failure and result in `null`
22
- const button = document.createElement('button');
23
- button.setAttribute('onclick', newValue);
24
- const fn = button.onclick;
25
- button.remove();
22
+ let fn;
23
+ try {
24
+ // Use eval to include scope
25
+ // https://blog.ltgt.net/html-event-handlers/
26
+ const scopedCode = 'with(this.ownerDocument ?? document){'
27
+ + 'with(this.form ?? {}){'
28
+ + `with(this){${newValue}}`
29
+ + '}'
30
+ + '}';
31
+ // eslint-disable-next-line no-new-func
32
+ fn = new Function(`return function ${name}(event){${scopedCode}}`)();
33
+ } catch {
34
+ // Assign to temp element, allow it to parse and then copy result.
35
+ // Let browser parse instead of using eval()
36
+ // CSP Violations will be thrown by browser on failure and result in `null`
37
+ const button = (this.ownerDocument ?? document).createElement('button');
38
+ button.setAttribute('onclick', newValue);
39
+ fn = button.onclick;
40
+ }
41
+
42
+ // @ts-expect-error Can't verify key
26
43
  this[name] = fn;
27
44
  },
28
45
  propChangedCallback(name, oldValue, newValue) {
@@ -36,23 +53,23 @@ export const EVENT_HANDLER_TYPE = {
36
53
  },
37
54
  };
38
55
 
39
- const weakRefValues = new WeakMap();
56
+ // const weakRefValues = new WeakMap();
40
57
 
41
- /**
42
- * @type {import('./typings.js').ObserverOptions<'object',HTMLElement>}
43
- */
44
- export const WEAKREF_TYPE = {
45
- type: 'object',
46
- reflect: false,
47
- value: null,
48
- parser(v) { return new WeakRef(v); },
49
- get() {
50
- if (weakRefValues.has(this)) {
51
- return weakRefValues.get(this).deref();
52
- }
53
- return undefined;
54
- },
55
- };
58
+ // /**
59
+ // * @type {import('./observe.js').ObserverOptions<'object',HTMLElement>}
60
+ // */
61
+ // export const WEAKREF_TYPE = {
62
+ // type: 'object',
63
+ // reflect: false,
64
+ // value: null,
65
+ // parser(v) { return new WeakRef(v); },
66
+ // get() {
67
+ // if (weakRefValues.has(this)) {
68
+ // return weakRefValues.get(this).deref();
69
+ // }
70
+ // return undefined;
71
+ // },
72
+ // };
56
73
 
57
74
  /**
58
75
  * @typedef {Object} ElementStylerOptions
@@ -61,15 +78,22 @@ export const WEAKREF_TYPE = {
61
78
  * @prop {EffectTiming} [timing]
62
79
  */
63
80
 
64
- /** @type {WeakMap<CustomElement, Set<string>} */
81
+ /**
82
+ * @typedef {Object} QueuedPropsMetadata
83
+ * @prop {boolean} initial
84
+ */
85
+
86
+ /** @type {WeakMap<CustomElement, Map<string, QueuedPropsMetadata>>} */
65
87
  const queuedPropsByElement = new WeakMap();
66
88
 
67
89
  /** @type {WeakMap<CustomElement, Map<string, Animation>>} */
68
90
  const previousAnimationsByElement = new WeakMap();
69
91
 
70
92
  /**
71
- * @param {string} name
72
- * @this {CustomElement}
93
+ * @template {CustomElement} T
94
+ * @template {keyof T & string} K
95
+ * @param {K} name
96
+ * @this {T & Record<K, ElementStylerOptions|null>}
73
97
  */
74
98
  function elementStylerMicrotaskCallback(name) {
75
99
  const previousAnimations = previousAnimationsByElement.get(this);
@@ -78,6 +102,9 @@ function elementStylerMicrotaskCallback(name) {
78
102
  if (previousAnimations?.has(name)) {
79
103
  previousAnimation = previousAnimations.get(name);
80
104
  }
105
+ const queuedProps = queuedPropsByElement.get(this);
106
+ const { initial } = queuedProps.get(name);
107
+ queuedProps.delete(name);
81
108
  const value = this[name];
82
109
  if (!value) {
83
110
  previousAnimation?.cancel();
@@ -90,6 +117,7 @@ function elementStylerMicrotaskCallback(name) {
90
117
  : this;
91
118
  const currentAnimation = el.animate(styles, {
92
119
  ...timing,
120
+ ...(initial ? { duration: 0 } : null),
93
121
  fill: 'forwards',
94
122
  });
95
123
  currentAnimation.onremove = () => {
@@ -106,42 +134,126 @@ function elementStylerMicrotaskCallback(name) {
106
134
  } else {
107
135
  previousAnimationsByElement.set(this, new Map([[name, currentAnimation]]));
108
136
  }
109
- queuedPropsByElement.get(this).delete(name);
110
137
  }
111
138
 
112
- /** @type {import('./typings.js').ObserverOptions<'object',ElementStylerOptions, CustomElement>} */
113
- export const ELEMENT_STYLER_TYPE = {
139
+ /** @type {WeakMap<Element, Function[]>} */
140
+ const pendingResizeCallbacks = new WeakMap();
141
+ const pendingConnections = new ResizeObserver((entries) => {
142
+ for (const { target } of entries) {
143
+ if (pendingResizeCallbacks.has(target)) {
144
+ const callbacks = pendingResizeCallbacks.get(target);
145
+ pendingResizeCallbacks.delete(target);
146
+ pendingConnections.unobserve(target);
147
+ for (const callback of callbacks) {
148
+ callback();
149
+ }
150
+ }
151
+ }
152
+ });
153
+
154
+ /** @type {import('./observe.js').ObserverOptions<'object',ElementStylerOptions, CustomElement>} */
155
+ export const ELEMENT_ANIMATION_TYPE = {
114
156
  type: 'object',
115
157
  reflect: false,
116
158
  diff: null, // Skip computing entire change
117
159
  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
160
  if (!newValue) {
125
- if (!hasQueue) return;
126
- console.warn('debug of cancel needed');
127
- if (queuedProps) {
128
- queuedProps.delete(name);
161
+ const previousAnimations = previousAnimationsByElement.get(this);
162
+ if (!previousAnimations?.has(name)) {
163
+ // Fast abort
164
+ return;
129
165
  }
130
- return;
131
- }
132
-
133
- if (hasQueue) {
134
- // Already scheduled
135
- return;
136
166
  }
167
+ const queuedProps = queuedPropsByElement.get(this);
137
168
 
169
+ const initial = !this.isConnected;
138
170
  if (queuedProps) {
139
- queuedProps.add(name);
171
+ if (queuedProps.has(name)) return;
172
+ queuedProps.set(name, { initial });
140
173
  } else {
141
- queuedPropsByElement.set(this, new Set([name]));
174
+ queuedPropsByElement.set(this, new Map([[name, { initial }]]));
142
175
  }
176
+ // TODO: Reuse callback instead constructing each tick
143
177
  // Animation styles may trickle in steps, so queue a microtask before doing any work.
144
178
  // Using requestAnimationFrame would fire one frame too late for CSS animations already scheduled
145
- queueMicrotask(elementStylerMicrotaskCallback.bind(this, name));
179
+ const callback = elementStylerMicrotaskCallback.bind(this, name);
180
+ if (this.isConnected) {
181
+ queueMicrotask(callback);
182
+ } else if (pendingResizeCallbacks.has(this)) {
183
+ pendingResizeCallbacks.get(this).push(callback);
184
+ } else {
185
+ pendingResizeCallbacks.set(this, [callback]);
186
+ pendingConnections.observe(this);
187
+ }
188
+ },
189
+ };
190
+
191
+ /**
192
+ * @type {WeakMap<CustomElement, Map<string, HTMLStyleElement|CSSStyleSheet>>}
193
+ */
194
+ const styleReferences = new WeakMap();
195
+
196
+ /** @type {boolean} */
197
+ let useAdoptedStyleSheets = null;
198
+
199
+ /** @type {import('./observe.js').ObserverOptions<'string',string, CustomElement>} */
200
+ export const ELEMENT_STYLE_TYPE = {
201
+ type: 'string',
202
+ reflect: false,
203
+ /**
204
+ * @param {string|Record<keyof CSSStyleDeclaration & string, string|number>} value
205
+ * @return {string}
206
+ */
207
+ parser(value) {
208
+ if (!value || typeof value === 'string') {
209
+ return /** @type {string} */ (value);
210
+ }
211
+ return `:host{${
212
+ Object.entries(value).map(([key, rule]) => `${attrNameFromPropName(key)}:${rule}`)
213
+ .join(';')
214
+ }}`;
215
+ },
216
+ propChangedCallback(name, oldValue, newValue) {
217
+ let mapOfStyles;
218
+
219
+ /** @type {HTMLStyleElement|CSSStyleSheet} */
220
+ let styles;
221
+ if (styleReferences.has(this)) {
222
+ mapOfStyles = styleReferences.get(this);
223
+ if (mapOfStyles.has(name)) {
224
+ styles = mapOfStyles.get(name);
225
+ }
226
+ } else {
227
+ // Skip build if blank
228
+ if (!newValue) return;
229
+ mapOfStyles = new Map();
230
+ styleReferences.set(this, mapOfStyles);
231
+ }
232
+
233
+ useAdoptedStyleSheets ??= 'adoptedStyleSheets' in ShadowRoot.prototype;
234
+ if (!styles) {
235
+ if (useAdoptedStyleSheets) {
236
+ styles = new CSSStyleSheet();
237
+ this.shadowRoot.adoptedStyleSheets = [
238
+ ...this.shadowRoot.adoptedStyleSheets,
239
+ styles,
240
+ ];
241
+ } else {
242
+ const styleElement = this.ownerDocument.createElement('style');
243
+ this.shadowRoot.prepend(styleElement);
244
+ styles = styleElement;
245
+ }
246
+ mapOfStyles.set(name, styles);
247
+ }
248
+ if (newValue) {
249
+ if (useAdoptedStyleSheets) {
250
+ /** @type {CSSStyleSheet} */(styles).replaceSync(newValue);
251
+ } else if (newValue) {
252
+ /** @type {HTMLStyleElement} */(styles).textContent = newValue;
253
+ }
254
+ styles.disabled = false;
255
+ } else {
256
+ styles.disabled = true;
257
+ }
146
258
  },
147
259
  };
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,8 @@ 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
+ // @ts-ignore runtime check
53
+ if (FIREFOX_VERSION < 113 && element.constructor.formAssociated && element.hasAttribute('disabled')) {
47
54
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1818287
48
55
  console.warn('Firefox bug 1818287: Disabled form associated custom element cannot receive focus.');
49
56
  return false;
@@ -8,17 +8,22 @@
8
8
  * @return {T1|T2|(T1 & T2)}
9
9
  */
10
10
  export function applyMergePatch(target, patch) {
11
+ // @ts-ignore Runtime check
11
12
  if (target === patch) return target;
12
13
  if (target == null || patch == null || typeof patch !== 'object') return patch;
13
14
  if (typeof target !== 'object') {
15
+ // @ts-ignore Forced cast to object
14
16
  target = {};
15
17
  }
16
18
  for (const [key, value] of Object.entries(patch)) {
17
19
  if (value == null) {
20
+ // @ts-ignore Runtime check
18
21
  if (key in target) {
22
+ // @ts-ignore T1 is always object
19
23
  delete target[key];
20
24
  }
21
25
  } else {
26
+ // @ts-ignore T1 is forced object
22
27
  target[key] = applyMergePatch(target[key], value);
23
28
  }
24
29
  }
@@ -54,20 +59,25 @@ export function buildMergePatch(previous, current, arrayStrategy = 'reference')
54
59
  return structuredClone(current);
55
60
  }
56
61
  for (const [index, value] of current.entries()) {
57
- if (value == null) {
58
- console.warn('Nullish value found at', index);
62
+ if (value === null) {
63
+ // @ts-ignore patch is ArrayLike
64
+ patch[index] = null;
59
65
  continue;
60
66
  }
67
+ if (value == null) {
68
+ continue; // Skip undefined
69
+ }
70
+ // @ts-ignore previous is ArrayLike
61
71
  const changes = buildMergePatch(previous[index], value, arrayStrategy);
62
- if (changes === null) {
63
- continue;
64
- } else {
72
+ if (changes !== null) {
73
+ // @ts-ignore patch is ArrayLike
65
74
  patch[index] = changes;
66
75
  }
67
76
  }
68
77
  // for (let i = current.length; i < previous.length; i++) {
69
78
  // patch[i] = null;
70
79
  // }
80
+ // @ts-ignore previous is ArrayLike
71
81
  if (current.length !== previous.length) {
72
82
  patch.length = current.length;
73
83
  }
@@ -77,20 +87,24 @@ export function buildMergePatch(previous, current, arrayStrategy = 'reference')
77
87
  const previousKeys = new Set(Object.keys(previous));
78
88
  for (const [key, value] of Object.entries(current)) {
79
89
  previousKeys.delete(key);
80
- if (value == null) {
81
- console.warn('Nullish value found at', key);
90
+ if (value === null) {
91
+ // @ts-ignore patch is Object
92
+ patch[key] = null;
82
93
  continue;
83
94
  }
95
+ if (value == null) {
96
+ continue; // Skip undefined
97
+ }
98
+ // @ts-ignore previous is Object
84
99
  const changes = buildMergePatch(previous[key], value, arrayStrategy);
85
- if (changes === null) {
86
- // console.log('keeping', key);
87
- } else {
100
+ if (changes !== null) {
101
+ // @ts-ignore patch is Object
88
102
  patch[key] = changes;
89
103
  }
90
104
  }
91
105
  for (const key of previousKeys) {
106
+ // @ts-ignore patch is Object
92
107
  patch[key] = null;
93
- console.log('removing', key);
94
108
  }
95
109
 
96
110
  return patch;
@@ -111,9 +125,11 @@ export function hasMergePatch(target, patch) {
111
125
  }
112
126
  for (const [key, value] of Object.entries(patch)) {
113
127
  if (value == null) {
128
+ // @ts-ignore Runtime check
114
129
  if (key in target) {
115
130
  return true;
116
131
  }
132
+ // @ts-ignore T is object
117
133
  } else if (hasMergePatch(target[key], value)) {
118
134
  return true;
119
135
  }