@shortfuse/materialdesignweb 0.5.0 → 0.7.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 (418) hide show
  1. package/README.md +155 -77
  2. package/bin/generate-css.js +12 -0
  3. package/components/Badge.css +30 -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 +146 -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 +77 -0
  17. package/components/Checkbox.js +59 -0
  18. package/components/CheckboxIcon.css +89 -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 +151 -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 +74 -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 +83 -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 +306 -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 +63 -0
  101. package/components/Switch.js +127 -0
  102. package/components/SwitchIcon.css +177 -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/mixins/AriaReflectorMixin.js +42 -0
  132. package/mixins/AriaToolbarMixin.js +13 -0
  133. package/mixins/ControlMixin.css +57 -0
  134. package/mixins/ControlMixin.js +212 -0
  135. package/mixins/DensityMixin.css +40 -0
  136. package/mixins/DensityMixin.js +11 -0
  137. package/mixins/FlexableMixin.css +79 -0
  138. package/mixins/FlexableMixin.js +32 -0
  139. package/mixins/FormAssociatedMixin.js +170 -0
  140. package/mixins/InputMixin.js +335 -0
  141. package/mixins/KeyboardNavMixin.js +244 -0
  142. package/mixins/RTLObserverMixin.js +35 -0
  143. package/mixins/ResizeObserverMixin.js +38 -0
  144. package/mixins/RippleMixin.css +12 -0
  145. package/mixins/RippleMixin.js +115 -0
  146. package/mixins/ScrollListenerMixin.js +100 -0
  147. package/mixins/ShapeMixin.css +135 -0
  148. package/mixins/ShapeMixin.js +31 -0
  149. package/mixins/StateMixin.css +82 -0
  150. package/mixins/StateMixin.js +114 -0
  151. package/mixins/SurfaceMixin.css +150 -0
  152. package/mixins/SurfaceMixin.js +32 -0
  153. package/mixins/TextFieldMixin.css +657 -0
  154. package/mixins/TextFieldMixin.js +121 -0
  155. package/mixins/ThemableMixin.css +204 -0
  156. package/mixins/ThemableMixin.js +16 -0
  157. package/mixins/TooltipTriggerMixin.css +27 -0
  158. package/mixins/TooltipTriggerMixin.js +366 -0
  159. package/mixins/TouchTargetMixin.css +26 -0
  160. package/mixins/TouchTargetMixin.js +9 -0
  161. package/package.json +54 -49
  162. package/theming/index.js +594 -0
  163. package/theming/loader.js +24 -0
  164. package/utils/cli.js +11 -0
  165. package/utils/color_keywords.js +151 -0
  166. package/utils/hct/Cam16.js +298 -0
  167. package/utils/hct/CorePalette.js +84 -0
  168. package/utils/hct/Hct.js +172 -0
  169. package/utils/hct/Scheme.js +587 -0
  170. package/utils/hct/TonalPalette.js +68 -0
  171. package/utils/hct/ViewingConditions.js +136 -0
  172. package/utils/hct/blend.js +93 -0
  173. package/utils/hct/colorUtils.js +302 -0
  174. package/utils/hct/hctSolver.js +559 -0
  175. package/utils/hct/helper.js +182 -0
  176. package/utils/hct/mathUtils.js +153 -0
  177. package/utils/jsonMergePatch.js +100 -0
  178. package/utils/jsx-runtime.js +101 -0
  179. package/utils/popup.js +117 -0
  180. package/utils/svg.js +129 -0
  181. package/.browserslistrc +0 -4
  182. package/.eslintrc.json +0 -204
  183. package/.stylelintrc.json +0 -645
  184. package/.vscode/launch.json +0 -31
  185. package/.vscode/settings.json +0 -3
  186. package/.vscode/tasks.json +0 -32
  187. package/CHANGELOG.md +0 -36
  188. package/CODE_OF_CONDUCT.md +0 -46
  189. package/adapters/datatable/column.js +0 -176
  190. package/adapters/datatable/index.js +0 -960
  191. package/adapters/dom/index.js +0 -586
  192. package/adapters/list/index.js +0 -69
  193. package/adapters/search/index.js +0 -495
  194. package/components/appbar/_spec.scss +0 -165
  195. package/components/appbar/_theme.scss +0 -0
  196. package/components/appbar/index.scss +0 -2
  197. package/components/banner/_spec.scss +0 -83
  198. package/components/banner/_theme.scss +0 -0
  199. package/components/banner/index.scss +0 -2
  200. package/components/bottomnav/README.md +0 -85
  201. package/components/bottomnav/_spec.scss +0 -149
  202. package/components/bottomnav/_theme.scss +0 -0
  203. package/components/bottomnav/index.js +0 -117
  204. package/components/bottomnav/index.scss +0 -2
  205. package/components/bottomnav/item.js +0 -88
  206. package/components/button/README.md +0 -61
  207. package/components/button/_spec.scss +0 -162
  208. package/components/button/_theme.scss +0 -42
  209. package/components/button/index.eta +0 -32
  210. package/components/button/index.js +0 -43
  211. package/components/button/index.pug +0 -18
  212. package/components/button/index.scss +0 -2
  213. package/components/card/_spec.scss +0 -241
  214. package/components/card/_theme.scss +0 -0
  215. package/components/card/index.scss +0 -2
  216. package/components/chip/_spec.scss +0 -111
  217. package/components/chip/_theme.scss +0 -105
  218. package/components/chip/index.js +0 -23
  219. package/components/chip/index.scss +0 -2
  220. package/components/chip/item.js +0 -20
  221. package/components/datatable/_spec.scss +0 -225
  222. package/components/datatable/_theme.scss +0 -128
  223. package/components/datatable/cell.js +0 -44
  224. package/components/datatable/columnheader.js +0 -46
  225. package/components/datatable/index.js +0 -374
  226. package/components/datatable/index.scss +0 -2
  227. package/components/datatable/row.js +0 -48
  228. package/components/datatable/rowheader.js +0 -18
  229. package/components/dialog/_spec.scss +0 -203
  230. package/components/dialog/_theme.scss +0 -7
  231. package/components/dialog/index.js +0 -601
  232. package/components/dialog/index.scss +0 -2
  233. package/components/divider/_spec.scss +0 -11
  234. package/components/divider/_theme.scss +0 -0
  235. package/components/divider/index.scss +0 -2
  236. package/components/elevation/_spec.scss +0 -9
  237. package/components/elevation/_theme.scss +0 -0
  238. package/components/elevation/index.scss +0 -2
  239. package/components/fab/_spec.scss +0 -210
  240. package/components/fab/_theme.scss +0 -0
  241. package/components/fab/index.js +0 -99
  242. package/components/fab/index.scss +0 -2
  243. package/components/grid/_spec.scss +0 -169
  244. package/components/grid/_theme.scss +0 -0
  245. package/components/grid/index.scss +0 -2
  246. package/components/layout/_mixins.scss +0 -11
  247. package/components/layout/_spec.scss +0 -916
  248. package/components/layout/_theme.scss +0 -19
  249. package/components/layout/index.js +0 -454
  250. package/components/layout/index.scss +0 -2
  251. package/components/list/_spec.scss +0 -363
  252. package/components/list/_theme.scss +0 -102
  253. package/components/list/content.js +0 -106
  254. package/components/list/index.js +0 -256
  255. package/components/list/index.scss +0 -2
  256. package/components/list/item.js +0 -167
  257. package/components/list/secondary.js +0 -45
  258. package/components/menu/_spec.scss +0 -329
  259. package/components/menu/_theme.scss +0 -0
  260. package/components/menu/index.js +0 -705
  261. package/components/menu/index.scss +0 -2
  262. package/components/menu/item.js +0 -231
  263. package/components/progress/_spec.scss +0 -156
  264. package/components/progress/_theme.scss +0 -0
  265. package/components/progress/index.js +0 -36
  266. package/components/progress/index.scss +0 -2
  267. package/components/selection/_spec.scss +0 -376
  268. package/components/selection/_theme.scss +0 -134
  269. package/components/selection/index.eta +0 -60
  270. package/components/selection/index.js +0 -70
  271. package/components/selection/index.pug +0 -30
  272. package/components/selection/index.scss +0 -2
  273. package/components/selection/input.js +0 -54
  274. package/components/selection/radiogroup.js +0 -40
  275. package/components/slider/_spec.scss +0 -59
  276. package/components/slider/_theme.scss +0 -0
  277. package/components/slider/index.scss +0 -2
  278. package/components/snackbar/_spec.scss +0 -150
  279. package/components/snackbar/_theme.scss +0 -0
  280. package/components/snackbar/index.js +0 -338
  281. package/components/snackbar/index.scss +0 -2
  282. package/components/tab/_spec.scss +0 -220
  283. package/components/tab/_theme.scss +0 -0
  284. package/components/tab/content.js +0 -210
  285. package/components/tab/index.js +0 -257
  286. package/components/tab/index.scss +0 -2
  287. package/components/tab/item.js +0 -88
  288. package/components/tab/list.js +0 -196
  289. package/components/tab/panel.js +0 -54
  290. package/components/textfield/README.md +0 -179
  291. package/components/textfield/_spec.scss +0 -763
  292. package/components/textfield/_theme.scss +0 -264
  293. package/components/textfield/index.eta +0 -74
  294. package/components/textfield/index.js +0 -160
  295. package/components/textfield/index.pug +0 -30
  296. package/components/textfield/index.scss +0 -2
  297. package/components/tooltip/_spec.scss +0 -185
  298. package/components/tooltip/_theme.scss +0 -0
  299. package/components/tooltip/index.scss +0 -2
  300. package/components/type/_spec.scss +0 -227
  301. package/components/type/_theme.scss +0 -0
  302. package/components/type/index.scss +0 -2
  303. package/core/_breakpoint.scss +0 -189
  304. package/core/_elevation.scss +0 -78
  305. package/core/_length.scss +0 -8
  306. package/core/_motion.scss +0 -31
  307. package/core/_platform.scss +0 -12
  308. package/core/_type.scss +0 -128
  309. package/core/aria/attributes.js +0 -141
  310. package/core/aria/button.js +0 -49
  311. package/core/aria/keyboard.js +0 -92
  312. package/core/aria/rovingtabindex.js +0 -175
  313. package/core/aria/tab.js +0 -59
  314. package/core/document/index.js +0 -39
  315. package/core/overlay/_spec.scss +0 -28
  316. package/core/overlay/_theme.scss +0 -147
  317. package/core/overlay/index.js +0 -95
  318. package/core/overlay/index.scss +0 -2
  319. package/core/ripple/_spec.scss +0 -196
  320. package/core/ripple/_theme.scss +0 -20
  321. package/core/ripple/index.js +0 -286
  322. package/core/ripple/index.scss +0 -2
  323. package/core/theme/_aliases.scss +0 -15
  324. package/core/theme/_config.scss +0 -8
  325. package/core/theme/_functions.scss +0 -22
  326. package/core/theme/_palettes.scss +0 -405
  327. package/core/theme/_spec.scss +0 -0
  328. package/core/theme/_theme.scss +0 -268
  329. package/core/theme/index.js +0 -50
  330. package/core/theme/index.scss +0 -4
  331. package/core/throttler.js +0 -42
  332. package/core/transition/index.js +0 -465
  333. package/docs/_flex.scss +0 -28
  334. package/docs/_menuoptions.js +0 -183
  335. package/docs/_partials/_androidnavbar.eta +0 -5
  336. package/docs/_partials/_androidstatusbar.eta +0 -13
  337. package/docs/_partials/_appbar.eta +0 -27
  338. package/docs/_partials/_buttontest.eta +0 -31
  339. package/docs/_partials/_header.eta +0 -146
  340. package/docs/_partials/_navlistitem.eta +0 -16
  341. package/docs/_partials/_target.eta +0 -1
  342. package/docs/_sample-utils.js +0 -88
  343. package/docs/_storage.js +0 -33
  344. package/docs/docs.scss +0 -331
  345. package/docs/framework.scss +0 -26
  346. package/docs/index.eta +0 -12
  347. package/docs/index.js +0 -7
  348. package/docs/pages/appbar.eta +0 -108
  349. package/docs/pages/appbar.js +0 -0
  350. package/docs/pages/bottomnav.eta +0 -188
  351. package/docs/pages/bottomnav.js +0 -118
  352. package/docs/pages/button.eta +0 -124
  353. package/docs/pages/button.js +0 -224
  354. package/docs/pages/card.eta +0 -90
  355. package/docs/pages/card.js +0 -175
  356. package/docs/pages/chip.eta +0 -122
  357. package/docs/pages/chip.js +0 -80
  358. package/docs/pages/color.eta +0 -143
  359. package/docs/pages/color.js +0 -261
  360. package/docs/pages/datatable.eta +0 -323
  361. package/docs/pages/datatable.js +0 -160
  362. package/docs/pages/dialog.eta +0 -184
  363. package/docs/pages/dialog.js +0 -174
  364. package/docs/pages/dom.eta +0 -26
  365. package/docs/pages/dom.js +0 -140
  366. package/docs/pages/elevation.eta +0 -35
  367. package/docs/pages/elevation.js +0 -0
  368. package/docs/pages/fab.eta +0 -99
  369. package/docs/pages/fab.js +0 -43
  370. package/docs/pages/grid.eta +0 -135
  371. package/docs/pages/grid.js +0 -128
  372. package/docs/pages/layout.eta +0 -8
  373. package/docs/pages/layout.js +0 -0
  374. package/docs/pages/list.eta +0 -465
  375. package/docs/pages/list.js +0 -8
  376. package/docs/pages/menu.eta +0 -274
  377. package/docs/pages/menu.js +0 -213
  378. package/docs/pages/overlay.eta +0 -69
  379. package/docs/pages/overlay.js +0 -3
  380. package/docs/pages/progress.eta +0 -23
  381. package/docs/pages/progress.js +0 -12
  382. package/docs/pages/ripple.eta +0 -27
  383. package/docs/pages/ripple.js +0 -3
  384. package/docs/pages/search.eta +0 -242
  385. package/docs/pages/search.js +0 -226
  386. package/docs/pages/selection.eta +0 -107
  387. package/docs/pages/selection.js +0 -12
  388. package/docs/pages/slider.eta +0 -23
  389. package/docs/pages/slider.js +0 -0
  390. package/docs/pages/snackbar.eta +0 -83
  391. package/docs/pages/snackbar.js +0 -157
  392. package/docs/pages/tab.eta +0 -407
  393. package/docs/pages/tab.js +0 -152
  394. package/docs/pages/textfield.eta +0 -487
  395. package/docs/pages/textfield.js +0 -257
  396. package/docs/pages/tooltip.eta +0 -92
  397. package/docs/pages/tooltip.js +0 -0
  398. package/docs/pages/transition.eta +0 -117
  399. package/docs/pages/transition.js +0 -52
  400. package/docs/pages/type.eta +0 -31
  401. package/docs/pages/type.js +0 -0
  402. package/docs/postrender.js +0 -41
  403. package/docs/prerender.js +0 -16
  404. package/docs/pwa/_dialogs.eta +0 -143
  405. package/docs/pwa/_menus.eta +0 -16
  406. package/docs/pwa/pwa-prerender.js +0 -3
  407. package/docs/pwa/pwa.eta +0 -478
  408. package/docs/pwa/pwa.js +0 -298
  409. package/docs/pwa/pwa.scss +0 -31
  410. package/docs/themes/theme-colored.scss +0 -15
  411. package/docs/themes/theme-default.scss +0 -3
  412. package/index.scss +0 -27
  413. package/jsconfig.json +0 -16
  414. package/scripts/deploy-docs.sh +0 -9
  415. package/templates/index.eta +0 -2
  416. package/templates/index.pug +0 -3
  417. package/tsconfig.json +0 -16
  418. package/webpack.config.js +0 -304
@@ -0,0 +1,121 @@
1
+ import { generateUID } from './identify.js';
2
+
3
+ /**
4
+ * Property are bound to an ID+Node
5
+ * Values are either getter or via an function
6
+ * @template {any} T
7
+ * @typedef {Object} InlineFunctionEntry
8
+ * @prop {(data:T) => any} fn
9
+ * @prop {Set<keyof T & string>} [props]
10
+ * @prop {T} [defaultValue]
11
+ */
12
+
13
+ /** @type {Document} */
14
+ let _inactiveDocument;
15
+
16
+ /** @type {boolean} */
17
+ let _cssStyleSheetConstructable;
18
+
19
+ /**
20
+ * @param {string} [fromString]
21
+ * @return {DocumentFragment}
22
+ */
23
+ export function generateFragment(fromString) {
24
+ _inactiveDocument ??= document.implementation.createHTMLDocument();
25
+ if (fromString == null) {
26
+ return _inactiveDocument.createDocumentFragment();
27
+ }
28
+ return _inactiveDocument.createRange().createContextualFragment(fromString);
29
+ }
30
+
31
+ /** @type {Map<string, InlineFunctionEntry<?>>} */
32
+ export const inlineFunctions = new Map();
33
+
34
+ /**
35
+ * @template T
36
+ * @typedef {Object} RenderOptions
37
+ * @prop {Object} context
38
+ * @prop {ParentNode} root
39
+ * @prop {Object<string, HTMLElement>} refs
40
+ */
41
+
42
+ /**
43
+ * @param {(data: Partial<any>) => any} fn
44
+ * @return {string}
45
+ */
46
+ export function addInlineFunction(fn) {
47
+ const internalName = `#${generateUID()}`;
48
+ inlineFunctions.set(internalName, { fn });
49
+ return `{${internalName}}`;
50
+ }
51
+
52
+ /**
53
+ * @param {TemplateStringsArray} array
54
+ * @param {...(string)} substitutions
55
+ * @return {HTMLStyleElement|CSSStyleSheet}
56
+ */
57
+ export function css(array, ...substitutions) {
58
+ const content = String.raw({ raw: array }, ...substitutions);
59
+ if (_cssStyleSheetConstructable == null) {
60
+ try {
61
+ const sheet = new CSSStyleSheet();
62
+ _cssStyleSheetConstructable = true;
63
+ sheet.replaceSync(content);
64
+ return sheet;
65
+ } catch {
66
+ _cssStyleSheetConstructable = false;
67
+ }
68
+ }
69
+ if (_cssStyleSheetConstructable) {
70
+ const sheet = new CSSStyleSheet();
71
+ _cssStyleSheetConstructable = true;
72
+ sheet.replaceSync(content);
73
+ return sheet;
74
+ }
75
+
76
+ _inactiveDocument ??= document.implementation.createHTMLDocument();
77
+ const style = _inactiveDocument.createElement('style');
78
+ style.textContent = content;
79
+ return style;
80
+ }
81
+
82
+ /**
83
+ * @template T1
84
+ * @template T2
85
+ * @param {TemplateStringsArray} strings
86
+ * @param {...(string|DocumentFragment|Element|((this:T1, data:T2) => any))} substitutions
87
+ * @return {DocumentFragment}
88
+ */
89
+ export function html(strings, ...substitutions) {
90
+ /** @type {Map<string, DocumentFragment|Element>} */
91
+ let tempSlots;
92
+ const replacements = substitutions.map((sub) => {
93
+ switch (typeof sub) {
94
+ case 'string': return sub;
95
+ case 'function': return addInlineFunction(sub);
96
+ case 'object': {
97
+ if (sub == null) {
98
+ console.warn(sub, 'is null', strings);
99
+ return '';
100
+ }
101
+ // Assume Element
102
+ const tempId = generateUID();
103
+ tempSlots ??= new Map();
104
+ tempSlots.set(tempId, sub);
105
+ return `<div id="${tempId}"></div>`;
106
+ }
107
+ default:
108
+ throw new Error(`Unexpected substitution: ${sub}`);
109
+ }
110
+ });
111
+ const compiledString = String.raw({ raw: strings }, ...replacements);
112
+ const fragment = generateFragment(compiledString);
113
+ if (tempSlots) {
114
+ for (const [id, element] of tempSlots) {
115
+ const slot = fragment.getElementById(id);
116
+ slot.replaceWith(element);
117
+ }
118
+ }
119
+
120
+ return fragment;
121
+ }
@@ -0,0 +1,135 @@
1
+ type ObserverPropertyType = 'string' | 'boolean' | 'map' | 'set' | 'float' | 'integer' | 'object' | 'function';
2
+
3
+ type InlineTemplate<T1, T2=T1> = (fn: (this:T1, data: T2) => any) => string;
4
+
5
+ type HTMLTemplater<T1, T2=T1> = ((
6
+ string: TemplateStringsArray, ...substitutions: (string|DocumentFragment|Element|((this:T1, data:T2) => any))[]
7
+ ) => DocumentFragment);
8
+
9
+ type ParsedObserverPropertyType<T extends ObserverPropertyType> =
10
+ T extends 'boolean' ? boolean
11
+ : T extends 'string' ? string
12
+ : T extends 'float' | 'integer' ? number
13
+ : T extends 'object' ? any
14
+ : T extends 'function' ? (...args:any) => any
15
+ : unknown;
16
+
17
+ type ObserverOptions<
18
+ T1 extends ObserverPropertyType,
19
+ T2 = any,
20
+ C extends object = any
21
+ > = {
22
+ type?: T1;
23
+ attr?: string;
24
+
25
+ /** Default true */
26
+ readonly?: boolean
27
+ enumerable?: boolean;
28
+
29
+ /** Defaults to false if type is boolean */
30
+ nullable?: boolean;
31
+
32
+ /** Empty value when not nullable */
33
+ empty?: T2;
34
+ /** Initial value (empty value if not specified) */
35
+ value?: T2;
36
+ values?: WeakMap<C, T2>;
37
+ reflect?: boolean | 'write' | 'read';
38
+ /** Function used when null passed */
39
+ changedCallback?: (this:C, oldValue:T2, newValue:T2, changes:any)=>any;
40
+ nullParser?: (this:C, value:null|undefined)=>T2;
41
+ parser?: (this:C, value:any)=>T2;
42
+ /** Function used when comparing */
43
+ diff?: (this:C, a:T2, b:T2)=> any,
44
+ is?: (this:C, a:T2, b:T2)=>boolean
45
+ get?: (this:C, data:Partial<C>, fn?: () => T2) => T2
46
+ set?: (this:C, value: T2, fn?:(value2: T2) => any) => any,
47
+ attributeChangedCallback?: (this:C, name:string, oldValue: string, newValue: string) => any;
48
+ propChangedCallback?: (this:C, name:string, oldValue: T2, newValue: T2, changes:any) => any;
49
+ validValues?: WeakMap<C, T2>;
50
+ watchers?: [keyof C, (this:C, ...args:any[]) => any][];
51
+ }
52
+
53
+ type ObserverConfiguration<
54
+ T1 extends ObserverPropertyType,
55
+ T2 = any,
56
+ K = string,
57
+ C extends object = any> = ObserverOptions<T1, T2, C> & {
58
+ key: K,
59
+ values?: WeakMap<C, T2>;
60
+ attrValues?: WeakMap<C, string>;
61
+ };
62
+
63
+ type ParsedProps<T> = {
64
+ [P in keyof T]:
65
+ T[P] extends (...args:any[]) => infer T2 ? T2
66
+ : T[P] extends ObserverPropertyType
67
+ ? ParsedObserverPropertyType<T[P]>
68
+ : T[P] extends {type: ObserverPropertyType}
69
+ ? ParsedObserverPropertyType<T[P]['type']>
70
+ : T[P] extends ObserverOptions<null, infer T2>
71
+ ? unknown extends T2 ? string : T2
72
+ : never
73
+ };
74
+
75
+ type HTMLElementCancellableEventMap = Pick<HTMLElementEventMap,
76
+ 'auxclick' |
77
+ 'beforeinput' |
78
+ // 'cancel' |
79
+ 'click' |
80
+ 'compositionstart' |
81
+ 'contextmenu' |
82
+ 'drag' |
83
+ 'dragenter' |
84
+ 'dragover' |
85
+ 'dragstart' |
86
+ 'drop' |
87
+ 'invalid' |
88
+ 'keydown' |
89
+ 'keypress' |
90
+ 'keyup' |
91
+ 'mousedown' |
92
+ 'mousemove' |
93
+ 'mouseout' |
94
+ 'mouseover' |
95
+ 'mouseup' |
96
+ 'pointerdown' |
97
+ 'pointermove' |
98
+ 'pointerout' |
99
+ 'pointerover' |
100
+ 'pointerup' |
101
+ 'reset' |
102
+ 'selectstart' |
103
+ 'submit' |
104
+ 'touchend' |
105
+ 'touchmove' |
106
+ 'touchstart' |
107
+ 'wheel'
108
+ >
109
+
110
+ type CompositionEventMap = HTMLElementEventMap & {
111
+ [P in keyof HTMLElementCancellableEventMap as `~${P}`]: Omit<HTMLElementCancellableEventMap[P], 'preventDefault'>
112
+ };
113
+
114
+ type CompositionEventListener<T, K = keyof CompositionEventMap> = {
115
+ type?: K
116
+ id?: string,
117
+ capture?: boolean;
118
+ once?: boolean;
119
+ passive?: boolean;
120
+ signal?: AbortSignal;
121
+ handleEvent?: (
122
+ this: T,
123
+ event: (K extends keyof CompositionEventMap ? CompositionEventMap[K] : Event) & {currentTarget:HTMLElement}
124
+ ) => any;
125
+ prop?: keyof T & string;
126
+ };
127
+
128
+ type CompositionEventListenerObject<T> =
129
+ {
130
+ [P in keyof CompositionEventMap]?: (keyof T & string)
131
+ | ((this: T, event: CompositionEventMap[P] & {currentTarget:HTMLElement}) => any)
132
+ | CompositionEventListener<T, P>
133
+ };
134
+
135
+ export type dummyObject = {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { attrNameFromPropName } from '../core/dom.js';
2
+
3
+ /** @param {typeof import('../core/CustomElement.js').default} Base */
4
+ export default function AriaReflectorMixin(Base) {
5
+ return Base
6
+ .extend()
7
+ .observe({
8
+ _ariaRole: 'string',
9
+ }).methods({
10
+ /**
11
+ * @param {keyof HTMLElement & keyof ElementInternals} name
12
+ * @param {string} value
13
+ */
14
+ updateAriaProperty(name, value) {
15
+ if (this.elementInternals && name in this.elementInternals) {
16
+ this.elementInternals[name] = value;
17
+ } else if (name in this) {
18
+ this[name] = value;
19
+ } else {
20
+ console.warn('Unknown ARIA property', name);
21
+ /** @type {string} */
22
+ let attrName = name;
23
+ if (attrName.startsWith('aria')) {
24
+ attrName = `aria-${attrName.slice(4).toLowerCase()}`;
25
+ }
26
+ if (value == null) {
27
+ this.removeAttribute(name);
28
+ } else {
29
+ this.setAttribute(attrName, value);
30
+ }
31
+ }
32
+ },
33
+ })
34
+ .on({
35
+ _ariaRoleChanged(oldValue, newValue) {
36
+ this.updateAriaProperty('role', newValue);
37
+ },
38
+ constructed() {
39
+ this.updateAriaProperty('role', this._ariaRole);
40
+ },
41
+ });
42
+ }
@@ -0,0 +1,13 @@
1
+ import KbdNavWidgetMixin from './KeyboardNavMixin.js';
2
+
3
+ /**
4
+ * @param {typeof import('../core/CustomElement.js').default} Base
5
+ */
6
+ export default function AriaToolbarMixin(Base) {
7
+ return Base
8
+ .mixin(KbdNavWidgetMixin)
9
+ .extend()
10
+ .set({
11
+ ariaOrientationDefault: 'horizontal',
12
+ });
13
+ }
@@ -0,0 +1,57 @@
1
+ :host {
2
+ display: inline-flex;
3
+ }
4
+
5
+ /* Remove Firefox inner */
6
+ :host(::-moz-focus-inner) {
7
+ border: 0;
8
+ }
9
+
10
+ #label {
11
+ display: contents;
12
+
13
+ pointer-events: none;
14
+ }
15
+
16
+ #control {
17
+ /* Control is the touch target */
18
+ /* Firefox requires at least 1px "visible" for screen reading */
19
+ /* Safari will not allow interaction with 0 opacity */
20
+ /* Chrome will not focus with visibility:hidden */
21
+
22
+ position: absolute;
23
+ inset: 50%;
24
+ /* --mdw-device-pixel-ratio: 1; */
25
+
26
+ block-size: 100%;
27
+ min-block-size: 48px;
28
+ inline-size:100%;
29
+ min-inline-size: 48px;
30
+ margin: 0;
31
+ border: 0;
32
+ padding: 0;
33
+
34
+ -webkit-appearance: none;
35
+ -moz-appearance: none;
36
+ appearance: none;
37
+
38
+ cursor: auto;
39
+ outline: none;
40
+
41
+ pointer-events: auto;
42
+
43
+ transform: translateX(-50%) translateY(-50%);
44
+
45
+ /* Safari and Chrome will emit two click events if not at top of stack */
46
+ /* Allows up to 3 other layers (eg: ripple, outline) */
47
+ z-index: 4;
48
+
49
+ background-color: transparent;
50
+
51
+ border-radius: 0;
52
+ color: transparent;
53
+ }
54
+
55
+ #control::-moz-focus-inner {
56
+ border: 0;
57
+ }
@@ -0,0 +1,212 @@
1
+ /* https://html.spec.whatwg.org/multipage/form-control-infrastructure.html */
2
+
3
+ import styles from './ControlMixin.css' assert { type: 'css' };
4
+ import FormAssociatedMixin from './FormAssociatedMixin.js';
5
+
6
+ /** @typedef {import('../core/CustomElement.js').default} CustomElement */
7
+
8
+ /** @typedef {'align'|'useMap'} DeprecatedHTMLInputElementProperties */
9
+
10
+ /** @typedef {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement} HTMLControlElement */
11
+
12
+ /**
13
+ * @param {ReturnType<import('./StateMixin.js').default>} Base
14
+ */
15
+ export default function ControlMixin(Base) {
16
+ class Control extends Base.mixin(FormAssociatedMixin) {
17
+ /** @return {Iterable<string>} */
18
+ static get observedAttributes() {
19
+ return [
20
+ ...super.observedAttributes,
21
+ 'aria-label',
22
+ ...this.valueChangingContentAttributes,
23
+ ...this.clonedContentAttributes,
24
+ ];
25
+ }
26
+
27
+ static controlTagName = 'input';
28
+
29
+ static controlVoidElement = true;
30
+
31
+ /** @type {string[]} */
32
+ static clonedContentAttributes = [
33
+ 'autocomplete', 'name', 'readonly', 'required',
34
+ ];
35
+
36
+ /** @type {string[]} */
37
+ static valueChangingContentAttributes = [];
38
+
39
+ /** @param {any[]} args */
40
+ constructor(...args) {
41
+ super(...args);
42
+ /** @type {string} */
43
+ this._value = this._control.value;
44
+ // Expose this element as focusable
45
+ if (!this.hasAttribute('tabindex')) {
46
+ this.tabIndex = 0;
47
+ }
48
+ }
49
+
50
+ /** @type {CustomElement['attributeChangedCallback']} */
51
+ attributeChangedCallback(name, oldValue, newValue) {
52
+ super.attributeChangedCallback(name, oldValue, newValue);
53
+ if (this.static.clonedContentAttributes.includes(name)) {
54
+ if (newValue == null) {
55
+ this._control.removeAttribute(name);
56
+ } else {
57
+ this._control.setAttribute(name, newValue);
58
+ }
59
+ }
60
+
61
+ if (this.static.valueChangingContentAttributes.includes(name)) {
62
+ if (!this.hasAttribute('value')) {
63
+ // Force HTMLInputElement to recalculate default
64
+ // Unintended effect of incrementally changing attributes (eg: range)
65
+ this._control.setAttribute('value', '');
66
+ }
67
+ // Changing control attribute may change the value (eg: min/max)
68
+ this._value = this._control.value;
69
+ }
70
+ }
71
+
72
+ /** @type {HTMLControlElement} */
73
+ get _control() { return this.refs.control; }
74
+
75
+ /**
76
+ * @param {Partial<this>} data
77
+ * @return {string}
78
+ */
79
+ computeAriaLabelledBy({ ariaLabel }) {
80
+ if (ariaLabel) return null;
81
+ return '#slot';
82
+ }
83
+
84
+ get stateTargetElement() { return this._control; }
85
+
86
+ click() {
87
+ /** Redirect click requests to control itself */
88
+ this._control.click();
89
+ }
90
+
91
+ static {
92
+ this.css(styles);
93
+ this.on({
94
+ // Wait until controlTagName is settled before templating
95
+ composed({ template, html }) {
96
+ template.append(html`
97
+ <label id=label disabled={disabledState}>
98
+ <${this.static.controlTagName} id=control aria-labelledby={computeAriaLabelledBy} aria-label={ariaLabel}
99
+ >${this.static.controlVoidElement ? '' : `</${this.static.controlTagName}>`}
100
+ </label>
101
+ `);
102
+ },
103
+ disabledStateChanged(oldValue, newValue) {
104
+ this._control.setAttribute('aria-disabled', `${newValue}`);
105
+ if (!this.focusableOnDisabled) {
106
+ this._control.disabled = newValue;
107
+ if (newValue) {
108
+ this.tabIndex = 0;
109
+ } else {
110
+ this.removeAttribute('tabindex');
111
+ }
112
+ }
113
+ },
114
+ });
115
+ this.childEvents({
116
+ control: {
117
+ input({ currentTarget }) {
118
+ const control = /** @type {HTMLControlElement} */ (currentTarget);
119
+ if (this.validity.valid) {
120
+ // Track internally
121
+ control.checkValidity();
122
+ this._badInput = control.validity.badInput;
123
+ } else {
124
+ // Perform check in case user has validated
125
+ this.checkValidity();
126
+ }
127
+ this._value = control.value;
128
+ },
129
+ change({ currentTarget }) {
130
+ const control = /** @type {HTMLControlElement} */ (currentTarget);
131
+ this._value = control.value;
132
+ this.checkValidity();
133
+ // Change event is NOT composed. Needs to escape shadow DOM
134
+ this.dispatchEvent(new Event('change', { bubbles: true }));
135
+ },
136
+ },
137
+ });
138
+ }
139
+
140
+ /** @type {HTMLElement['focus']} */
141
+ focus(...options) {
142
+ super.focus(...options);
143
+ this.refs.control.focus(...options);
144
+ }
145
+
146
+ /**
147
+ * @template {typeof Control & ReturnType<import('./RippleMixin.js').default> & ReturnType<import('./FormAssociatedMixin.js').default>} T
148
+ * @return {T}
149
+ */
150
+ get static() {
151
+ return /** @type {T} */ (/** @type {unknown} */ (super.static));
152
+ }
153
+
154
+ get form() { return this.elementInternals.form; }
155
+
156
+ // get name() { return this.getAttribute('name'); }
157
+ get value() {
158
+ return this._value;
159
+ }
160
+
161
+ set value(v) {
162
+ this._valueDirty = true;
163
+ this._control.value = v;
164
+ this._value = this._control.value;
165
+ }
166
+
167
+ get validity() { return this.elementInternals.validity; }
168
+
169
+ get validationMessage() { return this.elementInternals.validationMessage; }
170
+
171
+ get willValidate() { return this.elementInternals.willValidate; }
172
+
173
+ checkValidity() {
174
+ const validityState = this._control.checkValidity();
175
+ /** @type {Partial<ValidityState>} */
176
+ const newValidity = {};
177
+
178
+ // eslint-disable-next-line guard-for-in
179
+ for (const key in this._control.validity) {
180
+ // @ts-ignore Skip cast
181
+ newValidity[key] = this._control.validity[key];
182
+ }
183
+ this.elementInternals.setValidity(newValidity, this._control.validationMessage);
184
+ this._invalid = !validityState;
185
+ this._validationMessage = this._control.validationMessage;
186
+ this._badInput = this._control.validity.badInput;
187
+ return validityState;
188
+ }
189
+
190
+ reportValidity() {
191
+ this.checkValidity();
192
+ this._control.reportValidity();
193
+ return this.elementInternals.reportValidity();
194
+ }
195
+
196
+ /**
197
+ * @param {string} error
198
+ * @return {void}
199
+ */
200
+ setCustomValidity(error) {
201
+ this._control.setCustomValidity(error);
202
+ this.checkValidity();
203
+ }
204
+
205
+ get labels() { return this.elementInternals.labels; }
206
+ }
207
+ Control.prototype.ariaLabel = Control.prop('ariaLabel');
208
+ Control.prototype.delegatesFocus = true;
209
+ Control.prototype.focusableOnDisabled = false;
210
+
211
+ return Control;
212
+ }
@@ -0,0 +1,40 @@
1
+ :host {
2
+ --mdw-density: var(--mdw-density__default, 0);
3
+ }
4
+
5
+ /* Reset */
6
+ :host([density]) {
7
+ --mdw-density: 0;
8
+ }
9
+
10
+ :host([density="-1"]) {
11
+ --mdw-density: -1;
12
+ }
13
+
14
+ :host([density="-2"]) {
15
+ --mdw-density: -2;
16
+ }
17
+
18
+ :host([density="-3"]) {
19
+ --mdw-density: -2;
20
+ }
21
+
22
+ :host([density="-4"]) {
23
+ --mdw-density: -4;
24
+ }
25
+
26
+ :host([density="1"]) {
27
+ --mdw-density: 1;
28
+ }
29
+
30
+ :host([density="2"]) {
31
+ --mdw-density: 2;
32
+ }
33
+
34
+ :host([density="3"]) {
35
+ --mdw-density: 3;
36
+ }
37
+
38
+ :host([density="4"]) {
39
+ --mdw-density: 3;
40
+ }
@@ -0,0 +1,11 @@
1
+ import styles from './DensityMixin.css' assert {type: 'css'};
2
+
3
+ /** @param {typeof import('../core/CustomElement.js').default} Base */
4
+ export default function DensityMixin(Base) {
5
+ return Base
6
+ .extend()
7
+ .observe({
8
+ density: 'integer',
9
+ })
10
+ .css(styles);
11
+ }