@shortfuse/materialdesignweb 0.5.0 → 0.7.1-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 (419) hide show
  1. package/README.md +155 -77
  2. package/bin/generate-css.js +12 -0
  3. package/components/Badge.css +38 -0
  4. package/components/Badge.js +15 -0
  5. package/components/Body.css +14 -0
  6. package/components/Body.js +7 -0
  7. package/components/BottomAppBar.css +23 -0
  8. package/components/BottomAppBar.js +25 -0
  9. package/components/Box.css +31 -0
  10. package/components/Box.js +24 -0
  11. package/components/Button.css +147 -0
  12. package/components/Button.js +95 -0
  13. package/components/Button.md +61 -0
  14. package/components/Card.css +109 -0
  15. package/components/Card.js +82 -0
  16. package/components/Checkbox.css +89 -0
  17. package/components/Checkbox.js +59 -0
  18. package/components/CheckboxIcon.css +90 -0
  19. package/components/CheckboxIcon.js +41 -0
  20. package/components/Chip.css +35 -0
  21. package/components/Chip.js +22 -0
  22. package/components/Dialog.css +235 -0
  23. package/components/Dialog.js +327 -0
  24. package/components/DialogActions.js +13 -0
  25. package/components/Divider.css +41 -0
  26. package/components/Divider.js +13 -0
  27. package/components/ExtendedFab.css +24 -0
  28. package/components/ExtendedFab.js +11 -0
  29. package/components/Fab.css +23 -0
  30. package/components/Fab.js +26 -0
  31. package/components/FilterChip.css +80 -0
  32. package/components/FilterChip.js +51 -0
  33. package/components/Headline.css +14 -0
  34. package/components/Headline.js +33 -0
  35. package/components/Icon.css +76 -0
  36. package/components/Icon.js +174 -0
  37. package/components/IconButton.css +150 -0
  38. package/components/IconButton.js +65 -0
  39. package/components/Input.js +16 -0
  40. package/components/Label.css +14 -0
  41. package/components/Label.js +7 -0
  42. package/components/Layout.css +19 -0
  43. package/components/Layout.js +12 -0
  44. package/components/List.css +12 -0
  45. package/components/List.js +17 -0
  46. package/components/ListItem.css +224 -0
  47. package/components/ListItem.js +112 -0
  48. package/components/ListOption.css +34 -0
  49. package/components/ListOption.js +122 -0
  50. package/components/ListSelect.css +9 -0
  51. package/components/ListSelect.js +206 -0
  52. package/components/Menu.css +171 -0
  53. package/components/Menu.js +470 -0
  54. package/components/MenuItem.css +53 -0
  55. package/components/MenuItem.js +215 -0
  56. package/components/Nav.css +17 -0
  57. package/components/Nav.js +23 -0
  58. package/components/NavBar.css +34 -0
  59. package/components/NavBar.js +88 -0
  60. package/components/NavBarItem.css +41 -0
  61. package/components/NavBarItem.js +7 -0
  62. package/components/NavDrawer.css +31 -0
  63. package/components/NavDrawer.js +13 -0
  64. package/components/NavDrawerItem.css +42 -0
  65. package/components/NavDrawerItem.js +12 -0
  66. package/components/NavItem.css +181 -0
  67. package/components/NavItem.js +83 -0
  68. package/components/NavRail.css +47 -0
  69. package/components/NavRail.js +17 -0
  70. package/components/NavRailItem.css +25 -0
  71. package/components/NavRailItem.js +7 -0
  72. package/components/Option.js +91 -0
  73. package/components/Outline.css +138 -0
  74. package/components/Pane.css +261 -0
  75. package/components/Pane.js +21 -0
  76. package/components/Progress.css +75 -0
  77. package/components/Progress.js +67 -0
  78. package/components/ProgressCircle.css +226 -0
  79. package/components/ProgressLine.css +155 -0
  80. package/components/Radio.css +95 -0
  81. package/components/Radio.js +42 -0
  82. package/components/RadioIcon.css +73 -0
  83. package/components/RadioIcon.js +37 -0
  84. package/components/Ripple.css +74 -0
  85. package/components/Ripple.js +114 -0
  86. package/components/SegmentedButton.css +94 -0
  87. package/components/SegmentedButton.js +49 -0
  88. package/components/SegmentedButtonGroup.css +12 -0
  89. package/components/SegmentedButtonGroup.js +44 -0
  90. package/components/Select.css +52 -0
  91. package/components/Select.js +71 -0
  92. package/components/Shape.css +132 -0
  93. package/components/Shape.js +25 -0
  94. package/components/Slider.css +307 -0
  95. package/components/Slider.js +206 -0
  96. package/components/Snackbar.css +80 -0
  97. package/components/Snackbar.js +75 -0
  98. package/components/Surface.css +10 -0
  99. package/components/Surface.js +23 -0
  100. package/components/Switch.css +64 -0
  101. package/components/Switch.js +127 -0
  102. package/components/SwitchIcon.css +178 -0
  103. package/components/SwitchIcon.js +89 -0
  104. package/components/SwitchIconAnimations.css +89 -0
  105. package/components/Tab.css +85 -0
  106. package/components/Tab.js +103 -0
  107. package/components/TabContent.js +151 -0
  108. package/components/TabList.css +129 -0
  109. package/components/TabList.js +309 -0
  110. package/components/TabPanel.js +37 -0
  111. package/components/TextArea.css +93 -0
  112. package/components/TextArea.js +229 -0
  113. package/components/Title.css +14 -0
  114. package/components/Title.js +15 -0
  115. package/components/Tooltip.css +40 -0
  116. package/components/Tooltip.js +22 -0
  117. package/components/TopAppBar.css +209 -0
  118. package/components/TopAppBar.js +201 -0
  119. package/core/Composition.js +988 -0
  120. package/core/CustomElement.js +844 -0
  121. package/core/ICustomElement.d.ts +288 -0
  122. package/core/ICustomElement.js +1 -0
  123. package/core/css.js +51 -0
  124. package/core/customTypes.js +125 -0
  125. package/core/dom.js +56 -154
  126. package/core/identify.js +40 -0
  127. package/core/observe.js +410 -0
  128. package/core/template.js +121 -0
  129. package/core/typings.d.ts +135 -0
  130. package/core/typings.js +1 -0
  131. package/index.js +77 -0
  132. package/mixins/AriaReflectorMixin.js +42 -0
  133. package/mixins/AriaToolbarMixin.js +13 -0
  134. package/mixins/ControlMixin.css +57 -0
  135. package/mixins/ControlMixin.js +212 -0
  136. package/mixins/DensityMixin.css +40 -0
  137. package/mixins/DensityMixin.js +11 -0
  138. package/mixins/FlexableMixin.css +79 -0
  139. package/mixins/FlexableMixin.js +32 -0
  140. package/mixins/FormAssociatedMixin.js +170 -0
  141. package/mixins/InputMixin.js +335 -0
  142. package/mixins/KeyboardNavMixin.js +244 -0
  143. package/mixins/RTLObserverMixin.js +35 -0
  144. package/mixins/ResizeObserverMixin.js +38 -0
  145. package/mixins/RippleMixin.css +12 -0
  146. package/mixins/RippleMixin.js +115 -0
  147. package/mixins/ScrollListenerMixin.js +100 -0
  148. package/mixins/ShapeMixin.css +135 -0
  149. package/mixins/ShapeMixin.js +31 -0
  150. package/mixins/StateMixin.css +82 -0
  151. package/mixins/StateMixin.js +114 -0
  152. package/mixins/SurfaceMixin.css +150 -0
  153. package/mixins/SurfaceMixin.js +32 -0
  154. package/mixins/TextFieldMixin.css +657 -0
  155. package/mixins/TextFieldMixin.js +121 -0
  156. package/mixins/ThemableMixin.css +204 -0
  157. package/mixins/ThemableMixin.js +16 -0
  158. package/mixins/TooltipTriggerMixin.css +27 -0
  159. package/mixins/TooltipTriggerMixin.js +366 -0
  160. package/mixins/TouchTargetMixin.css +26 -0
  161. package/mixins/TouchTargetMixin.js +9 -0
  162. package/package.json +55 -49
  163. package/theming/index.js +473 -0
  164. package/theming/loader.js +24 -0
  165. package/utils/cli.js +11 -0
  166. package/utils/color_keywords.js +151 -0
  167. package/utils/hct/Cam16.js +298 -0
  168. package/utils/hct/CorePalette.js +84 -0
  169. package/utils/hct/Hct.js +172 -0
  170. package/utils/hct/Scheme.js +587 -0
  171. package/utils/hct/TonalPalette.js +68 -0
  172. package/utils/hct/ViewingConditions.js +136 -0
  173. package/utils/hct/blend.js +93 -0
  174. package/utils/hct/colorUtils.js +302 -0
  175. package/utils/hct/hctSolver.js +559 -0
  176. package/utils/hct/helper.js +182 -0
  177. package/utils/hct/mathUtils.js +153 -0
  178. package/utils/jsonMergePatch.js +100 -0
  179. package/utils/jsx-runtime.js +101 -0
  180. package/utils/popup.js +117 -0
  181. package/utils/svg.js +12 -0
  182. package/.browserslistrc +0 -4
  183. package/.eslintrc.json +0 -204
  184. package/.stylelintrc.json +0 -645
  185. package/.vscode/launch.json +0 -31
  186. package/.vscode/settings.json +0 -3
  187. package/.vscode/tasks.json +0 -32
  188. package/CHANGELOG.md +0 -36
  189. package/CODE_OF_CONDUCT.md +0 -46
  190. package/adapters/datatable/column.js +0 -176
  191. package/adapters/datatable/index.js +0 -960
  192. package/adapters/dom/index.js +0 -586
  193. package/adapters/list/index.js +0 -69
  194. package/adapters/search/index.js +0 -495
  195. package/components/appbar/_spec.scss +0 -165
  196. package/components/appbar/_theme.scss +0 -0
  197. package/components/appbar/index.scss +0 -2
  198. package/components/banner/_spec.scss +0 -83
  199. package/components/banner/_theme.scss +0 -0
  200. package/components/banner/index.scss +0 -2
  201. package/components/bottomnav/README.md +0 -85
  202. package/components/bottomnav/_spec.scss +0 -149
  203. package/components/bottomnav/_theme.scss +0 -0
  204. package/components/bottomnav/index.js +0 -117
  205. package/components/bottomnav/index.scss +0 -2
  206. package/components/bottomnav/item.js +0 -88
  207. package/components/button/README.md +0 -61
  208. package/components/button/_spec.scss +0 -162
  209. package/components/button/_theme.scss +0 -42
  210. package/components/button/index.eta +0 -32
  211. package/components/button/index.js +0 -43
  212. package/components/button/index.pug +0 -18
  213. package/components/button/index.scss +0 -2
  214. package/components/card/_spec.scss +0 -241
  215. package/components/card/_theme.scss +0 -0
  216. package/components/card/index.scss +0 -2
  217. package/components/chip/_spec.scss +0 -111
  218. package/components/chip/_theme.scss +0 -105
  219. package/components/chip/index.js +0 -23
  220. package/components/chip/index.scss +0 -2
  221. package/components/chip/item.js +0 -20
  222. package/components/datatable/_spec.scss +0 -225
  223. package/components/datatable/_theme.scss +0 -128
  224. package/components/datatable/cell.js +0 -44
  225. package/components/datatable/columnheader.js +0 -46
  226. package/components/datatable/index.js +0 -374
  227. package/components/datatable/index.scss +0 -2
  228. package/components/datatable/row.js +0 -48
  229. package/components/datatable/rowheader.js +0 -18
  230. package/components/dialog/_spec.scss +0 -203
  231. package/components/dialog/_theme.scss +0 -7
  232. package/components/dialog/index.js +0 -601
  233. package/components/dialog/index.scss +0 -2
  234. package/components/divider/_spec.scss +0 -11
  235. package/components/divider/_theme.scss +0 -0
  236. package/components/divider/index.scss +0 -2
  237. package/components/elevation/_spec.scss +0 -9
  238. package/components/elevation/_theme.scss +0 -0
  239. package/components/elevation/index.scss +0 -2
  240. package/components/fab/_spec.scss +0 -210
  241. package/components/fab/_theme.scss +0 -0
  242. package/components/fab/index.js +0 -99
  243. package/components/fab/index.scss +0 -2
  244. package/components/grid/_spec.scss +0 -169
  245. package/components/grid/_theme.scss +0 -0
  246. package/components/grid/index.scss +0 -2
  247. package/components/layout/_mixins.scss +0 -11
  248. package/components/layout/_spec.scss +0 -916
  249. package/components/layout/_theme.scss +0 -19
  250. package/components/layout/index.js +0 -454
  251. package/components/layout/index.scss +0 -2
  252. package/components/list/_spec.scss +0 -363
  253. package/components/list/_theme.scss +0 -102
  254. package/components/list/content.js +0 -106
  255. package/components/list/index.js +0 -256
  256. package/components/list/index.scss +0 -2
  257. package/components/list/item.js +0 -167
  258. package/components/list/secondary.js +0 -45
  259. package/components/menu/_spec.scss +0 -329
  260. package/components/menu/_theme.scss +0 -0
  261. package/components/menu/index.js +0 -705
  262. package/components/menu/index.scss +0 -2
  263. package/components/menu/item.js +0 -231
  264. package/components/progress/_spec.scss +0 -156
  265. package/components/progress/_theme.scss +0 -0
  266. package/components/progress/index.js +0 -36
  267. package/components/progress/index.scss +0 -2
  268. package/components/selection/_spec.scss +0 -376
  269. package/components/selection/_theme.scss +0 -134
  270. package/components/selection/index.eta +0 -60
  271. package/components/selection/index.js +0 -70
  272. package/components/selection/index.pug +0 -30
  273. package/components/selection/index.scss +0 -2
  274. package/components/selection/input.js +0 -54
  275. package/components/selection/radiogroup.js +0 -40
  276. package/components/slider/_spec.scss +0 -59
  277. package/components/slider/_theme.scss +0 -0
  278. package/components/slider/index.scss +0 -2
  279. package/components/snackbar/_spec.scss +0 -150
  280. package/components/snackbar/_theme.scss +0 -0
  281. package/components/snackbar/index.js +0 -338
  282. package/components/snackbar/index.scss +0 -2
  283. package/components/tab/_spec.scss +0 -220
  284. package/components/tab/_theme.scss +0 -0
  285. package/components/tab/content.js +0 -210
  286. package/components/tab/index.js +0 -257
  287. package/components/tab/index.scss +0 -2
  288. package/components/tab/item.js +0 -88
  289. package/components/tab/list.js +0 -196
  290. package/components/tab/panel.js +0 -54
  291. package/components/textfield/README.md +0 -179
  292. package/components/textfield/_spec.scss +0 -763
  293. package/components/textfield/_theme.scss +0 -264
  294. package/components/textfield/index.eta +0 -74
  295. package/components/textfield/index.js +0 -160
  296. package/components/textfield/index.pug +0 -30
  297. package/components/textfield/index.scss +0 -2
  298. package/components/tooltip/_spec.scss +0 -185
  299. package/components/tooltip/_theme.scss +0 -0
  300. package/components/tooltip/index.scss +0 -2
  301. package/components/type/_spec.scss +0 -227
  302. package/components/type/_theme.scss +0 -0
  303. package/components/type/index.scss +0 -2
  304. package/core/_breakpoint.scss +0 -189
  305. package/core/_elevation.scss +0 -78
  306. package/core/_length.scss +0 -8
  307. package/core/_motion.scss +0 -31
  308. package/core/_platform.scss +0 -12
  309. package/core/_type.scss +0 -128
  310. package/core/aria/attributes.js +0 -141
  311. package/core/aria/button.js +0 -49
  312. package/core/aria/keyboard.js +0 -92
  313. package/core/aria/rovingtabindex.js +0 -175
  314. package/core/aria/tab.js +0 -59
  315. package/core/document/index.js +0 -39
  316. package/core/overlay/_spec.scss +0 -28
  317. package/core/overlay/_theme.scss +0 -147
  318. package/core/overlay/index.js +0 -95
  319. package/core/overlay/index.scss +0 -2
  320. package/core/ripple/_spec.scss +0 -196
  321. package/core/ripple/_theme.scss +0 -20
  322. package/core/ripple/index.js +0 -286
  323. package/core/ripple/index.scss +0 -2
  324. package/core/theme/_aliases.scss +0 -15
  325. package/core/theme/_config.scss +0 -8
  326. package/core/theme/_functions.scss +0 -22
  327. package/core/theme/_palettes.scss +0 -405
  328. package/core/theme/_spec.scss +0 -0
  329. package/core/theme/_theme.scss +0 -268
  330. package/core/theme/index.js +0 -50
  331. package/core/theme/index.scss +0 -4
  332. package/core/throttler.js +0 -42
  333. package/core/transition/index.js +0 -465
  334. package/docs/_flex.scss +0 -28
  335. package/docs/_menuoptions.js +0 -183
  336. package/docs/_partials/_androidnavbar.eta +0 -5
  337. package/docs/_partials/_androidstatusbar.eta +0 -13
  338. package/docs/_partials/_appbar.eta +0 -27
  339. package/docs/_partials/_buttontest.eta +0 -31
  340. package/docs/_partials/_header.eta +0 -146
  341. package/docs/_partials/_navlistitem.eta +0 -16
  342. package/docs/_partials/_target.eta +0 -1
  343. package/docs/_sample-utils.js +0 -88
  344. package/docs/_storage.js +0 -33
  345. package/docs/docs.scss +0 -331
  346. package/docs/framework.scss +0 -26
  347. package/docs/index.eta +0 -12
  348. package/docs/index.js +0 -7
  349. package/docs/pages/appbar.eta +0 -108
  350. package/docs/pages/appbar.js +0 -0
  351. package/docs/pages/bottomnav.eta +0 -188
  352. package/docs/pages/bottomnav.js +0 -118
  353. package/docs/pages/button.eta +0 -124
  354. package/docs/pages/button.js +0 -224
  355. package/docs/pages/card.eta +0 -90
  356. package/docs/pages/card.js +0 -175
  357. package/docs/pages/chip.eta +0 -122
  358. package/docs/pages/chip.js +0 -80
  359. package/docs/pages/color.eta +0 -143
  360. package/docs/pages/color.js +0 -261
  361. package/docs/pages/datatable.eta +0 -323
  362. package/docs/pages/datatable.js +0 -160
  363. package/docs/pages/dialog.eta +0 -184
  364. package/docs/pages/dialog.js +0 -174
  365. package/docs/pages/dom.eta +0 -26
  366. package/docs/pages/dom.js +0 -140
  367. package/docs/pages/elevation.eta +0 -35
  368. package/docs/pages/elevation.js +0 -0
  369. package/docs/pages/fab.eta +0 -99
  370. package/docs/pages/fab.js +0 -43
  371. package/docs/pages/grid.eta +0 -135
  372. package/docs/pages/grid.js +0 -128
  373. package/docs/pages/layout.eta +0 -8
  374. package/docs/pages/layout.js +0 -0
  375. package/docs/pages/list.eta +0 -465
  376. package/docs/pages/list.js +0 -8
  377. package/docs/pages/menu.eta +0 -274
  378. package/docs/pages/menu.js +0 -213
  379. package/docs/pages/overlay.eta +0 -69
  380. package/docs/pages/overlay.js +0 -3
  381. package/docs/pages/progress.eta +0 -23
  382. package/docs/pages/progress.js +0 -12
  383. package/docs/pages/ripple.eta +0 -27
  384. package/docs/pages/ripple.js +0 -3
  385. package/docs/pages/search.eta +0 -242
  386. package/docs/pages/search.js +0 -226
  387. package/docs/pages/selection.eta +0 -107
  388. package/docs/pages/selection.js +0 -12
  389. package/docs/pages/slider.eta +0 -23
  390. package/docs/pages/slider.js +0 -0
  391. package/docs/pages/snackbar.eta +0 -83
  392. package/docs/pages/snackbar.js +0 -157
  393. package/docs/pages/tab.eta +0 -407
  394. package/docs/pages/tab.js +0 -152
  395. package/docs/pages/textfield.eta +0 -487
  396. package/docs/pages/textfield.js +0 -257
  397. package/docs/pages/tooltip.eta +0 -92
  398. package/docs/pages/tooltip.js +0 -0
  399. package/docs/pages/transition.eta +0 -117
  400. package/docs/pages/transition.js +0 -52
  401. package/docs/pages/type.eta +0 -31
  402. package/docs/pages/type.js +0 -0
  403. package/docs/postrender.js +0 -41
  404. package/docs/prerender.js +0 -16
  405. package/docs/pwa/_dialogs.eta +0 -143
  406. package/docs/pwa/_menus.eta +0 -16
  407. package/docs/pwa/pwa-prerender.js +0 -3
  408. package/docs/pwa/pwa.eta +0 -478
  409. package/docs/pwa/pwa.js +0 -298
  410. package/docs/pwa/pwa.scss +0 -31
  411. package/docs/themes/theme-colored.scss +0 -15
  412. package/docs/themes/theme-default.scss +0 -3
  413. package/index.scss +0 -27
  414. package/jsconfig.json +0 -16
  415. package/scripts/deploy-docs.sh +0 -9
  416. package/templates/index.eta +0 -2
  417. package/templates/index.pug +0 -3
  418. package/tsconfig.json +0 -16
  419. package/webpack.config.js +0 -304
@@ -0,0 +1,844 @@
1
+ /* eslint-disable max-classes-per-file */
2
+
3
+ import Composition from './Composition.js';
4
+ import { ICustomElement } from './ICustomElement.js';
5
+ import { attrNameFromPropName, attrValueFromDataValue } from './dom.js';
6
+ import { defineObservableProperty } from './observe.js';
7
+ import { addInlineFunction, css, html } from './template.js';
8
+
9
+ /**
10
+ * @template {abstract new (...args: any) => unknown} T
11
+ * @param {InstanceType<T>} instance
12
+ */
13
+ function superOf(instance) {
14
+ const staticContext = instance.constructor;
15
+ const superOfStatic = Object.getPrototypeOf(staticContext);
16
+ return superOfStatic.prototype;
17
+ }
18
+
19
+ const EVENT_PREFIX_REGEX = /^([*1~]+)?(.*)$/;
20
+
21
+ /**
22
+ * Web Component that can cache templates for minification or performance
23
+ */
24
+ export default class CustomElement extends ICustomElement {
25
+ /** @type {string} */
26
+ static elementName;
27
+
28
+ /** @return {Iterable<string>} */
29
+ static get observedAttributes() {
30
+ const s = new Set();
31
+ for (const config of this.propList.values()) {
32
+ if (config.reflect === true || config.reflect === 'read') {
33
+ s.add(config.attr);
34
+ }
35
+ }
36
+ return s;
37
+ }
38
+
39
+ /** @type {import('./Composition.js').Compositor<?>} */
40
+ compose() {
41
+ if (this.#composition) {
42
+ console.warn('Already composed. Generating *new* composition...');
43
+ }
44
+ this.#composition = new Composition();
45
+ return this.#composition;
46
+ }
47
+
48
+ /** @type {Composition<?>} */
49
+ static _composition = null;
50
+
51
+ /** @type {Map<string, import('./typings.js').ObserverConfiguration<?,?,?>>} */
52
+ static _props = new Map();
53
+
54
+ /** @type {Map<string, Function[]>} */
55
+ static _propChangedCallbacks = new Map();
56
+
57
+ /** @type {Map<string, Function[]>} */
58
+ static _attributeChangedCallbacks = new Map();
59
+
60
+ /** @type {typeof ICustomElement._onComposeCallbacks} */
61
+ static _onComposeCallbacks = [];
62
+
63
+ /** @type {typeof ICustomElement._onConnectedCallbacks} */
64
+ static _onConnectedCallbacks = [];
65
+
66
+ /** @type {typeof ICustomElement._onDisconnectedCallbacks} */
67
+ static _onDisconnectedCallbacks = [];
68
+
69
+ /** @type {typeof ICustomElement._onConstructedCallbacks} */
70
+ static _onConstructedCallbacks = [];
71
+
72
+ static interpolatesTemplate = true;
73
+
74
+ static supportsElementInternals = 'attachInternals' in HTMLElement.prototype;
75
+
76
+ static supportsElementInternalsRole = CustomElement.supportsElementInternals
77
+ && 'role' in ElementInternals.prototype;
78
+
79
+ /** @type {boolean} */
80
+ static templatable = null;
81
+
82
+ static defined = false;
83
+
84
+ static autoRegistration = true;
85
+
86
+ /** @type {Map<string, typeof CustomElement>} */
87
+ static registrations = new Map();
88
+
89
+ /** @type {typeof ICustomElement.expressions} */
90
+ static expressions = this.set;
91
+
92
+ /** @type {typeof ICustomElement.methods} */
93
+ static methods = this.set;
94
+
95
+ /** @type {typeof ICustomElement.overrides} */
96
+ static overrides = this.set;
97
+
98
+ /** @type {typeof ICustomElement.props} */
99
+ static props = this.observe;
100
+
101
+ /**
102
+ * @template {typeof CustomElement} T
103
+ * @this T
104
+ * @template {keyof T} K
105
+ * @param {K} collection
106
+ * @param {T[K] extends (infer R)[] ? R : never} callback
107
+ */
108
+ static _addCallback(collection, callback) {
109
+ if (!this.hasOwnProperty(collection)) {
110
+ this[collection] = [
111
+ ...this[collection],
112
+ ];
113
+ }
114
+ this[collection].push(callback);
115
+ }
116
+
117
+ /**
118
+ * Append parts to composition
119
+ * @type {typeof ICustomElement.append}
120
+ */
121
+ static append(...parts) {
122
+ this.on({
123
+ composed({ composition }) {
124
+ // console.debug('onComposed:append', ...parts);
125
+ composition.append(...parts);
126
+ },
127
+ });
128
+ // @ts-expect-error Can't cast T
129
+ return this;
130
+ }
131
+
132
+ /**
133
+ * Appends styles to composition
134
+ * @type {typeof ICustomElement.css}
135
+ */
136
+ static css(array, ...substitutions) {
137
+ if (Array.isArray(array)) {
138
+ // @ts-expect-error Complex cast
139
+ this.append(css(array, ...substitutions));
140
+ } else {
141
+ // @ts-expect-error Complex cast
142
+ this.append(array, ...substitutions);
143
+ }
144
+ // @ts-expect-error Can't cast T
145
+ return this;
146
+ }
147
+
148
+ /** @type {typeof ICustomElement['setSchema']} */
149
+ static setSchema(schema) {
150
+ this.schema = schema;
151
+ // @ts-expect-error Can't cast T
152
+ return this;
153
+ }
154
+
155
+ /**
156
+ * Registers class asynchronously at end of current event loop cycle
157
+ * via `queueMicrotask`. If class is registered before then,
158
+ * does nothing.
159
+ * @type {typeof ICustomElement['autoRegister']}
160
+ */
161
+ static autoRegister(elementName) {
162
+ if (elementName) {
163
+ this.elementName = elementName;
164
+ }
165
+ queueMicrotask(() => {
166
+ if (this.autoRegistration) {
167
+ this.register();
168
+ }
169
+ });
170
+ // @ts-expect-error Can't cast T
171
+ return this;
172
+ }
173
+
174
+ /**
175
+ * Appends DocumentFragment to composition
176
+ * @type {typeof ICustomElement.html}
177
+ */
178
+ static html(strings, ...substitutions) {
179
+ this.on({
180
+ composed({ composition }) {
181
+ // console.log('onComposed:html', strings);
182
+ composition.append(html(strings, ...substitutions));
183
+ },
184
+ });
185
+ // @ts-expect-error Can't cast T
186
+ return this;
187
+ }
188
+
189
+ /**
190
+ * Extends base class into a new class.
191
+ * Use to avoid mutating base class.
192
+ * TODO: Add constructor arguments typing
193
+ * @type {typeof ICustomElement.extend}
194
+ */
195
+ static extend() {
196
+ // @ts-expect-error Can't cast T
197
+ return class ExtendedClass extends this {};
198
+ }
199
+
200
+ /**
201
+ * Extends base class into a new class.
202
+ * Use to avoid mutating base class.
203
+ * TODO: Add constructor arguments typing
204
+ * @type {typeof ICustomElement.tsClassFix}
205
+ */
206
+ static tsClassFix() {
207
+ // @ts-expect-error Can't cast T
208
+ return this;
209
+ }
210
+
211
+ /**
212
+ * Assigns static values to class
213
+ * @type {typeof ICustomElement.setStatic}
214
+ */
215
+ static setStatic(source) {
216
+ Object.assign(this, source);
217
+ // @ts-expect-error Can't cast T
218
+ return this;
219
+ }
220
+
221
+ /**
222
+ * Assigns values directly to all instances (via prototype)
223
+ * @type {typeof ICustomElement.set}
224
+ */
225
+ static readonly(source, options) {
226
+ // @ts-expect-error Can't cast T
227
+ return this.set(source, { ...options, writable: false });
228
+ }
229
+
230
+ /**
231
+ * Assigns values directly to all instances (via prototype)
232
+ * @type {typeof ICustomElement.set}
233
+ */
234
+ static set(source, options) {
235
+ Object.defineProperties(
236
+ this.prototype,
237
+ Object.fromEntries(
238
+ Object.entries(source).map(([name, value]) => {
239
+ // Tap into .map() to avoid double iteration
240
+ // Property may be redefined observable
241
+ this.undefine(name);
242
+ return [
243
+ name,
244
+ {
245
+ enumerable: name[0] !== '_',
246
+ configurable: true,
247
+ value,
248
+ writable: true,
249
+ ...options,
250
+ },
251
+ ];
252
+ }),
253
+ ),
254
+ );
255
+ // @ts-expect-error Can't cast T
256
+ return this;
257
+ }
258
+
259
+ /**
260
+ * Returns result of calling mixin with current class
261
+ * @type {typeof ICustomElement.mixin}
262
+ */
263
+ static mixin(mixin) {
264
+ return mixin(this);
265
+ }
266
+
267
+ /**
268
+ * Registers class with window.customElements synchronously
269
+ * @type {typeof ICustomElement['register']}
270
+ */
271
+ static register(elementName, force = false) {
272
+ if (this.hasOwnProperty('defined') && this.defined && !force) {
273
+ console.warn(this.elementName, 'already registered.');
274
+ // @ts-expect-error Can't cast T
275
+ return this;
276
+ }
277
+
278
+ if (elementName) {
279
+ this.elementName = elementName;
280
+ }
281
+
282
+ customElements.define(this.elementName, this);
283
+ CustomElement.registrations.set(this.elementName, this);
284
+ this.defined = true;
285
+ // @ts-expect-error Can't cast T
286
+ return this;
287
+ }
288
+
289
+ static get propList() {
290
+ if (!this.hasOwnProperty('_props')) {
291
+ this._props = new Map(this._props);
292
+ }
293
+ return this._props;
294
+ }
295
+
296
+ static get propChangedCallbacks() {
297
+ if (!this.hasOwnProperty('_propChangedCallbacks')) {
298
+ // structuredClone()
299
+ this._propChangedCallbacks = new Map(
300
+ [
301
+ ...this._propChangedCallbacks,
302
+ ].map(([name, array]) => [name, array.slice()]),
303
+ );
304
+ }
305
+ return this._propChangedCallbacks;
306
+ }
307
+
308
+ static get attributeChangedCallbacks() {
309
+ if (!this.hasOwnProperty('_attributeChangedCallbacks')) {
310
+ this._attributeChangedCallbacks = new Map(
311
+ [
312
+ ...this._attributeChangedCallbacks,
313
+ ].map(([name, array]) => [name, array.slice()]),
314
+ );
315
+ }
316
+ return this._attributeChangedCallbacks;
317
+ }
318
+
319
+ /**
320
+ * Creates observable property on instances (via prototype)
321
+ * @template {import('./typings.js').ObserverPropertyType} [T1=null]
322
+ * @template {import('./typings.js').ObserverPropertyType} [T2=null]
323
+ * @template {any} [T3=null]
324
+ * @param {string} name
325
+ * @param {T1|import('./typings.js').ObserverOptions<T2,T3>} [typeOrOptions='string']
326
+ * @return {(
327
+ * T3 extends null ?
328
+ * T2 extends null ?
329
+ * T1 extends null ?
330
+ * string
331
+ * : import('./typings.js').ParsedObserverPropertyType<T1>
332
+ * : import('./typings.js').ParsedObserverPropertyType<T2>
333
+ * : T3
334
+ * )}
335
+ */
336
+ static prop(name, typeOrOptions) {
337
+ // TODO: Cache and save configuration for reuse (mixins)
338
+ /** @type {import('./typings.js').ObserverOptions<?,?>} */
339
+ const options = {
340
+ ...((typeof typeOrOptions === 'string') ? { type: typeOrOptions } : typeOrOptions),
341
+ };
342
+
343
+ const customCallback = options.changedCallback;
344
+
345
+ if (customCallback) {
346
+ // Move callback to later in stack for attribute-based changes as well
347
+ this.onPropChanged({ [name]: customCallback });
348
+ }
349
+
350
+ // TODO: Inspect possible closure bloat
351
+ options.changedCallback = function wrappedChangedCallback(oldValue, newValue, changes) {
352
+ this._onObserverPropertyChanged.call(this, name, oldValue, newValue, changes);
353
+ };
354
+
355
+ const config = defineObservableProperty(this.prototype, name, options);
356
+
357
+ this.propList.set(name, config);
358
+ for (const [prop, callback] of config.watchers) {
359
+ this.on(`${prop}Changed`, callback);
360
+ }
361
+
362
+ return config.INIT_SYMBOL;
363
+ }
364
+
365
+ /**
366
+ * Define properties on instances via Object.defineProperties().
367
+ * Automatically sets property non-enumerable if name begins with `_`.
368
+ * @type {typeof ICustomElement.define}
369
+ */
370
+ static define(props) {
371
+ Object.defineProperties(
372
+ this.prototype,
373
+ Object.fromEntries(
374
+ Object.entries(props).map(([name, options]) => {
375
+ // Tap into .map() to avoid double iteration
376
+ // Property may be redefined observable
377
+ this.undefine(name);
378
+ return [
379
+ name,
380
+ {
381
+ enumerable: name[0] !== '_',
382
+ configurable: true,
383
+ ...(
384
+ typeof options === 'function'
385
+ ? { get: options }
386
+ : options
387
+ ),
388
+ },
389
+ ];
390
+ }),
391
+ ),
392
+ );
393
+
394
+ // @ts-expect-error Can't cast T
395
+ return this;
396
+ }
397
+
398
+ static undefine(name) {
399
+ Reflect.deleteProperty(this.prototype, name);
400
+ const config = this.propList.get(name);
401
+ if (config && config.watchers.length) {
402
+ const propWatchers = this.propChangedCallbacks.get(name);
403
+ if (propWatchers) {
404
+ for (const watcher of config.watchers) {
405
+ const index = propWatchers.indexOf(watcher);
406
+ if (index !== -1) {
407
+ console.warn('Unwatching', name);
408
+ propWatchers.splice(index, 1);
409
+ }
410
+ }
411
+ }
412
+ }
413
+ this.propList.delete(name);
414
+ return this;
415
+ }
416
+
417
+ /**
418
+ * Creates observable properties on instances
419
+ * @type {typeof ICustomElement.observe}
420
+ */
421
+ static observe(props) {
422
+ for (const [name, typeOrOptions] of Object.entries(props ?? {})) {
423
+ if (typeof typeOrOptions === 'function') {
424
+ this.prop(name, {
425
+ reflect: false,
426
+ get: typeOrOptions,
427
+ });
428
+ } else {
429
+ this.prop(name, typeOrOptions);
430
+ }
431
+ }
432
+ // @ts-expect-error Can't cast T
433
+ return this;
434
+ }
435
+
436
+ /** @type {typeof ICustomElement.defineStatic} */
437
+ static defineStatic(props) {
438
+ for (const [name, typeOrOptions] of Object.entries(props ?? {})) {
439
+ const options = (typeof typeOrOptions === 'function')
440
+ ? { get: typeOrOptions }
441
+ : (typeof typeOrOptions === 'string'
442
+ ? { type: typeOrOptions }
443
+ : typeOrOptions);
444
+ defineObservableProperty(this, name, {
445
+ reflect: false,
446
+ ...options,
447
+ });
448
+ }
449
+ // @ts-expect-error Can't cast T
450
+ return this;
451
+ }
452
+
453
+ /** @type {typeof ICustomElement.events} */
454
+ static events(listeners, options) {
455
+ this.on({
456
+ composed({ composition }) {
457
+ for (const [key, listenerOptions] of Object.entries(listeners)) {
458
+ const [, flags, type] = key.match(EVENT_PREFIX_REGEX);
459
+ composition.addCompositionEventListener({
460
+ type,
461
+ once: flags?.includes('1'),
462
+ passive: flags?.includes('~'),
463
+ capture: flags?.includes('*'),
464
+ ...(
465
+ typeof listenerOptions === 'function'
466
+ ? { handleEvent: listenerOptions }
467
+ : (typeof listenerOptions === 'string'
468
+ ? { prop: listenerOptions }
469
+ : listenerOptions)
470
+ ),
471
+ ...(
472
+ options
473
+ )
474
+ ,
475
+ });
476
+ }
477
+ },
478
+ });
479
+
480
+ // @ts-expect-error Can't cast T
481
+ return this;
482
+ }
483
+
484
+ /** @type {typeof ICustomElement.childEvents} */
485
+ static childEvents(listenerMap, options) {
486
+ for (const [id, listeners] of Object.entries(listenerMap)) {
487
+ this.events(listeners, {
488
+ id,
489
+ ...options,
490
+ });
491
+ }
492
+
493
+ // @ts-expect-error Can't cast T
494
+ return this;
495
+ }
496
+
497
+ /** @type {typeof ICustomElement['on']} */
498
+ static on(nameOrCallbacks, callback) {
499
+ const callbacks = typeof nameOrCallbacks === 'string'
500
+ ? { [nameOrCallbacks]: callback }
501
+ : nameOrCallbacks;
502
+ for (const [name, fn] of Object.entries(callbacks)) {
503
+ /** @type {keyof (typeof CustomElement)} */
504
+ let arrayPropName;
505
+ switch (name) {
506
+ case 'composed': arrayPropName = '_onComposeCallbacks'; break;
507
+ case 'constructed': arrayPropName = '_onConstructedCallbacks'; break;
508
+ case 'connected': arrayPropName = '_onConnectedCallbacks'; break;
509
+ case 'disconnected': arrayPropName = '_onDisconnectedCallbacks'; break;
510
+ case 'props':
511
+ this.onPropChanged(fn);
512
+ continue;
513
+ case 'attrs':
514
+ this.onAttributeChanged(fn);
515
+ continue;
516
+ default:
517
+ if (name.endsWith('Changed')) {
518
+ const prop = name.slice(0, name.length - 'Changed'.length);
519
+ this.onPropChanged({ [prop]: fn });
520
+ continue;
521
+ }
522
+ throw new Error('Invalid callback name');
523
+ }
524
+ this._addCallback(arrayPropName, fn);
525
+ }
526
+
527
+ // @ts-expect-error Can't cast T
528
+ return this;
529
+ }
530
+
531
+ /** @type {typeof ICustomElement['onPropChanged']} */
532
+ static onPropChanged(options) {
533
+ for (const [prop, callback] of Object.entries(options)) {
534
+ let array = this.propChangedCallbacks.get(prop);
535
+ if (!array) {
536
+ array = [];
537
+ this.propChangedCallbacks.set(prop, array);
538
+ }
539
+ array.push(callback);
540
+ }
541
+
542
+ // @ts-expect-error Can't cast T
543
+ return this;
544
+ }
545
+
546
+ /** @type {typeof ICustomElement['onAttributeChanged']} */
547
+ static onAttributeChanged(options) {
548
+ for (const [name, callback] of Object.entries(options)) {
549
+ let array = this.attributeChangedCallbacks.get(name);
550
+ if (!array) {
551
+ array = [];
552
+ this.attributeChangedCallbacks.set(name, array);
553
+ }
554
+ array.push(callback);
555
+ }
556
+
557
+ // @ts-expect-error Can't cast T
558
+ return this;
559
+ }
560
+
561
+ /** @type {Record<string, HTMLElement>}} */
562
+ #refsProxy;
563
+
564
+ /** @type {Map<string, WeakRef<HTMLElement>>}} */
565
+ #refsCache = new Map();
566
+
567
+ /** @type {Map<string, WeakRef<HTMLElement>>}} */
568
+ #refsCompositionCache = new Map();
569
+
570
+ /** @type {Composition<?>} */
571
+ #composition;
572
+
573
+ /** @type {Map<string,null|[string,any]>} */
574
+ _propAttributeCache;
575
+
576
+ /** @type {import('./ICustomElement.js').CallbackArguments} */
577
+ _callbackArguments = null;
578
+
579
+ /** @param {any[]} args */
580
+ constructor(...args) {
581
+ super();
582
+
583
+ if (CustomElement.supportsElementInternals) {
584
+ this.elementInternals = this.attachInternals();
585
+ }
586
+
587
+ this.attachShadow({ mode: 'open', delegatesFocus: this.delegatesFocus });
588
+
589
+ this.composition.initialRender(this.shadowRoot, this);
590
+
591
+ for (const callback of this.static._onConstructedCallbacks) {
592
+ callback.call(this, this.callbackArguments);
593
+ }
594
+ }
595
+
596
+ /**
597
+ * Updates nodes based on data
598
+ * Expects data in JSON Merge Patch format
599
+ * @see https://www.rfc-editor.org/rfc/rfc7386
600
+ * @param {?} data
601
+ * @param {?} [store]
602
+ * @return {void}
603
+ */
604
+ render(data, store) {
605
+ // console.log('render', data);
606
+ this.composition.render(this.shadowRoot, data, this, store ? { ...this, store } : this);
607
+ }
608
+
609
+ /** @type {InstanceType<typeof ICustomElement>['propChangedCallback']} */
610
+ propChangedCallback(name, oldValue, newValue, changes = newValue) {
611
+ const callbacks = this.static.propChangedCallbacks.get(name);
612
+ if (callbacks) {
613
+ for (const callback of callbacks) {
614
+ callback.call(this, oldValue, newValue, changes, this);
615
+ }
616
+ }
617
+
618
+ this.render({ [name]: changes });
619
+ }
620
+
621
+ /**
622
+ * @param {string} name
623
+ * @param {string|null} oldValue
624
+ * @param {string|null} newValue
625
+ */
626
+ attributeChangedCallback(name, oldValue, newValue) {
627
+ const callbacks = this.static.attributeChangedCallbacks.get(name);
628
+ if (callbacks) {
629
+ for (const callback of callbacks) {
630
+ callback.call(this, oldValue, newValue, this);
631
+ }
632
+ }
633
+
634
+ // Array.find
635
+ for (const config of this.static.propList.values()) {
636
+ if (config.attr !== name) continue;
637
+
638
+ if (config.reflect !== true && config.reflect !== 'read') return;
639
+
640
+ if (config.attributeChangedCallback) {
641
+ config.attributeChangedCallback.call(this, name, oldValue, newValue);
642
+ return;
643
+ }
644
+
645
+ const [stringValue] = this.attributeCache.get(name) ?? [null, null];
646
+ if (stringValue === newValue) {
647
+ // Attribute was changed via data change event. Ignore.
648
+ return;
649
+ }
650
+
651
+ // @ts-expect-error any
652
+ const previousDataValue = this[config.key];
653
+ const parsedValue = newValue === null
654
+ ? config.nullParser(/** @type {null} */ (newValue))
655
+ // Avoid Boolean('') === false
656
+ : (config.type === 'boolean' ? true : config.parser(newValue));
657
+
658
+ if (parsedValue === previousDataValue) {
659
+ // No internal value change
660
+ return;
661
+ }
662
+ // "Remember" that this attrValue equates to this data value
663
+ // Avoids rewriting attribute later on data change event
664
+ this.attributeCache.set(name, [newValue, parsedValue]);
665
+ // @ts-expect-error any
666
+ this[config.key] = parsedValue;
667
+ return;
668
+ }
669
+ }
670
+
671
+ get #template() {
672
+ return this.#composition?.template;
673
+ }
674
+
675
+ /**
676
+ * @param {string} name
677
+ * @param {any} oldValue
678
+ * @param {any} newValue
679
+ * @param {any} changes
680
+ */
681
+ _onObserverPropertyChanged(name, oldValue, newValue, changes) {
682
+ const { reflect, attr } = this.static.propList.get(name);
683
+ if (attr && (reflect === true || reflect === 'write')) {
684
+ const [, dataValue] = this.attributeCache.get(attr) ?? [null, null];
685
+ // Don't change attribute if data value is equivalent
686
+ // (eg: Boolean('foo') === true; Number("1.0") === 1)
687
+ if (dataValue !== newValue) {
688
+ const attrValue = attrValueFromDataValue(newValue);
689
+ // Cache attrValue to ignore attributeChangedCallback later
690
+ this.attributeCache.set(attr, [attrValue, newValue]);
691
+ if (attrValue == null) {
692
+ this.removeAttribute(attr);
693
+ } else {
694
+ this.setAttribute(attr, attrValue);
695
+ }
696
+ }
697
+ }
698
+
699
+ // Invoke change => render
700
+ this.propChangedCallback(name, oldValue, newValue, changes);
701
+ }
702
+
703
+ /**
704
+ * Proxy object that returns shadow DOM elements by ID.
705
+ * If called before interpolation (eg: on composed), returns from template
706
+ * @return {Record<string,HTMLElement>}
707
+ */
708
+ get refs() {
709
+ // eslint-disable-next-line no-return-assign
710
+ return (this.#refsProxy ??= new Proxy({}, {
711
+ /**
712
+ * @param {any} target
713
+ * @param {string} id
714
+ * @return {Element}
715
+ */
716
+ get: (target, id) => {
717
+ if (!this.#composition) {
718
+ console.warn(this.static.name, 'Attempted to access references before composing!');
719
+ }
720
+ const composition = this.composition;
721
+ if (!composition.interpolated) {
722
+ let element = this.#refsCompositionCache.get(id)?.deref();
723
+ if (element) return element;
724
+ const formattedId = attrNameFromPropName(id);
725
+ // console.warn(this.tagName, 'Returning template reference');
726
+ element = composition.template.getElementById(formattedId);
727
+ if (!element) return null;
728
+ this.#refsCompositionCache.set(id, new WeakRef(element));
729
+ return element;
730
+ }
731
+ let element = this.#refsCache.get(id)?.deref();
732
+ if (element) {
733
+ return element;
734
+ }
735
+ const formattedId = attrNameFromPropName(id);
736
+ element = composition.getElement(this.shadowRoot, formattedId);
737
+ if (!element) return null;
738
+ this.#refsCache.set(id, new WeakRef(element));
739
+ return element;
740
+ },
741
+ }));
742
+ }
743
+
744
+ get attributeCache() {
745
+ this._propAttributeCache ??= new Map();
746
+ return this._propAttributeCache;
747
+ }
748
+
749
+ get tabIndex() {
750
+ return super.tabIndex;
751
+ }
752
+
753
+ set tabIndex(value) {
754
+ if (value === super.tabIndex && value !== -1) {
755
+ // Non -1 value already set
756
+ return;
757
+ }
758
+
759
+ if (this.delegatesFocus && document.activeElement === this) {
760
+ if (this.getAttribute('tabindex') === value.toString()) {
761
+ // Skip if possible
762
+ return;
763
+ }
764
+
765
+ // Chrome blurs on tabindex changes with delegatesFocus
766
+ // Fixed in Chrome 111
767
+ // Remove this code ~June 2023
768
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=1346606
769
+ /** @type {EventListener} */
770
+ const listener = (e) => {
771
+ e.stopImmediatePropagation();
772
+ e.stopPropagation();
773
+ if (e.type === 'blur') {
774
+ console.warn('Chromium bug 1346606: Tabindex change caused blur. Giving focusing back.', this);
775
+ this.focus();
776
+ } else {
777
+ console.warn('Chromium bug 1346606: Blocking focus event.', this);
778
+ }
779
+ };
780
+ this.addEventListener('blur', listener, { capture: true, once: true });
781
+ this.addEventListener('focus', listener, { capture: true, once: true });
782
+ super.tabIndex = value;
783
+ this.removeEventListener('blur', listener, { capture: true });
784
+ this.removeEventListener('focus', listener, { capture: true });
785
+ return;
786
+ }
787
+
788
+ super.tabIndex = value;
789
+ }
790
+
791
+ get static() { return /** @type {typeof CustomElement} */ (/** @type {unknown} */ (this.constructor)); }
792
+
793
+ get unique() { return false; }
794
+
795
+ get callbackArguments() {
796
+ // eslint-disable-next-line no-return-assign
797
+ return this._callbackArguments ??= {
798
+ composition: this.#composition,
799
+ html: html.bind(this),
800
+ inline: addInlineFunction,
801
+ template: this.#template,
802
+ element: this,
803
+ };
804
+ }
805
+
806
+ /** @return {Composition<?>} */
807
+ get composition() {
808
+ if (this.#composition) return this.#composition;
809
+
810
+ if (!this.unique && this.static.hasOwnProperty('_composition')) {
811
+ this.#composition = this.static._composition;
812
+ return this.static._composition;
813
+ }
814
+
815
+ // TODO: Use Composition to track uniqueness
816
+ // console.log('composing', this.static.elementName);
817
+ this.compose();
818
+ for (const callback of this.static._onComposeCallbacks) {
819
+ // console.log(this.static.elementName, 'composition callback');
820
+ callback.call(this, this.callbackArguments);
821
+ }
822
+
823
+ if (!this.unique) {
824
+ // Cache compilation into static property
825
+ this.static._composition = this.#composition;
826
+ }
827
+
828
+ return this.#composition;
829
+ }
830
+
831
+ connectedCallback() {
832
+ for (const callbacks of this.static._onConnectedCallbacks) {
833
+ callbacks.call(this, this.callbackArguments);
834
+ }
835
+ }
836
+
837
+ disconnectedCallback() {
838
+ for (const callbacks of this.static._onDisconnectedCallbacks) {
839
+ callbacks.call(this, this.callbackArguments);
840
+ }
841
+ }
842
+ }
843
+
844
+ CustomElement.prototype.delegatesFocus = false;