@zeix/le-truc 0.15.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 (406) hide show
  1. package/.ai-context.md +234 -0
  2. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
  3. package/.editorconfig +12 -0
  4. package/.github/copilot-instructions.md +62 -0
  5. package/.github/workflows/codeql.yml +108 -0
  6. package/.github/workflows/static.yml +43 -0
  7. package/.prettierrc +17 -0
  8. package/CLAUDE.md +215 -0
  9. package/CODE_OF_CONDUCT.md +128 -0
  10. package/CONTRIBUTING.md +160 -0
  11. package/LICENSE +21 -0
  12. package/README.md +474 -0
  13. package/biome.json +295 -0
  14. package/bun.lock +239 -0
  15. package/docs/about.html +105 -0
  16. package/docs/assets/main.css +1 -0
  17. package/docs/assets/main.js +10 -0
  18. package/docs/assets/main.js.map +66 -0
  19. package/docs/components.html +293 -0
  20. package/docs/data-flow.html +308 -0
  21. package/docs/examples/basic-button.html +367 -0
  22. package/docs/examples/basic-counter.html +188 -0
  23. package/docs/examples/basic-hello.html +138 -0
  24. package/docs/examples/basic-number.html +271 -0
  25. package/docs/examples/basic-pluralize.html +214 -0
  26. package/docs/examples/card-callout.html +152 -0
  27. package/docs/examples/card-mediaqueries.html +138 -0
  28. package/docs/examples/context-media.html +198 -0
  29. package/docs/examples/empty.html +37 -0
  30. package/docs/examples/form-checkbox.html +233 -0
  31. package/docs/examples/form-combobox.html +420 -0
  32. package/docs/examples/form-listbox.html +434 -0
  33. package/docs/examples/form-radiogroup.html +296 -0
  34. package/docs/examples/form-spinbutton.html +402 -0
  35. package/docs/examples/form-textbox.html +361 -0
  36. package/docs/examples/layout.html +67 -0
  37. package/docs/examples/module-carousel.html +552 -0
  38. package/docs/examples/module-catalog.html +241 -0
  39. package/docs/examples/module-codeblock.html +270 -0
  40. package/docs/examples/module-dialog.html +343 -0
  41. package/docs/examples/module-lazyload.html +289 -0
  42. package/docs/examples/module-list.html +197 -0
  43. package/docs/examples/module-pagination.html +283 -0
  44. package/docs/examples/module-scrollarea.html +447 -0
  45. package/docs/examples/module-tabgroup.html +526 -0
  46. package/docs/examples/module-todo.html +367 -0
  47. package/docs/examples/module-with-type.html +63 -0
  48. package/docs/examples/nested-components.html +88 -0
  49. package/docs/examples/recursive.html +56 -0
  50. package/docs/examples/simple-text.html +39 -0
  51. package/docs/examples/snippet.html +93 -0
  52. package/docs/examples/with-styles.html +75 -0
  53. package/docs/getting-started.html +143 -0
  54. package/docs/index.html +112 -0
  55. package/docs/sitemap.xml +28 -0
  56. package/docs/styling.html +160 -0
  57. package/docs/sw.js +112 -0
  58. package/docs-src/api/README.md +478 -0
  59. package/docs-src/api/_media/LICENSE +21 -0
  60. package/docs-src/api/classes/CircularDependencyError.md +299 -0
  61. package/docs-src/api/classes/CircularMutationError.md +301 -0
  62. package/docs-src/api/classes/ContextRequestEvent.md +590 -0
  63. package/docs-src/api/classes/DependencyTimeoutError.md +301 -0
  64. package/docs-src/api/classes/InvalidCallbackError.md +303 -0
  65. package/docs-src/api/classes/InvalidComponentNameError.md +295 -0
  66. package/docs-src/api/classes/InvalidCustomElementError.md +301 -0
  67. package/docs-src/api/classes/InvalidEffectsError.md +301 -0
  68. package/docs-src/api/classes/InvalidPropertyNameError.md +307 -0
  69. package/docs-src/api/classes/InvalidReactivesError.md +307 -0
  70. package/docs-src/api/classes/InvalidSignalValueError.md +303 -0
  71. package/docs-src/api/classes/MissingElementError.md +307 -0
  72. package/docs-src/api/classes/NullishSignalValueError.md +299 -0
  73. package/docs-src/api/classes/StoreKeyExistsError.md +303 -0
  74. package/docs-src/api/classes/StoreKeyRangeError.md +299 -0
  75. package/docs-src/api/classes/StoreKeyReadonlyError.md +303 -0
  76. package/docs-src/api/functions/asBoolean.md +21 -0
  77. package/docs-src/api/functions/asEnum.md +31 -0
  78. package/docs-src/api/functions/asInteger.md +39 -0
  79. package/docs-src/api/functions/asJSON.md +49 -0
  80. package/docs-src/api/functions/asNumber.md +37 -0
  81. package/docs-src/api/functions/asString.md +37 -0
  82. package/docs-src/api/functions/createCollection.md +83 -0
  83. package/docs-src/api/functions/createSensor.md +71 -0
  84. package/docs-src/api/functions/dangerouslySetInnerHTML.md +48 -0
  85. package/docs-src/api/functions/defineComponent.md +65 -0
  86. package/docs-src/api/functions/isCollection.md +37 -0
  87. package/docs-src/api/functions/isParser.md +41 -0
  88. package/docs-src/api/functions/match.md +47 -0
  89. package/docs-src/api/functions/on.md +58 -0
  90. package/docs-src/api/functions/pass.md +53 -0
  91. package/docs-src/api/functions/provideContexts.md +47 -0
  92. package/docs-src/api/functions/read.md +47 -0
  93. package/docs-src/api/functions/requestContext.md +51 -0
  94. package/docs-src/api/functions/resolve.md +40 -0
  95. package/docs-src/api/functions/runEffects.md +51 -0
  96. package/docs-src/api/functions/runElementEffects.md +57 -0
  97. package/docs-src/api/functions/schedule.md +33 -0
  98. package/docs-src/api/functions/setAttribute.md +48 -0
  99. package/docs-src/api/functions/setProperty.md +52 -0
  100. package/docs-src/api/functions/setStyle.md +48 -0
  101. package/docs-src/api/functions/setText.md +42 -0
  102. package/docs-src/api/functions/show.md +42 -0
  103. package/docs-src/api/functions/toSignal.md +37 -0
  104. package/docs-src/api/functions/toggleAttribute.md +48 -0
  105. package/docs-src/api/functions/toggleClass.md +48 -0
  106. package/docs-src/api/functions/updateElement.md +53 -0
  107. package/docs-src/api/globals.md +131 -0
  108. package/docs-src/api/type-aliases/Cleanup.md +27 -0
  109. package/docs-src/api/type-aliases/Collection.md +91 -0
  110. package/docs-src/api/type-aliases/CollectionListener.md +27 -0
  111. package/docs-src/api/type-aliases/Component.md +17 -0
  112. package/docs-src/api/type-aliases/ComponentProp.md +11 -0
  113. package/docs-src/api/type-aliases/ComponentProps.md +11 -0
  114. package/docs-src/api/type-aliases/ComponentSetup.md +31 -0
  115. package/docs-src/api/type-aliases/ComponentUI.md +27 -0
  116. package/docs-src/api/type-aliases/Computed.md +49 -0
  117. package/docs-src/api/type-aliases/ComputedCallback.md +29 -0
  118. package/docs-src/api/type-aliases/Context.md +33 -0
  119. package/docs-src/api/type-aliases/ContextType.md +19 -0
  120. package/docs-src/api/type-aliases/DangerouslySetInnerHTMLOptions.md +27 -0
  121. package/docs-src/api/type-aliases/DiffResult.md +61 -0
  122. package/docs-src/api/type-aliases/Effect.md +35 -0
  123. package/docs-src/api/type-aliases/EffectCallback.md +23 -0
  124. package/docs-src/api/type-aliases/Effects.md +21 -0
  125. package/docs-src/api/type-aliases/ElementEffects.md +21 -0
  126. package/docs-src/api/type-aliases/ElementFromKey.md +21 -0
  127. package/docs-src/api/type-aliases/ElementQueries.md +27 -0
  128. package/docs-src/api/type-aliases/ElementUpdater.md +131 -0
  129. package/docs-src/api/type-aliases/EventHandler.md +31 -0
  130. package/docs-src/api/type-aliases/EventType.md +17 -0
  131. package/docs-src/api/type-aliases/Fallback.md +21 -0
  132. package/docs-src/api/type-aliases/Initializers.md +21 -0
  133. package/docs-src/api/type-aliases/LooseReader.md +31 -0
  134. package/docs-src/api/type-aliases/MatchHandlers.md +77 -0
  135. package/docs-src/api/type-aliases/MaybeCleanup.md +23 -0
  136. package/docs-src/api/type-aliases/MaybeSignal.md +17 -0
  137. package/docs-src/api/type-aliases/Parser.md +39 -0
  138. package/docs-src/api/type-aliases/ParserOrFallback.md +21 -0
  139. package/docs-src/api/type-aliases/PassedProp.md +25 -0
  140. package/docs-src/api/type-aliases/PassedProps.md +21 -0
  141. package/docs-src/api/type-aliases/Reactive.md +25 -0
  142. package/docs-src/api/type-aliases/Reader.md +31 -0
  143. package/docs-src/api/type-aliases/ReservedWords.md +11 -0
  144. package/docs-src/api/type-aliases/ResolveResult.md +29 -0
  145. package/docs-src/api/type-aliases/SensorEvents.md +25 -0
  146. package/docs-src/api/type-aliases/Signal.md +41 -0
  147. package/docs-src/api/type-aliases/State.md +85 -0
  148. package/docs-src/api/type-aliases/Store.md +29 -0
  149. package/docs-src/api/type-aliases/UI.md +11 -0
  150. package/docs-src/api/type-aliases/UnknownContext.md +13 -0
  151. package/docs-src/api/variables/CONTEXT_REQUEST.md +11 -0
  152. package/docs-src/api/variables/UNSET.md +23 -0
  153. package/docs-src/api/variables/batch.md +25 -0
  154. package/docs-src/api/variables/createComputed.md +41 -0
  155. package/docs-src/api/variables/createEffect.md +35 -0
  156. package/docs-src/api/variables/createState.md +37 -0
  157. package/docs-src/api/variables/createStore.md +42 -0
  158. package/docs-src/api/variables/diff.md +43 -0
  159. package/docs-src/api/variables/isAbortError.md +33 -0
  160. package/docs-src/api/variables/isAsyncFunction.md +39 -0
  161. package/docs-src/api/variables/isComputed.md +37 -0
  162. package/docs-src/api/variables/isEqual.md +49 -0
  163. package/docs-src/api/variables/isFunction.md +39 -0
  164. package/docs-src/api/variables/isMutableSignal.md +37 -0
  165. package/docs-src/api/variables/isNumber.md +33 -0
  166. package/docs-src/api/variables/isRecord.md +39 -0
  167. package/docs-src/api/variables/isRecordOrArray.md +39 -0
  168. package/docs-src/api/variables/isSignal.md +37 -0
  169. package/docs-src/api/variables/isState.md +37 -0
  170. package/docs-src/api/variables/isStore.md +37 -0
  171. package/docs-src/api/variables/isString.md +33 -0
  172. package/docs-src/api/variables/isSymbol.md +33 -0
  173. package/docs-src/api/variables/toError.md +33 -0
  174. package/docs-src/api/variables/valueString.md +33 -0
  175. package/docs-src/includes/menu.html +44 -0
  176. package/docs-src/pages/about.md +89 -0
  177. package/docs-src/pages/components.md +437 -0
  178. package/docs-src/pages/data-flow.md +449 -0
  179. package/docs-src/pages/getting-started.md +170 -0
  180. package/docs-src/pages/index.md +98 -0
  181. package/docs-src/pages/styling.md +165 -0
  182. package/eslint.config.js +64 -0
  183. package/examples/_common/clear.ts +49 -0
  184. package/examples/_common/fetch.ts +160 -0
  185. package/examples/_common/focus.ts +45 -0
  186. package/examples/_common/highlight.ts +5 -0
  187. package/examples/_global.css +463 -0
  188. package/examples/basic-button/basic-button.css +176 -0
  189. package/examples/basic-button/basic-button.html +46 -0
  190. package/examples/basic-button/basic-button.spec.ts +160 -0
  191. package/examples/basic-button/basic-button.ts +45 -0
  192. package/examples/basic-button/copyToClipboard.ts +37 -0
  193. package/examples/basic-counter/basic-counter.css +21 -0
  194. package/examples/basic-counter/basic-counter.html +24 -0
  195. package/examples/basic-counter/basic-counter.spec.ts +85 -0
  196. package/examples/basic-counter/basic-counter.ts +43 -0
  197. package/examples/basic-hello/basic-hello.html +34 -0
  198. package/examples/basic-hello/basic-hello.spec.ts +110 -0
  199. package/examples/basic-hello/basic-hello.ts +36 -0
  200. package/examples/basic-number/basic-number.html +79 -0
  201. package/examples/basic-number/basic-number.spec.ts +175 -0
  202. package/examples/basic-number/basic-number.ts +124 -0
  203. package/examples/basic-pluralize/basic-pluralize.html +64 -0
  204. package/examples/basic-pluralize/basic-pluralize.spec.ts +258 -0
  205. package/examples/basic-pluralize/basic-pluralize.ts +82 -0
  206. package/examples/card-callout/card-callout.css +79 -0
  207. package/examples/card-callout/card-callout.html +5 -0
  208. package/examples/card-mediaqueries/card-mediaqueries.html +29 -0
  209. package/examples/card-mediaqueries/card-mediaqueries.spec.ts +300 -0
  210. package/examples/card-mediaqueries/card-mediaqueries.ts +41 -0
  211. package/examples/context-media/context-media.html +3 -0
  212. package/examples/context-media/context-media.ts +127 -0
  213. package/examples/form-checkbox/form-checkbox.css +70 -0
  214. package/examples/form-checkbox/form-checkbox.html +13 -0
  215. package/examples/form-checkbox/form-checkbox.spec.ts +357 -0
  216. package/examples/form-checkbox/form-checkbox.ts +50 -0
  217. package/examples/form-checkbox/vanilla-checkbox.ts +101 -0
  218. package/examples/form-combobox/form-combobox.css +118 -0
  219. package/examples/form-combobox/form-combobox.html +74 -0
  220. package/examples/form-combobox/form-combobox.spec.ts +977 -0
  221. package/examples/form-combobox/form-combobox.ts +128 -0
  222. package/examples/form-listbox/form-listbox.css +71 -0
  223. package/examples/form-listbox/form-listbox.html +67 -0
  224. package/examples/form-listbox/form-listbox.spec.ts +1050 -0
  225. package/examples/form-listbox/form-listbox.ts +196 -0
  226. package/examples/form-listbox/mocks/timezones.json +495 -0
  227. package/examples/form-radiogroup/form-radiogroup.css +87 -0
  228. package/examples/form-radiogroup/form-radiogroup.html +51 -0
  229. package/examples/form-radiogroup/form-radiogroup.spec.ts +515 -0
  230. package/examples/form-radiogroup/form-radiogroup.ts +58 -0
  231. package/examples/form-spinbutton/form-spinbutton.css +95 -0
  232. package/examples/form-spinbutton/form-spinbutton.html +96 -0
  233. package/examples/form-spinbutton/form-spinbutton.spec.ts +688 -0
  234. package/examples/form-spinbutton/form-spinbutton.ts +111 -0
  235. package/examples/form-textbox/form-textbox.css +104 -0
  236. package/examples/form-textbox/form-textbox.html +53 -0
  237. package/examples/form-textbox/form-textbox.spec.ts +542 -0
  238. package/examples/form-textbox/form-textbox.ts +104 -0
  239. package/examples/main.css +22 -0
  240. package/examples/main.ts +23 -0
  241. package/examples/module-carousel/module-carousel.css +113 -0
  242. package/examples/module-carousel/module-carousel.html +208 -0
  243. package/examples/module-carousel/module-carousel.spec.ts +523 -0
  244. package/examples/module-carousel/module-carousel.ts +131 -0
  245. package/examples/module-catalog/module-catalog.css +22 -0
  246. package/examples/module-catalog/module-catalog.html +82 -0
  247. package/examples/module-catalog/module-catalog.spec.ts +396 -0
  248. package/examples/module-catalog/module-catalog.ts +37 -0
  249. package/examples/module-codeblock/module-codeblock.css +95 -0
  250. package/examples/module-codeblock/module-codeblock.html +28 -0
  251. package/examples/module-codeblock/module-codeblock.ts +47 -0
  252. package/examples/module-demo/module-demo.css +13 -0
  253. package/examples/module-dialog/module-dialog.css +96 -0
  254. package/examples/module-dialog/module-dialog.html +66 -0
  255. package/examples/module-dialog/module-dialog.spec.ts +557 -0
  256. package/examples/module-dialog/module-dialog.ts +81 -0
  257. package/examples/module-lazyload/mocks/empty.html +1 -0
  258. package/examples/module-lazyload/mocks/module-with-type.html +27 -0
  259. package/examples/module-lazyload/mocks/nested-components.html +52 -0
  260. package/examples/module-lazyload/mocks/recursive.html +20 -0
  261. package/examples/module-lazyload/mocks/simple-text.html +3 -0
  262. package/examples/module-lazyload/mocks/snippet.html +57 -0
  263. package/examples/module-lazyload/mocks/with-styles.html +39 -0
  264. package/examples/module-lazyload/module-lazyload.html +132 -0
  265. package/examples/module-lazyload/module-lazyload.spec.ts +734 -0
  266. package/examples/module-lazyload/module-lazyload.ts +89 -0
  267. package/examples/module-list/module-list.html +30 -0
  268. package/examples/module-list/module-list.spec.ts +592 -0
  269. package/examples/module-list/module-list.ts +99 -0
  270. package/examples/module-pagination/module-pagination.css +79 -0
  271. package/examples/module-pagination/module-pagination.html +16 -0
  272. package/examples/module-pagination/module-pagination.spec.ts +701 -0
  273. package/examples/module-pagination/module-pagination.ts +88 -0
  274. package/examples/module-scrollarea/module-scrollarea.css +77 -0
  275. package/examples/module-scrollarea/module-scrollarea.html +189 -0
  276. package/examples/module-scrollarea/module-scrollarea.spec.ts +445 -0
  277. package/examples/module-scrollarea/module-scrollarea.ts +81 -0
  278. package/examples/module-tabgroup/module-tabgroup.css +55 -0
  279. package/examples/module-tabgroup/module-tabgroup.html +269 -0
  280. package/examples/module-tabgroup/module-tabgroup.spec.ts +631 -0
  281. package/examples/module-tabgroup/module-tabgroup.ts +102 -0
  282. package/examples/module-toc/module-toc.css +34 -0
  283. package/examples/module-todo/module-todo.css +84 -0
  284. package/examples/module-todo/module-todo.html +92 -0
  285. package/examples/module-todo/module-todo.spec.ts +528 -0
  286. package/examples/module-todo/module-todo.ts +91 -0
  287. package/examples/section-hero/section-hero.css +37 -0
  288. package/examples/section-menu/section-menu.css +81 -0
  289. package/examples/server.ts +95 -0
  290. package/examples/test-setup.md +314 -0
  291. package/index.dev.js +1688 -0
  292. package/index.dev.ts +127 -0
  293. package/index.js +3 -0
  294. package/index.js.map +42 -0
  295. package/index.ts +127 -0
  296. package/package.json +64 -0
  297. package/playwright.config.ts +31 -0
  298. package/server/BUILD_SYSTEM.md +428 -0
  299. package/server/SERVER.md +286 -0
  300. package/server/build.ts +91 -0
  301. package/server/config.ts +130 -0
  302. package/server/effects/api.ts +28 -0
  303. package/server/effects/css.ts +31 -0
  304. package/server/effects/examples.ts +109 -0
  305. package/server/effects/js.ts +32 -0
  306. package/server/effects/menu.ts +34 -0
  307. package/server/effects/pages.ts +178 -0
  308. package/server/effects/service-worker.ts +57 -0
  309. package/server/effects/sitemap.ts +27 -0
  310. package/server/file-signals.ts +361 -0
  311. package/server/file-watcher.ts +77 -0
  312. package/server/io.ts +174 -0
  313. package/server/layout-engine.ts +470 -0
  314. package/server/layout-utils.ts +615 -0
  315. package/server/layouts/api.html +76 -0
  316. package/server/layouts/base.html +37 -0
  317. package/server/layouts/blog.html +115 -0
  318. package/server/layouts/example.html +104 -0
  319. package/server/layouts/overview.html +165 -0
  320. package/server/layouts/page.html +36 -0
  321. package/server/layouts/test.html +24 -0
  322. package/server/markdoc-helpers.ts +217 -0
  323. package/server/markdoc.config.ts +29 -0
  324. package/server/schema/callout.markdoc.ts +17 -0
  325. package/server/schema/carousel.markdoc.ts +118 -0
  326. package/server/schema/demo.markdoc.ts +74 -0
  327. package/server/schema/fence.markdoc.ts +84 -0
  328. package/server/schema/heading.markdoc.ts +23 -0
  329. package/server/schema/hero.markdoc.ts +59 -0
  330. package/server/schema/section.markdoc.ts +10 -0
  331. package/server/schema/slide.markdoc.ts +17 -0
  332. package/server/schema/source.markdoc.ts +53 -0
  333. package/server/schema/tabgroup.markdoc.ts +102 -0
  334. package/server/serve.ts +635 -0
  335. package/server/templates/README.md +352 -0
  336. package/server/templates/constants.ts +236 -0
  337. package/server/templates/fragments.ts +159 -0
  338. package/server/templates/hmr.ts +269 -0
  339. package/server/templates/menu.ts +33 -0
  340. package/server/templates/performance-hints.ts +94 -0
  341. package/server/templates/service-worker.ts +403 -0
  342. package/server/templates/sitemap.ts +57 -0
  343. package/server/templates/toc.ts +41 -0
  344. package/server/templates/utils.ts +378 -0
  345. package/src/component.ts +215 -0
  346. package/src/context.ts +156 -0
  347. package/src/effects/attribute.ts +82 -0
  348. package/src/effects/class.ts +28 -0
  349. package/src/effects/event.ts +67 -0
  350. package/src/effects/html.ts +60 -0
  351. package/src/effects/method.ts +57 -0
  352. package/src/effects/pass.ts +103 -0
  353. package/src/effects/property.ts +57 -0
  354. package/src/effects/style.ts +34 -0
  355. package/src/effects/text.ts +28 -0
  356. package/src/effects.ts +412 -0
  357. package/src/errors.ts +160 -0
  358. package/src/parsers/boolean.ts +14 -0
  359. package/src/parsers/json.ts +33 -0
  360. package/src/parsers/number.ts +55 -0
  361. package/src/parsers/string.ts +32 -0
  362. package/src/parsers.ts +90 -0
  363. package/src/scheduler.ts +47 -0
  364. package/src/signals/collection.ts +253 -0
  365. package/src/signals/sensor.ts +131 -0
  366. package/src/ui.ts +236 -0
  367. package/src/util.ts +187 -0
  368. package/tsconfig.json +34 -0
  369. package/types/examples/basic-button/basic-button.d.ts +16 -0
  370. package/types/examples/basic-hello/basic-hello.d.ts +18 -0
  371. package/types/index.d.ts +27 -0
  372. package/types/index.dev.d.ts +27 -0
  373. package/types/src/collection.d.ts +27 -0
  374. package/types/src/component.d.ts +32 -0
  375. package/types/src/context.d.ts +85 -0
  376. package/types/src/effects/attribute.d.ts +23 -0
  377. package/types/src/effects/callMethod.d.ts +23 -0
  378. package/types/src/effects/class.d.ts +13 -0
  379. package/types/src/effects/dangerouslySetInnerHTML.d.ts +18 -0
  380. package/types/src/effects/event.d.ts +18 -0
  381. package/types/src/effects/html.d.ts +17 -0
  382. package/types/src/effects/method.d.ts +22 -0
  383. package/types/src/effects/pass.d.ts +18 -0
  384. package/types/src/effects/property.d.ts +22 -0
  385. package/types/src/effects/setAttribute.d.ts +24 -0
  386. package/types/src/effects/setProperty.d.ts +23 -0
  387. package/types/src/effects/setStyle.d.ts +14 -0
  388. package/types/src/effects/setText.d.ts +13 -0
  389. package/types/src/effects/style.d.ts +13 -0
  390. package/types/src/effects/text.d.ts +12 -0
  391. package/types/src/effects/toggleClass.d.ts +14 -0
  392. package/types/src/effects.d.ts +153 -0
  393. package/types/src/errors.d.ts +99 -0
  394. package/types/src/events.d.ts +27 -0
  395. package/types/src/extractors.d.ts +23 -0
  396. package/types/src/parsers/boolean.d.ts +10 -0
  397. package/types/src/parsers/json.d.ts +13 -0
  398. package/types/src/parsers/number.d.ts +21 -0
  399. package/types/src/parsers/string.d.ts +19 -0
  400. package/types/src/parsers.d.ts +41 -0
  401. package/types/src/scheduler.d.ts +11 -0
  402. package/types/src/sensor.d.ts +27 -0
  403. package/types/src/signals/collection.d.ts +32 -0
  404. package/types/src/signals/sensor.d.ts +27 -0
  405. package/types/src/ui.d.ts +37 -0
  406. package/types/src/util.d.ts +65 -0
@@ -0,0 +1,33 @@
1
+ [**le-truc**](../README.md)
2
+
3
+ ***
4
+
5
+ [le-truc](../globals.md) / toError
6
+
7
+ # Variable: toError()
8
+
9
+ > `const` **toError**: (`reason`) => `Error`
10
+
11
+ Defined in: node\_modules/@zeix/cause-effect/types/src/util.d.ts:12
12
+
13
+ ## Parameters
14
+
15
+ ### reason
16
+
17
+ `unknown`
18
+
19
+ ## Returns
20
+
21
+ `Error`
22
+
23
+ ## Name
24
+
25
+ Le Truc
26
+
27
+ ## Version
28
+
29
+ 0.15.0
30
+
31
+ ## Author
32
+
33
+ Esther Brunner
@@ -0,0 +1,33 @@
1
+ [**le-truc**](../README.md)
2
+
3
+ ***
4
+
5
+ [le-truc](../globals.md) / valueString
6
+
7
+ # Variable: valueString()
8
+
9
+ > `const` **valueString**: (`value`) => `string`
10
+
11
+ Defined in: node\_modules/@zeix/cause-effect/types/src/util.d.ts:15
12
+
13
+ ## Parameters
14
+
15
+ ### value
16
+
17
+ `unknown`
18
+
19
+ ## Returns
20
+
21
+ `string`
22
+
23
+ ## Name
24
+
25
+ Le Truc
26
+
27
+ ## Version
28
+
29
+ 0.15.0
30
+
31
+ ## Author
32
+
33
+ Esther Brunner
@@ -0,0 +1,44 @@
1
+ <section-menu>
2
+ <nav>
3
+ <h2 class="visually-hidden">Main Menu</h2>
4
+ <ol>
5
+ <li>
6
+ <a href="index.html">
7
+ <span class="icon">📖</span>
8
+ <strong>Introduction</strong>
9
+ <small>Overview and key benefits of Le Truc</small>
10
+ </a>
11
+ </li><li>
12
+ <a href="getting-started.html">
13
+ <span class="icon">🚀</span>
14
+ <strong>Getting Started</strong>
15
+ <small>Installation, setup, and first steps</small>
16
+ </a>
17
+ </li><li>
18
+ <a href="components.html">
19
+ <span class="icon">🏗️</span>
20
+ <strong>Components</strong>
21
+ <small>Anatomy, lifecycle, signals, effects</small>
22
+ </a>
23
+ </li><li>
24
+ <a href="styling.html">
25
+ <span class="icon">🎨</span>
26
+ <strong>Styling</strong>
27
+ <small>Scoped styles, CSS custom properties</small>
28
+ </a>
29
+ </li><li>
30
+ <a href="data-flow.html">
31
+ <span class="icon">🔄</span>
32
+ <strong>Data Flow</strong>
33
+ <small>Passing state, events, context</small>
34
+ </a>
35
+ </li><li>
36
+ <a href="about.html">
37
+ <span class="icon">🤝</span>
38
+ <strong>About</strong>
39
+ <small>License, versioning, getting involved</small>
40
+ </a>
41
+ </li>
42
+ </ol>
43
+ </nav>
44
+ </section-menu>
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: 'About'
3
+ emoji: '🤝'
4
+ description: 'License, versioning, getting involved'
5
+ ---
6
+
7
+ {% hero %}
8
+ # 🤝 About
9
+
10
+ **Join the Le Truc community!** This page covers the people behind Le Truc, how you can contribute, versioning details, and licensing. Whether you're a developer, designer, or sponsor, there are many ways to get involved.
11
+ {% /hero %}
12
+
13
+ {% section %}
14
+ ## Who's Behind Le Truc?
15
+
16
+ Le Truc is an **open-source project**, actively developed by [Zeix AG](https://zeix.com), a Switzerland-based agency for User-Centered Design, committed to enhancing accessibility and usability in web technologies.
17
+
18
+ ### Core Team & Contributors
19
+
20
+ - **Zeix AG**: [@zeixcom](https://github.com/zeixcom) – Maintainers and primary developers
21
+ - **Esther Brunner**: [@estherbrunner](https://github.com/estherbrunner) – Lead developer
22
+ - **Fabian Haefliger**: [@fabianhaef](https://github.com/fabianhaef) – Core team
23
+
24
+ ### Sponsors
25
+
26
+ {% callout class="note" %}
27
+ **Become a Sponsor**
28
+
29
+ Le Truc is free and open-source. If your organization finds it valuable, consider [sponsoring its development](info@zeix.com) to help make web development **lightweight, accessible, and fun** again!
30
+ {% /callout %}
31
+
32
+ {% /section %}
33
+
34
+ {% section %}
35
+ ## License
36
+
37
+ This project is licensed under the [MIT License](https://opensource.org/licenses/MIT), which means you can **use, modify, and distribute** it freely – even in commercial projects.
38
+
39
+ A copy of the license can be found in the [LICENSE](https://github.com/zeixcom/le-truc/blob/main/LICENSE) file of the repository.
40
+
41
+ {% /section %}
42
+
43
+ {% section %}
44
+
45
+ ## Version History
46
+
47
+ ### Current Version: 0.15.0
48
+
49
+ {% callout class="caution" %}
50
+
51
+ **Release candidate**
52
+
53
+ This version is a **pre-release** of Le Truc, meaning **breaking changes** may still occur before the official release of version 1.0. Please check the [release notes](https://github.com/zeixcom/le-truc/releases) before updating.
54
+
55
+ {% /callout %}
56
+
57
+ ### Versioning Scheme
58
+
59
+ Le Truc follows [Semantic Versioning](https://semver.org/) (SemVer), which is structured as `MAJOR.MINOR.PATCH`.
60
+
61
+ - **MAJOR**: Breaking changes that require migrations.
62
+ - **MINOR**: New features that are backwards compatible.
63
+ - **PATCH**: Bug fixes and performance improvements.
64
+
65
+ ### Previous Pre-Releases
66
+
67
+ View all releases and associated notes on [Github Releases](https://github.com/zeixcom/le-truc/releases).
68
+
69
+ {% /section %}
70
+
71
+ {% section %}
72
+ ## Getting Involved
73
+
74
+ Le Truc is **an open-source project**, and contributions are always welcome! Whether you’re **reporting bugs, improving documentation, or suggesting features**, here's how you can help:
75
+
76
+ - [Open an Issue](https://github.com/zeixcom/le-truc/issues) – Report bugs or suggest features.
77
+ - [Submit a Pull Request](https://github.com/zeixcom/le-truc/blob/main/CONTRIBUTING.md) – Help improve Le Truc by fixing issues or adding new features.
78
+ - Join the Discussion – Share ideas and get feedback from the community.
79
+
80
+ ### Contributing Code
81
+
82
+ - Fork the repository, create a new branch, and submit a pull request.
83
+ - Read the [Contributing Guidelines](https://github.com/zeixcom/le-truc/blob/main/CONTRIBUTING.md) for setting up a development environment and best practices.
84
+
85
+ ### Community Guidelines
86
+
87
+ We strive for a welcoming and inclusive environment. Please follow our [Code of Conduct](https://github.com/zeixcom/le-truc/blob/main/CODE_OF_CONDUCT.md) when contributing.
88
+
89
+ {% /section %}
@@ -0,0 +1,437 @@
1
+ ---
2
+ title: 'Components'
3
+ emoji: '🏗️'
4
+ description: 'Anatomy, lifecycle, signals, effects'
5
+ ---
6
+
7
+ {% hero %}
8
+ # 🏗️ Components
9
+
10
+ **Create lightweight, self-contained Web Components with built-in reactivity**. Le Truc lets you define custom elements that manage state efficiently, update the DOM automatically, and enhance server-rendered pages without an SPA framework.
11
+ {% /hero %}
12
+
13
+ {% section %}
14
+ ## Defining a Component
15
+
16
+ Le Truc builds on **Web Components**, extending `HTMLElement` to provide **built-in state management and reactive updates**.
17
+
18
+ Le Truc creates components using the `defineComponent()` function:
19
+
20
+ ```js
21
+ defineComponent('my-component', {}, {}, () => [
22
+ // Component setup
23
+ ])
24
+ ```
25
+
26
+ Every Le Truc component must be registered with a valid custom element tag name (two or more words joined with `-`) as the first parameter.
27
+
28
+ ### Using the Custom Element in HTML
29
+
30
+ Once registered, the component can be used like any native HTML element:
31
+
32
+ ```html
33
+ <my-component>Content goes here</my-component>
34
+ ```
35
+
36
+ ### Anatomy of a Component
37
+
38
+ Let's examine a complete component example to understand how Le Truc works:
39
+
40
+ ```js
41
+ defineComponent(
42
+ 'basic-hello',
43
+ {
44
+ name: asString(ui => ui.output.textContent),
45
+ },
46
+ ({ first }) => ({
47
+ input: first('input', 'Needed to enter the name.'),
48
+ output: first('output', 'Needed to display the name.'),
49
+ }),
50
+ ({ host, input }) => {
51
+ const fallback = host.name
52
+ return {
53
+ input: on('input', () => {
54
+ host.name = input.value || fallback
55
+ }),
56
+ output: setText('name'),
57
+ }
58
+ },
59
+ )
60
+ ```
61
+
62
+ #### Reactive Properties
63
+
64
+ ```js
65
+ {
66
+ name: asString(ui => ui.output.textContent),
67
+ }
68
+ ```
69
+
70
+ This creates a reactive property called `name`:
71
+
72
+ - `asString()` observes the attribute `name` and assigns its value as a string to the `name` property
73
+ - `ui => ...` is an instruction how to get the fallback value in the DOM if there is no name attribute
74
+ - Le Truc automatically reads "World" from the `<output>` element as the initial value
75
+ - When `name` changes, any effects that depend on it automatically update
76
+
77
+ #### Select Function
78
+
79
+ The select function is used to find descendant elements within the component's DOM:
80
+
81
+ ```js
82
+ ({ first }) => ({
83
+ input: first('input', 'Needed to enter the name.'),
84
+ output: first('output', 'Needed to display the name.'),
85
+ }),
86
+ ```
87
+
88
+ The select function must return a record of the selected elements, commonly called `ui` to which initializer functions for reactive properties and the setup function for effects have access to. In the above example, the helper function `first()` is used to find the first descendant matching a selector. Also available is `all()` to find all descendants matching a selector, dynamically updating the list of elements when the DOM changes. Both helper functions take a selector string and an optional error message to display if no element is found.
89
+
90
+ #### Setup Function
91
+
92
+ The setup function must return a record with an array of effects for properties of the `ui` object that is passed in. The additional `host` key of the `ui` object holds the component element itself.
93
+
94
+ ```js
95
+ ({ host, input }) => {
96
+ const fallback = host.name
97
+ return {
98
+ input: on('input', () => {
99
+ host.name = input.value || fallback
100
+ }),
101
+ output: setText('name'),
102
+ }
103
+ },
104
+ ```
105
+
106
+ Effects define **component behaviors**:
107
+
108
+ - `input: on('input', ...)` adds an event listener to the `<input>` element
109
+ - `output: setText('name')` keeps its text in sync with the `name` property
110
+
111
+ Characteristics of effects:
112
+
113
+ - Effects run when the component is added to the page
114
+ - Effects rerun when their dependencies change
115
+ - Effects may return a cleanup function to be executed when the target element or the component is removed from the page
116
+
117
+ The bundled effects `on()` and `setText()` in this case are partially applied functions that connect to component properties and the target element and return the appropriate cleanup function.
118
+
119
+ {% /section %}
120
+
121
+ {% section %}
122
+ ## Component Lifecycle
123
+
124
+ Le Truc manages the **Web Component lifecycle** from creation to removal. Here's what happens.
125
+
126
+ ### Connected to the DOM
127
+
128
+ In the `connectedCallback()` reactive properties are initialized. You pass a second argument to the `defineComponent()` function to define initial values for **component states**.
129
+
130
+ ```js
131
+ defineComponent(
132
+ 'my-component',
133
+ {
134
+ count: 0, // Initial value of "count" signal
135
+ value: asInteger(5), // Parse "value" attribute as integer defaulting to 5
136
+ isEven: ui => () => !(ui.host.count % 2), // Computed signal based on "count" signal
137
+ name: fromContext('display-name', 'World'), // Consume "display-name" signal from closest context provider
138
+ },
139
+ () => ({
140
+ // Component UI
141
+ }),
142
+ ui => ({
143
+ // Component setup
144
+ })
145
+ )
146
+ ```
147
+
148
+ In this example you see all three ways to define a reactive property:
149
+
150
+ - A **static initial value** creates a `State` signal with the initial value
151
+ - An **attribute parser** creates a `State` signal may from the attribute or fallback value, updating the state whenever the attribute changes
152
+ - An **initializer** function that creates a `State` or a `Computed` signal depending on the return type of the function. If the function returns a value, it creates a `State` signal. If the function returns a function, it creates a `Computed` signal. Initializer functions have access to the component's `ui` object, allowing them to create signals based on the component's state or descendant elements.
153
+
154
+ ### Disconnected from the DOM
155
+
156
+ In the `disconnectedCallback()` Le Truc runs all cleanup functions returned by effects during the setup phase in `connectedCallback()`. This will remove all event listeners and unsubscribe all signals the component is subscribed to, so you don't need to worry about memory leaks.
157
+
158
+ If you added **event listeners** outside the scope of your component or **subscribed manually to external APIs** in a custom effect, you need to return a cleanup function:
159
+
160
+ ```js
161
+ defineComponent('my-component', {}, {}, ({ host }) => {
162
+ // Setup logic
163
+ host: () => {
164
+ const observer = new IntersectionObserver(([entry]) => {
165
+ // Do something
166
+ })
167
+ observer.observe(host)
168
+
169
+ // Cleanup logic
170
+ return () => observer.disconnect()
171
+ },
172
+ })
173
+ ```
174
+
175
+ ## Managing State with Signals
176
+
177
+ Le Truc manages state using **signals**, which are atomic reactive states that trigger updates when they change. We use regular properties for public component states:
178
+
179
+ ```js
180
+ console.log('count' in el) // Check if the signal exists
181
+ console.log(el.count) // Read the signal value
182
+ el.count = 42 // Update the signal value
183
+ ```
184
+
185
+ ### Characteristics and Special Values
186
+
187
+ Signals in Le Truc are of a **static type** and **non-nullable**. This allows to **simplify the logic** as you will never have to check the type or perform null-checks.
188
+
189
+ - If you use **TypeScript** (recommended), **you will be warned** that `null` or `undefined` cannot be assigned to a signal or if you try to assign a value of a wrong type.
190
+ - If you use vanilla **JavaScript** without a build step, setting a signal to `null` or `undefined` **will throw a `NullishSignalValueError`**. However, strict type checking is not enforced at runtime.
191
+
192
+ Because of the **non-nullable nature of signals** in Le Truc, we need two special values that can be assigned to any signal type:
193
+
194
+ - **`RESET`**: Will **reset to the server-rendered version** that was there before Le Truc took control. This is what you want to do most of the times when a signal lacks a specific value.
195
+ - **`UNSET`**: Will **delete the signal**, **unsubscribe its watchers** and also **delete related attributes or style properties** in effects. Use this with special care!
196
+
197
+ ### Initializing State from Attributes
198
+
199
+ The standard way to set initial state in Le Truc is via **server-rendered attributes** on the component that needs it. No props drilling as in other frameworks. Le Trucs provides some bundled attribute parsers to convert attribute values to the desired type. And you can also define your own custom parsers.
200
+
201
+ ```js
202
+ defineComponent(
203
+ 'my-component',
204
+ {
205
+ count: asInteger(), // Bundled parser: Convert '42' -> 42
206
+ date: (_, v) => new Date(v), // Custom parser: '2025-12-12' -> Date object
207
+ },
208
+ () => ({
209
+ // Component UI
210
+ })
211
+ () => ({
212
+ // Component setup
213
+ }),
214
+ )
215
+ ```
216
+
217
+ {% callout class="caution" %}
218
+ **Careful**: Attributes **may not be present** on the element or **parsing to the desired type may fail**. To ensure **non-nullability** of signals, Le Truc falls back to neutral defaults if no fallback value is provided:
219
+
220
+ - `""` (empty string) for `string`
221
+ - `0` for `number`
222
+ - `{}` (empty object) for objects of any kind
223
+ {% /callout %}
224
+
225
+ ### Bundled Attribute Parsers
226
+
227
+ Le Truc provides several built-in parsers for common attribute types. See the [Parsers section](api.html#parsers) in the API reference for detailed descriptions and usage examples.
228
+
229
+ {% /section %}
230
+
231
+ {% section %}
232
+
233
+ ## Selecting Elements
234
+
235
+ Use the provided selector utilities to find descendant elements within your component:
236
+
237
+ ### first()
238
+
239
+ Selects the first matching element:
240
+
241
+ ```js
242
+ defineComponent(
243
+ 'basic-counter',
244
+ {
245
+ // Initialize properties
246
+ },
247
+ ({ first }) => ({
248
+ increment: first(
249
+ 'button',
250
+ 'Add a native button element to increment the count.',
251
+ ),
252
+ count: first('span', 'Add a span to display the count.'),
253
+ }),
254
+ ui => ({
255
+ // Component setup
256
+ }),
257
+ )
258
+ ```
259
+
260
+ ### all()
261
+
262
+ Selects all matching elements:
263
+
264
+ ```js
265
+ defineComponent(
266
+ 'module-tabgroup',
267
+ {
268
+ // Initialize properties
269
+ },
270
+ ({ all }) => ({
271
+ tabs: all(
272
+ 'button[role="tab"]',
273
+ 'At least 2 tabs as children of a <[role="tablist"]> element are needed. Each tab must reference a unique id of a <[role="tabpanel"]> element.',
274
+ ),
275
+ panels: all(
276
+ '[role="tabpanel"]',
277
+ 'At least 2 tabpanels are needed. Each tabpanel must have a unique id.',
278
+ ),
279
+ }),
280
+ ui => ({
281
+ // Component setup
282
+ }),
283
+ )
284
+ ```
285
+
286
+ The `first()` function expects the matched element to be present at connection time. If not, it will silently ignore the call.
287
+
288
+ On the other hand, the `all()` function creates a dynamic array of elements that will be updated whenever the matching elements are added or removed from the component's DOM branch. Le Truc will apply the given setup functions to added elements and run the cleanup functions on removed elements.
289
+
290
+ {% callout class="tip" %}
291
+ **Tip**: The `all()` function is more flexible but also more resource-intensive than `first()`. Prefer `first()` when targeting a single element known to be present at connection time.
292
+ {% /callout %}
293
+
294
+ {% /section %}
295
+
296
+ {% section %}
297
+
298
+ ## Adding Event Listeners
299
+
300
+ Event listeners allow to respond to user interactions. They are the the main cause for changes in the component's state. Le Truc provides the `on()` function to add event listeners to elements and remove them when the component is disconnected.
301
+
302
+ ```js
303
+ defineComponent(
304
+ 'my-component',
305
+ {
306
+ active: 0,
307
+ value: ''
308
+ },
309
+ ({ all, first }) => ({
310
+ buttons: all('button'),
311
+ input: first('input')
312
+ }),
313
+ ({ host, input }) => ({
314
+ buttons: on('click', ({ target }) => {
315
+ // Set 'active' signal to value of data-index attribute of button
316
+ const index = parseInt(target.dataset.index, 10);
317
+ host.active = Number.isInteger(index) ? index : 0;
318
+ })
319
+ input: on('change', () => {
320
+ // Set 'value' signal to value of input element
321
+ host.value = target.value;
322
+ })
323
+ })
324
+ )
325
+ ```
326
+
327
+ {% /section %}
328
+
329
+ {% section %}
330
+
331
+ ## Synchronizing State with Effects
332
+
333
+ Effects **automatically update the DOM** when signals change, avoiding manual DOM manipulation.
334
+
335
+ ### Applying Effects
336
+
337
+ Apply one or multiple effects in the setup function (for component itself) or in element selector functions:
338
+
339
+ ```js
340
+ return {
341
+ // On the component itself
342
+ host: setAttribute('open', 'open'), // Set 'open' attribute according to 'open' signal
343
+ // On element for the 'count' property of the UI object
344
+ count: [
345
+ setText('count'), // Update text content according to 'count' signal
346
+ toggleClass('even', 'isEven') // Toggle 'even' class according to 'isEven' signal
347
+ ]
348
+ }
349
+ ```
350
+
351
+ The order of effects is not important. Feel free to apply them in any order that suits your needs.
352
+
353
+ ### Bundled Effects
354
+
355
+ Le Truc provides many built-in effects for common DOM operations. See the [Effects section](api.html#effects) in the API reference for detailed descriptions and usage examples.
356
+
357
+ ### Simplifying Effect Notation
358
+
359
+ For effects that take two arguments, **the second argument can be omitted** if the signal key matches the targeted property name, attribute, class, or style property.
360
+
361
+ The following are equivalent:
362
+
363
+ ```js
364
+ // setAttribute('open', 'open')
365
+ setAttribute('open')
366
+ ```
367
+
368
+ Here, `setAttribute('open')` automatically uses the `open` signal.
369
+
370
+ ### Using Local Signals for Private State
371
+
372
+ Local signals are useful for storing state that should not be exposed to the outside world. They can be used to manage internal state within a component:
373
+
374
+ ```js
375
+ defineComponent(
376
+ 'my-component',
377
+ {},
378
+ ({ first }) => ({
379
+ increment: first('button.increment'),
380
+ count: first('.count'),
381
+ double: first('.double')
382
+ }),
383
+ () => {
384
+ const count = createState(0)
385
+ const double = createComputed(() => count.get() * 2)
386
+ return {
387
+ increment: on('click', () => {
388
+ count.update(v => ++v)
389
+ }),
390
+ count: setText(count),
391
+ double: setText(double),
392
+ }
393
+ }
394
+ )
395
+ ```
396
+
397
+ Outside components cannot access the `count` or `double` signals.
398
+
399
+ ### Using Functions for Ad-hoc Derived State
400
+
401
+ Instead of a signal key or a local signal, you can **pass a function** that derives a value dynamically:
402
+
403
+ ```js
404
+ defineComponent(
405
+ 'my-component',
406
+ {
407
+ count: 0,
408
+ },
409
+ ({ first }) => ({
410
+ count: first('.count'),
411
+ double: first('.double')
412
+ }),
413
+ ({ host }) => ({
414
+ count: toggleClass('even', () => !(host.count % 2)),
415
+ double: setText(() => String(host.count * 2))
416
+ })
417
+ )
418
+ ```
419
+
420
+ {% callout class="tip" %}
421
+ **When to use**
422
+
423
+ - **Use a signal key or a local signal** when the state is part of the component's public interface or internally reused.
424
+ - **Use a function** to **derive a value on the fly** when it is needed only in this one place.
425
+
426
+ Ad-hoc derived state is more efficient than the overhead of a memoized computed signal for simple functions like converting to a string or boolean, formatting a value or performing a calculation.
427
+ {% /callout %}
428
+
429
+ ### Efficient & Fine-Grained Updates
430
+
431
+ Unlike some frameworks that **re-render entire components**, Le Truc updates only what changes:
432
+
433
+ - **No virtual DOM** – Le Truc modifies the DOM directly.
434
+ - **Signals propagate automatically** – no need to track dependencies manually.
435
+ - **Optimized with a scheduler** – multiple updates are batched efficiently.
436
+
437
+ {% /section %}