@lo-tek/interfaces 0.0.0 → 0.38.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 (456) hide show
  1. package/CHANGELOG.md +3389 -0
  2. package/LICENSE +21 -0
  3. package/README.md +129 -1
  4. package/agent/astro.md +400 -0
  5. package/agent/bundles.md +429 -0
  6. package/agent/datastar.md +409 -0
  7. package/agent/html.md +388 -0
  8. package/agent/react.md +440 -0
  9. package/agent/templates.md +472 -0
  10. package/core/lotek-core.wasm +0 -0
  11. package/core/lotek.wasm +0 -0
  12. package/dist/cli.d.ts +12 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +14 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/components/css/accordion/accordion.d.ts +37 -0
  17. package/dist/components/css/accordion/accordion.d.ts.map +1 -0
  18. package/dist/components/css/accordion/accordion.js +31 -0
  19. package/dist/components/css/accordion/accordion.js.map +1 -0
  20. package/dist/components/css/alert/alert.d.ts +35 -0
  21. package/dist/components/css/alert/alert.d.ts.map +1 -0
  22. package/dist/components/css/alert/alert.js +29 -0
  23. package/dist/components/css/alert/alert.js.map +1 -0
  24. package/dist/components/css/avatar/avatar.d.ts +40 -0
  25. package/dist/components/css/avatar/avatar.d.ts.map +1 -0
  26. package/dist/components/css/avatar/avatar.js +30 -0
  27. package/dist/components/css/avatar/avatar.js.map +1 -0
  28. package/dist/components/css/badge/badge.d.ts +24 -0
  29. package/dist/components/css/badge/badge.d.ts.map +1 -0
  30. package/dist/components/css/badge/badge.js +24 -0
  31. package/dist/components/css/badge/badge.js.map +1 -0
  32. package/dist/components/css/breadcrumbs/breadcrumbs.d.ts +26 -0
  33. package/dist/components/css/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  34. package/dist/components/css/breadcrumbs/breadcrumbs.js +24 -0
  35. package/dist/components/css/breadcrumbs/breadcrumbs.js.map +1 -0
  36. package/dist/components/css/button/button.d.ts +26 -0
  37. package/dist/components/css/button/button.d.ts.map +1 -0
  38. package/dist/components/css/button/button.js +25 -0
  39. package/dist/components/css/button/button.js.map +1 -0
  40. package/dist/components/css/card/card.d.ts +36 -0
  41. package/dist/components/css/card/card.d.ts.map +1 -0
  42. package/dist/components/css/card/card.js +28 -0
  43. package/dist/components/css/card/card.js.map +1 -0
  44. package/dist/components/css/checkbox/checkbox.d.ts +32 -0
  45. package/dist/components/css/checkbox/checkbox.d.ts.map +1 -0
  46. package/dist/components/css/checkbox/checkbox.js +27 -0
  47. package/dist/components/css/checkbox/checkbox.js.map +1 -0
  48. package/dist/components/css/divider/divider.d.ts +29 -0
  49. package/dist/components/css/divider/divider.d.ts.map +1 -0
  50. package/dist/components/css/divider/divider.js +23 -0
  51. package/dist/components/css/divider/divider.js.map +1 -0
  52. package/dist/components/css/error-text/error-text.d.ts +24 -0
  53. package/dist/components/css/error-text/error-text.d.ts.map +1 -0
  54. package/dist/components/css/error-text/error-text.js +18 -0
  55. package/dist/components/css/error-text/error-text.js.map +1 -0
  56. package/dist/components/css/fieldset/fieldset.d.ts +55 -0
  57. package/dist/components/css/fieldset/fieldset.d.ts.map +1 -0
  58. package/dist/components/css/fieldset/fieldset.js +39 -0
  59. package/dist/components/css/fieldset/fieldset.js.map +1 -0
  60. package/dist/components/css/file-upload/file-upload.d.ts +41 -0
  61. package/dist/components/css/file-upload/file-upload.d.ts.map +1 -0
  62. package/dist/components/css/file-upload/file-upload.js +32 -0
  63. package/dist/components/css/file-upload/file-upload.js.map +1 -0
  64. package/dist/components/css/heading/heading.d.ts +29 -0
  65. package/dist/components/css/heading/heading.d.ts.map +1 -0
  66. package/dist/components/css/heading/heading.js +23 -0
  67. package/dist/components/css/heading/heading.js.map +1 -0
  68. package/dist/components/css/help-text/help-text.d.ts +24 -0
  69. package/dist/components/css/help-text/help-text.d.ts.map +1 -0
  70. package/dist/components/css/help-text/help-text.js +23 -0
  71. package/dist/components/css/help-text/help-text.js.map +1 -0
  72. package/dist/components/css/icon/icon.d.ts +34 -0
  73. package/dist/components/css/icon/icon.d.ts.map +1 -0
  74. package/dist/components/css/icon/icon.js +25 -0
  75. package/dist/components/css/icon/icon.js.map +1 -0
  76. package/dist/components/css/input/input.d.ts +40 -0
  77. package/dist/components/css/input/input.d.ts.map +1 -0
  78. package/dist/components/css/input/input.js +45 -0
  79. package/dist/components/css/input/input.js.map +1 -0
  80. package/dist/components/css/label/label.d.ts +33 -0
  81. package/dist/components/css/label/label.d.ts.map +1 -0
  82. package/dist/components/css/label/label.js +23 -0
  83. package/dist/components/css/label/label.js.map +1 -0
  84. package/dist/components/css/link/link.d.ts +28 -0
  85. package/dist/components/css/link/link.d.ts.map +1 -0
  86. package/dist/components/css/link/link.js +20 -0
  87. package/dist/components/css/link/link.js.map +1 -0
  88. package/dist/components/css/list/list.d.ts +31 -0
  89. package/dist/components/css/list/list.d.ts.map +1 -0
  90. package/dist/components/css/list/list.js +25 -0
  91. package/dist/components/css/list/list.js.map +1 -0
  92. package/dist/components/css/pagination/pagination.d.ts +27 -0
  93. package/dist/components/css/pagination/pagination.d.ts.map +1 -0
  94. package/dist/components/css/pagination/pagination.js +25 -0
  95. package/dist/components/css/pagination/pagination.js.map +1 -0
  96. package/dist/components/css/paragraph/paragraph.d.ts +36 -0
  97. package/dist/components/css/paragraph/paragraph.d.ts.map +1 -0
  98. package/dist/components/css/paragraph/paragraph.js +26 -0
  99. package/dist/components/css/paragraph/paragraph.js.map +1 -0
  100. package/dist/components/css/progress/progress.d.ts +53 -0
  101. package/dist/components/css/progress/progress.d.ts.map +1 -0
  102. package/dist/components/css/progress/progress.js +38 -0
  103. package/dist/components/css/progress/progress.js.map +1 -0
  104. package/dist/components/css/radio/radio.d.ts +32 -0
  105. package/dist/components/css/radio/radio.d.ts.map +1 -0
  106. package/dist/components/css/radio/radio.js +27 -0
  107. package/dist/components/css/radio/radio.js.map +1 -0
  108. package/dist/components/css/search/search.d.ts +34 -0
  109. package/dist/components/css/search/search.d.ts.map +1 -0
  110. package/dist/components/css/search/search.js +32 -0
  111. package/dist/components/css/search/search.js.map +1 -0
  112. package/dist/components/css/select/select.d.ts +40 -0
  113. package/dist/components/css/select/select.d.ts.map +1 -0
  114. package/dist/components/css/select/select.js +31 -0
  115. package/dist/components/css/select/select.js.map +1 -0
  116. package/dist/components/css/shared.d.ts +90 -0
  117. package/dist/components/css/shared.d.ts.map +1 -0
  118. package/dist/components/css/shared.js +167 -0
  119. package/dist/components/css/shared.js.map +1 -0
  120. package/dist/components/css/skeleton/skeleton.d.ts +29 -0
  121. package/dist/components/css/skeleton/skeleton.d.ts.map +1 -0
  122. package/dist/components/css/skeleton/skeleton.js +23 -0
  123. package/dist/components/css/skeleton/skeleton.js.map +1 -0
  124. package/dist/components/css/skip-link/skip-link.d.ts +18 -0
  125. package/dist/components/css/skip-link/skip-link.d.ts.map +1 -0
  126. package/dist/components/css/skip-link/skip-link.js +16 -0
  127. package/dist/components/css/skip-link/skip-link.js.map +1 -0
  128. package/dist/components/css/spinner/spinner.d.ts +33 -0
  129. package/dist/components/css/spinner/spinner.d.ts.map +1 -0
  130. package/dist/components/css/spinner/spinner.js +25 -0
  131. package/dist/components/css/spinner/spinner.js.map +1 -0
  132. package/dist/components/css/sr-only/sr-only.d.ts +17 -0
  133. package/dist/components/css/sr-only/sr-only.d.ts.map +1 -0
  134. package/dist/components/css/sr-only/sr-only.js +15 -0
  135. package/dist/components/css/sr-only/sr-only.js.map +1 -0
  136. package/dist/components/css/switch/switch.d.ts +37 -0
  137. package/dist/components/css/switch/switch.d.ts.map +1 -0
  138. package/dist/components/css/switch/switch.js +29 -0
  139. package/dist/components/css/switch/switch.js.map +1 -0
  140. package/dist/components/css/table/table.d.ts +76 -0
  141. package/dist/components/css/table/table.d.ts.map +1 -0
  142. package/dist/components/css/table/table.js +59 -0
  143. package/dist/components/css/table/table.js.map +1 -0
  144. package/dist/components/css/tag/tag.d.ts +35 -0
  145. package/dist/components/css/tag/tag.d.ts.map +1 -0
  146. package/dist/components/css/tag/tag.js +27 -0
  147. package/dist/components/css/tag/tag.js.map +1 -0
  148. package/dist/components/css/textarea/textarea.d.ts +23 -0
  149. package/dist/components/css/textarea/textarea.d.ts.map +1 -0
  150. package/dist/components/css/textarea/textarea.js +18 -0
  151. package/dist/components/css/textarea/textarea.js.map +1 -0
  152. package/dist/components/css/toggle-group/toggle-group.d.ts +31 -0
  153. package/dist/components/css/toggle-group/toggle-group.d.ts.map +1 -0
  154. package/dist/components/css/toggle-group/toggle-group.js +29 -0
  155. package/dist/components/css/toggle-group/toggle-group.js.map +1 -0
  156. package/dist/components/css/tooltip/tooltip.d.ts +31 -0
  157. package/dist/components/css/tooltip/tooltip.d.ts.map +1 -0
  158. package/dist/components/css/tooltip/tooltip.js +29 -0
  159. package/dist/components/css/tooltip/tooltip.js.map +1 -0
  160. package/dist/components/default-texts.d.ts +41 -0
  161. package/dist/components/default-texts.d.ts.map +1 -0
  162. package/dist/components/default-texts.js +41 -0
  163. package/dist/components/default-texts.js.map +1 -0
  164. package/dist/components/events.d.ts +77 -0
  165. package/dist/components/events.d.ts.map +1 -0
  166. package/dist/components/events.js +3 -0
  167. package/dist/components/events.js.map +1 -0
  168. package/dist/components/frame/dialog/dialog.d.ts +122 -0
  169. package/dist/components/frame/dialog/dialog.d.ts.map +1 -0
  170. package/dist/components/frame/dialog/dialog.js +112 -0
  171. package/dist/components/frame/dialog/dialog.js.map +1 -0
  172. package/dist/components/frame/dialog/lt-dialog.d.ts +104 -0
  173. package/dist/components/frame/dialog/lt-dialog.d.ts.map +1 -0
  174. package/dist/components/frame/dialog/lt-dialog.js +434 -0
  175. package/dist/components/frame/dialog/lt-dialog.js.map +1 -0
  176. package/dist/components/frame/error-summary/error-summary.d.ts +53 -0
  177. package/dist/components/frame/error-summary/error-summary.d.ts.map +1 -0
  178. package/dist/components/frame/error-summary/error-summary.js +54 -0
  179. package/dist/components/frame/error-summary/error-summary.js.map +1 -0
  180. package/dist/components/frame/error-summary/lt-error-summary.d.ts +93 -0
  181. package/dist/components/frame/error-summary/lt-error-summary.d.ts.map +1 -0
  182. package/dist/components/frame/error-summary/lt-error-summary.js +408 -0
  183. package/dist/components/frame/error-summary/lt-error-summary.js.map +1 -0
  184. package/dist/components/frame/field/field-core.d.ts +92 -0
  185. package/dist/components/frame/field/field-core.d.ts.map +1 -0
  186. package/dist/components/frame/field/field-core.js +63 -0
  187. package/dist/components/frame/field/field-core.js.map +1 -0
  188. package/dist/components/frame/field/lt-field.d.ts +173 -0
  189. package/dist/components/frame/field/lt-field.d.ts.map +1 -0
  190. package/dist/components/frame/field/lt-field.js +600 -0
  191. package/dist/components/frame/field/lt-field.js.map +1 -0
  192. package/dist/components/frame/popover/lt-popover.d.ts +136 -0
  193. package/dist/components/frame/popover/lt-popover.d.ts.map +1 -0
  194. package/dist/components/frame/popover/lt-popover.js +520 -0
  195. package/dist/components/frame/popover/lt-popover.js.map +1 -0
  196. package/dist/components/frame/popover/popover.d.ts +49 -0
  197. package/dist/components/frame/popover/popover.d.ts.map +1 -0
  198. package/dist/components/frame/popover/popover.js +64 -0
  199. package/dist/components/frame/popover/popover.js.map +1 -0
  200. package/dist/components/frame/session-timeout/lt-session-timeout.d.ts +198 -0
  201. package/dist/components/frame/session-timeout/lt-session-timeout.d.ts.map +1 -0
  202. package/dist/components/frame/session-timeout/lt-session-timeout.js +610 -0
  203. package/dist/components/frame/session-timeout/lt-session-timeout.js.map +1 -0
  204. package/dist/components/frame/session-timeout/session-timeout.d.ts +113 -0
  205. package/dist/components/frame/session-timeout/session-timeout.d.ts.map +1 -0
  206. package/dist/components/frame/session-timeout/session-timeout.js +101 -0
  207. package/dist/components/frame/session-timeout/session-timeout.js.map +1 -0
  208. package/dist/components/frame/suggestion/lt-suggestion.d.ts +367 -0
  209. package/dist/components/frame/suggestion/lt-suggestion.d.ts.map +1 -0
  210. package/dist/components/frame/suggestion/lt-suggestion.js +1171 -0
  211. package/dist/components/frame/suggestion/lt-suggestion.js.map +1 -0
  212. package/dist/components/frame/suggestion/suggestion.d.ts +143 -0
  213. package/dist/components/frame/suggestion/suggestion.d.ts.map +1 -0
  214. package/dist/components/frame/suggestion/suggestion.js +127 -0
  215. package/dist/components/frame/suggestion/suggestion.js.map +1 -0
  216. package/dist/components/frame/tabs/lt-tabs.d.ts +426 -0
  217. package/dist/components/frame/tabs/lt-tabs.d.ts.map +1 -0
  218. package/dist/components/frame/tabs/lt-tabs.js +1265 -0
  219. package/dist/components/frame/tabs/lt-tabs.js.map +1 -0
  220. package/dist/components/frame/tabs/tabs.d.ts +112 -0
  221. package/dist/components/frame/tabs/tabs.d.ts.map +1 -0
  222. package/dist/components/frame/tabs/tabs.js +107 -0
  223. package/dist/components/frame/tabs/tabs.js.map +1 -0
  224. package/dist/components/host-element.d.ts +184 -0
  225. package/dist/components/host-element.d.ts.map +1 -0
  226. package/dist/components/host-element.js +440 -0
  227. package/dist/components/host-element.js.map +1 -0
  228. package/dist/components/standalone/connection-status/connection-status.d.ts +32 -0
  229. package/dist/components/standalone/connection-status/connection-status.d.ts.map +1 -0
  230. package/dist/components/standalone/connection-status/connection-status.js +26 -0
  231. package/dist/components/standalone/connection-status/connection-status.js.map +1 -0
  232. package/dist/components/standalone/connection-status/lt-connection-status.d.ts +86 -0
  233. package/dist/components/standalone/connection-status/lt-connection-status.d.ts.map +1 -0
  234. package/dist/components/standalone/connection-status/lt-connection-status.js +240 -0
  235. package/dist/components/standalone/connection-status/lt-connection-status.js.map +1 -0
  236. package/dist/components/standalone/toast/lt-toast.d.ts +109 -0
  237. package/dist/components/standalone/toast/lt-toast.d.ts.map +1 -0
  238. package/dist/components/standalone/toast/lt-toast.js +256 -0
  239. package/dist/components/standalone/toast/lt-toast.js.map +1 -0
  240. package/dist/components/standalone/toast/toast.d.ts +52 -0
  241. package/dist/components/standalone/toast/toast.d.ts.map +1 -0
  242. package/dist/components/standalone/toast/toast.js +42 -0
  243. package/dist/components/standalone/toast/toast.js.map +1 -0
  244. package/dist/diagnostics/core.d.ts +171 -0
  245. package/dist/diagnostics/core.d.ts.map +1 -0
  246. package/dist/diagnostics/core.js +84 -0
  247. package/dist/diagnostics/core.js.map +1 -0
  248. package/dist/diagnostics/default-core.d.ts +10 -0
  249. package/dist/diagnostics/default-core.d.ts.map +1 -0
  250. package/dist/diagnostics/default-core.js +72 -0
  251. package/dist/diagnostics/default-core.js.map +1 -0
  252. package/dist/diagnostics/index.d.ts +84 -0
  253. package/dist/diagnostics/index.d.ts.map +1 -0
  254. package/dist/diagnostics/index.js +106 -0
  255. package/dist/diagnostics/index.js.map +1 -0
  256. package/dist/dom.d.ts +55 -0
  257. package/dist/dom.d.ts.map +1 -0
  258. package/dist/dom.js +162 -0
  259. package/dist/dom.js.map +1 -0
  260. package/dist/index.d.ts +97 -0
  261. package/dist/index.d.ts.map +1 -0
  262. package/dist/index.js +58 -0
  263. package/dist/index.js.map +1 -0
  264. package/dist/jsx/react.d.ts +180 -0
  265. package/dist/jsx/react.d.ts.map +1 -0
  266. package/dist/jsx/react.js +2 -0
  267. package/dist/jsx/react.js.map +1 -0
  268. package/dist/lotek.css +3617 -0
  269. package/dist/lt.d.ts +325 -0
  270. package/dist/lt.d.ts.map +1 -0
  271. package/dist/lt.js +183 -0
  272. package/dist/lt.js.map +1 -0
  273. package/dist/react.d.ts +494 -0
  274. package/dist/react.d.ts.map +1 -0
  275. package/dist/react.js +296 -0
  276. package/dist/react.js.map +1 -0
  277. package/dist/register.d.ts +17 -0
  278. package/dist/register.d.ts.map +1 -0
  279. package/dist/register.js +35 -0
  280. package/dist/register.js.map +1 -0
  281. package/dist/tokens/color.d.ts +43 -0
  282. package/dist/tokens/color.d.ts.map +1 -0
  283. package/dist/tokens/color.js +123 -0
  284. package/dist/tokens/color.js.map +1 -0
  285. package/dist/tokens/contract.d.ts +18 -0
  286. package/dist/tokens/contract.d.ts.map +1 -0
  287. package/dist/tokens/contract.js +18 -0
  288. package/dist/tokens/contract.js.map +1 -0
  289. package/dist/tokens/matrix-cells.d.ts +30 -0
  290. package/dist/tokens/matrix-cells.d.ts.map +1 -0
  291. package/dist/tokens/matrix-cells.js +273 -0
  292. package/dist/tokens/matrix-cells.js.map +1 -0
  293. package/dist/tokens/matrix.d.ts +18 -0
  294. package/dist/tokens/matrix.d.ts.map +1 -0
  295. package/dist/tokens/matrix.js +21 -0
  296. package/dist/tokens/matrix.js.map +1 -0
  297. package/dist/tokens/theme-check.d.ts +42 -0
  298. package/dist/tokens/theme-check.d.ts.map +1 -0
  299. package/dist/tokens/theme-check.js +10 -0
  300. package/dist/tokens/theme-check.js.map +1 -0
  301. package/dist/tokens/theme.d.ts +94 -0
  302. package/dist/tokens/theme.d.ts.map +1 -0
  303. package/dist/tokens/theme.js +14 -0
  304. package/dist/tokens/theme.js.map +1 -0
  305. package/dist/tokens/tokens.d.ts +122 -0
  306. package/dist/tokens/tokens.d.ts.map +1 -0
  307. package/dist/tokens/tokens.js +158 -0
  308. package/dist/tokens/tokens.js.map +1 -0
  309. package/dist/vocabulary/classes.d.ts +3 -0
  310. package/dist/vocabulary/classes.d.ts.map +1 -0
  311. package/dist/vocabulary/classes.js +1354 -0
  312. package/dist/vocabulary/classes.js.map +1 -0
  313. package/dist/vocabulary/elements.d.ts +3 -0
  314. package/dist/vocabulary/elements.d.ts.map +1 -0
  315. package/dist/vocabulary/elements.js +490 -0
  316. package/dist/vocabulary/elements.js.map +1 -0
  317. package/dist/vocabulary/types.d.ts +229 -0
  318. package/dist/vocabulary/types.d.ts.map +1 -0
  319. package/dist/vocabulary/types.js +11 -0
  320. package/dist/vocabulary/types.js.map +1 -0
  321. package/dist/wasi-host.d.ts +24 -0
  322. package/dist/wasi-host.d.ts.map +1 -0
  323. package/dist/wasi-host.js +140 -0
  324. package/dist/wasi-host.js.map +1 -0
  325. package/live-templates.xml +63 -0
  326. package/manifest/files.json +373 -0
  327. package/manifest/manifest.json +5090 -0
  328. package/manifest/manifest.schema.json +586 -0
  329. package/package.json +399 -5
  330. package/src/cli.ts +21 -0
  331. package/src/components/css/accordion/accordion.css +102 -0
  332. package/src/components/css/accordion/accordion.ts +50 -0
  333. package/src/components/css/alert/alert.css +53 -0
  334. package/src/components/css/alert/alert.ts +48 -0
  335. package/src/components/css/avatar/avatar.css +96 -0
  336. package/src/components/css/avatar/avatar.ts +57 -0
  337. package/src/components/css/badge/badge.css +42 -0
  338. package/src/components/css/badge/badge.ts +43 -0
  339. package/src/components/css/breadcrumbs/breadcrumbs.css +62 -0
  340. package/src/components/css/breadcrumbs/breadcrumbs.ts +30 -0
  341. package/src/components/css/button/button.css +128 -0
  342. package/src/components/css/button/button.ts +44 -0
  343. package/src/components/css/card/card.css +65 -0
  344. package/src/components/css/card/card.ts +50 -0
  345. package/src/components/css/checkbox/checkbox.css +114 -0
  346. package/src/components/css/checkbox/checkbox.ts +50 -0
  347. package/src/components/css/divider/divider.css +38 -0
  348. package/src/components/css/divider/divider.ts +42 -0
  349. package/src/components/css/error-text/error-text.css +21 -0
  350. package/src/components/css/error-text/error-text.ts +37 -0
  351. package/src/components/css/fieldset/fieldset.css +72 -0
  352. package/src/components/css/fieldset/fieldset.ts +87 -0
  353. package/src/components/css/file-upload/file-upload.css +102 -0
  354. package/src/components/css/file-upload/file-upload.ts +65 -0
  355. package/src/components/css/heading/heading.css +33 -0
  356. package/src/components/css/heading/heading.ts +42 -0
  357. package/src/components/css/help-text/help-text.css +24 -0
  358. package/src/components/css/help-text/help-text.ts +42 -0
  359. package/src/components/css/icon/icon.css +20 -0
  360. package/src/components/css/icon/icon.ts +44 -0
  361. package/src/components/css/input/input.css +145 -0
  362. package/src/components/css/input/input.ts +77 -0
  363. package/src/components/css/label/label.css +42 -0
  364. package/src/components/css/label/label.ts +51 -0
  365. package/src/components/css/link/link.css +38 -0
  366. package/src/components/css/link/link.ts +38 -0
  367. package/src/components/css/list/list.css +53 -0
  368. package/src/components/css/list/list.ts +44 -0
  369. package/src/components/css/pagination/pagination.css +95 -0
  370. package/src/components/css/pagination/pagination.ts +33 -0
  371. package/src/components/css/paragraph/paragraph.css +31 -0
  372. package/src/components/css/paragraph/paragraph.ts +53 -0
  373. package/src/components/css/progress/progress.css +161 -0
  374. package/src/components/css/progress/progress.ts +78 -0
  375. package/src/components/css/radio/radio.css +94 -0
  376. package/src/components/css/radio/radio.ts +50 -0
  377. package/src/components/css/search/search.css +50 -0
  378. package/src/components/css/search/search.ts +56 -0
  379. package/src/components/css/select/select.css +321 -0
  380. package/src/components/css/select/select.ts +63 -0
  381. package/src/components/css/shared.ts +199 -0
  382. package/src/components/css/skeleton/skeleton.css +62 -0
  383. package/src/components/css/skeleton/skeleton.ts +43 -0
  384. package/src/components/css/skip-link/skip-link.css +41 -0
  385. package/src/components/css/skip-link/skip-link.ts +22 -0
  386. package/src/components/css/spinner/spinner.css +48 -0
  387. package/src/components/css/spinner/spinner.ts +48 -0
  388. package/src/components/css/sr-only/sr-only.css +16 -0
  389. package/src/components/css/sr-only/sr-only.ts +21 -0
  390. package/src/components/css/switch/switch.css +105 -0
  391. package/src/components/css/switch/switch.ts +50 -0
  392. package/src/components/css/table/table.css +159 -0
  393. package/src/components/css/table/table.ts +107 -0
  394. package/src/components/css/tag/tag.css +58 -0
  395. package/src/components/css/tag/tag.ts +49 -0
  396. package/src/components/css/textarea/textarea.css +83 -0
  397. package/src/components/css/textarea/textarea.ts +40 -0
  398. package/src/components/css/toggle-group/toggle-group.css +92 -0
  399. package/src/components/css/toggle-group/toggle-group.ts +37 -0
  400. package/src/components/css/tooltip/tooltip.css +89 -0
  401. package/src/components/css/tooltip/tooltip.ts +37 -0
  402. package/src/components/default-texts.ts +41 -0
  403. package/src/components/events.ts +68 -0
  404. package/src/components/frame/dialog/dialog.css +306 -0
  405. package/src/components/frame/dialog/dialog.ts +166 -0
  406. package/src/components/frame/dialog/lt-dialog.ts +513 -0
  407. package/src/components/frame/error-summary/error-summary.css +47 -0
  408. package/src/components/frame/error-summary/error-summary.ts +90 -0
  409. package/src/components/frame/error-summary/lt-error-summary.ts +458 -0
  410. package/src/components/frame/field/field-core.ts +152 -0
  411. package/src/components/frame/field/field.css +17 -0
  412. package/src/components/frame/field/lt-field.ts +790 -0
  413. package/src/components/frame/popover/lt-popover.ts +586 -0
  414. package/src/components/frame/popover/popover.css +50 -0
  415. package/src/components/frame/popover/popover.ts +102 -0
  416. package/src/components/frame/session-timeout/lt-session-timeout.ts +715 -0
  417. package/src/components/frame/session-timeout/session-timeout.css +50 -0
  418. package/src/components/frame/session-timeout/session-timeout.ts +156 -0
  419. package/src/components/frame/suggestion/lt-suggestion.ts +1379 -0
  420. package/src/components/frame/suggestion/suggestion.css +132 -0
  421. package/src/components/frame/suggestion/suggestion.ts +172 -0
  422. package/src/components/frame/tabs/lt-tabs.ts +1395 -0
  423. package/src/components/frame/tabs/tabs.css +128 -0
  424. package/src/components/frame/tabs/tabs.ts +188 -0
  425. package/src/components/host-element.ts +493 -0
  426. package/src/components/standalone/connection-status/connection-status.css +41 -0
  427. package/src/components/standalone/connection-status/connection-status.ts +47 -0
  428. package/src/components/standalone/connection-status/lt-connection-status.ts +268 -0
  429. package/src/components/standalone/toast/lt-toast.ts +300 -0
  430. package/src/components/standalone/toast/toast.css +78 -0
  431. package/src/components/standalone/toast/toast.ts +70 -0
  432. package/src/diagnostics/core.ts +227 -0
  433. package/src/diagnostics/default-core.ts +81 -0
  434. package/src/diagnostics/index.ts +150 -0
  435. package/src/dom.ts +185 -0
  436. package/src/index.ts +218 -0
  437. package/src/jsx/react.ts +212 -0
  438. package/src/lt.ts +192 -0
  439. package/src/react.ts +411 -0
  440. package/src/register.ts +43 -0
  441. package/src/tailwind/tailwind.css +169 -0
  442. package/src/tokens/boundary.css +104 -0
  443. package/src/tokens/color-contract.json +231 -0
  444. package/src/tokens/color.ts +150 -0
  445. package/src/tokens/contract.ts +24 -0
  446. package/src/tokens/matrix-cells.ts +375 -0
  447. package/src/tokens/matrix.ts +32 -0
  448. package/src/tokens/theme-check.ts +51 -0
  449. package/src/tokens/theme.ts +104 -0
  450. package/src/tokens/tokens.css +569 -0
  451. package/src/tokens/tokens.ts +223 -0
  452. package/src/vocabulary/classes.ts +1356 -0
  453. package/src/vocabulary/elements.ts +492 -0
  454. package/src/vocabulary/types.ts +228 -0
  455. package/src/wasi-host.ts +155 -0
  456. package/web-types.json +800 -0
@@ -0,0 +1,409 @@
1
+ # LO-TEK with Datastar
2
+
3
+ The rulebook for LO-TEK together with [Datastar](https://data-star.dev), which
4
+ adds reactivity to ordinary HTML with `data-*` attributes. One script, no
5
+ build step, the same premise as LO-TEK.
6
+
7
+ That means two things for this file: the addresses are URLs, since a browser
8
+ without a bundler does not resolve a package name, and the state is controlled
9
+ with attributes, which is exactly what the `frame` components expect.
10
+
11
+ This is @lo-tek/interfaces 0.38.0. The file is generated by the package and
12
+ follows its version, so it can never say anything other than the code next to
13
+ it.
14
+
15
+ ## Short version
16
+
17
+ 1. **One `<link>` to `lotek.css`, before everything else.** Without it, the
18
+ components look unstyled. The answer is then to add the link, never to
19
+ write your own CSS to make them look right.
20
+ 2. **Use only the classes and elements in the tables below.** `lt-modal`,
21
+ `lt-datepicker` and `data-variant="outlined"` exist in other design
22
+ systems, not in LO-TEK. If you are unsure whether something exists, it is
23
+ listed here or it does not exist.
24
+ 3. **No hard-coded colours or pixels.** `var(--lt-color-…)` and
25
+ `var(--lt-spacing-…)`.
26
+ 4. **`defineLt*()` runs once in a `<script type="module">` with the full
27
+ URL,** and the state is set with `data-attr:`, which adds and removes the
28
+ attribute. `hidden="false"` would hide the error text all the same.
29
+ 5. **Run the check on what you have written:**
30
+ `npx @lo-tek/interfaces check page.html`. It knows every class, every
31
+ element, every attribute and every allowed value, prints
32
+ `file:line:column: error: message`, or `warning:`, and exits with an error
33
+ code if it finds anything. With the app running, also check every page you
34
+ have changed: `npx @lo-tek/interfaces check http://localhost:8080/page`.
35
+ That also requires every `for` and `aria-describedby` to point to an id
36
+ that exists, and every field to have a label. You are done when both answer
37
+ "The markup matches LO-TEK".
38
+
39
+ ## 1. The stylesheet and Datastar
40
+
41
+ ```html
42
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/lotek.css">
43
+ <script
44
+ type="module"
45
+ src="https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar.js"
46
+ ></script>
47
+ ```
48
+
49
+ `lotek.css` is 103 kB, 13 kB compressed, and has all the components. If you
50
+ want only what you use, `tokens.css` defines all the variables, and all the
51
+ other stylesheets build on it. It must be loaded, and comes first out of
52
+ habit: the order between it and the others does not matter.
53
+
54
+ ## 2. What exists
55
+
56
+ 35 CSS components and 9 web components, and this is the whole list. The
57
+ classes are `lt-` + kebab-case. Variants are always `data-*` attributes, never
58
+ classes of their own: `data-variant="secondary"`, not `lt-button--secondary`.
59
+ The default variant has no attribute.
60
+
61
+ ### CSS components (no JavaScript)
62
+
63
+ | Class | Stylesheet | Attributes |
64
+ | --- | --- | --- |
65
+ | `lt-accordion`<br>`lt-accordion__content` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/accordion/accordion.css` | `data-variant`: plain |
66
+ | `lt-alert`<br>`lt-alert__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/alert/alert.css` | `data-color`: info, success, warning, danger |
67
+ | `lt-avatar`<br>`lt-avatar-stack` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/avatar/avatar.css` | `data-variant`: square<br>`data-size`: small, large |
68
+ | `lt-badge` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/badge/badge.css` | `data-color`: success, warning, danger, neutral |
69
+ | `lt-breadcrumbs` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/breadcrumbs/breadcrumbs.css` | none |
70
+ | `lt-button` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/button/button.css` | `data-variant`: secondary, ghost, danger |
71
+ | `lt-card`<br>`lt-card__title` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/card/card.css` | `data-variant`: filled<br>`data-interactive` (flag) |
72
+ | `lt-checkbox`<br>`lt-checkbox-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/checkbox/checkbox.css` | `data-state`: invalid, success |
73
+ | `lt-divider` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/divider/divider.css` | `data-variant`: subtle, strong |
74
+ | `lt-error-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/error-text/error-text.css` | `data-variant`: warning |
75
+ | `lt-fieldset`<br>`lt-legend` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/fieldset/fieldset.css` | `data-state`: invalid, success<br>`data-required`: symbol, text<br>`data-optional` (flag) |
76
+ | `lt-file-upload`<br>`lt-file-upload-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/file-upload/file-upload.css` | `data-state`: invalid, success |
77
+ | `lt-heading` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/heading/heading.css` | `data-size`: xs, s, m, xl, mega |
78
+ | `lt-help-text` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/help-text/help-text.css` | `data-variant`: strong, success, warning |
79
+ | `lt-icon` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/icon/icon.css` | none |
80
+ | `lt-input` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/input/input.css` | `data-state`: invalid, success<br>`data-variant`: date, datetime-local, time |
81
+ | `lt-label` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/label/label.css` | `data-required`: symbol, text<br>`data-optional` (flag) |
82
+ | `lt-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/link/link.css` | none |
83
+ | `lt-list` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/list/list.css` | `data-variant`: plain, divided |
84
+ | `lt-pagination`<br>`lt-pagination__gap` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/pagination/pagination.css` | none |
85
+ | `lt-paragraph` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/paragraph/paragraph.css` | `data-variant`: lead<br>`data-size`: small, large |
86
+ | `lt-progress` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/progress/progress.css` | `data-color`: success, warning, danger |
87
+ | `lt-radio`<br>`lt-radio-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/radio/radio.css` | `data-state`: invalid, success |
88
+ | `lt-search`<br>`lt-search-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/search/search.css` | `data-state`: invalid, success |
89
+ | `lt-select` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/select/select.css` | `data-state`: invalid, success<br>`data-picker`: styled |
90
+ | `lt-skeleton` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/skeleton/skeleton.css` | `data-variant`: text, circle |
91
+ | `lt-skip-link` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/skip-link/skip-link.css` | none |
92
+ | `lt-spinner` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/spinner/spinner.css` | `data-size`: small, large |
93
+ | `lt-sr-only` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/sr-only/sr-only.css` | none |
94
+ | `lt-switch`<br>`lt-switch-row` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/switch/switch.css` | none |
95
+ | `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/table/table.css` | `data-variant`: striped<br>`data-hoverable` (flag) |
96
+ | `lt-tag` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/tag/tag.css` | `data-variant`: filled<br>`data-selectable` (flag) |
97
+ | `lt-textarea` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/textarea/textarea.css` | `data-state`: invalid, success |
98
+ | `lt-toggle-group`<br>`lt-toggle-group__option` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/toggle-group/toggle-group.css` | none |
99
+ | `lt-tooltip`<br>`lt-tooltip__bubble` | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/css/tooltip/tooltip.css` | none |
100
+
101
+ There is also `lt-theme-control`, a class on a radio button that lets the user
102
+ choose a theme. It is in `tokens.css`, and is described under Tokens.
103
+
104
+ ## 3. Tokens
105
+
106
+ One layer. A colour is a cell in a matrix of **family**, that is, what it
107
+ means, and **role**, that is, what it does, and the name is
108
+ `--lt-color-<family>-<role>`. Every family has every role, so
109
+ `--lt-color-danger-border` and `--lt-color-success-border` both exist. The
110
+ roles are the same whatever the family: `surface` is a tinted surface, `fill`
111
+ a filled one, `content` the text on top of `fill`, `border` a border, and
112
+ `text` the family's colour as text. Border and text each have a weaker and a
113
+ stronger step next to them.
114
+
115
+ ```
116
+ Families: `accent`, `visited`, `brand1`, `brand2`, `brand3`, `neutral`, `danger`, `warning`, `success`.
117
+
118
+ Roles: `surface`, `border-subtle`, `border`, `border-strong`, `fill`, `text`, `text-strong`, `text-subtle`, `content`.
119
+
120
+ Outside the matrix: `--lt-color-disabled-surface`, `--lt-color-disabled-text`, `--lt-color-neutral-canvas`, `--lt-color-neutral-raised`, `--lt-color-overlay`, `--lt-focus-ring`, `--lt-icon-calendar`, `--lt-icon-check`, `--lt-icon-clock`, `--lt-icon-dash`, `--lt-icon-search`, `--lt-shadow-overlay`.
121
+ ```
122
+
123
+ Spacing: `--lt-spacing-0-5`, `--lt-spacing-1`, `--lt-spacing-10`,
124
+ `--lt-spacing-12`, `--lt-spacing-16`, `--lt-spacing-2`, `--lt-spacing-3`,
125
+ `--lt-spacing-4`, `--lt-spacing-5`, `--lt-spacing-6`, `--lt-spacing-7`,
126
+ `--lt-spacing-8`, `--lt-spacing-px`.
127
+
128
+ Font: `--lt-font-size-l`, `--lt-font-size-m`, `--lt-font-size-mega`,
129
+ `--lt-font-size-reference`, `--lt-font-size-s`, `--lt-font-size-xl`,
130
+ `--lt-font-size-xs`, `--lt-font-size-xxl`, `--lt-font-size-xxs`,
131
+ `--lt-font-weight-bold`, `--lt-font-weight-medium`,
132
+ `--lt-font-weight-regular`, `--lt-font-weight-semibold`.
133
+
134
+ Line height: `--lt-line-height-article`, `--lt-line-height-compact`,
135
+ `--lt-line-height-default`, `--lt-line-height-heading`.
136
+
137
+ `disabled` and `neutral` are not the same. `disabled` is for controls that are
138
+ turned off, and is exempt from the contrast requirement in WCAG 1.4.3.
139
+ `neutral` is for subdued information the user actually has to read or press,
140
+ and holds 4.5:1. Never use the `disabled` colours to subdue something that is
141
+ meant to be read.
142
+
143
+ ### Light and dark
144
+
145
+ Without you doing anything, the colours follow the device's setting. A page
146
+ that wants to decide for itself sets `data-theme="light"` or
147
+ `data-theme="dark"` on `<html>`.
148
+
149
+ The attribute is a **theme boundary** and works on any element, not only on
150
+ the root. One theme can sit inside another, both ways.
151
+
152
+ This is what an embedded component should use. When you put LO-TEK into a page
153
+ you do not control, set the attribute on the component's own root element:
154
+
155
+ ```html
156
+ <div data-theme="light">
157
+ <button class="lt-button">Save</button>
158
+ </div>
159
+ ```
160
+
161
+ The component is then light whatever the device is set to, and the host is
162
+ left alone.
163
+
164
+ **The host's CSS stops at the boundary.** The host often has rules without a
165
+ layer, such as `button { background: none; border: none }` or a normalize, and
166
+ they beat `@layer lotek`. In that case, set `data-lt-boundary` on the same
167
+ root element:
168
+
169
+ ```html
170
+ <div data-lt-boundary data-theme="light">
171
+ <button class="lt-button">Save</button>
172
+ </div>
173
+ ```
174
+
175
+ Below the root element the browser then ignores the host's CSS without a
176
+ layer, unless a rule of the host's wins on specificity as described below, and
177
+ LO-TEK's layer applies again. The rule is in `lotek.css` and in
178
+ `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/tokens/boundary.css`.
179
+ Fonts and other inherited properties still come from the host, and the
180
+ `--lt-*` variables work. Three things follow from it:
181
+
182
+ - Your own CSS inside the boundary must be in a layer after `lotek`. CSS
183
+ without a layer disappears there in the same way as the host's.
184
+ - Elements without a LO-TEK class lose the host's CSS without a layer. A layer
185
+ the host has declared before `lotek`, such as Tailwind's Preflight in
186
+ `base`, still applies where LO-TEK sets nothing.
187
+ - The boundary has the specificity (0,2,0). A rule from the host with the same
188
+ specificity wins if it is loaded after the boundary, and one with more
189
+ always wins. So do `!important` and layers the host has declared after
190
+ `lotek`.
191
+
192
+ LO-TEK sets `color-scheme` only where someone has chosen a theme: on
193
+ `[data-theme="light"]`, on `[data-theme="dark"]` and on the options of the
194
+ theme picker below. Bare `:root` never gets it. The property controls the
195
+ browser's own surfaces, that is, scrollbars, dropdowns and calendar panels,
196
+ and it is inherited. A child can opt out with `color-scheme: normal`, but that
197
+ is a counter-rule the host never asked to have to write: with the value on the
198
+ root, it applied to the whole document, including where the package is only a
199
+ guest. If the whole page should follow the system, write
200
+ `color-scheme: light dark` on `<html>` yourself, in the same way as you set
201
+ the layer order yourself.
202
+
203
+ ### Letting the user choose a theme
204
+
205
+ `lt-theme-control` on a radio button makes `value` a theme choice. It is plain
206
+ CSS, without a line of JavaScript:
207
+
208
+ ```html
209
+ <fieldset class="lt-toggle-group">
210
+ <legend class="lt-sr-only">Theme</legend>
211
+ <label class="lt-toggle-group__option">
212
+ <input class="lt-theme-control" type="radio" name="theme"
213
+ value="auto" checked /> Follow the system
214
+ </label>
215
+ <label class="lt-toggle-group__option">
216
+ <input class="lt-theme-control" type="radio" name="theme"
217
+ value="light" /> Light
218
+ </label>
219
+ <label class="lt-toggle-group__option">
220
+ <input class="lt-theme-control" type="radio" name="theme"
221
+ value="dark" /> Dark
222
+ </label>
223
+ </fieldset>
224
+ ```
225
+
226
+ The choice controls two things. LO-TEK's colours come from the tokens, and the
227
+ browser's **own** surfaces from `color-scheme`: `light` gives `light`, `dark`
228
+ gives `dark`, and `auto` gives `light dark`. `light dark` is not a theme, but
229
+ the statement that the page works in both, so the browser can choose by the
230
+ system.
231
+
232
+ "Follow the system" has no theme block, and that is on purpose: a value
233
+ without a block matches nothing, and then the media query applies again.
234
+
235
+ Do not write `color-scheme` yourself when the picker is in use. Such a rule
236
+ outside a layer beats `@layer lotek` and locks the browser's surfaces to the
237
+ system while the user has chosen something else.
238
+
239
+ `light` and `dark` win over `data-theme` on `<html>`, so the server can send
240
+ the stored choice while a click still takes effect before the response is
241
+ back. `auto` does not: it means "no override from me", so if the server has
242
+ written `data-theme`, the server's value stands. For "follow the system" to
243
+ work at once, whatever stores the choice must also remove the attribute.
244
+
245
+ Two things it does not do. It **stores nothing**: submit the group in a form
246
+ and store the choice in a cookie the server reads, or in `localStorage`. And
247
+ it must be in the **same tree as `<html>`**, since `:has()` does not see out
248
+ of its own tree; a control inside a shadow root does not set the theme on the
249
+ page.
250
+
251
+ ## 4. Web components
252
+
253
+ Three rules apply to all of them:
254
+
255
+ 1. **`defineLt*()` runs once** in a `<script type="module">` in the page
256
+ template. The import has no side effect on its own; it is the `define` call
257
+ that registers the element.
258
+ 2. **Boolean attributes are true as long as they are present.**
259
+ `hidden="false"`, `disabled="false"` and `open="false"` turn it *on*. To
260
+ turn any of them off, remove the attribute entirely.
261
+ 3. **You write the markup, the component adds the behaviour.** `<lt-field>`
262
+ does not create your label or your control. You write `for` on the label
263
+ and `id` on the control, or wrap the control in a `<label>`, so the field
264
+ has a name without JavaScript too. The component wires the help text and
265
+ the error text with `aria-describedby` and `aria-invalid`, and never writes
266
+ an id on the control: an id the server did not send makes an update from
267
+ the server replace the field, with the focus and what the user has typed.
268
+ The field is invalid when the error text is there without `hidden`.
269
+
270
+ | Element | Category | Stylesheet | Registration | Attributes | Events | Classes inside |
271
+ | --- | --- | --- | --- | --- | --- | --- |
272
+ | `<lt-field>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/field/field.css` | `defineLtField()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/field/lt-field.js` | `disabled` (flag)<br>`optional` (flag)<br>`described-by` (text) | none | none |
273
+ | `<lt-tabs>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/tabs/tabs.css` | `defineLtTabs()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/tabs/lt-tabs.js` | `server-controlled` (flag)<br>`activation`: manual, automatic | `tab-select` (index) | `lt-tabs__list`<br>`lt-tabs__panel` |
274
+ | `<lt-error-summary>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/error-summary/error-summary.css` | `defineLtErrorSummary()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/error-summary/lt-error-summary.js` | `data-autofocus`: false, true<br>`hidden` (flag) | none | `lt-error-summary`<br>`lt-error-summary__title` |
275
+ | `<lt-popover>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/popover/popover.css` | `defineLtPopover()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/popover/lt-popover.js` | `open` (flag)<br>`placement`: bottom-start, bottom-end, top-start, top-end<br>`server-controlled` (flag) | `popover-toggle` (open) | `lt-popover` |
276
+ | `<lt-suggestion>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/suggestion/suggestion.css` | `defineLtSuggestion()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/suggestion/lt-suggestion.js` | `prefiltered` (flag)<br>`count-none` (text)<br>`count-zero` (text)<br>`count-one` (text)<br>`count-two` (text)<br>`count-few` (text)<br>`count-many` (text)<br>`count-other` (text)<br>`server-controlled` (flag) | `suggestion-select` (value, label) | `lt-suggestion__list`<br>`lt-suggestion__option`<br>`lt-suggestion__value`<br>`lt-suggestion__empty` |
277
+ | `<lt-dialog>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/dialog/dialog.css` | `defineLtDialog()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/dialog/lt-dialog.js` | `open` (flag)<br>`server-controlled` (flag) | `dialog-toggle` (open, returnValue) | `lt-dialog` (`data-color`: brand, info, success, warning, danger)<br>`lt-dialog__body`<br>`lt-dialog__title`<br>`lt-dialog__footer`<br>`lt-dialog__header`<br>`lt-dialog__subtitle` |
278
+ | `<lt-toast>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/standalone/toast/toast.css` | `defineLtToast()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/standalone/toast/lt-toast.js` | `duration` (number)<br>`label` (text)<br>`close-label` (text) | `toast-dismiss` | `lt-toast`<br>`lt-toast__message`<br>`lt-toast__close` |
279
+ | `<lt-session-timeout>` | frame | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/frame/session-timeout/session-timeout.css` | `defineLtSessionTimeout()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/session-timeout/lt-session-timeout.js` | `warn-at` (number)<br>`expires-at` (number)<br>`activity-interval` (number) | `session-warn`<br>`session-extend`<br>`session-logout`<br>`session-expired`<br>`session-activity` | `lt-session-timeout`<br>`lt-session-timeout__dialog`<br>`lt-session-timeout__title`<br>`lt-session-timeout__text`<br>`lt-session-timeout__count`<br>`lt-session-timeout__actions` |
280
+ | `<lt-connection-status>` | standalone | `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/src/components/standalone/connection-status/connection-status.css` | `defineLtConnectionStatus()` from `https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/standalone/connection-status/lt-connection-status.js` | `offline-text` (text)<br>`online-text` (text) | `connection-lost`<br>`connection-restored` | `lt-connection-status`<br>`lt-connection-status__bar` |
281
+
282
+ None of them uses shadow DOM. The content is in plain DOM, so `querySelector`,
283
+ `FormData` and ordinary CSS work straight into it.
284
+
285
+ ## 5. A form with Datastar
286
+
287
+ ```html
288
+ <form
289
+ data-signals="{name: '', touched: false}"
290
+ data-computed:invalid="$touched && $name.trim() === ''"
291
+ >
292
+ <lt-field>
293
+ <label class="lt-label" for="name" data-required="symbol">Full name</label>
294
+ <input
295
+ class="lt-input"
296
+ id="name"
297
+ type="text"
298
+ name="name"
299
+ data-bind:name
300
+ data-on:blur="$touched = true"
301
+ />
302
+ <p class="lt-error-text" hidden data-attr:hidden="!$invalid">Enter your name.</p>
303
+ </lt-field>
304
+
305
+ <button class="lt-button" type="submit">Send</button>
306
+ </form>
307
+
308
+ <script type="module">
309
+ import { defineLtField } from
310
+ "https://cdn.jsdelivr.net/npm/@lo-tek/interfaces@0.38.0/dist/components/frame/field/lt-field.js"
311
+
312
+ defineLtField()
313
+ </script>
314
+ ```
315
+
316
+ `data-signals` creates the state, `data-computed:invalid` derives the
317
+ validation from it, `data-bind:name` binds the field both ways, and
318
+ `data-on:blur` records that the user has left it.
319
+
320
+ `data-attr:hidden` on the error text is the link to the component: it sets
321
+ `hidden` when the field is valid and removes it when it is invalid, and
322
+ `<lt-field>` counts the field as invalid when the error text is visible. None
323
+ of the React pitfalls exist here. Datastar works directly on the attributes.
324
+
325
+ ## 6. HTML from the server
326
+
327
+ Datastar can let the server send HTML as the page runs, over Server-Sent
328
+ Events. A web component upgrades itself when it is inserted into the document,
329
+ as long as `defineLtField()` has run once. The server can therefore send this
330
+ as plain HTML:
331
+
332
+ ```html
333
+ <lt-field>
334
+ <label class="lt-label" for="email" data-required="text">Email address</label>
335
+ <input class="lt-input" id="email" type="email" value="alex@" />
336
+ <p class="lt-help-text">We will send the receipt here.</p>
337
+ <p class="lt-error-text">Enter a valid address.</p>
338
+ </lt-field>
339
+ ```
340
+
341
+ The component then gives the help text and the error text ids, adds
342
+ `aria-invalid` because the error text is visible, and builds
343
+ `aria-describedby`, without any JavaScript being sent for this particular
344
+ field. That is the point of the `frame` components living in plain DOM: the
345
+ markup is the data, and the accessibility is wired where it lands.
346
+
347
+ If the server patches a component that holds state, the question is what
348
+ decides it. By default the web component does: `<lt-tabs>` remembers the tab
349
+ the user selected, and puts it back after a patch. `outer` and `inner` morph,
350
+ so the links are kept and the selection with them. `replace` replaces the
351
+ nodes, and then the component selects the tab the server marked with
352
+ `aria-selected="true"`, otherwise the one the URL points to, otherwise the one
353
+ whose panel the server left without `hidden`, otherwise the first. And a morph
354
+ keeps an element only when the ids match: an element with an id the server did
355
+ not send is replaced. The components therefore never write an id on what the
356
+ user touches. The tabs are links without an id, and the panels have the id the
357
+ link points to, the same on every render, as `lt.tabs()` writes it. The panel
358
+ in `<lt-popover>` needs an id in the same way; the component creates none. The
359
+ control in `<lt-field>` and the field in `<lt-suggestion>` never get an id
360
+ from the component: the template writes `for` and `id`, which HTML requires
361
+ for the field to have a name without JavaScript, or the label wraps the field
362
+ and no id is needed. `<lt-field>` and `<lt-suggestion>` warn in the console
363
+ when a patch replaces the field with one that has another id, the same `name`
364
+ and another value, and `<lt-popover>` when a patch replaces the open panel
365
+ with one that has another id. `<lt-tabs>` repairs the selection without a
366
+ word. If the server should be able to move the tab, say so with
367
+ `server-controlled`:
368
+
369
+ ```html
370
+ <lt-tabs server-controlled data-on:tab-select="$tab = evt.detail.index">
371
+ <ul class="lt-tabs__list" aria-label="Parts of the case">
372
+ <li><a href="#application">Application</a></li>
373
+ <li><a href="#attachments">Attachments</a></li>
374
+ </ul>
375
+ <section class="lt-tabs__panel" id="application">…</section>
376
+ <section class="lt-tabs__panel" id="attachments" hidden="until-found">…</section>
377
+ </lt-tabs>
378
+ ```
379
+
380
+ The attribute exists on `<lt-tabs>`, `<lt-popover>`, `<lt-dialog>` and
381
+ `<lt-suggestion>`. Without it the server and the component would fight over
382
+ the same state.
383
+
384
+ `lt` can be used on the server or in a build step. Datastar does not need it
385
+ in the browser.
386
+
387
+ ## Known pitfalls
388
+
389
+ | Symptom | Cause |
390
+ | --- | --- |
391
+ | The styles are missing | The `<link>` to `lotek.css` is missing, or its address answers 404. With one stylesheet per component instead, `tokens.css` is not loaded |
392
+ | An `<lt-toast>` or `<lt-connection-status>` shows nothing, an `<lt-session-timeout>` never warns, or another component does nothing | The `define` function has not run. `<lt-toast>` and `<lt-connection-status>` create their content themselves and are empty without it, and `<lt-session-timeout>` does not count the time. The markup in the others comes from you and is there regardless, with two exceptions until they are registered. `<lt-tabs>` shows one panel: of those the server left without `hidden`, the one the URL points to, otherwise the first, and under `server-controlled` always the first. `<lt-suggestion>` hides the list |
393
+ | A component speaks English on a page in another language | The text in the markup comes from you, and is written with the app's own translation setup. The few default texts the package has are replaced with `label` and `close-label` on `<lt-toast>`, `offline-text` and `online-text` on `<lt-connection-status>`, `count-none`, `count-one` and `count-other` on `<lt-suggestion>`, and `--lt-label-required-text`, `--lt-label-optional-text` and `--lt-label-required-symbol` in CSS. Numbers and durations follow the nearest `lang`, usually the one on `<html>`. See https://lo-tek.sobernetics.no/translation/ |
394
+ | The error text never shows, and the field counts as valid | `hidden="false"` is set on the error text, and it hides it all the same. The attribute must be removed, not set to `false` |
395
+ | `SyntaxError` in the browser | TypeScript syntax in a `<script type="module">` without a build step |
396
+
397
+ ## When CSS is not enough
398
+
399
+ The components are customised with tokens and `--lt-` variables. If that is
400
+ not enough, `npx @lo-tek/interfaces takeover <component>` copies the source
401
+ code of one component into `src/lotek/<component>/`, so the code is yours to
402
+ change. The copy is TypeScript that imports from the package by name, so it
403
+ needs a build step. It is renamed from `lt-` to `app-`, and a
404
+ `lotek-manifest.json` next to it teaches the check the new names:
405
+ `npx @lo-tek/interfaces check --manifest=src/lotek/<component>/lotek-manifest.json <files>`.
406
+ A complete colour theme from your brand colours is made with
407
+ `npx @lo-tek/interfaces theme`.
408
+
409
+ All of this, with live examples: https://lo-tek.sobernetics.no/