@lo-tek/interfaces 0.0.0-stage → 0.37.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 +3254 -0
  2. package/LICENSE +21 -0
  3. package/README.md +129 -2
  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 +35 -0
  161. package/dist/components/default-texts.d.ts.map +1 -0
  162. package/dist/components/default-texts.js +35 -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 +431 -0
  175. package/dist/components/frame/dialog/lt-dialog.js.map +1 -0
  176. package/dist/components/frame/error-summary/error-summary.d.ts +40 -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 +32 -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 +82 -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 +302 -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 +580 -0
  191. package/dist/components/frame/field/lt-field.js.map +1 -0
  192. package/dist/components/frame/popover/lt-popover.d.ts +132 -0
  193. package/dist/components/frame/popover/lt-popover.d.ts.map +1 -0
  194. package/dist/components/frame/popover/lt-popover.js +490 -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 +573 -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 +361 -0
  209. package/dist/components/frame/suggestion/lt-suggestion.d.ts.map +1 -0
  210. package/dist/components/frame/suggestion/lt-suggestion.js +1152 -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 +404 -0
  217. package/dist/components/frame/tabs/lt-tabs.d.ts.map +1 -0
  218. package/dist/components/frame/tabs/lt-tabs.js +1201 -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 +135 -0
  225. package/dist/components/host-element.d.ts.map +1 -0
  226. package/dist/components/host-element.js +366 -0
  227. package/dist/components/host-element.js.map +1 -0
  228. package/dist/components/standalone/connection-status/connection-status.d.ts +28 -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 +22 -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 +81 -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 +216 -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 +137 -0
  245. package/dist/diagnostics/core.d.ts.map +1 -0
  246. package/dist/diagnostics/core.js +72 -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 +492 -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 +1320 -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 +410 -0
  316. package/dist/vocabulary/elements.js.map +1 -0
  317. package/dist/vocabulary/types.d.ts +175 -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 +62 -0
  326. package/manifest/files.json +373 -0
  327. package/manifest/manifest.json +4965 -0
  328. package/manifest/manifest.schema.json +513 -0
  329. package/package.json +404 -4
  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 +34 -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 +510 -0
  407. package/src/components/frame/error-summary/error-summary.css +47 -0
  408. package/src/components/frame/error-summary/error-summary.ts +56 -0
  409. package/src/components/frame/error-summary/lt-error-summary.ts +344 -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 +753 -0
  413. package/src/components/frame/popover/lt-popover.ts +555 -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 +681 -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 +1358 -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 +1319 -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 +400 -0
  426. package/src/components/standalone/connection-status/connection-status.css +41 -0
  427. package/src/components/standalone/connection-status/connection-status.ts +41 -0
  428. package/src/components/standalone/connection-status/lt-connection-status.ts +242 -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 +210 -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 +1322 -0
  453. package/src/vocabulary/elements.ts +412 -0
  454. package/src/vocabulary/types.ts +178 -0
  455. package/src/wasi-host.ts +155 -0
  456. package/web-types.json +800 -0
package/agent/react.md ADDED
@@ -0,0 +1,440 @@
1
+ # LO-TEK in React
2
+
3
+ The rulebook for LO-TEK in a React app.
4
+
5
+ React differs from all the other environments in one thing, and it matters
6
+ enough to have its own file: React rewrites the attribute names. `class` is
7
+ `className` and `for` is `htmlFor`, and if you use the builder functions from
8
+ the main entry, React prints "Invalid DOM property" in the console, once for
9
+ each attribute name. That is why the package has a React entry of its own.
10
+
11
+ This is @lo-tek/interfaces 0.37.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. **Import the stylesheets in `main.tsx`**, `tokens.css` first. Without them,
18
+ the components look unstyled. The answer is then to add the import, never
19
+ to 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 at the top of `main.tsx`,** not in a `useEffect`, and
27
+ a boolean attribute on a web component is set as
28
+ `open={isOpen || undefined}`. The two other ways of writing it are each
29
+ wrong in one of the React versions.
30
+ 5. **The types are your check.** `lt.button({ variant })` from
31
+ `@lo-tek/interfaces/react` turns a variant that does not exist into a
32
+ compile error, and `@lo-tek/interfaces/react-jsx`, imported once in a
33
+ `.d.ts` file, does the same for attribute names without a hyphen on the web
34
+ components. Run `tsc`. TypeScript never flags an unknown attribute with a
35
+ hyphen, such as `close-labl`, and most of LO-TEK's attributes have one, so
36
+ also run `npx @lo-tek/interfaces check src/*.tsx`: it reads the attributes
37
+ on the web components in the file. A hand-written `className` or
38
+ `data-variant` is seen by none of them, since the check reads `class`, not
39
+ `className`, so use the builder functions.
40
+
41
+ ## 1. The stylesheets
42
+
43
+ `tokens.css` defines all the variables, and all the other stylesheets build on
44
+ it. It must be loaded, and comes first out of habit: the order between it and
45
+ the others does not matter. After that, one per component you use:
46
+
47
+ ```tsx
48
+ // main.tsx, at the top
49
+ import "@lo-tek/interfaces/tokens.css"
50
+ import "@lo-tek/interfaces/field.css"
51
+ import "@lo-tek/interfaces/button.css"
52
+ ```
53
+
54
+ The name of each stylesheet is in the tables below.
55
+
56
+ ## 2. What exists
57
+
58
+ 35 CSS components and 9 web components, and this is the whole list. The
59
+ classes are `lt-` + kebab-case. Variants are always `data-*` attributes, never
60
+ classes of their own: `data-variant="secondary"`, not `lt-button--secondary`.
61
+ The default variant has no attribute.
62
+
63
+ ### CSS components (no JavaScript)
64
+
65
+ | Class | Stylesheet | Attributes |
66
+ | --- | --- | --- |
67
+ | `lt-accordion`<br>`lt-accordion__content` | `@lo-tek/interfaces/accordion.css` | `data-variant`: plain |
68
+ | `lt-alert`<br>`lt-alert__title` | `@lo-tek/interfaces/alert.css` | `data-color`: info, success, warning, danger |
69
+ | `lt-avatar`<br>`lt-avatar-stack` | `@lo-tek/interfaces/avatar.css` | `data-variant`: square<br>`data-size`: small, large |
70
+ | `lt-badge` | `@lo-tek/interfaces/badge.css` | `data-color`: success, warning, danger, neutral |
71
+ | `lt-breadcrumbs` | `@lo-tek/interfaces/breadcrumbs.css` | none |
72
+ | `lt-button` | `@lo-tek/interfaces/button.css` | `data-variant`: secondary, ghost, danger |
73
+ | `lt-card`<br>`lt-card__title` | `@lo-tek/interfaces/card.css` | `data-variant`: filled<br>`data-interactive` (flag) |
74
+ | `lt-checkbox`<br>`lt-checkbox-row` | `@lo-tek/interfaces/checkbox.css` | `data-state`: invalid, success |
75
+ | `lt-divider` | `@lo-tek/interfaces/divider.css` | `data-variant`: subtle, strong |
76
+ | `lt-error-text` | `@lo-tek/interfaces/error-text.css` | `data-variant`: warning |
77
+ | `lt-fieldset`<br>`lt-legend` | `@lo-tek/interfaces/fieldset.css` | `data-state`: invalid, success<br>`data-required`: symbol, text<br>`data-optional` (flag) |
78
+ | `lt-file-upload`<br>`lt-file-upload-list` | `@lo-tek/interfaces/file-upload.css` | `data-state`: invalid, success |
79
+ | `lt-heading` | `@lo-tek/interfaces/heading.css` | `data-size`: xs, s, m, xl, mega |
80
+ | `lt-help-text` | `@lo-tek/interfaces/help-text.css` | `data-variant`: strong, success, warning |
81
+ | `lt-icon` | `@lo-tek/interfaces/icon.css` | none |
82
+ | `lt-input` | `@lo-tek/interfaces/input.css` | `data-state`: invalid, success<br>`data-variant`: date, datetime-local, time |
83
+ | `lt-label` | `@lo-tek/interfaces/label.css` | `data-required`: symbol, text<br>`data-optional` (flag) |
84
+ | `lt-link` | `@lo-tek/interfaces/link.css` | none |
85
+ | `lt-list` | `@lo-tek/interfaces/list.css` | `data-variant`: plain, divided |
86
+ | `lt-pagination`<br>`lt-pagination__gap` | `@lo-tek/interfaces/pagination.css` | none |
87
+ | `lt-paragraph` | `@lo-tek/interfaces/paragraph.css` | `data-variant`: lead<br>`data-size`: small, large |
88
+ | `lt-progress` | `@lo-tek/interfaces/progress.css` | `data-color`: success, warning, danger |
89
+ | `lt-radio`<br>`lt-radio-row` | `@lo-tek/interfaces/radio.css` | `data-state`: invalid, success |
90
+ | `lt-search`<br>`lt-search-row` | `@lo-tek/interfaces/search.css` | `data-state`: invalid, success |
91
+ | `lt-select` | `@lo-tek/interfaces/select.css` | `data-state`: invalid, success<br>`data-picker`: styled |
92
+ | `lt-skeleton` | `@lo-tek/interfaces/skeleton.css` | `data-variant`: text, circle |
93
+ | `lt-skip-link` | `@lo-tek/interfaces/skip-link.css` | none |
94
+ | `lt-spinner` | `@lo-tek/interfaces/spinner.css` | `data-size`: small, large |
95
+ | `lt-sr-only` | `@lo-tek/interfaces/sr-only.css` | none |
96
+ | `lt-switch`<br>`lt-switch-row` | `@lo-tek/interfaces/switch.css` | none |
97
+ | `lt-table`<br>`lt-table__sort`<br>`lt-table-scroll` | `@lo-tek/interfaces/table.css` | `data-variant`: striped<br>`data-hoverable` (flag) |
98
+ | `lt-tag` | `@lo-tek/interfaces/tag.css` | `data-variant`: filled<br>`data-selectable` (flag) |
99
+ | `lt-textarea` | `@lo-tek/interfaces/textarea.css` | `data-state`: invalid, success |
100
+ | `lt-toggle-group`<br>`lt-toggle-group__option` | `@lo-tek/interfaces/toggle-group.css` | none |
101
+ | `lt-tooltip`<br>`lt-tooltip__bubble` | `@lo-tek/interfaces/tooltip.css` | none |
102
+
103
+ There is also `lt-theme-control`, a class on a radio button that lets the user
104
+ choose a theme. It is in `tokens.css`, and is described under Tokens.
105
+
106
+ ## 3. Tokens
107
+
108
+ One layer. A colour is a cell in a matrix of **family**, that is, what it
109
+ means, and **role**, that is, what it does, and the name is
110
+ `--lt-color-<family>-<role>`. Every family has every role, so
111
+ `--lt-color-danger-border` and `--lt-color-success-border` both exist. The
112
+ roles are the same whatever the family: `surface` is a tinted surface, `fill`
113
+ a filled one, `content` the text on top of `fill`, `border` a border, and
114
+ `text` the family's colour as text. Border and text each have a weaker and a
115
+ stronger step next to them.
116
+
117
+ ```
118
+ Families: `accent`, `visited`, `brand1`, `brand2`, `brand3`, `neutral`, `danger`, `warning`, `success`.
119
+
120
+ Roles: `surface`, `border-subtle`, `border`, `border-strong`, `fill`, `text`, `text-strong`, `text-subtle`, `content`.
121
+
122
+ 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`.
123
+ ```
124
+
125
+ Spacing: `--lt-spacing-0-5`, `--lt-spacing-1`, `--lt-spacing-10`,
126
+ `--lt-spacing-12`, `--lt-spacing-16`, `--lt-spacing-2`, `--lt-spacing-3`,
127
+ `--lt-spacing-4`, `--lt-spacing-5`, `--lt-spacing-6`, `--lt-spacing-7`,
128
+ `--lt-spacing-8`, `--lt-spacing-px`.
129
+
130
+ Font: `--lt-font-size-l`, `--lt-font-size-m`, `--lt-font-size-mega`,
131
+ `--lt-font-size-reference`, `--lt-font-size-s`, `--lt-font-size-xl`,
132
+ `--lt-font-size-xs`, `--lt-font-size-xxl`, `--lt-font-size-xxs`,
133
+ `--lt-font-weight-bold`, `--lt-font-weight-medium`,
134
+ `--lt-font-weight-regular`, `--lt-font-weight-semibold`.
135
+
136
+ Line height: `--lt-line-height-article`, `--lt-line-height-compact`,
137
+ `--lt-line-height-default`, `--lt-line-height-heading`.
138
+
139
+ `disabled` and `neutral` are not the same. `disabled` is for controls that are
140
+ turned off, and is exempt from the contrast requirement in WCAG 1.4.3.
141
+ `neutral` is for subdued information the user actually has to read or press,
142
+ and holds 4.5:1. Never use the `disabled` colours to subdue something that is
143
+ meant to be read.
144
+
145
+ ### Light and dark
146
+
147
+ Without you doing anything, the colours follow the device's setting. A page
148
+ that wants to decide for itself sets `data-theme="light"` or
149
+ `data-theme="dark"` on `<html>`.
150
+
151
+ The attribute is a **theme boundary** and works on any element, not only on
152
+ the root. One theme can sit inside another, both ways.
153
+
154
+ This is what an embedded component should use. When you put LO-TEK into a page
155
+ you do not control, set the attribute on the component's own root element:
156
+
157
+ ```tsx
158
+ <div data-theme="light">
159
+ <button {...lt.button()}>Save</button>
160
+ </div>
161
+ ```
162
+
163
+ The component is then light whatever the device is set to, and the host is
164
+ left alone.
165
+
166
+ **The host's CSS stops at the boundary.** The host often has rules without a
167
+ layer, such as `button { background: none; border: none }` or a normalize, and
168
+ they beat `@layer lotek`. In that case, set `data-lt-boundary` on the same
169
+ root element:
170
+
171
+ ```tsx
172
+ <div data-lt-boundary data-theme="light">
173
+ <button {...lt.button()}>Save</button>
174
+ </div>
175
+ ```
176
+
177
+ Below the root element the browser then ignores the host's CSS without a
178
+ layer, unless a rule of the host's wins on specificity as described below, and
179
+ LO-TEK's layer applies again. The rule is in `lotek.css` and in
180
+ `@lo-tek/interfaces/boundary.css`. Fonts and other inherited properties still
181
+ come from the host, and the `--lt-*` variables work. Three things follow from
182
+ it:
183
+
184
+ - Your own CSS inside the boundary must be in a layer after `lotek`. CSS
185
+ without a layer disappears there in the same way as the host's.
186
+ - Elements without a LO-TEK class lose the host's CSS without a layer. A layer
187
+ the host has declared before `lotek`, such as Tailwind's Preflight in
188
+ `base`, still applies where LO-TEK sets nothing.
189
+ - The boundary has the specificity (0,2,0). A rule from the host with the same
190
+ specificity wins if it is loaded after the boundary, and one with more
191
+ always wins. So do `!important` and layers the host has declared after
192
+ `lotek`.
193
+
194
+ LO-TEK sets `color-scheme` only where someone has chosen a theme: on
195
+ `[data-theme="light"]`, on `[data-theme="dark"]` and on the options of the
196
+ theme picker below. Bare `:root` never gets it. The property controls the
197
+ browser's own surfaces, that is, scrollbars, dropdowns and calendar panels,
198
+ and it is inherited. A child can opt out with `color-scheme: normal`, but that
199
+ is a counter-rule the host never asked to have to write: with the value on the
200
+ root, it applied to the whole document, including where the package is only a
201
+ guest. If the whole page should follow the system, write
202
+ `color-scheme: light dark` on `<html>` yourself, in the same way as you set
203
+ the layer order yourself.
204
+
205
+ ### Letting the user choose a theme
206
+
207
+ `lt-theme-control` on a radio button makes `value` a theme choice. It is plain
208
+ CSS, without a line of JavaScript:
209
+
210
+ ```tsx
211
+ <fieldset {...lt.toggleGroup()}>
212
+ <legend {...lt.srOnly()}>Theme</legend>
213
+ <label className={lt.toggleGroup.option}>
214
+ <input className="lt-theme-control" type="radio" name="theme"
215
+ value="auto" defaultChecked /> Follow the system
216
+ </label>
217
+ <label className={lt.toggleGroup.option}>
218
+ <input className="lt-theme-control" type="radio" name="theme"
219
+ value="light" /> Light
220
+ </label>
221
+ <label className={lt.toggleGroup.option}>
222
+ <input className="lt-theme-control" type="radio" name="theme"
223
+ value="dark" /> Dark
224
+ </label>
225
+ </fieldset>
226
+ ```
227
+
228
+ `lt-theme-control` has no builder function, so it is the one class written as
229
+ a string.
230
+
231
+ The choice controls two things. LO-TEK's colours come from the tokens, and the
232
+ browser's **own** surfaces from `color-scheme`: `light` gives `light`, `dark`
233
+ gives `dark`, and `auto` gives `light dark`. `light dark` is not a theme, but
234
+ the statement that the page works in both, so the browser can choose by the
235
+ system.
236
+
237
+ "Follow the system" has no theme block, and that is on purpose: a value
238
+ without a block matches nothing, and then the media query applies again.
239
+
240
+ Do not write `color-scheme` yourself when the picker is in use. Such a rule
241
+ outside a layer beats `@layer lotek` and locks the browser's surfaces to the
242
+ system while the user has chosen something else.
243
+
244
+ `light` and `dark` win over `data-theme` on `<html>`, so the server can send
245
+ the stored choice while a click still takes effect before the response is
246
+ back. `auto` does not: it means "no override from me", so if the server has
247
+ written `data-theme`, the server's value stands. For "follow the system" to
248
+ work at once, whatever stores the choice must also remove the attribute.
249
+
250
+ Two things it does not do. It **stores nothing**: submit the group in a form
251
+ and store the choice in a cookie the server reads, or in `localStorage`. And
252
+ it must be in the **same tree as `<html>`**, since `:has()` does not see out
253
+ of its own tree; a control inside a shadow root does not set the theme on the
254
+ page.
255
+
256
+ ## 4. Web components
257
+
258
+ Three rules apply to all of them:
259
+
260
+ 1. **`defineLt*()` runs once** at the top of the module, before `createRoot`,
261
+ not in a `useEffect`. The import has no side effect on its own; it is the
262
+ `define` call that registers the element.
263
+ 2. **Boolean attributes are true as long as they are present.**
264
+ `hidden="false"`, `disabled="false"` and `open="false"` turn it *on*. To
265
+ turn any of them off, remove the attribute entirely.
266
+ 3. **You write the markup, the component adds the behaviour.** `<lt-field>`
267
+ does not create your label or your control. You write `htmlFor` on the
268
+ label and `id` on the control, or wrap the control in a `<label>`, so the
269
+ field has a name without JavaScript too. The component wires the help text
270
+ and the error text with `aria-describedby` and `aria-invalid`, and never
271
+ writes an id on the control, so the id is yours, from `useId()`. The field
272
+ is invalid when the error text is there without `hidden`.
273
+
274
+ | Element | Category | Stylesheet | Registration | Attributes | Events | Classes inside |
275
+ | --- | --- | --- | --- | --- | --- | --- |
276
+ | `<lt-field>` | frame | `@lo-tek/interfaces/field.css` | `defineLtField()` from `@lo-tek/interfaces/field` | `disabled` (flag)<br>`optional` (flag)<br>`described-by` (text) | none | none |
277
+ | `<lt-tabs>` | frame | `@lo-tek/interfaces/tabs.css` | `defineLtTabs()` from `@lo-tek/interfaces/tabs` | `server-controlled` (flag)<br>`activation`: manual, automatic | `tab-select` (index) | `lt-tabs__list`<br>`lt-tabs__panel` |
278
+ | `<lt-error-summary>` | frame | `@lo-tek/interfaces/error-summary.css` | `defineLtErrorSummary()` from `@lo-tek/interfaces/error-summary` | `data-autofocus`: false, true<br>`hidden` (flag) | none | `lt-error-summary`<br>`lt-error-summary__title` |
279
+ | `<lt-popover>` | frame | `@lo-tek/interfaces/popover.css` | `defineLtPopover()` from `@lo-tek/interfaces/popover` | `open` (flag)<br>`placement`: bottom-start, bottom-end, top-start, top-end<br>`server-controlled` (flag) | `popover-toggle` (open) | `lt-popover` |
280
+ | `<lt-suggestion>` | frame | `@lo-tek/interfaces/suggestion.css` | `defineLtSuggestion()` from `@lo-tek/interfaces/suggestion` | `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` |
281
+ | `<lt-dialog>` | frame | `@lo-tek/interfaces/dialog.css` | `defineLtDialog()` from `@lo-tek/interfaces/dialog` | `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` |
282
+ | `<lt-toast>` | standalone | `@lo-tek/interfaces/toast.css` | `defineLtToast()` from `@lo-tek/interfaces/toast` | `duration` (number)<br>`label` (text)<br>`close-label` (text) | `toast-dismiss` | `lt-toast`<br>`lt-toast__message`<br>`lt-toast__close` |
283
+ | `<lt-session-timeout>` | frame | `@lo-tek/interfaces/session-timeout.css` | `defineLtSessionTimeout()` from `@lo-tek/interfaces/session-timeout` | `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` |
284
+ | `<lt-connection-status>` | standalone | `@lo-tek/interfaces/connection-status.css` | `defineLtConnectionStatus()` from `@lo-tek/interfaces/connection-status` | `offline-text` (text)<br>`online-text` (text) | `connection-lost`<br>`connection-restored` | `lt-connection-status`<br>`lt-connection-status__bar` |
285
+
286
+ None of them uses shadow DOM. The content is in plain DOM, so `querySelector`,
287
+ `FormData` and ordinary CSS work straight into it.
288
+
289
+ ## 5. Registration, types and use
290
+
291
+ ```tsx
292
+ // main.tsx, runs once when the app starts
293
+ import "@lo-tek/interfaces/tokens.css"
294
+ import "@lo-tek/interfaces/field.css"
295
+ import "@lo-tek/interfaces/button.css"
296
+ import { defineLt } from "@lo-tek/interfaces/register"
297
+
298
+ defineLt()
299
+ ```
300
+
301
+ The call is at the top of the module, not in a `useEffect`. An effect runs
302
+ after the first paint, so the elements are plain `HTMLElement`s when React
303
+ renders them, and a call to `show()` or `reportFailure()` before the effect
304
+ fails with "is not a function". The function does nothing on a server, so it
305
+ can sit in a root module that runs in both places. If you use only one
306
+ component, it has its own function, such as `defineLtTabs()` in
307
+ `@lo-tek/interfaces/tabs`.
308
+
309
+ ```ts
310
+ // src/lotek.d.ts, gives the web components types in JSX
311
+ import "@lo-tek/interfaces/react-jsx"
312
+ ```
313
+
314
+ A field is written with `lt.field()`. The wiring is then in the markup React
315
+ renders itself, on the server as in the browser. `<lt-field>` writes the
316
+ wiring on the elements before React hydrates, and with server rendering React
317
+ reports mismatches on the label, the field and the error text. Without a
318
+ server it works, but `lt.field()` is the way in both.
319
+
320
+ ```tsx
321
+ // ContactForm.tsx
322
+ import { lt } from "@lo-tek/interfaces/react"
323
+ import { useId, useState } from "react"
324
+
325
+ export function ContactForm() {
326
+ const [name, setName] = useState("")
327
+ const [touched, setTouched] = useState(false)
328
+
329
+ const invalid = touched && name.trim() === ""
330
+ const field = lt.field({
331
+ id: useId(),
332
+ required: "symbol",
333
+ error: true,
334
+ invalid,
335
+ })
336
+
337
+ return (
338
+ <form onSubmit={(e) => e.preventDefault()}>
339
+ <label {...field.label}>Full name</label>
340
+ <input
341
+ {...lt.input({ type: "text" })}
342
+ {...field.control}
343
+ name="name"
344
+ required
345
+ value={name}
346
+ onChange={(e) => setName(e.target.value)}
347
+ onBlur={() => setTouched(true)}
348
+ />
349
+ <p {...lt.errorText()} {...field.error}>Enter your name.</p>
350
+
351
+ <button {...lt.button()} type="submit">Send</button>
352
+ </form>
353
+ )
354
+ }
355
+ ```
356
+
357
+ The id comes from `useId()`, so the server and the browser create the same
358
+ one.
359
+
360
+ `lt` is imported from `@lo-tek/interfaces/react`, never from the main entry:
361
+ the React entry gives `className` and `htmlFor`, the main entry gives `class`
362
+ and `for`. The 46 builder functions are in both:
363
+
364
+ `lt.accordion()`, `lt.alert()`, `lt.avatar()`, `lt.badge()`,
365
+ `lt.breadcrumbs()`, `lt.button()`, `lt.card()`, `lt.checkbox()`,
366
+ `lt.connectionStatus()`, `lt.dialog()`, `lt.divider()`, `lt.errorSummary()`,
367
+ `lt.errorText()`, `lt.field()`, `lt.fieldset()`, `lt.fileUpload()`,
368
+ `lt.heading()`, `lt.helpText()`, `lt.icon()`, `lt.input()`, `lt.label()`,
369
+ `lt.legend()`, `lt.link()`, `lt.list()`, `lt.pagination()`, `lt.paragraph()`,
370
+ `lt.popover()`, `lt.progress()`, `lt.radio()`, `lt.search()`, `lt.select()`,
371
+ `lt.sessionTimeout()`, `lt.skeleton()`, `lt.skipLink()`, `lt.spinner()`,
372
+ `lt.srOnly()`, `lt.suggestion()`, `lt.switch()`, `lt.table()`,
373
+ `lt.tableSort()`, `lt.tabs()`, `lt.tag()`, `lt.textarea()`, `lt.toast()`,
374
+ `lt.toggleGroup()`, `lt.tooltip()`
375
+
376
+ ## 6. Only `open={isOpen || undefined}` works
377
+
378
+ This applies to every boolean attribute on a web component, such as `open` on
379
+ `<lt-dialog>` and `<lt-popover>`. React treats web components differently
380
+ between versions, and only this pattern is right in both:
381
+
382
+ | How it is written | React 18 (sets attribute) | React 19 (sets property) |
383
+ | --- | --- | --- |
384
+ | `open=""` | works | never open |
385
+ | `open={isOpen}` | always open | works |
386
+ | `open={isOpen \|\| undefined}` | works | works |
387
+
388
+ React 18 stringifies `false` to the attribute `open="false"`. The attribute is
389
+ then present, and so it is true. React 19 sets the property to `""`, and the
390
+ component reads the empty string as false.
391
+
392
+ If you import `@lo-tek/interfaces/react-jsx`, the first two forms become
393
+ compile errors.
394
+
395
+ The builder functions pass `true` or nothing, so
396
+ `{...lt.dialog({ titleId, open: isOpen }).host}` is already right.
397
+
398
+ ## 7. The types
399
+
400
+ Without `@lo-tek/interfaces/react-jsx` TypeScript does not know `<lt-field>`
401
+ at all, and you get
402
+ `Property 'lt-field' does not exist on type 'JSX.IntrinsicElements'`. With it
403
+ you get autocompletion and errors on the attributes:
404
+
405
+ ```tsx
406
+ <lt-field describedBy="terms" /> // error: the attribute is described-by
407
+ <lt-toast closeLabel="Close" /> // error: the attribute is close-label
408
+ <lt-connection-status offline="Down" /> // error: unknown attribute
409
+ ```
410
+
411
+ The types work by the package extending React's `JSX.IntrinsicElements`. If
412
+ the project has two installations of `@types/react`, which easily happens in a
413
+ monorepo, the package extends one while your code uses the other, and the
414
+ elements stay unknown. Run `npm ls @types/react` if something looks odd.
415
+
416
+ ## Known pitfalls
417
+
418
+ | Symptom | Cause |
419
+ | --- | --- |
420
+ | The styles are missing | `tokens.css` is not loaded. The order between it and the component's stylesheet does not matter |
421
+ | 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 |
422
+ | 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/ |
423
+ | 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` |
424
+ | The component does nothing, and nothing says so | The registration runs only on the server, where it does nothing. It must also run in the browser |
425
+ | "Invalid DOM property `class`" | `lt` is imported from the main entry. Use `@lo-tek/interfaces/react` |
426
+ | `Property 'lt-field' does not exist` | `@lo-tek/interfaces/react-jsx` is not imported in a `.d.ts` file |
427
+
428
+ ## When CSS is not enough
429
+
430
+ The components are customised with tokens and `--lt-` variables. If that is
431
+ not enough, `npx @lo-tek/interfaces takeover <component>` copies the source
432
+ code of one component into `src/lotek/<component>/`, so the code is yours to
433
+ change. The copy is TypeScript that imports from the package by name, so it
434
+ needs a build step. It is renamed from `lt-` to `app-`, and a
435
+ `lotek-manifest.json` next to it teaches the check the new names:
436
+ `npx @lo-tek/interfaces check --manifest=src/lotek/<component>/lotek-manifest.json <files>`.
437
+ A complete colour theme from your brand colours is made with
438
+ `npx @lo-tek/interfaces theme`.
439
+
440
+ All of this, with live examples: https://lo-tek.sobernetics.no/