@epa-wg/custom-element-dist 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/.editorconfig +11 -0
  2. package/.gitignore +26 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/compiler.xml +6 -0
  5. package/.idea/custom-element-dist.iml +13 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/misc.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/vcs.xml +6 -0
  10. package/.storybook/main.ts +21 -0
  11. package/.storybook/preview.ts +17 -0
  12. package/.vscode/settings.json +24 -0
  13. package/LICENSE +201 -0
  14. package/README.md +32 -0
  15. package/bin/build.sh +8 -0
  16. package/bin/clean.sh +5 -0
  17. package/bin/postinstall.sh +17 -0
  18. package/bin/start.sh +2 -0
  19. package/coverage/base.css +224 -0
  20. package/coverage/block-navigation.js +87 -0
  21. package/coverage/coverage-final.json +16 -0
  22. package/coverage/favicon.png +0 -0
  23. package/coverage/index.html +161 -0
  24. package/coverage/prettify.css +1 -0
  25. package/coverage/prettify.js +2 -0
  26. package/coverage/sort-arrow-sprite.png +0 -0
  27. package/coverage/sorter.js +196 -0
  28. package/coverage/src/coverage.svg +10 -0
  29. package/coverage/src/custom-element/coverage.svg +10 -0
  30. package/coverage/src/custom-element/custom-element.js/coverage.svg +10 -0
  31. package/coverage/src/custom-element/custom-element.js.html +2149 -0
  32. package/coverage/src/custom-element/http-request.js/coverage.svg +10 -0
  33. package/coverage/src/custom-element/http-request.js.html +352 -0
  34. package/coverage/src/custom-element/index.html +161 -0
  35. package/coverage/src/custom-element/local-storage.js/coverage.svg +10 -0
  36. package/coverage/src/custom-element/local-storage.js.html +346 -0
  37. package/coverage/src/custom-element/location-element.js/coverage.svg +10 -0
  38. package/coverage/src/custom-element/location-element.js.html +343 -0
  39. package/coverage/src/index.html +116 -0
  40. package/coverage/src/mocks/coverage.svg +10 -0
  41. package/coverage/src/mocks/handlers.ts/coverage.svg +10 -0
  42. package/coverage/src/mocks/handlers.ts.html +172 -0
  43. package/coverage/src/mocks/index.html +116 -0
  44. package/coverage/src/stories/attributes.stories.ts/coverage.svg +10 -0
  45. package/coverage/src/stories/attributes.stories.ts.html +481 -0
  46. package/coverage/src/stories/coverage.svg +10 -0
  47. package/coverage/src/stories/css.stories.ts/coverage.svg +10 -0
  48. package/coverage/src/stories/css.stories.ts.html +397 -0
  49. package/coverage/src/stories/dom-merge.stories.ts/coverage.svg +10 -0
  50. package/coverage/src/stories/dom-merge.stories.ts.html +424 -0
  51. package/coverage/src/stories/external-template.stories.ts/coverage.svg +10 -0
  52. package/coverage/src/stories/external-template.stories.ts.html +820 -0
  53. package/coverage/src/stories/http-request.stories.ts/coverage.svg +10 -0
  54. package/coverage/src/stories/http-request.stories.ts.html +817 -0
  55. package/coverage/src/stories/index.html +236 -0
  56. package/coverage/src/stories/local-storage.stories.ts/coverage.svg +10 -0
  57. package/coverage/src/stories/local-storage.stories.ts.html +1249 -0
  58. package/coverage/src/stories/location-element.stories.ts/coverage.svg +10 -0
  59. package/coverage/src/stories/location-element.stories.ts.html +484 -0
  60. package/coverage/src/stories/renderPlay.ts/coverage.svg +10 -0
  61. package/coverage/src/stories/renderPlay.ts.html +151 -0
  62. package/coverage/src/stories/slice-events.stories.ts/coverage.svg +10 -0
  63. package/coverage/src/stories/slice-events.stories.ts.html +436 -0
  64. package/coverage/src/sum.ts/coverage.svg +10 -0
  65. package/coverage/src/sum.ts.html +94 -0
  66. package/dist/confused.svg +37 -0
  67. package/dist/custom-element-B4v-KaIh.cjs +53 -0
  68. package/dist/custom-element-_g0GTup2.js +436 -0
  69. package/dist/custom-element-bundle.cjs +1 -0
  70. package/dist/custom-element-bundle.js +31 -0
  71. package/dist/embed-1.html +3 -0
  72. package/dist/html-template.html +126 -0
  73. package/dist/html-template.xhtml +45 -0
  74. package/dist/html-template.xml +45 -0
  75. package/dist/http-request-BOvP4KTl.js +56 -0
  76. package/dist/http-request-DPrY7mGh.cjs +1 -0
  77. package/dist/local-storage-Boafngui.cjs +1 -0
  78. package/dist/local-storage-BqDEu2kF.js +59 -0
  79. package/dist/location-element-2m0gWq_d.cjs +1 -0
  80. package/dist/location-element-nA_wsqBt.js +49 -0
  81. package/dist/mockServiceWorker.js +284 -0
  82. package/dist/tree.xsl +33 -0
  83. package/dist/vite.svg +1 -0
  84. package/index.html +17 -0
  85. package/package.json +97 -0
  86. package/public/confused.svg +37 -0
  87. package/public/embed-1.html +3 -0
  88. package/public/html-template.html +126 -0
  89. package/public/html-template.xhtml +45 -0
  90. package/public/html-template.xml +45 -0
  91. package/public/mockServiceWorker.js +284 -0
  92. package/public/tree.xsl +33 -0
  93. package/public/vite.svg +1 -0
  94. package/src/assets/lit.svg +1 -0
  95. package/src/custom-element/custom-element.d.ts +36 -0
  96. package/src/custom-element/custom-element.js +688 -0
  97. package/src/custom-element/demo/a.html +63 -0
  98. package/src/custom-element/demo/confused.svg +37 -0
  99. package/src/custom-element/demo/data-slices.html +184 -0
  100. package/src/custom-element/demo/dce-social-preview.png +0 -0
  101. package/src/custom-element/demo/demo.css +22 -0
  102. package/src/custom-element/demo/dom-merge.html +123 -0
  103. package/src/custom-element/demo/embed-1.html +3 -0
  104. package/src/custom-element/demo/external-template.html +179 -0
  105. package/src/custom-element/demo/hex-grid-dce.html +183 -0
  106. package/src/custom-element/demo/hex-grid-transform.png +0 -0
  107. package/src/custom-element/demo/hex-grid.html +66 -0
  108. package/src/custom-element/demo/html-template.html +126 -0
  109. package/src/custom-element/demo/html-template.xhtml +45 -0
  110. package/src/custom-element/demo/html-template.xml +45 -0
  111. package/src/custom-element/demo/http-request.html +143 -0
  112. package/src/custom-element/demo/local-storage.html +218 -0
  113. package/src/custom-element/demo/location-element.html +155 -0
  114. package/src/custom-element/demo/logo.png +0 -0
  115. package/src/custom-element/demo/parameters.html +70 -0
  116. package/src/custom-element/demo/s.xml +14 -0
  117. package/src/custom-element/demo/s.xslt +76 -0
  118. package/src/custom-element/demo/scoped-css.html +169 -0
  119. package/src/custom-element/demo/ss.html +57 -0
  120. package/src/custom-element/demo/table.xml +25 -0
  121. package/src/custom-element/demo/table.xsl +293 -0
  122. package/src/custom-element/demo/template.xsl +46 -0
  123. package/src/custom-element/demo/tree.xml +25 -0
  124. package/src/custom-element/demo/tree.xsl +33 -0
  125. package/src/custom-element/demo/wc-square.svg +1 -0
  126. package/src/custom-element/demo/xhtml-template.xhtml +45 -0
  127. package/src/custom-element/demo/z.html +62 -0
  128. package/src/custom-element/demo/z.xml +60 -0
  129. package/src/custom-element/http-request.js +89 -0
  130. package/src/custom-element/ide/IDE.md +31 -0
  131. package/src/custom-element/ide/customData-dce.json +112 -0
  132. package/src/custom-element/ide/customData-xsl.json +1018 -0
  133. package/src/custom-element/ide/web-types-dce.json +111 -0
  134. package/src/custom-element/ide/web-types-xsl.json +867 -0
  135. package/src/custom-element/index.html +168 -0
  136. package/src/custom-element/index.js +7 -0
  137. package/src/custom-element/local-storage.js +87 -0
  138. package/src/custom-element/location-element.js +87 -0
  139. package/src/custom-element.test.ts +10 -0
  140. package/src/index.css +38 -0
  141. package/src/mocks/handlers.ts +29 -0
  142. package/src/mocks/pokemons.mock.ts +13 -0
  143. package/src/stories/Configure.mdx +364 -0
  144. package/src/stories/assets/accessibility.png +0 -0
  145. package/src/stories/assets/accessibility.svg +5 -0
  146. package/src/stories/assets/addon-library.png +0 -0
  147. package/src/stories/assets/assets.png +0 -0
  148. package/src/stories/assets/avif-test-image.avif +0 -0
  149. package/src/stories/assets/context.png +0 -0
  150. package/src/stories/assets/discord.svg +15 -0
  151. package/src/stories/assets/docs.png +0 -0
  152. package/src/stories/assets/figma-plugin.png +0 -0
  153. package/src/stories/assets/github.svg +3 -0
  154. package/src/stories/assets/share.png +0 -0
  155. package/src/stories/assets/styling.png +0 -0
  156. package/src/stories/assets/testing.png +0 -0
  157. package/src/stories/assets/theming.png +0 -0
  158. package/src/stories/assets/tutorials.svg +12 -0
  159. package/src/stories/assets/youtube.svg +4 -0
  160. package/src/stories/attributes.stories.ts +132 -0
  161. package/src/stories/attributes.test.ts +14 -0
  162. package/src/stories/css.stories.ts +104 -0
  163. package/src/stories/css.test.ts +12 -0
  164. package/src/stories/dom-merge.stories.ts +113 -0
  165. package/src/stories/dom-merge.test.ts +12 -0
  166. package/src/stories/external-template.stories.ts +245 -0
  167. package/src/stories/external-template.test.ts +12 -0
  168. package/src/stories/http-request.stories.ts +244 -0
  169. package/src/stories/http-request.test.ts +29 -0
  170. package/src/stories/local-storage.stories.ts +388 -0
  171. package/src/stories/local-storage.test.ts +12 -0
  172. package/src/stories/location-element.stories.ts +133 -0
  173. package/src/stories/location-element.test.ts +14 -0
  174. package/src/stories/renderPlay.ts +22 -0
  175. package/src/stories/slice-events.stories.ts +117 -0
  176. package/src/stories/slice-events.test.ts +12 -0
  177. package/src/sum.test.ts +6 -0
  178. package/src/sum.ts +4 -0
  179. package/src/vite-env.d.ts +1 -0
  180. package/storybook-static/assets/Color-RQJUDNI5-C4yZhNbM.js +1 -0
  181. package/storybook-static/assets/Configure-C7d36rng.js +173 -0
  182. package/storybook-static/assets/DocsRenderer-K4EAMTCU-BLMupvSb.js +2 -0
  183. package/storybook-static/assets/WithTooltip-Y7J54OF7-BAQSPSFk.js +1 -0
  184. package/storybook-static/assets/accessibility-W_h2acOZ.png +0 -0
  185. package/storybook-static/assets/addon-library-BWUCAmyN.png +0 -0
  186. package/storybook-static/assets/attributes.stories-ZB0RTY1d.js +151 -0
  187. package/storybook-static/assets/context-C0qIqeS4.png +0 -0
  188. package/storybook-static/assets/css.stories-CLSX-Xxd.js +86 -0
  189. package/storybook-static/assets/custom-element-BLZZ00dz.js +53 -0
  190. package/storybook-static/assets/docs---vsFbMi.png +0 -0
  191. package/storybook-static/assets/dom-merge.stories-CgHZUABU.js +138 -0
  192. package/storybook-static/assets/entry-preview-CQqNFx4W.js +8 -0
  193. package/storybook-static/assets/entry-preview-docs-CWgqLfd3.js +2 -0
  194. package/storybook-static/assets/external-template.stories-DtSLMxvg.js +316 -0
  195. package/storybook-static/assets/figma-plugin-CH2hELiO.png +0 -0
  196. package/storybook-static/assets/formatter-B5HCVTEV-tKeEfJA9.js +58 -0
  197. package/storybook-static/assets/http-request.stories-CUzlXO89.js +300 -0
  198. package/storybook-static/assets/iframe-gCvlWuoC.js +2 -0
  199. package/storybook-static/assets/index-CBQwM6ST.js +508 -0
  200. package/storybook-static/assets/index-CDavW7r9.js +193 -0
  201. package/storybook-static/assets/index-CQA5dlr6.js +13 -0
  202. package/storybook-static/assets/index-Cc7K62zD.js +3 -0
  203. package/storybook-static/assets/index-DgaNIR0t.js +1 -0
  204. package/storybook-static/assets/index-Dkj0J1ds.js +1 -0
  205. package/storybook-static/assets/index-DnEJ_bKa.js +1 -0
  206. package/storybook-static/assets/index-DrFu-skq.js +6 -0
  207. package/storybook-static/assets/lit-element-B4_0akdT.js +19 -0
  208. package/storybook-static/assets/local-storage.stories-BkO6djDz.js +415 -0
  209. package/storybook-static/assets/location-element.stories-DCIOUd0D.js +108 -0
  210. package/storybook-static/assets/preview-B4GcaC1c.js +1 -0
  211. package/storybook-static/assets/preview-B63p-W8V.js +20 -0
  212. package/storybook-static/assets/preview-BAz7FMXc.js +396 -0
  213. package/storybook-static/assets/preview-BDY5ThwJ.js +1 -0
  214. package/storybook-static/assets/preview-C6t8KBFr.js +1 -0
  215. package/storybook-static/assets/preview-CYD85dwb.js +7 -0
  216. package/storybook-static/assets/preview-CkgAD_DE.js +2 -0
  217. package/storybook-static/assets/preview-D8LadFCz.js +48 -0
  218. package/storybook-static/assets/preview-DNpCpRPf.js +1 -0
  219. package/storybook-static/assets/preview-PxUn-cIn.js +1 -0
  220. package/storybook-static/assets/share-DGA-UcQf.png +0 -0
  221. package/storybook-static/assets/slice-events.stories-DXKjXI37.js +115 -0
  222. package/storybook-static/assets/styling-Bk6zjRzU.png +0 -0
  223. package/storybook-static/assets/syntaxhighlighter-JOJW2KGS-C04pIVD3.js +1 -0
  224. package/storybook-static/assets/testing-cbzR9l9r.png +0 -0
  225. package/storybook-static/assets/theming-D6WJLNoW.png +0 -0
  226. package/storybook-static/assets/tiny-invariant-BxWVcicq.js +1 -0
  227. package/storybook-static/confused.svg +37 -0
  228. package/storybook-static/embed-1.html +3 -0
  229. package/storybook-static/favicon.svg +7 -0
  230. package/storybook-static/html-template.html +126 -0
  231. package/storybook-static/html-template.xhtml +45 -0
  232. package/storybook-static/html-template.xml +45 -0
  233. package/storybook-static/iframe.html +492 -0
  234. package/storybook-static/index.html +163 -0
  235. package/storybook-static/index.json +1 -0
  236. package/storybook-static/mockServiceWorker.js +284 -0
  237. package/storybook-static/project.json +1 -0
  238. package/storybook-static/sb-addons/chromatic-com-storybook-9/manager-bundle.js +327 -0
  239. package/storybook-static/sb-addons/chromatic-com-storybook-9/manager-bundle.js.LEGAL.txt +40 -0
  240. package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
  241. package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js.LEGAL.txt +0 -0
  242. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +12 -0
  243. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js.LEGAL.txt +0 -0
  244. package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js +60 -0
  245. package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js.LEGAL.txt +18 -0
  246. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +3 -0
  247. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js.LEGAL.txt +0 -0
  248. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +3 -0
  249. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js.LEGAL.txt +0 -0
  250. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +3 -0
  251. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js.LEGAL.txt +0 -0
  252. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +3 -0
  253. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js.LEGAL.txt +0 -0
  254. package/storybook-static/sb-addons/interactions-10/manager-bundle.js +33 -0
  255. package/storybook-static/sb-addons/interactions-10/manager-bundle.js.LEGAL.txt +0 -0
  256. package/storybook-static/sb-addons/links-1/manager-bundle.js +3 -0
  257. package/storybook-static/sb-addons/links-1/manager-bundle.js.LEGAL.txt +0 -0
  258. package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +3 -0
  259. package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js.LEGAL.txt +0 -0
  260. package/storybook-static/sb-common-assets/fonts.css +31 -0
  261. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  262. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  263. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  264. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  265. package/storybook-static/sb-manager/WithTooltip-Y7J54OF7-CEHQ77YF.js +1 -0
  266. package/storybook-static/sb-manager/chunk-E3WK6ZOZ.js +234 -0
  267. package/storybook-static/sb-manager/chunk-E6ABNH5R.js +183 -0
  268. package/storybook-static/sb-manager/chunk-FEE35O7J.js +9 -0
  269. package/storybook-static/sb-manager/chunk-S4VOIVUE.js +347 -0
  270. package/storybook-static/sb-manager/chunk-XCO5HRLK.js +6 -0
  271. package/storybook-static/sb-manager/chunk-XP3HGWTR.js +1 -0
  272. package/storybook-static/sb-manager/formatter-B5HCVTEV-7DCBOGO6.js +58 -0
  273. package/storybook-static/sb-manager/globals-module-info.js +1 -0
  274. package/storybook-static/sb-manager/globals-runtime.js +1 -0
  275. package/storybook-static/sb-manager/globals.js +1 -0
  276. package/storybook-static/sb-manager/index.js +1 -0
  277. package/storybook-static/sb-manager/runtime.js +1 -0
  278. package/storybook-static/sb-manager/syntaxhighlighter-JOJW2KGS-VF6EEVPI.js +1 -0
  279. package/storybook-static/sb-preview/globals.js +1 -0
  280. package/storybook-static/sb-preview/runtime.js +139 -0
  281. package/storybook-static/tree.xsl +33 -0
  282. package/storybook-static/vite.svg +1 -0
  283. package/tsconfig.json +25 -0
  284. package/vite.config.js +55 -0
@@ -0,0 +1,168 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>custom-element Declarative Custom Element implementation demo</title>
6
+ <link rel="icon" href="demo/wc-square.svg" />
7
+ <script type="module" src="custom-element.js"></script>
8
+ <style>
9
+ @import "demo/demo.css";
10
+ </style>
11
+ </head>
12
+ <body xmlns:xhtml="http://www.w3.org/1999/xhtml">
13
+ <nav>
14
+ <h3><code>custom-element</code> demo</h3>
15
+ <div><a href="https://github.com/EPA-WG/custom-element"
16
+ ><img src="https://cdnjs.cloudflare.com/ajax/libs/octicons/8.5.0/svg/mark-github.svg" alt="icon">GIT</a>
17
+ | <a href="https://github.com/EPA-WG/custom-element/blob/main/README.md">README</a>
18
+ | <a href="https://stackblitz.com/github/EPA-WG/custom-element?file=index.html">Sandbox</a>
19
+ | <a href="https://chrome.google.com/webstore/detail/epa-wgcustom-element/hiofgpmmkdembdogjpagmbbbmefefhbl"
20
+ >Chrome devtools plugin</a>
21
+ </div>
22
+ <p>
23
+ This <em>Declarative Custom Element</em> allows to define<br/>
24
+ custom HTML tag with template filled from slots, attributes, dataset. </p>
25
+ <p>The template is fully loaded with variables, conditions, loops, etc. <br/>
26
+ The data query is powered by XPath. </p>
27
+ <p>Try in <a href="https://stackblitz.com/github/EPA-WG/custom-element?file=index.html" >Sandbox</a> </p>
28
+ <section>
29
+ <h4>Features demo</h4>
30
+ <a href="./demo/local-storage.html" >local-storage </a> |
31
+ <a href="./demo/http-request.html" >http-request </a> |
32
+ <a href="./demo/location-element.html" >location-element </a> |
33
+ <a href="./demo/external-template.html" >external template </a> <br/>
34
+ <a href="./demo/hex-grid.html" >hex grid lib </a> |
35
+ <a href="./demo/scoped-css.html" >scoped CSS </a> |
36
+ <a href="./demo/parameters.html" >attributes </a> |
37
+ <a href="./demo/data-slices.html" >data slices/events </a> |
38
+ <a href="./demo/dom-merge.html" >DOM merge on dynamic update </a>
39
+ </section>
40
+ </nav>
41
+ <html-demo-element legend="1. simple payload"
42
+ description="payload is ignored as in DCE definition there is no default slot">
43
+ <template>
44
+ <custom-element tag="dce-link" hidden>
45
+ <a href="#">link 😃</a>
46
+ </custom-element>
47
+ <dce-link><i>🍋</i></dce-link>
48
+ </template>
49
+ </html-demo-element>
50
+
51
+ <html-demo-element legend="2. payload with slot definition and slot value"
52
+ description="slots are filled as in template+shadow root">
53
+ <template>
54
+ <custom-element tag="dce-1-slot" hidden>
55
+ 🐇❤️<slot name="slot1"> 🥦</slot>
56
+ </custom-element>
57
+ <dce-1-slot><i slot="slot1">🥕</i></dce-1-slot>
58
+ </template>
59
+ </html-demo-element>
60
+
61
+ <html-demo-element legend="2a. payload with slot definition and slot value"
62
+ description="unlike in TEMPLATE, same slot can be used multiple times and within attribute ">
63
+ <template>
64
+ <custom-element tag="dce-2-slots" hidden>
65
+ <slot name="slot2"> 😃</slot> and again:
66
+ <slot name="slot2"> 😃</slot>
67
+ <xhtml:input placeholder="🐇❤️{//*[@slot='slot2']}"/>
68
+ </custom-element>
69
+ <dce-2-slots><i slot="slot2">🥕</i></dce-2-slots>
70
+ <dce-2-slots></dce-2-slots>
71
+ </template>
72
+ </html-demo-element>
73
+
74
+ <html-demo-element legend="2b. named default slot"
75
+ description="slot without `name` attribute or with blank value `name=''` use whole payload">
76
+ <template>
77
+ <custom-element tag="dce-3-slot" hidden>
78
+ #1
79
+ <slot name=""> 😃</slot>
80
+ and
81
+ <slot> 😃</slot>
82
+ </custom-element>
83
+ <dce-3-slot><i slot="">🥕</i></dce-3-slot>
84
+ </template>
85
+ </html-demo-element>
86
+
87
+ <html-demo-element legend="2c. named default slot"
88
+ description="slot without `name` attribute or with blank value `name=''` use whole payload">
89
+ <template>
90
+ <custom-element tag="dce-4-slot" hidden>
91
+ #2
92
+ <slot name=""> 😃</slot>
93
+ and
94
+ <slot> 😃</slot>
95
+ </custom-element>
96
+ <dce-4-slot>🥕</dce-4-slot>
97
+ </template>
98
+ </html-demo-element>
99
+
100
+ <html-demo-element legend="2d. default slot"
101
+ description="slot without `name` attribute use whole payload">
102
+ <template>
103
+
104
+ <custom-element tag="greet-element" hidden>
105
+ <slot> Hello </slot> World!
106
+ </custom-element>
107
+ <greet-element></greet-element>
108
+ <greet-element>👋</greet-element>
109
+ </template>
110
+ </html-demo-element>
111
+
112
+ <html-demo-element legend="3. 💪 DCE template "
113
+ description="Complex case with slots, attributes, dataset, conditional render">
114
+ <template>
115
+
116
+ <custom-element tag="pokemon-tile" hidden id="shared-template">
117
+ <template>
118
+ <h3> {title} </h3> <!-- title is an attribute in instance
119
+ mapped into /*/attributes/title -->
120
+ <if test="//smile"> <!-- data-smile DCE instance attribute,
121
+ mapped into /*/dataset/smile
122
+ used in condition -->
123
+ <!-- data-smile DCE instance attribute, used as HTML -->
124
+ <div>Smile as: {//smile}</div> <!-- /datadom/dataset/smile -->
125
+ </if>
126
+ <!-- image would not be visible in sandbox, see live demo -->
127
+ <img src="https://unpkg.com/pokeapi-sprites@2.0.2/sprites/pokemon/other/dream-world/{pokemon-id}.svg"
128
+ alt="{title} image"/>
129
+ <!-- image-src and title are DCE instance attributes,
130
+ mapped into /*/attributes/
131
+ used within output attribute via curly brackets -->
132
+
133
+ <!-- `slot name=xxx` replaced with elements with `slot=xxx` attribute -->
134
+ <p><slot name="description"><i>description is not available</i></slot></p>
135
+ <for-each select="//*[@pokemon-id]">
136
+ <!-- loop over payload elements with `pokemon-id` attribute,
137
+ i.e LI elements -->
138
+ <button>
139
+ <img height="32"
140
+ src="https://unpkg.com/pokeapi-sprites@2.0.2/sprites/pokemon/other/dream-world/{@pokemon-id}.svg"
141
+ alt="{text()}"/>
142
+ <br/>
143
+ {text()} <!-- text from LI element in loop -->
144
+ </button>
145
+
146
+ </for-each>
147
+ </template>
148
+ </custom-element>
149
+
150
+ <pokemon-tile title="bulbasaur" data-smile="👼" pokemon-id="1" >
151
+ <p slot="description">Bulbasaur is a cute Pokémon born with a large seed firmly affixed to its back;
152
+ the seed grows in size as the Pokémon does.</p>
153
+ <ul>
154
+ <li pokemon-id="2">ivysaur</li>
155
+ <li pokemon-id="3">venusaur</li>
156
+ </ul>
157
+ </pokemon-tile>
158
+
159
+ <pokemon-tile title="ninetales" pokemon-id="38" >
160
+ <li pokemon-id="37">vulpix</li>
161
+ </pokemon-tile>
162
+ </template>
163
+ </html-demo-element>
164
+
165
+ <script type="module" src="https://unpkg.com/html-demo-element@1.0/html-demo-element.js"></script>
166
+
167
+ </body>
168
+ </html>
@@ -0,0 +1,7 @@
1
+ import CustomElement from "./custom-element.js";
2
+ export default CustomElement;
3
+
4
+ export * from "./custom-element.js";
5
+ export * from "./http-request.js";
6
+ export * from "./local-storage.js";
7
+ export * from "./location-element.js";
@@ -0,0 +1,87 @@
1
+ const string2value = (type, v) =>
2
+ { if( type === 'text')
3
+ return v;
4
+ if( type === 'json')
5
+ try{ return JSON.parse( v );}
6
+ catch(err){ return null }
7
+ const el = document.createElement('input');
8
+ el.setAttribute('type',type);
9
+ if( 'number' === type )
10
+ { el.value = v;
11
+ return el.valueAsNumber;
12
+ }
13
+ if( 'date' === type )
14
+ { if(!v) return null;
15
+ el.valueAsDate = new Date( v );
16
+ return el.value;
17
+ }
18
+ el.value = v;
19
+ return el.value;
20
+ };
21
+
22
+ let originalSetItem,originalRemoveItem,originalClear;
23
+
24
+ function ensureTrackLocalStorage()
25
+ { if( originalSetItem )
26
+ return;
27
+ originalSetItem = localStorage.setItem;
28
+ localStorage.setItem = function( key, value, ...rest )
29
+ { originalSetItem.apply(this, [ key, value, ...rest ]);
30
+ window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
31
+ };
32
+ originalRemoveItem = localStorage.removeItem;
33
+ localStorage.removeItem = function( key, ...rest )
34
+ { originalRemoveItem.apply(this, [ key, ...rest ]);
35
+ window.dispatchEvent( new CustomEvent('local-storage',{detail:{key}}) );
36
+ };
37
+ originalClear = localStorage.clear;
38
+ localStorage.clear = function( ...rest )
39
+ { originalClear.apply(this, [ ...rest ]);
40
+ window.dispatchEvent( new CustomEvent('local-storage',{detail:{}}) );
41
+ };
42
+ }
43
+
44
+ export function localStorageSetItem(key, value)
45
+ { localStorage.setItem(key, value);
46
+ window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
47
+ }
48
+ export class LocalStorageElement extends HTMLElement
49
+ {
50
+ static observedAttributes=
51
+ [ 'value' // populated from localStorage, if defined initially, sets the value in storage
52
+ , 'slice'
53
+ , 'key'
54
+ , 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
55
+ , 'live' // monitors localStorage change
56
+ ];
57
+
58
+ #value;
59
+ get value(){ return this.#value ===null ? undefined: this.#value }
60
+ set value(o){ return this.#value = o; }
61
+
62
+ async connectedCallback()
63
+ {
64
+ const attr = attr => this.getAttribute(attr)
65
+ , fromStorage = ()=>
66
+ { this.#value = string2value( attr('type'), localStorage.getItem( attr( 'key' ) ) );
67
+ this.dispatchEvent( new Event('change') )
68
+ }
69
+ this.#value = string2value( attr('type'), localStorage.getItem( attr( 'key' ) ) );
70
+
71
+ if( this.hasAttribute('value'))
72
+ localStorageSetItem( attr( 'key' ), this.#value = attr( 'value' ) )
73
+ else
74
+ fromStorage()
75
+
76
+ if( this.hasAttribute('live') )
77
+ { const listener = (e => (e.detail.key === attr( 'key' ) || !e.detail.key ) && fromStorage());
78
+ window.addEventListener( 'local-storage', listener );
79
+ ensureTrackLocalStorage();
80
+ this._destroy = ()=> window.removeEventListener('local-storage', listener );
81
+ }
82
+ }
83
+ disconnectedCallback(){ this._destroy?.(); }
84
+ }
85
+
86
+ window.customElements.define( 'local-storage', LocalStorageElement );
87
+ export default LocalStorageElement;
@@ -0,0 +1,87 @@
1
+ const attr = ( el, attr )=> el.getAttribute( attr );
2
+
3
+ let originalHistory;
4
+
5
+ function ensureTrackLocationChange()
6
+ { if( originalHistory )
7
+ return;
8
+ originalHistory = {};
9
+ 'back,forward,go,pushState,replaceState'.split(',').forEach( k =>
10
+ {
11
+ originalHistory[ k ] = history[ k ];
12
+ history[ k ] = function(...rest )
13
+ {
14
+ originalHistory[k].apply( history, rest );
15
+ window.dispatchEvent( new CustomEvent('dce-location',{detail:{ k }}) );
16
+ }
17
+ });
18
+ }
19
+
20
+ export class LocationElement extends HTMLElement
21
+ {
22
+ static observedAttributes=
23
+ [ 'value' // populated from url
24
+ , 'slice'
25
+ , 'href' // url to be parsed. When omitted window.location is used.
26
+ , 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
27
+ , 'live' // monitors history change, applicable only when href is omitted.
28
+ ];
29
+
30
+ constructor()
31
+ {
32
+ super();
33
+ const state = {}
34
+ , listener = () => setTimeout( propagateSlice,1 )
35
+ , propagateSlice = ()=>
36
+ { const urlStr = attr(this,'href')
37
+ if(!urlStr)
38
+ ensureTrackLocationChange();
39
+ const url = urlStr? new URL(urlStr, window.location) : window.location;
40
+
41
+ const params= {}
42
+ const search = new URLSearchParams(url.search);
43
+ for (const key of search.keys())
44
+ params[key] = search.getAll(key)
45
+
46
+ const detail = {params}
47
+ for( const k in url )
48
+ { if ('string' === typeof url[k])
49
+ detail[k] = url[k]
50
+ }
51
+ this.value = detail;
52
+ this.dispatchEvent( new Event('change') );
53
+ };
54
+ this.sliceInit = s =>
55
+ {
56
+ if( !state.listener && this.hasAttribute('live') )
57
+ { state.listener = 1;
58
+ window.navigation?.addEventListener("navigate", listener );
59
+ window.addEventListener( 'popstate' , listener );
60
+ window.addEventListener( 'hashchange' , listener );
61
+ window.addEventListener( 'dce-location' , listener );
62
+ }
63
+ propagateSlice();
64
+ return s || {}
65
+ }
66
+ this._destroy = ()=>
67
+ {
68
+ window.removeEventListener('popstate' , listener);
69
+ window.removeEventListener('hashchange' , listener);
70
+ window.removeEventListener('dce-location', listener);
71
+ delete state.listener;
72
+ };
73
+
74
+ }
75
+ attributeChangedCallback(name, oldValue, newValue)
76
+ {
77
+ if('href'!== name)
78
+ return;
79
+ this.sliceInit && this.sliceInit();
80
+ }
81
+
82
+ connectedCallback(){ this.sliceInit() }
83
+ disconnectedCallback(){ this._destroy() }
84
+ }
85
+
86
+ window.customElements.define( 'location-element', LocationElement );
87
+ export default LocationElement;
@@ -0,0 +1,10 @@
1
+ import { expect, test } from 'vitest'
2
+ import { deepEqual} from './custom-element/custom-element.js'
3
+
4
+ test('deepEqual', () => {
5
+ expect(deepEqual(1, 1) ).toBe(true);
6
+ expect(deepEqual({}, null) ).toBe(false);
7
+ expect(deepEqual({a:1},{a:1,b:2}) ).toBe(false);
8
+ expect(deepEqual({a:1},{a:2}) ).toBe(false);
9
+ expect(deepEqual({a:1},{a:1}) ).toBe(true);
10
+ })
package/src/index.css ADDED
@@ -0,0 +1,38 @@
1
+ :root {
2
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ @media (prefers-color-scheme: light) {
34
+ :root {
35
+ color: #213547;
36
+ background-color: #ffffff;
37
+ }
38
+ }
@@ -0,0 +1,29 @@
1
+ import {delay, http, HttpResponse} from 'msw'
2
+
3
+ import pokemonsMock from './pokemons.mock.ts';
4
+
5
+ export const handlers =
6
+ [ http.get('/pokemon', ({ request }) =>
7
+ {
8
+ const url = new URL(request.url);
9
+ const limit = url.searchParams.get('limit');
10
+ const data = structuredClone(pokemonsMock);
11
+ if( limit )
12
+ data.results = data.results.slice(0,Number(limit))
13
+ return HttpResponse.json(data); })
14
+ , http.get('/noreturn', async () =>
15
+ {
16
+ await delay(500);
17
+ // half second to be able to catch the initial state before the full data returned;
18
+ return HttpResponse.json(pokemonsMock);
19
+ })
20
+ , http.get('/reflect', ({request}) =>
21
+ { const headers: Record<string, string> = {};
22
+ [...request.headers.entries()].map(([key, val]) => headers[key] = 'reflected-'+val);
23
+ headers['x-added'] = 'abc';
24
+ return HttpResponse.json(pokemonsMock, {headers});
25
+ })
26
+ , http.get('/404', () =>
27
+ {
28
+ return new HttpResponse(null, {status: 404, statusText: 'not found'}) })
29
+ ];
@@ -0,0 +1,13 @@
1
+ export default {
2
+ "count": 1279,
3
+ "next": "https://pokeapi.co/api/v2/pokemon?offset=6&limit=6",
4
+ "previous": null,
5
+ "results":
6
+ [ {"name": "bulbasaur" ,"url": "https://pokeapi.co/api/v2/pokemon/1/" }
7
+ , {"name": "ivysaur" ,"url": "https://pokeapi.co/api/v2/pokemon/2/" }
8
+ , {"name": "venusaur" ,"url": "https://pokeapi.co/api/v2/pokemon/3/" }
9
+ , {"name": "charmander" ,"url": "https://pokeapi.co/api/v2/pokemon/4/" }
10
+ , {"name": "charmeleon" ,"url": "https://pokeapi.co/api/v2/pokemon/5/" }
11
+ , {"name": "charizard" ,"url": "https://pokeapi.co/api/v2/pokemon/6/" }
12
+ ]
13
+ }