@shortfuse/materialdesignweb 0.7.6 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (412) hide show
  1. package/README.md +87 -90
  2. package/bin/mdw-css.js +1 -1
  3. package/components/Badge.js +14 -7
  4. package/components/Body.js +3 -0
  5. package/components/BottomAppBar.js +4 -13
  6. package/components/BottomSheet.js +424 -0
  7. package/components/Box.js +20 -28
  8. package/components/Button.js +85 -79
  9. package/components/Button.md +9 -9
  10. package/components/Card.js +60 -72
  11. package/components/Checkbox.js +33 -42
  12. package/components/CheckboxIcon.js +11 -29
  13. package/components/Chip.js +13 -11
  14. package/components/Dialog.js +214 -394
  15. package/components/DialogActions.js +2 -2
  16. package/components/Display.js +55 -0
  17. package/components/Divider.js +3 -3
  18. package/components/Fab.js +83 -18
  19. package/components/FabContainer.js +48 -0
  20. package/components/FilterChip.js +35 -33
  21. package/components/Grid.js +176 -0
  22. package/components/Headline.js +5 -28
  23. package/components/Icon.js +61 -76
  24. package/components/IconButton.js +72 -126
  25. package/components/Input.js +859 -1
  26. package/components/InputChip.js +161 -0
  27. package/components/Label.js +3 -0
  28. package/components/List.js +4 -6
  29. package/components/ListItem.js +46 -30
  30. package/components/ListOption.js +86 -53
  31. package/components/Listbox.js +248 -0
  32. package/components/Menu.js +69 -528
  33. package/components/MenuItem.js +33 -36
  34. package/components/NavBar.js +49 -86
  35. package/components/NavDrawer.js +16 -15
  36. package/components/NavDrawerItem.js +4 -5
  37. package/components/NavItem.js +58 -41
  38. package/components/NavRail.js +30 -20
  39. package/components/NavRailItem.js +8 -3
  40. package/components/Page.js +105 -0
  41. package/components/Pane.js +11 -274
  42. package/components/Popup.js +29 -0
  43. package/components/Progress.js +24 -23
  44. package/components/Radio.js +40 -36
  45. package/components/RadioIcon.js +12 -16
  46. package/components/Ripple.js +13 -10
  47. package/components/Root.js +209 -0
  48. package/components/Scrim.js +87 -0
  49. package/components/Search.js +77 -0
  50. package/components/SegmentedButton.js +33 -45
  51. package/components/SegmentedButtonGroup.js +25 -13
  52. package/components/Select.js +10 -11
  53. package/components/Shape.js +5 -65
  54. package/components/SideSheet.js +308 -0
  55. package/components/Slider.js +108 -78
  56. package/components/Snackbar.js +26 -21
  57. package/components/SnackbarContainer.js +42 -0
  58. package/components/Surface.js +17 -12
  59. package/components/Switch.js +45 -24
  60. package/components/SwitchIcon.js +49 -39
  61. package/components/Tab.js +64 -43
  62. package/components/TabContent.js +5 -3
  63. package/components/TabList.js +62 -34
  64. package/components/TabPanel.js +11 -8
  65. package/components/Table.js +116 -0
  66. package/components/TextArea.js +54 -50
  67. package/components/Title.js +4 -9
  68. package/components/Tooltip.js +44 -22
  69. package/components/TopAppBar.js +68 -172
  70. package/constants/shapes.js +36 -0
  71. package/constants/typography.js +127 -0
  72. package/core/Composition.js +1164 -645
  73. package/core/CompositionAdapter.js +314 -0
  74. package/core/CustomElement.js +701 -286
  75. package/core/css.js +121 -15
  76. package/core/customTypes.js +157 -40
  77. package/core/dom.js +17 -11
  78. package/{utils → core}/jsonMergePatch.js +42 -18
  79. package/core/observe.js +343 -244
  80. package/core/optimizations.js +23 -0
  81. package/core/template.js +19 -56
  82. package/core/uid.js +13 -0
  83. package/dist/index.min.js +85 -184
  84. package/dist/index.min.js.map +4 -4
  85. package/dist/meta.json +1 -1
  86. package/dom/HTMLOptionsCollectionProxy.js +106 -0
  87. package/loaders/palette.js +13 -0
  88. package/loaders/theme.js +12 -0
  89. package/mixins/AriaReflectorMixin.js +53 -14
  90. package/mixins/AriaToolbarMixin.js +5 -3
  91. package/mixins/ControlMixin.js +92 -41
  92. package/mixins/DelegatesFocusMixin.js +54 -0
  93. package/mixins/DensityMixin.js +2 -3
  94. package/mixins/ElevationMixin.js +62 -0
  95. package/mixins/FlexableMixin.js +67 -39
  96. package/mixins/FormAssociatedMixin.js +71 -16
  97. package/mixins/HyperlinkMixin.js +66 -0
  98. package/mixins/InputMixin.js +205 -39
  99. package/mixins/KeyboardNavMixin.js +22 -7
  100. package/mixins/NavigationListenerMixin.js +33 -0
  101. package/mixins/PopupMixin.js +725 -0
  102. package/mixins/RTLObserverMixin.js +0 -1
  103. package/mixins/ResizeObserverMixin.js +16 -5
  104. package/mixins/RippleMixin.js +11 -10
  105. package/mixins/ScrollListenerMixin.js +42 -33
  106. package/mixins/SemiStickyMixin.js +97 -0
  107. package/mixins/ShapeMaskedMixin.js +117 -0
  108. package/mixins/ShapeMixin.js +17 -194
  109. package/mixins/StateMixin.js +80 -39
  110. package/mixins/TextFieldMixin.js +139 -183
  111. package/mixins/ThemableMixin.js +71 -161
  112. package/mixins/TooltipTriggerMixin.js +292 -366
  113. package/mixins/TouchTargetMixin.js +5 -4
  114. package/mixins/TypographyMixin.js +121 -0
  115. package/package.json +111 -71
  116. package/services/rtl.js +10 -0
  117. package/services/svgAlias.js +17 -0
  118. package/{theming/index.js → services/theme.js} +25 -175
  119. package/types/bin/mdw-css.d.ts +3 -0
  120. package/types/bin/mdw-css.d.ts.map +1 -0
  121. package/types/components/Badge.d.ts +39 -0
  122. package/types/components/Badge.d.ts.map +1 -0
  123. package/types/components/Body.d.ts +29 -0
  124. package/types/components/Body.d.ts.map +1 -0
  125. package/types/components/BottomAppBar.d.ts +73 -0
  126. package/types/components/BottomAppBar.d.ts.map +1 -0
  127. package/types/components/BottomSheet.d.ts +109 -0
  128. package/types/components/BottomSheet.d.ts.map +1 -0
  129. package/types/components/Box.d.ts +16 -0
  130. package/types/components/Box.d.ts.map +1 -0
  131. package/types/components/Button.d.ts +714 -0
  132. package/types/components/Button.d.ts.map +1 -0
  133. package/types/components/Card.d.ts +412 -0
  134. package/types/components/Card.d.ts.map +1 -0
  135. package/types/components/Checkbox.d.ts +205 -0
  136. package/types/components/Checkbox.d.ts.map +1 -0
  137. package/types/components/CheckboxIcon.d.ts +44 -0
  138. package/types/components/CheckboxIcon.d.ts.map +1 -0
  139. package/types/components/Chip.d.ts +1425 -0
  140. package/types/components/Chip.d.ts.map +1 -0
  141. package/types/components/Dialog.d.ts +286 -0
  142. package/types/components/Dialog.d.ts.map +1 -0
  143. package/types/components/DialogActions.d.ts +4 -0
  144. package/types/components/DialogActions.d.ts.map +1 -0
  145. package/types/components/Display.d.ts +45 -0
  146. package/types/components/Display.d.ts.map +1 -0
  147. package/types/components/Divider.d.ts +10 -0
  148. package/types/components/Divider.d.ts.map +1 -0
  149. package/types/components/Fab.d.ts +741 -0
  150. package/types/components/Fab.d.ts.map +1 -0
  151. package/types/components/FabContainer.d.ts +10 -0
  152. package/types/components/FabContainer.d.ts.map +1 -0
  153. package/types/components/FilterChip.d.ts +4283 -0
  154. package/types/components/FilterChip.d.ts.map +1 -0
  155. package/types/components/Grid.d.ts +37 -0
  156. package/types/components/Grid.d.ts.map +1 -0
  157. package/types/components/Headline.d.ts +47 -0
  158. package/types/components/Headline.d.ts.map +1 -0
  159. package/types/components/Icon.d.ts +103 -0
  160. package/types/components/Icon.d.ts.map +1 -0
  161. package/types/components/IconButton.d.ts +1486 -0
  162. package/types/components/IconButton.d.ts.map +1 -0
  163. package/types/components/Input.d.ts +51288 -0
  164. package/types/components/Input.d.ts.map +1 -0
  165. package/types/components/InputChip.d.ts +243 -0
  166. package/types/components/InputChip.d.ts.map +1 -0
  167. package/types/components/Label.d.ts +29 -0
  168. package/types/components/Label.d.ts.map +1 -0
  169. package/types/components/List.d.ts +31 -0
  170. package/types/components/List.d.ts.map +1 -0
  171. package/types/components/ListItem.d.ts +349 -0
  172. package/types/components/ListItem.d.ts.map +1 -0
  173. package/types/components/ListOption.d.ts +1493 -0
  174. package/types/components/ListOption.d.ts.map +1 -0
  175. package/types/components/Listbox.d.ts +12012 -0
  176. package/types/components/Listbox.d.ts.map +1 -0
  177. package/types/components/Menu.d.ts +119 -0
  178. package/types/components/Menu.d.ts.map +1 -0
  179. package/types/components/MenuItem.d.ts +3109 -0
  180. package/types/components/MenuItem.d.ts.map +1 -0
  181. package/types/components/NavBar.d.ts +18 -0
  182. package/types/components/NavBar.d.ts.map +1 -0
  183. package/types/components/NavBarItem.d.ts +186 -0
  184. package/types/components/NavBarItem.d.ts.map +1 -0
  185. package/types/components/NavDrawer.d.ts +108 -0
  186. package/types/components/NavDrawer.d.ts.map +1 -0
  187. package/types/components/NavDrawerItem.d.ts +186 -0
  188. package/types/components/NavDrawerItem.d.ts.map +1 -0
  189. package/types/components/NavItem.d.ts +190 -0
  190. package/types/components/NavItem.d.ts.map +1 -0
  191. package/types/components/NavRail.d.ts +109 -0
  192. package/types/components/NavRail.d.ts.map +1 -0
  193. package/types/components/NavRailItem.d.ts +186 -0
  194. package/types/components/NavRailItem.d.ts.map +1 -0
  195. package/types/components/Page.d.ts +24 -0
  196. package/types/components/Page.d.ts.map +1 -0
  197. package/types/components/Pane.d.ts +44 -0
  198. package/types/components/Pane.d.ts.map +1 -0
  199. package/types/components/Popup.d.ts +76 -0
  200. package/types/components/Popup.d.ts.map +1 -0
  201. package/types/components/Progress.d.ts +19 -0
  202. package/types/components/Progress.d.ts.map +1 -0
  203. package/types/components/Radio.d.ts +199 -0
  204. package/types/components/Radio.d.ts.map +1 -0
  205. package/types/components/RadioIcon.d.ts +46 -0
  206. package/types/components/RadioIcon.d.ts.map +1 -0
  207. package/types/components/Ripple.d.ts +34 -0
  208. package/types/components/Ripple.d.ts.map +1 -0
  209. package/types/components/Root.d.ts +68 -0
  210. package/types/components/Root.d.ts.map +1 -0
  211. package/types/components/Scrim.d.ts +6 -0
  212. package/types/components/Scrim.d.ts.map +1 -0
  213. package/types/components/Search.d.ts +16 -0
  214. package/types/components/Search.d.ts.map +1 -0
  215. package/types/components/SegmentedButton.d.ts +718 -0
  216. package/types/components/SegmentedButton.d.ts.map +1 -0
  217. package/types/components/SegmentedButtonGroup.d.ts +44 -0
  218. package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
  219. package/types/components/Select.d.ts +1361 -0
  220. package/types/components/Select.d.ts.map +1 -0
  221. package/types/components/Shape.d.ts +10 -0
  222. package/types/components/Shape.d.ts.map +1 -0
  223. package/types/components/SideSheet.d.ts +106 -0
  224. package/types/components/SideSheet.d.ts.map +1 -0
  225. package/types/components/Slider.d.ts +382 -0
  226. package/types/components/Slider.d.ts.map +1 -0
  227. package/types/components/Snackbar.d.ts +65 -0
  228. package/types/components/Snackbar.d.ts.map +1 -0
  229. package/types/components/SnackbarContainer.d.ts +6 -0
  230. package/types/components/SnackbarContainer.d.ts.map +1 -0
  231. package/types/components/Surface.d.ts +45 -0
  232. package/types/components/Surface.d.ts.map +1 -0
  233. package/types/components/Switch.d.ts +183 -0
  234. package/types/components/Switch.d.ts.map +1 -0
  235. package/types/components/SwitchIcon.d.ts +169 -0
  236. package/types/components/SwitchIcon.d.ts.map +1 -0
  237. package/types/components/Tab.d.ts +879 -0
  238. package/types/components/Tab.d.ts.map +1 -0
  239. package/types/components/TabContent.d.ts +122 -0
  240. package/types/components/TabContent.d.ts.map +1 -0
  241. package/types/components/TabList.d.ts +6266 -0
  242. package/types/components/TabList.d.ts.map +1 -0
  243. package/types/components/TabPanel.d.ts +28 -0
  244. package/types/components/TabPanel.d.ts.map +1 -0
  245. package/types/components/Table.d.ts +2 -0
  246. package/types/components/Table.d.ts.map +1 -0
  247. package/types/components/TextArea.d.ts +1394 -0
  248. package/types/components/TextArea.d.ts.map +1 -0
  249. package/types/components/Title.d.ts +47 -0
  250. package/types/components/Title.d.ts.map +1 -0
  251. package/types/components/Tooltip.d.ts +49 -0
  252. package/types/components/Tooltip.d.ts.map +1 -0
  253. package/types/components/TopAppBar.d.ts +130 -0
  254. package/types/components/TopAppBar.d.ts.map +1 -0
  255. package/types/constants/colorKeywords.d.ts +2 -0
  256. package/types/constants/colorKeywords.d.ts.map +1 -0
  257. package/types/constants/shapes.d.ts +38 -0
  258. package/types/constants/shapes.d.ts.map +1 -0
  259. package/types/constants/typography.d.ts +212 -0
  260. package/types/constants/typography.d.ts.map +1 -0
  261. package/types/core/Composition.d.ts +252 -0
  262. package/types/core/Composition.d.ts.map +1 -0
  263. package/types/core/CompositionAdapter.d.ts +92 -0
  264. package/types/core/CompositionAdapter.d.ts.map +1 -0
  265. package/types/core/CustomElement.d.ts +302 -0
  266. package/types/core/CustomElement.d.ts.map +1 -0
  267. package/types/core/css.d.ts +44 -0
  268. package/types/core/css.d.ts.map +1 -0
  269. package/types/core/customTypes.d.ts +26 -0
  270. package/types/core/customTypes.d.ts.map +1 -0
  271. package/types/core/dom.d.ts +32 -0
  272. package/types/core/dom.d.ts.map +1 -0
  273. package/types/core/jsonMergePatch.d.ts +31 -0
  274. package/types/core/jsonMergePatch.d.ts.map +1 -0
  275. package/types/core/observe.d.ts +113 -0
  276. package/types/core/observe.d.ts.map +1 -0
  277. package/types/core/optimizations.d.ts +7 -0
  278. package/types/core/optimizations.d.ts.map +1 -0
  279. package/types/core/template.d.ts +47 -0
  280. package/types/core/template.d.ts.map +1 -0
  281. package/types/core/uid.d.ts +6 -0
  282. package/types/core/uid.d.ts.map +1 -0
  283. package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
  284. package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
  285. package/types/index.d.ts +88 -0
  286. package/types/index.d.ts.map +1 -0
  287. package/types/loaders/palette.d.ts +2 -0
  288. package/types/loaders/palette.d.ts.map +1 -0
  289. package/types/loaders/theme.d.ts +2 -0
  290. package/types/loaders/theme.d.ts.map +1 -0
  291. package/types/mixins/AriaReflectorMixin.d.ts +23 -0
  292. package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
  293. package/types/mixins/AriaToolbarMixin.d.ts +32 -0
  294. package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
  295. package/types/mixins/ControlMixin.d.ts +124 -0
  296. package/types/mixins/ControlMixin.d.ts.map +1 -0
  297. package/types/mixins/DelegatesFocusMixin.d.ts +5 -0
  298. package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
  299. package/types/mixins/DensityMixin.d.ts +5 -0
  300. package/types/mixins/DensityMixin.d.ts.map +1 -0
  301. package/types/mixins/ElevationMixin.d.ts +33 -0
  302. package/types/mixins/ElevationMixin.d.ts.map +1 -0
  303. package/types/mixins/FlexableMixin.d.ts +13 -0
  304. package/types/mixins/FlexableMixin.d.ts.map +1 -0
  305. package/types/mixins/FormAssociatedMixin.d.ts +122 -0
  306. package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
  307. package/types/mixins/HyperlinkMixin.d.ts +22 -0
  308. package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
  309. package/types/mixins/InputMixin.d.ts +179 -0
  310. package/types/mixins/InputMixin.d.ts.map +1 -0
  311. package/types/mixins/KeyboardNavMixin.d.ts +47 -0
  312. package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
  313. package/types/mixins/NavigationListenerMixin.d.ts +8 -0
  314. package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
  315. package/types/mixins/PopupMixin.d.ts +82 -0
  316. package/types/mixins/PopupMixin.d.ts.map +1 -0
  317. package/types/mixins/RTLObserverMixin.d.ts +7 -0
  318. package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
  319. package/types/mixins/ResizeObserverMixin.d.ts +12 -0
  320. package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
  321. package/types/mixins/RippleMixin.d.ts +92 -0
  322. package/types/mixins/RippleMixin.d.ts.map +1 -0
  323. package/types/mixins/ScrollListenerMixin.d.ts +41 -0
  324. package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
  325. package/types/mixins/SemiStickyMixin.d.ts +50 -0
  326. package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
  327. package/types/mixins/ShapeMaskedMixin.d.ts +9 -0
  328. package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
  329. package/types/mixins/ShapeMixin.d.ts +38 -0
  330. package/types/mixins/ShapeMixin.d.ts.map +1 -0
  331. package/types/mixins/StateMixin.d.ts +27 -0
  332. package/types/mixins/StateMixin.d.ts.map +1 -0
  333. package/types/mixins/TextFieldMixin.d.ts +1354 -0
  334. package/types/mixins/TextFieldMixin.d.ts.map +1 -0
  335. package/types/mixins/ThemableMixin.d.ts +9 -0
  336. package/types/mixins/ThemableMixin.d.ts.map +1 -0
  337. package/types/mixins/TooltipTriggerMixin.d.ts +106 -0
  338. package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
  339. package/types/mixins/TouchTargetMixin.d.ts +3 -0
  340. package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
  341. package/types/mixins/TypographyMixin.d.ts +17 -0
  342. package/types/mixins/TypographyMixin.d.ts.map +1 -0
  343. package/types/services/rtl.d.ts +3 -0
  344. package/types/services/rtl.d.ts.map +1 -0
  345. package/types/services/svgAlias.d.ts +13 -0
  346. package/types/services/svgAlias.d.ts.map +1 -0
  347. package/types/services/theme.d.ts +45 -0
  348. package/types/services/theme.d.ts.map +1 -0
  349. package/types/utils/cli.d.ts +3 -0
  350. package/types/utils/cli.d.ts.map +1 -0
  351. package/types/utils/function.d.ts +3 -0
  352. package/types/utils/function.d.ts.map +1 -0
  353. package/types/utils/jsx-runtime.d.ts +20 -0
  354. package/types/utils/jsx-runtime.d.ts.map +1 -0
  355. package/types/utils/material-color/blend.d.ts +34 -0
  356. package/types/utils/material-color/blend.d.ts.map +1 -0
  357. package/types/utils/material-color/hct/Cam16.d.ts +142 -0
  358. package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
  359. package/types/utils/material-color/hct/Hct.d.ts +93 -0
  360. package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
  361. package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
  362. package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
  363. package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
  364. package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
  365. package/types/utils/material-color/helper.d.ts +8 -0
  366. package/types/utils/material-color/helper.d.ts.map +1 -0
  367. package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
  368. package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
  369. package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
  370. package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
  371. package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
  372. package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
  373. package/types/utils/material-color/utils/color.d.ts +172 -0
  374. package/types/utils/material-color/utils/color.d.ts.map +1 -0
  375. package/types/utils/material-color/utils/math.d.ts +94 -0
  376. package/types/utils/material-color/utils/math.d.ts.map +1 -0
  377. package/types/utils/pixelmatch.d.ts +22 -0
  378. package/types/utils/pixelmatch.d.ts.map +1 -0
  379. package/types/utils/popup.d.ts +106 -0
  380. package/types/utils/popup.d.ts.map +1 -0
  381. package/types/utils/searchParams.d.ts +3 -0
  382. package/types/utils/searchParams.d.ts.map +1 -0
  383. package/types/utils/svg.d.ts +7 -0
  384. package/types/utils/svg.d.ts.map +1 -0
  385. package/utils/{hct → material-color}/blend.js +8 -10
  386. package/utils/{hct → material-color/hct}/Cam16.js +196 -69
  387. package/utils/{hct → material-color/hct}/Hct.js +61 -19
  388. package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
  389. package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
  390. package/utils/{hct → material-color}/helper.js +11 -18
  391. package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
  392. package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
  393. package/utils/material-color/scheme/Scheme.js +376 -0
  394. package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
  395. package/utils/pixelmatch.js +360 -0
  396. package/utils/popup.js +127 -30
  397. package/utils/searchParams.js +19 -0
  398. package/components/ExtendedFab.js +0 -36
  399. package/components/Layout.js +0 -35
  400. package/components/ListSelect.js +0 -220
  401. package/components/Nav.js +0 -40
  402. package/components/Option.js +0 -91
  403. package/core/ICustomElement.d.ts +0 -291
  404. package/core/ICustomElement.js +0 -1
  405. package/core/identify.js +0 -40
  406. package/core/typings.d.ts +0 -136
  407. package/core/typings.js +0 -1
  408. package/mixins/SurfaceMixin.js +0 -181
  409. package/theming/loader.js +0 -22
  410. package/utils/hct/Scheme.js +0 -587
  411. /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
  412. /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
package/core/observe.js CHANGED
@@ -1,57 +1,63 @@
1
- import { buildMergePatch, hasMergePatch } from '../utils/jsonMergePatch.js';
2
-
3
1
  import { attrNameFromPropName } from './dom.js';
2
+ import { buildMergePatch, hasMergePatch } from './jsonMergePatch.js';
4
3
 
5
- /** @typedef {import('./typings.js').ObserverPropertyType} ObserverPropertyType */
6
-
7
- /** @return {null} */
8
- const DEFAULT_NULL_PARSER = () => null;
9
-
10
- /**
11
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#boolean_coercion
12
- * @param {any} v
13
- * @return {boolean}
14
- */
15
- const DEFAULT_BOOLEAN_PARSER = (v) => !!v;
4
+ /** @typedef {'string' | 'boolean' | 'map' | 'set' | 'float' | 'integer' | 'object' | 'function' | 'array'} ObserverPropertyType */
16
5
 
17
6
  /**
18
- * Doesn't support `BigInt` types
19
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion
20
- * @param {any} v
21
- * @return {number}
7
+ * @template {ObserverPropertyType} T
8
+ * @typedef {(
9
+ * T extends 'boolean' ? boolean
10
+ * : T extends 'string' ? string
11
+ * : T extends 'float' | 'integer' ? number
12
+ * : T extends 'array' ? any[]
13
+ * : T extends 'object' ? any
14
+ * : T extends 'function' ? (...args:any) => any
15
+ * : unknown
16
+ * )} ParsedObserverPropertyType
22
17
  */
23
- const DEFAULT_NUMBER_PARSER = (v) => +v;
24
18
 
25
19
  /**
26
- * Doesn't support `Symbol` types
27
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion
28
- * @param {any} v
29
- * @return {string}
30
- */
31
- const DEFAULT_STRING_PARSER = (v) => `${v}`;
32
-
33
- /**
34
- * @template T
35
- * @param {T} o
36
- * @return {T}
37
- */
38
- const DEFAULT_OBJECT_PARSER = (o) => o;
39
-
40
- /**
41
- * @template T
42
- * @param {T} a
43
- * @param {T} b
44
- * @return {boolean} true if equal
20
+ * @template {ObserverPropertyType} T1
21
+ * @template {any} T2
22
+ * @template {Object} [C=any]
23
+ * @typedef {Object} ObserverOptions
24
+ * @prop {T1} [type]
25
+ * @prop {string} [attr]
26
+ * @prop {boolean} [readonly]
27
+ * @prop {boolean} [enumerable]
28
+ * Defaults to false if type is boolean
29
+ * @prop {boolean} [nullable]
30
+ * @prop {T2} [empty]
31
+ * @prop {T2} [value]
32
+ * @prop {WeakMap<C,T2>} [values]
33
+ * @prop {boolean|'write'|'read'} [reflect]
34
+ * Function used when null passed
35
+ * @prop {(this:C, value:null|undefined)=>T2} [nullParser]
36
+ * @prop {(this:C, value:any)=>T2} [parser]
37
+ * Function used when comparing
38
+ * @prop {(this:C, a:T2, b:T2)=> any} [diff]
39
+ * @prop {(this:C, a:T2, b:T2)=>boolean} [is]
40
+ * @prop {(this:C, data:Partial<C>, fn?: () => T2) => T2} [get]
41
+ * @prop {(this:C, value: T2, fn?:(value2: T2) => any) => any} [set]
42
+ * Simple callback
43
+ * @prop {(this:C, oldValue:T2, newValue:T2, changes:any)=>any} [changedCallback]
44
+ * Named callback
45
+ * @prop {(this:C, name:string, oldValue: T2, newValue: T2, changes:any) => any} [propChangedCallback]
46
+ * Attribute callback
47
+ * @prop {(this:C, name:string, oldValue: string, newValue: string) => any} [attributeChangedCallback]
48
+ * @prop {WeakMap<C, T2>} [computedValues]
49
+ * @prop {[keyof C, (this:C, ...args:any[]) => any][]} [watchers]
50
+ * @prop {WeakSet<C>} [needsSelfInvalidation]
51
+ * @prop {Set<keyof C>} [props]
45
52
  */
46
- export const DEFAULT_OBJECT_COMPARATOR = (a, b) => !hasMergePatch(a, b);
47
53
 
48
54
  /**
49
- * @template T
50
- * @param {T} a
51
- * @param {T} b
52
- * @return {boolean} true if equal
55
+ * @template {ObserverPropertyType} T1
56
+ * @template {any} [T2=any]
57
+ * @template {string} [K=string]
58
+ * @template {Object} [C=any]
59
+ * @typedef {ObserverOptions<T1, T2, C> & { key: K, values?: WeakMap<C, T2>; attrValues?: WeakMap<C, string> }} ObserverConfiguration
53
60
  */
54
- export const DEFAULT_OBJECT_DIFF = (a, b) => buildMergePatch(a, b, 'object');
55
61
 
56
62
  /**
57
63
  * @param {ObserverPropertyType} type
@@ -78,6 +84,50 @@ function emptyFromType(type) {
78
84
  }
79
85
  }
80
86
 
87
+ /**
88
+ * @template {Object} T
89
+ * @param {T} proxyTarget
90
+ * @param {Set<string>} set
91
+ * @param {Set<string>} deepSet
92
+ * @param {string} [prefix]
93
+ * @return {T}
94
+ */
95
+ function buildProxy(proxyTarget, set, deepSet, prefix) {
96
+ // @ts-ignore
97
+ proxyTarget ??= {};
98
+ return new Proxy(proxyTarget, {
99
+ get(target, p) {
100
+ // @ts-ignore
101
+ const value = target[p];
102
+ if (typeof p !== 'symbol') {
103
+ const arg = prefix ? `${prefix}.${p}` : p;
104
+ if (prefix) {
105
+ deepSet.add(arg);
106
+ } else {
107
+ set.add(arg);
108
+ }
109
+ if (typeof value === 'object' && value != null) {
110
+ console.debug('tried to arg poke object get', p, value);
111
+ return buildProxy(value, set, deepSet, arg);
112
+ }
113
+ }
114
+ return value;
115
+ },
116
+ has(target, p) {
117
+ const value = Reflect.has(target, p);
118
+ if (typeof p !== 'symbol') {
119
+ const arg = prefix ? `${prefix}.p` : p;
120
+ if (prefix) {
121
+ deepSet.add(arg);
122
+ } else {
123
+ set.add(arg);
124
+ }
125
+ }
126
+ return value;
127
+ },
128
+ });
129
+ }
130
+
81
131
  /**
82
132
  * @param {ObserverPropertyType} type
83
133
  * @return {any}
@@ -85,127 +135,218 @@ function emptyFromType(type) {
85
135
  function defaultParserFromType(type) {
86
136
  switch (type) {
87
137
  case 'boolean':
88
- return DEFAULT_BOOLEAN_PARSER;
138
+ /**
139
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#boolean_coercion
140
+ * @param {any} v
141
+ * @return {boolean}
142
+ */
143
+ return (v) => !!v;
89
144
  case 'integer':
90
145
  // Calls ToNumber(x)
91
146
  return Math.round;
92
147
  case 'float':
93
- return DEFAULT_NUMBER_PARSER;
148
+ /**
149
+ * Doesn't support `BigInt` types
150
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion
151
+ * @param {any} v
152
+ * @return {number}
153
+ */
154
+ return (v) => +v;
94
155
  case 'map':
95
156
  return Map;
96
157
  case 'set':
97
158
  return Set;
98
159
  case 'object':
99
- return DEFAULT_OBJECT_PARSER;
100
160
  case 'array':
101
- return Array.from;
161
+ /**
162
+ * Reflect self
163
+ * @template T
164
+ * @param {T} o
165
+ * @return {T}
166
+ */
167
+ return (o) => o;
102
168
  default:
103
169
  case 'string':
104
- return DEFAULT_STRING_PARSER;
170
+ /**
171
+ * Doesn't support `Symbol` types
172
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion
173
+ * @param {any} v
174
+ * @return {string}
175
+ */
176
+ return (v) => `${v}`;
105
177
  }
106
178
  }
107
179
 
180
+ /**
181
+ * @param {(data: Partial<any>) => any} fn
182
+ * @param {...any} args
183
+ * @this {any}
184
+ * @return {{
185
+ * props: {
186
+ * this: string[],
187
+ * args: string[][],
188
+ * },
189
+ * deepPropStrings: {
190
+ * this: string[],
191
+ * args: string[][],
192
+ * },
193
+ * deepProps: {
194
+ * this: string[][],
195
+ * args: string[][][],
196
+ * },
197
+ * defaultValue: any,
198
+ * reusable: boolean,
199
+ * }}
200
+ */
201
+ export function observeFunction(fn, ...args) {
202
+ /** @type {Set<string>} */
203
+ const thisPoked = new Set();
204
+ /** @type {Set<string>} */
205
+ const thisPokedDeep = new Set();
206
+
207
+ const argWatchers = args.map((arg) => {
208
+ const poked = new Set();
209
+ const pokedDeep = new Set();
210
+ const proxy = buildProxy(arg, poked, pokedDeep);
211
+ return { poked, pokedDeep, proxy };
212
+ });
213
+
214
+ const thisProxy = buildProxy(this ?? {}, thisPoked, thisPokedDeep);
215
+ const defaultValue = fn.apply(thisProxy, argWatchers.map((watcher) => watcher.proxy));
216
+ /* Arrow functions can reused if they don't poke `this` */
217
+ const reusable = fn.name ? true : !thisPoked.size;
218
+
219
+ return {
220
+ props: {
221
+ this: [...thisPoked],
222
+ args: argWatchers.map((watcher) => [...watcher.poked]),
223
+ },
224
+ deepPropStrings: {
225
+ this: [...thisPokedDeep],
226
+ args: argWatchers.map((watcher) => [...watcher.pokedDeep]),
227
+ },
228
+ deepProps: {
229
+ this: [...thisPokedDeep].map((deepPropString) => deepPropString.split('.')),
230
+ args: argWatchers.map((watcher) => [...watcher.pokedDeep].map((deepPropString) => deepPropString.split('.'))),
231
+ },
232
+ defaultValue,
233
+ reusable,
234
+ };
235
+ }
236
+
108
237
  /**
109
238
  * @template {string} K
110
239
  * @template {ObserverPropertyType} [T1=any]
111
- * @template {any} [T2=import('./typings.js').ParsedObserverPropertyType<T1>]
240
+ * @template {any} [T2=ParsedObserverPropertyType<T1>]
112
241
  * @param {K} name
113
- * @param {T1|import('./typings.js').ObserverOptions<T1,T2>} [typeOrOptions='string']
114
- * @param {any} object
115
- * @return {import('./typings.js').ObserverConfiguration<T1,T2,K> & import('./typings.js').ObserverOptions<T1,T2>}
242
+ * @param {T1|ObserverOptions<T1,T2>} [typeOrOptions='string']
243
+ * @param {any} [object]
244
+ * @return {ObserverConfiguration<T1,T2,K> & ObserverOptions<T1,T2>}
116
245
  */
117
246
  export function parseObserverOptions(name, typeOrOptions, object) {
118
- /** @type {Partial<import('./typings.js').ObserverOptions<T1,T2>>} */
119
- const options = {
120
- ...((typeof typeOrOptions === 'string') ? { type: typeOrOptions } : typeOrOptions),
121
- };
247
+ /** @type {Partial<ObserverOptions<T1,T2>>} */
248
+ const options = (typeof typeOrOptions === 'string')
249
+ ? { type: typeOrOptions }
250
+ : typeOrOptions;
251
+
252
+ let {
253
+ watchers, value, readonly,
254
+ empty, type,
255
+ enumerable, reflect, attr,
256
+ nullable, parser, nullParser,
257
+ get,
258
+ is, diff,
259
+ props,
260
+ } = options;
122
261
 
123
- let { enumerable, attr, reflect } = options;
124
- const { type, empty, changedCallback } = options;
262
+ watchers ??= [];
263
+ readonly ??= false;
264
+
265
+ if (empty === undefined) {
266
+ empty = null;
267
+ }
268
+
269
+ value ??= empty;
270
+
271
+ if (get && !props) {
272
+ // Custom `get` uses computed values.
273
+ // Invalidate computed value when dependent `prop` changes
274
+ const observeResult = observeFunction(get.bind(object), object, () => value);
275
+ value ??= observeResult.defaultValue;
276
+ const uniqueProps = new Set([
277
+ ...observeResult.props.this,
278
+ ...observeResult.props.args[0],
279
+ ]);
280
+ props = uniqueProps;
281
+ }
125
282
 
126
283
  /** @type {ObserverPropertyType} */
127
- let parsedType = type;
128
- if (parsedType == null) {
129
- // Use .value or .get() to parse type
130
- const value = options.value ?? empty ?? options.get?.call(object ?? {}, object ?? {});
284
+ if (!type) {
131
285
  if (value == null) {
132
- parsedType = 'string';
286
+ // @ts-ignore
287
+ type = 'string';
133
288
  } else {
134
289
  const parsed = typeof value;
135
- parsedType = (parsed === 'number')
290
+ // @ts-ignore
291
+ type = (parsed === 'number')
136
292
  ? (Number.isInteger(value) ? 'integer' : 'number')
137
293
  : parsed;
138
294
  }
139
295
  }
140
296
 
141
297
  enumerable ??= name[0] !== '_';
142
- reflect ??= enumerable ? parsedType !== 'object' : (attr ? 'write' : false);
298
+ reflect ??= enumerable ? type !== 'object' : (attr ? 'write' : false);
143
299
  attr ??= (reflect ? attrNameFromPropName(name) : null);
300
+ nullable ??= (type === 'boolean') ? false : (empty == null);
301
+ if (!nullable) {
302
+ empty ??= emptyFromType(type);
303
+ value ??= empty;
304
+ }
144
305
 
145
306
  // if defined ? value
146
307
  // else if boolean ? false
147
308
  // else if onNullish ? false
148
309
  // else if empty == null
149
- const parser = options.parser ?? defaultParserFromType(parsedType);
150
- let nullParser = options.nullParser;
151
- let parsedEmpty = empty ?? null;
310
+ parser ??= defaultParserFromType(type);
152
311
  if (!nullParser) {
153
- const nullable = options.nullable ?? (
154
- parsedType === 'boolean'
155
- ? false
156
- : (empty == null));
157
312
  if (nullable) {
158
- nullParser = DEFAULT_NULL_PARSER;
313
+ nullParser = () => null;
159
314
  } else {
160
- parsedEmpty ??= emptyFromType(parsedType);
161
- nullParser = parsedEmpty === null ? () => emptyFromType(parsedType) : () => parsedEmpty;
315
+ nullParser = (empty === null)
316
+ ? () => emptyFromType(type)
317
+ : () => empty;
162
318
  }
163
319
  }
164
320
 
165
- let isFn = options.is;
166
- if (!isFn) {
167
- isFn = parsedType === 'object'
168
- ? DEFAULT_OBJECT_COMPARATOR
169
- : Object.is;
170
- }
321
+ is ??= (type === 'object')
322
+ ? (a, b) => !hasMergePatch(a, b)
323
+ : ((type === 'array') ? () => false : Object.is);
171
324
 
172
- const diff = 'diff' in options
173
- ? options.diff
174
- : ((parsedType === 'object') ? DEFAULT_OBJECT_DIFF : null);
325
+ if (diff === undefined) {
326
+ // @ts-ignore
327
+ diff = ((type === 'object') ? (a, b) => buildMergePatch(a, b, 'reference') : null);
328
+ }
175
329
 
176
330
  return {
177
331
  ...options,
178
- type: parsedType,
179
- is: isFn,
332
+ type,
333
+ is,
180
334
  diff,
181
335
  attr,
182
336
  reflect,
183
- readonly: options.readonly ?? false,
337
+ readonly,
184
338
  enumerable,
185
- value: options.value ?? parsedEmpty,
339
+ value,
186
340
  parser,
187
341
  nullParser,
188
342
  key: name,
189
- changedCallback,
190
- watchers: options.watchers ?? [],
191
- values: options.values ?? new WeakMap(),
192
- computedValues: options.computedValues ?? new WeakMap(),
193
- attributeChangedCallback: options.attributeChangedCallback,
194
- needsSelfInvalidation: options.needsSelfInvalidation ?? new WeakSet(),
343
+ props,
344
+ watchers,
195
345
  };
196
346
  }
197
347
 
198
- const INIT_SYMBOL = Symbol('PROP_INIT');
199
-
200
- /** @type {Partial<import('./typings.js').ObserverConfiguration<?,?,?>>} */
201
- const DEFAULT_OBSERVER_CONFIGURATION = {
202
- nullParser: DEFAULT_NULL_PARSER,
203
- is: Object.is,
204
- INIT_SYMBOL,
205
- };
206
-
207
348
  /**
208
- * @this {import('./typings.js').ObserverConfiguration<?,?,?>}
349
+ * @this {ObserverConfiguration<?,?,?>}
209
350
  * @param {*} value
210
351
  */
211
352
  export function parsePropertyValue(value) {
@@ -216,61 +357,58 @@ export function parsePropertyValue(value) {
216
357
  }
217
358
 
218
359
  /**
219
- * @param {(data: Partial<any>) => any} fn
220
- * @param {any} arg0
221
- * @param {any} args[]
222
- * @param {...any} args
223
- * @this {any}
224
- * @return {{props:Set<string>, defaultValue:any, reusable: boolean}}
360
+ * @param {ObserverConfiguration<?,?,?,?>} config
361
+ * @param {any} oldValue
362
+ * @param {any} value
363
+ * @return {boolean} changed
225
364
  */
226
- export function observeFunction(fn, arg0, ...args) {
227
- const argPoked = new Set();
228
- const thisPoked = new Set();
365
+ function detectChange(config, oldValue, value) {
366
+ if (config.get) {
367
+ // TODO: Custom getter vs parser
368
+ }
229
369
 
230
- /**
231
- * @template {Object} T
232
- * @param {T} proxyTarget
233
- * @param {Set<string>} set
234
- * @param {string} [prefix]
235
- * @return {T}
236
- */
237
- function buildProxy(proxyTarget, set, prefix) {
238
- return new Proxy(proxyTarget, {
239
- get(target, p) {
240
- const arg = prefix ? `${prefix}.${p}` : p;
241
- set.add(arg);
242
- const value = Reflect.get(target, p);
243
- if (typeof value === 'object' && value != null) {
244
- console.debug('tried to arg poke object get', p, value);
245
- return buildProxy(value, set, arg);
246
- }
247
- return value;
248
- },
249
- has(target, p) {
250
- const arg = prefix ? `${prefix}.p` : p;
251
- set.add(arg);
252
- const value = Reflect.has(target, p);
253
- return value;
254
- },
255
- });
370
+ // Compute real new value after parsing
371
+ const newValue = (value == null)
372
+ ? config.nullParser.call(this, value)
373
+ : config.parser.call(this, value);
374
+
375
+ // Default change is the newValue
376
+ let changes = newValue;
377
+
378
+ // Null check
379
+ if (oldValue == null) {
380
+ if (newValue == null) {
381
+ // Both nullish
382
+ return false;
383
+ }
384
+ } else if (newValue != null) {
385
+ // Both non-null, compare
386
+ if (config.diff) {
387
+ // Custom change diff
388
+ changes = config.diff.call(this, oldValue, newValue);
389
+ if (changes == null) {
390
+ // No difference
391
+ return false;
392
+ }
393
+ } else if (config.is.call(this, oldValue, newValue)) {
394
+ // Non-equal
395
+ return false;
396
+ }
256
397
  }
257
398
 
258
- const argProxy = buildProxy(arg0, argPoked);
259
- const thisProxy = buildProxy(this ?? arg0, thisPoked);
260
- const defaultValue = fn.call(thisProxy, argProxy, ...args);
261
- /* Arrow functions can reused if they don't poke `this` */
262
- const reusable = fn.name ? true : !thisPoked.size;
399
+ // Commit value
400
+ if (config.values) {
401
+ config.values.set(this, newValue);
402
+ } else {
403
+ config.values = new WeakMap([[this, newValue]]);
404
+ }
263
405
 
264
- const props = new Set([
265
- ...argPoked,
266
- ...thisPoked,
267
- ]);
406
+ // Emit change
268
407
 
269
- return {
270
- props,
271
- defaultValue,
272
- reusable,
273
- };
408
+ config.propChangedCallback?.call(this, config.key, oldValue, newValue, changes);
409
+ config.changedCallback?.call(this, oldValue, newValue, changes);
410
+
411
+ return true;
274
412
  }
275
413
 
276
414
  /**
@@ -280,56 +418,20 @@ export function observeFunction(fn, arg0, ...args) {
280
418
  * @template [C=any]
281
419
  * @param {C} object
282
420
  * @param {K} key
283
- * @param {import('./typings.js').ObserverOptions<T1, T2, C>} options
284
- * @return {import('./typings.js').ObserverConfiguration<T1,T2,K,C>}
421
+ * @param {ObserverOptions<T1, T2, C>} options
422
+ * @return {ObserverConfiguration<T1,T2,K,C>}
285
423
  */
286
424
  export function defineObservableProperty(object, key, options) {
287
- /** @type {import('./typings.js').ObserverConfiguration<T1,T2,K,C>} */
288
- const config = {
289
- ...DEFAULT_OBSERVER_CONFIGURATION,
290
- ...parseObserverOptions(key, options, object),
291
- changedCallback: options.changedCallback,
292
- };
425
+ /** @type {ObserverConfiguration<T1,T2,K,C>} */
426
+ // @ts-ignore
427
+ const config = parseObserverOptions(key, options, object);
293
428
 
294
- /**
295
- * @param {T2} oldValue
296
- * @param {T2} value
297
- * @return {boolean} changed
298
- */
299
- function detectChange(oldValue, value) {
300
- if (oldValue === value) return false;
301
- if (config.get) {
302
- // TODO: Custom getter vs parser
303
- }
304
- let newValue = value;
305
- newValue = (value == null)
306
- ? config.nullParser.call(this, value)
307
- : config.parser.call(this, newValue);
308
-
309
- let changes = newValue;
310
- if (oldValue == null) {
311
- if (newValue == null) return false; // Both nullish
312
- } else if (newValue != null) {
313
- if (oldValue === newValue) return false;
314
- if (config.diff) {
315
- changes = config.diff.call(this, oldValue, newValue);
316
- if (changes == null) return false;
317
- }
318
- if (config.is.call(this, oldValue, newValue)) return false;
319
- }
320
-
321
- config.values.set(this, newValue);
322
- // console.log(key, 'value.set', newValue);
323
- config.propChangedCallback?.call(this, key, oldValue, newValue, changes);
324
- config.changedCallback?.call(this, oldValue, newValue, changes);
325
- return true;
326
- }
327
429
  /**
328
430
  * @this {C}
329
431
  * @return {T2}
330
432
  */
331
433
  function internalGet() {
332
- return config.values.has(this) ? config.values.get(this) : config.value;
434
+ return config.values?.has(this) ? config.values.get(this) : config.value;
333
435
  }
334
436
 
335
437
  /**
@@ -338,68 +440,65 @@ export function defineObservableProperty(object, key, options) {
338
440
  * @return {void}
339
441
  */
340
442
  function internalSet(value) {
443
+ // @ts-ignore
341
444
  const oldValue = this[key];
342
- // console.log(key, 'internalSet', oldValue, '=>', value);
343
- detectChange.call(this, oldValue, value);
445
+ detectChange.call(this, config, oldValue, value);
344
446
  }
345
447
 
346
448
  /** @return {void} */
347
449
  function onInvalidate() {
348
450
  // Current value is now invalidated. Recompute and check if changed
349
- const oldValue = config.computedValues.get(this);
451
+ // eslint-disable-next-line no-multi-assign
452
+
453
+ const oldValue = config.computedValues?.get(this);
350
454
  const newValue = this[key];
351
- // console.debug('observe: onInvalidate called for', key, oldValue, '=>', newValue, this);
352
- config.needsSelfInvalidation.delete(this);
353
- detectChange.call(this, oldValue, newValue);
455
+ config.needsSelfInvalidation?.delete(this);
456
+ detectChange.call(this, config, oldValue, newValue);
354
457
  }
355
458
 
356
- if (config.get) {
357
- // Custom `get` uses computed values.
358
- // Invalidate computed value when dependent `prop` changes
359
- const { props } = observeFunction(config.get.bind(object), object, internalGet.bind(object));
360
- config.watchers.push(
361
- ...[...props].map((prop) => [prop, onInvalidate]),
362
- );
363
- // TODO: May be able to cache value if props are present
459
+ if (config.props) {
460
+ for (const prop of config.props) {
461
+ config.watchers.push([prop, onInvalidate]);
462
+ }
364
463
  }
464
+
465
+ /**
466
+ * @this {C}
467
+ * @return {T2}
468
+ */
469
+ function cachedGet() {
470
+ const newValue = config.get.call(this, this, internalGet.bind(this));
471
+ // Store computed value internally. Used by onInvalidate to get previous value
472
+ const computedValues = (config.computedValues ??= new WeakMap());
473
+ computedValues.set(this, newValue);
474
+ return newValue;
475
+ }
476
+
477
+ /**
478
+ * @this {C}
479
+ * @param {T2} value
480
+ * @return {void}
481
+ */
482
+ function cachedSet(value) {
483
+ if (config.needsSelfInvalidation) {
484
+ config.needsSelfInvalidation.add(this);
485
+ } else {
486
+ config.needsSelfInvalidation = new WeakSet([this]);
487
+ }
488
+ const oldValue = this[key];
489
+ config.set.call(this, value, internalSet.bind(this));
490
+ const newValue = this[key];
491
+ if (!config.needsSelfInvalidation.has(this)) return;
492
+ config.needsSelfInvalidation.delete(this);
493
+ detectChange.call(this, config, oldValue, newValue);
494
+ }
495
+
365
496
  /** @type {Partial<PropertyDescriptor>} */
366
497
  const descriptor = {
367
498
  enumerable: config.enumerable,
368
- /**
369
- * @this {C}
370
- * @return {T2}
371
- */
372
- get() {
373
- if (config.get) {
374
- const newValue = config.get.call(this, this, internalGet.bind(this));
375
- // Store computed value internally. Used by onInvalidate to get previous value
376
- config.computedValues.set(this, newValue);
377
- return newValue;
378
- }
379
- return internalGet.call(this);
380
- },
381
- /**
382
- * @this {C}
383
- * @param {T2} value
384
- * @return {void}
385
- */
386
- set(value) {
387
- if (value === INIT_SYMBOL) {
388
- // console.log(key, 'returning due to INIT');
389
- return;
390
- }
391
- if (config.set) {
392
- config.needsSelfInvalidation.add(this);
393
- const oldValue = this[key];
394
- config.set.call(this, value, internalSet.bind(this));
395
- const newValue = this[key];
396
- if (!config.needsSelfInvalidation.has(this)) return;
397
- config.needsSelfInvalidation.delete(this);
398
- detectChange.call(this, oldValue, newValue);
399
- } else {
400
- internalSet.call(this, value);
401
- }
402
- },
499
+ configurable: true,
500
+ get: config.get ? cachedGet : internalGet,
501
+ set: config.set ? cachedSet : internalSet,
403
502
  };
404
503
 
405
504
  Object.defineProperty(object, key, descriptor);