@toa.io/extensions.configuration 1.0.0-alpha.273 → 1.0.0-alpha.274

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 (521) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/components/configuration.values/manifest.toa.yaml +158 -0
  3. package/components/configuration.values/source/create.ts +56 -0
  4. package/components/configuration.values/source/fetch.ts +24 -0
  5. package/components/configuration.values/source/get.ts +33 -0
  6. package/components/configuration.values/source/lib/map.test.ts +34 -0
  7. package/components/configuration.values/source/lib/map.ts +34 -0
  8. package/components/configuration.values/source/lib/resolve.ts +54 -0
  9. package/components/configuration.values/source/list.ts +19 -0
  10. package/components/configuration.values/tsconfig.json +9 -0
  11. package/cucumber.js +8 -0
  12. package/features/site/_app/immutable/asset.js +1 -0
  13. package/features/site/index.html +6 -0
  14. package/features/steps/UI.ts +88 -0
  15. package/features/steps/tsconfig.json +9 -0
  16. package/features/ui.feature +85 -0
  17. package/package.json +12 -5
  18. package/readme.md +150 -34
  19. package/schemas/annotation.cos.yaml +27 -2
  20. package/source/Aspect.test.ts +84 -8
  21. package/source/Aspect.ts +59 -5
  22. package/source/Client.test.ts +104 -0
  23. package/source/Client.ts +258 -0
  24. package/source/Composition.ts +57 -0
  25. package/source/Factory.ts +28 -5
  26. package/source/Secret.test.ts +29 -0
  27. package/source/Secret.ts +29 -0
  28. package/source/UI.ts +197 -0
  29. package/source/configuration.test.ts +84 -52
  30. package/source/configuration.ts +28 -9
  31. package/source/const.ts +17 -0
  32. package/source/deployment.test.ts +80 -1
  33. package/source/deployment.ts +73 -23
  34. package/source/epoch.test.ts +26 -0
  35. package/source/epoch.ts +21 -0
  36. package/source/index.ts +2 -1
  37. package/transpiled/Aspect.d.ts +18 -4
  38. package/transpiled/Aspect.js +47 -3
  39. package/transpiled/Aspect.js.map +1 -1
  40. package/transpiled/Aspect.test.js +59 -9
  41. package/transpiled/Aspect.test.js.map +1 -1
  42. package/transpiled/Client.d.ts +61 -0
  43. package/transpiled/Client.js +173 -0
  44. package/transpiled/Client.js.map +1 -0
  45. package/transpiled/Client.test.d.ts +1 -0
  46. package/transpiled/Client.test.js +77 -0
  47. package/transpiled/Client.test.js.map +1 -0
  48. package/transpiled/Composition.d.ts +14 -0
  49. package/transpiled/Composition.js +43 -0
  50. package/transpiled/Composition.js.map +1 -0
  51. package/transpiled/Factory.d.ts +8 -2
  52. package/transpiled/Factory.js +17 -2
  53. package/transpiled/Factory.js.map +1 -1
  54. package/transpiled/Secret.d.ts +13 -0
  55. package/transpiled/Secret.js +26 -0
  56. package/transpiled/Secret.js.map +1 -0
  57. package/transpiled/Secret.test.d.ts +1 -0
  58. package/transpiled/Secret.test.js +26 -0
  59. package/transpiled/Secret.test.js.map +1 -0
  60. package/transpiled/UI.d.ts +25 -0
  61. package/transpiled/UI.js +186 -0
  62. package/transpiled/UI.js.map +1 -0
  63. package/transpiled/configuration.d.ts +7 -2
  64. package/transpiled/configuration.js +30 -12
  65. package/transpiled/configuration.js.map +1 -1
  66. package/transpiled/configuration.test.js +77 -51
  67. package/transpiled/configuration.test.js.map +1 -1
  68. package/transpiled/const.d.ts +11 -0
  69. package/transpiled/const.js +14 -0
  70. package/transpiled/const.js.map +1 -0
  71. package/transpiled/deployment.d.ts +10 -4
  72. package/transpiled/deployment.js +57 -20
  73. package/transpiled/deployment.js.map +1 -1
  74. package/transpiled/deployment.test.js +60 -0
  75. package/transpiled/deployment.test.js.map +1 -1
  76. package/transpiled/epoch.d.ts +2 -0
  77. package/transpiled/epoch.js +21 -0
  78. package/transpiled/epoch.js.map +1 -0
  79. package/transpiled/epoch.test.d.ts +1 -0
  80. package/transpiled/epoch.test.js +22 -0
  81. package/transpiled/epoch.test.js.map +1 -0
  82. package/transpiled/index.d.ts +2 -1
  83. package/transpiled/index.js +4 -1
  84. package/transpiled/index.js.map +1 -1
  85. package/transpiled/tsconfig.tsbuildinfo +1 -1
  86. package/ui/.agents/skills/antcn/SKILL.md +91 -0
  87. package/ui/.agents/skills/antcn/references/analytics.md +78 -0
  88. package/ui/.agents/skills/antcn/references/bridge.md +41 -0
  89. package/ui/.agents/skills/antcn/references/clipboard.md +23 -0
  90. package/ui/.agents/skills/antcn/references/dismissable.md +75 -0
  91. package/ui/.agents/skills/antcn/references/dropdown.md +153 -0
  92. package/ui/.agents/skills/antcn/references/fragments.md +29 -0
  93. package/ui/.agents/skills/antcn/references/fullscreen.md +157 -0
  94. package/ui/.agents/skills/antcn/references/geo.md +27 -0
  95. package/ui/.agents/skills/antcn/references/globals.md +31 -0
  96. package/ui/.agents/skills/antcn/references/grammatical-form.md +69 -0
  97. package/ui/.agents/skills/antcn/references/hints.md +44 -0
  98. package/ui/.agents/skills/antcn/references/hold.md +34 -0
  99. package/ui/.agents/skills/antcn/references/iam.md +117 -0
  100. package/ui/.agents/skills/antcn/references/input-form.md +34 -0
  101. package/ui/.agents/skills/antcn/references/locale.md +66 -0
  102. package/ui/.agents/skills/antcn/references/net.md +33 -0
  103. package/ui/.agents/skills/antcn/references/panel.md +44 -0
  104. package/ui/.agents/skills/antcn/references/passkeys.md +27 -0
  105. package/ui/.agents/skills/antcn/references/payments.md +99 -0
  106. package/ui/.agents/skills/antcn/references/realtime.md +69 -0
  107. package/ui/.agents/skills/antcn/references/scrollable.md +39 -0
  108. package/ui/.agents/skills/antcn/references/selector.md +71 -0
  109. package/ui/.agents/skills/antcn/references/shake.md +36 -0
  110. package/ui/.agents/skills/antcn/references/share.md +28 -0
  111. package/ui/.agents/skills/antcn/references/shell.md +139 -0
  112. package/ui/.agents/skills/antcn/references/stack.md +53 -0
  113. package/ui/.agents/skills/antcn/references/system.md +149 -0
  114. package/ui/.agents/skills/antcn/references/taptap.md +28 -0
  115. package/ui/.agents/skills/antcn/references/tools.md +68 -0
  116. package/ui/.agents/skills/antcn/references/transmission.md +96 -0
  117. package/ui/.agents/skills/shadcn-svelte/SKILL.md +227 -0
  118. package/ui/.agents/skills/shadcn-svelte/agents/openai.yml +5 -0
  119. package/ui/.agents/skills/shadcn-svelte/assets/shadcn-svelte-small.png +0 -0
  120. package/ui/.agents/skills/shadcn-svelte/assets/shadcn-svelte.png +0 -0
  121. package/ui/.agents/skills/shadcn-svelte/cli.md +166 -0
  122. package/ui/.agents/skills/shadcn-svelte/customization.md +213 -0
  123. package/ui/.agents/skills/shadcn-svelte/evals/evals.json +47 -0
  124. package/ui/.agents/skills/shadcn-svelte/rules/composition.md +244 -0
  125. package/ui/.agents/skills/shadcn-svelte/rules/forms.md +234 -0
  126. package/ui/.agents/skills/shadcn-svelte/rules/icons.md +107 -0
  127. package/ui/.agents/skills/shadcn-svelte/rules/styling.md +195 -0
  128. package/ui/.agents/skills/svas/SKILL.md +169 -0
  129. package/ui/.agents/skills/svas/references/patterns.md +95 -0
  130. package/ui/.agents/skills/svintl/SKILL.md +176 -0
  131. package/ui/.claude/settings.json +15 -0
  132. package/ui/.codex/hooks.json +15 -0
  133. package/ui/.cursor/hooks.json +11 -0
  134. package/ui/.env.example +1 -0
  135. package/ui/.prettierrc +9 -0
  136. package/ui/.vscode/extensions.json +7 -0
  137. package/ui/.vscode/settings.json +27 -0
  138. package/ui/AGENTS.md +51 -0
  139. package/ui/architecture.md +390 -0
  140. package/ui/components.json +20 -0
  141. package/ui/eslint.config.js +152 -0
  142. package/ui/features/base.ts +2 -0
  143. package/ui/features/boot.feature +5 -0
  144. package/ui/features/steps/authentication.ts +34 -0
  145. package/ui/features/steps/navigaton.ts +37 -0
  146. package/ui/features/steps/typing.ts +24 -0
  147. package/ui/package-lock.json +8173 -0
  148. package/ui/package.json +76 -0
  149. package/ui/playwright.config.ts +13 -0
  150. package/ui/skills-lock.json +30 -0
  151. package/ui/src/@/configuration/index.ts +1 -0
  152. package/ui/src/@/configuration/svc/create.ts +29 -0
  153. package/ui/src/@/configuration/svc/index.ts +3 -0
  154. package/ui/src/@/configuration/svc/net/Configuration.ts +18 -0
  155. package/ui/src/@/configuration/svc/net/index.ts +2 -0
  156. package/ui/src/@/configuration/svc/net/interface.ts +35 -0
  157. package/ui/src/@/configuration/svc/store.ts +14 -0
  158. package/ui/src/@/configuration/ui/Configurations.svelte +85 -0
  159. package/ui/src/@/configuration/ui/Configurations.ts +5 -0
  160. package/ui/src/@/configuration/ui/Create.svelte +64 -0
  161. package/ui/src/@/configuration/ui/Create.ts +7 -0
  162. package/ui/src/@/configuration/ui/Form.svelte +75 -0
  163. package/ui/src/@/configuration/ui/Form.ts +79 -0
  164. package/ui/src/@/configuration/ui/Row.svelte +44 -0
  165. package/ui/src/@/configuration/ui/Row.ts +9 -0
  166. package/ui/src/@/configuration/ui/Value.svelte +33 -0
  167. package/ui/src/@/configuration/ui/Value.ts +6 -0
  168. package/ui/src/@/configuration/ui/index.ts +9 -0
  169. package/ui/src/@/configuration/ui/intl/built.js +38 -0
  170. package/ui/src/@/configuration/ui/intl/context.yaml +51 -0
  171. package/ui/src/@/configuration/ui/intl/en-US.yaml +21 -0
  172. package/ui/src/@/configuration/ui/intl/index.ts +9 -0
  173. package/ui/src/@/configuration/ui/intl/types.ts +31 -0
  174. package/ui/src/@/configuration/ui/read.test.ts +75 -0
  175. package/ui/src/@/configuration/ui/read.ts +102 -0
  176. package/ui/src/@/configuration/ui/ui.test.ts +69 -0
  177. package/ui/src/@/configuration/ui/ui.ts +115 -0
  178. package/ui/src/@/iam/index.ts +1 -0
  179. package/ui/src/@/iam/rc.ts +22 -0
  180. package/ui/src/@/iam/svc/authenticated.ts +17 -0
  181. package/ui/src/@/iam/svc/basic.ts +23 -0
  182. package/ui/src/@/iam/svc/index.ts +10 -0
  183. package/ui/src/@/iam/svc/logout.ts +5 -0
  184. package/ui/src/@/iam/svc/named.ts +16 -0
  185. package/ui/src/@/iam/svc/net/Echo.ts +9 -0
  186. package/ui/src/@/iam/svc/net/basic/index.ts +1 -0
  187. package/ui/src/@/iam/svc/net/basic/interface.ts +15 -0
  188. package/ui/src/@/iam/svc/net/federation/index.ts +1 -0
  189. package/ui/src/@/iam/svc/net/federation/interface.ts +12 -0
  190. package/ui/src/@/iam/svc/net/index.ts +6 -0
  191. package/ui/src/@/iam/svc/net/interface.ts +17 -0
  192. package/ui/src/@/iam/svc/net/otp/index.ts +1 -0
  193. package/ui/src/@/iam/svc/net/otp/interface.ts +14 -0
  194. package/ui/src/@/iam/svc/net/passkeys/index.ts +1 -0
  195. package/ui/src/@/iam/svc/net/passkeys/interface.ts +12 -0
  196. package/ui/src/@/iam/svc/oidc/apple.ts +47 -0
  197. package/ui/src/@/iam/svc/oidc/authenticate.ts +62 -0
  198. package/ui/src/@/iam/svc/oidc/google.ts +45 -0
  199. package/ui/src/@/iam/svc/oidc/hello.ts +82 -0
  200. package/ui/src/@/iam/svc/oidc/index.ts +3 -0
  201. package/ui/src/@/iam/svc/oidc/nonce.ts +5 -0
  202. package/ui/src/@/iam/svc/oidc/providers.ts +28 -0
  203. package/ui/src/@/iam/svc/oidc/standard.ts +28 -0
  204. package/ui/src/@/iam/svc/otp.ts +18 -0
  205. package/ui/src/@/iam/svc/passkeys/create.ts +20 -0
  206. package/ui/src/@/iam/svc/passkeys/index.ts +2 -0
  207. package/ui/src/@/iam/svc/passkeys/login.ts +21 -0
  208. package/ui/src/@/iam/svc/store.ts +36 -0
  209. package/ui/src/@/iam/svc/sync.ts +18 -0
  210. package/ui/src/@/iam/svc/transfer.ts +11 -0
  211. package/ui/src/@/iam/svc/update.ts +8 -0
  212. package/ui/src/@/iam/ui/AccountLike.ts +4 -0
  213. package/ui/src/@/iam/ui/Authenticated.svelte +37 -0
  214. package/ui/src/@/iam/ui/Authenticated.ts +10 -0
  215. package/ui/src/@/iam/ui/Authentication.svelte +50 -0
  216. package/ui/src/@/iam/ui/Authentication.ts +9 -0
  217. package/ui/src/@/iam/ui/Authorized.svelte +32 -0
  218. package/ui/src/@/iam/ui/Authorized.ts +65 -0
  219. package/ui/src/@/iam/ui/Card.svelte +14 -0
  220. package/ui/src/@/iam/ui/Card.ts +7 -0
  221. package/ui/src/@/iam/ui/Refresh.svelte +39 -0
  222. package/ui/src/@/iam/ui/credentials/Credentials.svelte +26 -0
  223. package/ui/src/@/iam/ui/credentials/Credentials.ts +5 -0
  224. package/ui/src/@/iam/ui/credentials/Provider.svelte +24 -0
  225. package/ui/src/@/iam/ui/credentials/Provider.ts +5 -0
  226. package/ui/src/@/iam/ui/credentials/index.ts +1 -0
  227. package/ui/src/@/iam/ui/credentials/passkeys/Key.svelte +42 -0
  228. package/ui/src/@/iam/ui/credentials/passkeys/Key.ts +29 -0
  229. package/ui/src/@/iam/ui/credentials/passkeys/Manager.svelte +83 -0
  230. package/ui/src/@/iam/ui/credentials/passkeys/Manager.ts +5 -0
  231. package/ui/src/@/iam/ui/credentials/passkeys/Passkeys.svelte +39 -0
  232. package/ui/src/@/iam/ui/credentials/passkeys/Summary.svelte +27 -0
  233. package/ui/src/@/iam/ui/credentials/passkeys/Summary.ts +5 -0
  234. package/ui/src/@/iam/ui/credentials/passkeys/index.ts +1 -0
  235. package/ui/src/@/iam/ui/credentials/providers.ts +15 -0
  236. package/ui/src/@/iam/ui/credentials/transfer/Qr.svelte +24 -0
  237. package/ui/src/@/iam/ui/credentials/transfer/Qr.ts +3 -0
  238. package/ui/src/@/iam/ui/credentials/transfer/Transfer.svelte +48 -0
  239. package/ui/src/@/iam/ui/credentials/transfer/Transfer.ts +5 -0
  240. package/ui/src/@/iam/ui/credentials/transfer/index.ts +1 -0
  241. package/ui/src/@/iam/ui/index.ts +3 -0
  242. package/ui/src/@/iam/ui/intl/built.js +79 -0
  243. package/ui/src/@/iam/ui/intl/context.yaml +91 -0
  244. package/ui/src/@/iam/ui/intl/en-US.yaml +64 -0
  245. package/ui/src/@/iam/ui/intl/index.ts +10 -0
  246. package/ui/src/@/iam/ui/intl/types.ts +70 -0
  247. package/ui/src/@/iam/ui/oidc/Authentication.svelte +16 -0
  248. package/ui/src/@/iam/ui/oidc/Authentication.ts +5 -0
  249. package/ui/src/@/iam/ui/oidc/Button.svelte +36 -0
  250. package/ui/src/@/iam/ui/oidc/Button.ts +11 -0
  251. package/ui/src/@/iam/ui/oidc/Refresh.svelte +16 -0
  252. package/ui/src/@/iam/ui/oidc/icons/Apple.svelte +19 -0
  253. package/ui/src/@/iam/ui/oidc/icons/Google.svelte +31 -0
  254. package/ui/src/@/iam/ui/oidc/icons/index.ts +11 -0
  255. package/ui/src/@/iam/ui/oidc/index.ts +2 -0
  256. package/ui/src/@/iam/ui/passkey/Authentication.svelte +64 -0
  257. package/ui/src/@/iam/ui/passkey/Authentication.ts +8 -0
  258. package/ui/src/@/iam/ui/passkey/Create.svelte +53 -0
  259. package/ui/src/@/iam/ui/passkey/Create.ts +7 -0
  260. package/ui/src/@/iam/ui/passkey/Login.svelte +29 -0
  261. package/ui/src/@/iam/ui/passkey/Refresh.svelte +29 -0
  262. package/ui/src/@/iam/ui/passkey/index.ts +2 -0
  263. package/ui/src/@/iam/ui/password/Authentication.svelte +19 -0
  264. package/ui/src/@/iam/ui/password/Authentication.ts +8 -0
  265. package/ui/src/@/iam/ui/password/Form.svelte +151 -0
  266. package/ui/src/@/iam/ui/password/Form.ts +6 -0
  267. package/ui/src/@/iam/ui/password/Password.svelte +39 -0
  268. package/ui/src/@/iam/ui/password/Password.ts +6 -0
  269. package/ui/src/@/iam/ui/password/Refresh.svelte +5 -0
  270. package/ui/src/@/iam/ui/password/index.ts +2 -0
  271. package/ui/src/@/net/index.ts +1 -0
  272. package/ui/src/@/net/svc/index.ts +3 -0
  273. package/ui/src/@/net/svc/origin.ts +8 -0
  274. package/ui/src/@/net/svc/query.test.ts +45 -0
  275. package/ui/src/@/net/svc/query.ts +25 -0
  276. package/ui/src/@/passkeys/index.ts +1 -0
  277. package/ui/src/@/passkeys/svc/add.ts +15 -0
  278. package/ui/src/@/passkeys/svc/create.ts +58 -0
  279. package/ui/src/@/passkeys/svc/credentials/convert.ts +32 -0
  280. package/ui/src/@/passkeys/svc/credentials/create.ts +34 -0
  281. package/ui/src/@/passkeys/svc/credentials/get.ts +14 -0
  282. package/ui/src/@/passkeys/svc/credentials/index.ts +3 -0
  283. package/ui/src/@/passkeys/svc/credentials/key.ts +10 -0
  284. package/ui/src/@/passkeys/svc/get.ts +10 -0
  285. package/ui/src/@/passkeys/svc/index.ts +6 -0
  286. package/ui/src/@/passkeys/svc/net/CreationResponse.ts +15 -0
  287. package/ui/src/@/passkeys/svc/net/Passkey.ts +8 -0
  288. package/ui/src/@/passkeys/svc/net/RequestResponse.ts +12 -0
  289. package/ui/src/@/passkeys/svc/net/challenges/Options.ts +21 -0
  290. package/ui/src/@/passkeys/svc/net/challenges/index.ts +2 -0
  291. package/ui/src/@/passkeys/svc/net/challenges/interface.ts +16 -0
  292. package/ui/src/@/passkeys/svc/net/index.ts +4 -0
  293. package/ui/src/@/passkeys/svc/net/interface.ts +29 -0
  294. package/ui/src/@/passkeys/svc/remove.ts +13 -0
  295. package/ui/src/@/passkeys/svc/request.ts +50 -0
  296. package/ui/src/@/passkeys/svc/store.ts +13 -0
  297. package/ui/src/@/passkeys/svc/supported.ts +1 -0
  298. package/ui/src/@/passkeys/ui/aaguid.json +150 -0
  299. package/ui/src/@/realtime/events.ts +1 -0
  300. package/ui/src/@/realtime/index.ts +1 -0
  301. package/ui/src/@/realtime/rc.ts +13 -0
  302. package/ui/src/@/realtime/svc/connect.ts +67 -0
  303. package/ui/src/@/realtime/svc/events.ts +17 -0
  304. package/ui/src/@/realtime/svc/index.ts +5 -0
  305. package/ui/src/@/realtime/svc/net/Message.ts +6 -0
  306. package/ui/src/@/realtime/svc/net/index.ts +2 -0
  307. package/ui/src/@/realtime/svc/net/interface.ts +13 -0
  308. package/ui/src/@/realtime/svc/reset.ts +5 -0
  309. package/ui/src/@/realtime/svc/status.ts +12 -0
  310. package/ui/src/@/realtime/svc/store.ts +30 -0
  311. package/ui/src/@/realtime/svc/time.ts +15 -0
  312. package/ui/src/app.d.ts +20 -0
  313. package/ui/src/app.html +13 -0
  314. package/ui/src/config/index.ts +70 -0
  315. package/ui/src/lib/assets/favicon.svg +1 -0
  316. package/ui/src/lib/components/clipboard/Clipboard.svelte +63 -0
  317. package/ui/src/lib/components/clipboard/Clipboard.ts +12 -0
  318. package/ui/src/lib/components/clipboard/index.ts +1 -0
  319. package/ui/src/lib/components/dismissable/Dismissable.svelte +81 -0
  320. package/ui/src/lib/components/dismissable/Dismissable.ts +7 -0
  321. package/ui/src/lib/components/dismissable/index.ts +1 -0
  322. package/ui/src/lib/components/dropdown/Back.svelte +14 -0
  323. package/ui/src/lib/components/dropdown/Back.ts +3 -0
  324. package/ui/src/lib/components/dropdown/Content.svelte +76 -0
  325. package/ui/src/lib/components/dropdown/Content.ts +13 -0
  326. package/ui/src/lib/components/dropdown/Context.ts +18 -0
  327. package/ui/src/lib/components/dropdown/Group.svelte +24 -0
  328. package/ui/src/lib/components/dropdown/Group.ts +8 -0
  329. package/ui/src/lib/components/dropdown/GroupContext.ts +15 -0
  330. package/ui/src/lib/components/dropdown/Item.svelte +31 -0
  331. package/ui/src/lib/components/dropdown/Item.ts +5 -0
  332. package/ui/src/lib/components/dropdown/Layer.svelte +11 -0
  333. package/ui/src/lib/components/dropdown/Layer.ts +7 -0
  334. package/ui/src/lib/components/dropdown/Root.svelte +88 -0
  335. package/ui/src/lib/components/dropdown/Root.ts +6 -0
  336. package/ui/src/lib/components/dropdown/Separator.svelte +13 -0
  337. package/ui/src/lib/components/dropdown/Separator.ts +5 -0
  338. package/ui/src/lib/components/dropdown/Trigger.svelte +33 -0
  339. package/ui/src/lib/components/dropdown/Trigger.ts +5 -0
  340. package/ui/src/lib/components/dropdown/index.ts +8 -0
  341. package/ui/src/lib/components/fullscreen/Fullscreen.svelte +97 -0
  342. package/ui/src/lib/components/fullscreen/Fullscreen.ts +18 -0
  343. package/ui/src/lib/components/fullscreen/Overlay.svelte +15 -0
  344. package/ui/src/lib/components/fullscreen/Overlay.ts +7 -0
  345. package/ui/src/lib/components/fullscreen/index.ts +2 -0
  346. package/ui/src/lib/components/hold/Hold.svelte +133 -0
  347. package/ui/src/lib/components/hold/Hold.ts +23 -0
  348. package/ui/src/lib/components/hold/index.ts +1 -0
  349. package/ui/src/lib/components/scrollable/Scrollable.svelte +49 -0
  350. package/ui/src/lib/components/scrollable/Scrollable.ts +117 -0
  351. package/ui/src/lib/components/scrollable/index.ts +2 -0
  352. package/ui/src/lib/components/shake/Shake.svelte +62 -0
  353. package/ui/src/lib/components/shake/Shake.ts +7 -0
  354. package/ui/src/lib/components/shake/index.ts +1 -0
  355. package/ui/src/lib/components/share/Share.svelte +58 -0
  356. package/ui/src/lib/components/share/Share.ts +9 -0
  357. package/ui/src/lib/components/share/index.ts +1 -0
  358. package/ui/src/lib/components/shell/Attention.svelte +11 -0
  359. package/ui/src/lib/components/shell/Attention.ts +6 -0
  360. package/ui/src/lib/components/shell/Header.svelte +18 -0
  361. package/ui/src/lib/components/shell/Header.ts +7 -0
  362. package/ui/src/lib/components/shell/Screen.svelte +28 -0
  363. package/ui/src/lib/components/shell/Screen.ts +11 -0
  364. package/ui/src/lib/components/shell/Sticky.svelte +23 -0
  365. package/ui/src/lib/components/shell/Sticky.ts +8 -0
  366. package/ui/src/lib/components/shell/Underlay.svelte +21 -0
  367. package/ui/src/lib/components/shell/Underlay.ts +6 -0
  368. package/ui/src/lib/components/shell/index.ts +6 -0
  369. package/ui/src/lib/components/shell/nav/Actions.svelte +31 -0
  370. package/ui/src/lib/components/shell/nav/Actions.ts +16 -0
  371. package/ui/src/lib/components/shell/nav/Back.svelte +20 -0
  372. package/ui/src/lib/components/shell/nav/Back.ts +9 -0
  373. package/ui/src/lib/components/shell/nav/Bar.svelte +24 -0
  374. package/ui/src/lib/components/shell/nav/Bar.ts +3 -0
  375. package/ui/src/lib/components/shell/nav/Button.svelte +64 -0
  376. package/ui/src/lib/components/shell/nav/Button.ts +7 -0
  377. package/ui/src/lib/components/shell/nav/Nav.svelte +62 -0
  378. package/ui/src/lib/components/shell/nav/Nav.ts +35 -0
  379. package/ui/src/lib/components/shell/nav/Return.svelte +29 -0
  380. package/ui/src/lib/components/shell/nav/Return.ts +15 -0
  381. package/ui/src/lib/components/shell/nav/Sections.svelte +58 -0
  382. package/ui/src/lib/components/shell/nav/Sections.ts +6 -0
  383. package/ui/src/lib/components/shell/nav/Toolbar.svelte +73 -0
  384. package/ui/src/lib/components/shell/nav/Toolbar.ts +3 -0
  385. package/ui/src/lib/components/shell/nav/history.ts +36 -0
  386. package/ui/src/lib/components/shell/nav/index.ts +5 -0
  387. package/ui/src/lib/components/shell/nav/store.ts +24 -0
  388. package/ui/src/lib/components/ui/alert/alert-action.svelte +20 -0
  389. package/ui/src/lib/components/ui/alert/alert-description.svelte +23 -0
  390. package/ui/src/lib/components/ui/alert/alert-title.svelte +23 -0
  391. package/ui/src/lib/components/ui/alert/alert.svelte +43 -0
  392. package/ui/src/lib/components/ui/alert/index.ts +17 -0
  393. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +27 -0
  394. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +27 -0
  395. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +32 -0
  396. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
  397. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +23 -0
  398. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  399. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-media.svelte +20 -0
  400. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +17 -0
  401. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte +7 -0
  402. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
  403. package/ui/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
  404. package/ui/src/lib/components/ui/alert-dialog/alert-dialog.svelte +7 -0
  405. package/ui/src/lib/components/ui/alert-dialog/index.ts +40 -0
  406. package/ui/src/lib/components/ui/badge/badge.svelte +49 -0
  407. package/ui/src/lib/components/ui/badge/index.ts +2 -0
  408. package/ui/src/lib/components/ui/button/button.svelte +82 -0
  409. package/ui/src/lib/components/ui/button/index.ts +17 -0
  410. package/ui/src/lib/components/ui/button-group/button-group-separator.svelte +23 -0
  411. package/ui/src/lib/components/ui/button-group/button-group-text.svelte +28 -0
  412. package/ui/src/lib/components/ui/button-group/button-group.svelte +46 -0
  413. package/ui/src/lib/components/ui/button-group/index.ts +15 -0
  414. package/ui/src/lib/components/ui/card/card-action.svelte +23 -0
  415. package/ui/src/lib/components/ui/card/card-content.svelte +20 -0
  416. package/ui/src/lib/components/ui/card/card-description.svelte +20 -0
  417. package/ui/src/lib/components/ui/card/card-footer.svelte +20 -0
  418. package/ui/src/lib/components/ui/card/card-header.svelte +23 -0
  419. package/ui/src/lib/components/ui/card/card-title.svelte +20 -0
  420. package/ui/src/lib/components/ui/card/card.svelte +22 -0
  421. package/ui/src/lib/components/ui/card/index.ts +25 -0
  422. package/ui/src/lib/components/ui/checkbox/checkbox.svelte +39 -0
  423. package/ui/src/lib/components/ui/checkbox/index.ts +6 -0
  424. package/ui/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  425. package/ui/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  426. package/ui/src/lib/components/ui/collapsible/collapsible.svelte +20 -0
  427. package/ui/src/lib/components/ui/collapsible/index.ts +13 -0
  428. package/ui/src/lib/components/ui/input/index.ts +7 -0
  429. package/ui/src/lib/components/ui/input/input.svelte +48 -0
  430. package/ui/src/lib/components/ui/input-otp/index.ts +15 -0
  431. package/ui/src/lib/components/ui/input-otp/input-otp-group.svelte +20 -0
  432. package/ui/src/lib/components/ui/input-otp/input-otp-separator.svelte +27 -0
  433. package/ui/src/lib/components/ui/input-otp/input-otp-slot.svelte +31 -0
  434. package/ui/src/lib/components/ui/input-otp/input-otp.svelte +23 -0
  435. package/ui/src/lib/components/ui/item/index.ts +34 -0
  436. package/ui/src/lib/components/ui/item/item-actions.svelte +20 -0
  437. package/ui/src/lib/components/ui/item/item-content.svelte +23 -0
  438. package/ui/src/lib/components/ui/item/item-description.svelte +23 -0
  439. package/ui/src/lib/components/ui/item/item-footer.svelte +20 -0
  440. package/ui/src/lib/components/ui/item/item-group.svelte +21 -0
  441. package/ui/src/lib/components/ui/item/item-header.svelte +20 -0
  442. package/ui/src/lib/components/ui/item/item-media.svelte +42 -0
  443. package/ui/src/lib/components/ui/item/item-separator.svelte +19 -0
  444. package/ui/src/lib/components/ui/item/item-title.svelte +20 -0
  445. package/ui/src/lib/components/ui/item/item.svelte +61 -0
  446. package/ui/src/lib/components/ui/kbd/index.ts +10 -0
  447. package/ui/src/lib/components/ui/kbd/kbd-group.svelte +20 -0
  448. package/ui/src/lib/components/ui/kbd/kbd.svelte +23 -0
  449. package/ui/src/lib/components/ui/label/index.ts +7 -0
  450. package/ui/src/lib/components/ui/label/label.svelte +20 -0
  451. package/ui/src/lib/components/ui/progress/index.ts +7 -0
  452. package/ui/src/lib/components/ui/progress/progress.svelte +27 -0
  453. package/ui/src/lib/components/ui/select/index.ts +37 -0
  454. package/ui/src/lib/components/ui/select/select-content.svelte +45 -0
  455. package/ui/src/lib/components/ui/select/select-group-heading.svelte +21 -0
  456. package/ui/src/lib/components/ui/select/select-group.svelte +17 -0
  457. package/ui/src/lib/components/ui/select/select-item.svelte +40 -0
  458. package/ui/src/lib/components/ui/select/select-label.svelte +20 -0
  459. package/ui/src/lib/components/ui/select/select-portal.svelte +7 -0
  460. package/ui/src/lib/components/ui/select/select-scroll-down-button.svelte +20 -0
  461. package/ui/src/lib/components/ui/select/select-scroll-up-button.svelte +20 -0
  462. package/ui/src/lib/components/ui/select/select-separator.svelte +18 -0
  463. package/ui/src/lib/components/ui/select/select-trigger.svelte +29 -0
  464. package/ui/src/lib/components/ui/select/select.svelte +11 -0
  465. package/ui/src/lib/components/ui/separator/index.ts +7 -0
  466. package/ui/src/lib/components/ui/separator/separator.svelte +23 -0
  467. package/ui/src/lib/components/ui/spinner/index.ts +1 -0
  468. package/ui/src/lib/components/ui/spinner/spinner.svelte +18 -0
  469. package/ui/src/lib/components/ui/tabs/index.ts +18 -0
  470. package/ui/src/lib/components/ui/tabs/tabs-content.svelte +17 -0
  471. package/ui/src/lib/components/ui/tabs/tabs-list.svelte +40 -0
  472. package/ui/src/lib/components/ui/tabs/tabs-trigger.svelte +23 -0
  473. package/ui/src/lib/components/ui/tabs/tabs.svelte +19 -0
  474. package/ui/src/lib/components/ui/textarea/index.ts +7 -0
  475. package/ui/src/lib/components/ui/textarea/textarea.svelte +22 -0
  476. package/ui/src/lib/intl/bcp.ts +25 -0
  477. package/ui/src/lib/intl/built.js +18 -0
  478. package/ui/src/lib/intl/context.yaml +18 -0
  479. package/ui/src/lib/intl/en-US.yaml +6 -0
  480. package/ui/src/lib/intl/index.ts +65 -0
  481. package/ui/src/lib/intl/types.ts +19 -0
  482. package/ui/src/lib/tools/ago.ts +10 -0
  483. package/ui/src/lib/tools/assert.ts +3 -0
  484. package/ui/src/lib/tools/cap.ts +5 -0
  485. package/ui/src/lib/tools/clicks.ts +25 -0
  486. package/ui/src/lib/tools/contextmenu.ts +19 -0
  487. package/ui/src/lib/tools/convert.ts +32 -0
  488. package/ui/src/lib/tools/currency.test.ts +10 -0
  489. package/ui/src/lib/tools/currency.ts +55 -0
  490. package/ui/src/lib/tools/date.test.ts +21 -0
  491. package/ui/src/lib/tools/date.ts +35 -0
  492. package/ui/src/lib/tools/delay.ts +7 -0
  493. package/ui/src/lib/tools/image.ts +39 -0
  494. package/ui/src/lib/tools/index.ts +20 -0
  495. package/ui/src/lib/tools/location.ts +41 -0
  496. package/ui/src/lib/tools/metronome.ts +11 -0
  497. package/ui/src/lib/tools/mq.ts +84 -0
  498. package/ui/src/lib/tools/onsubmit.ts +21 -0
  499. package/ui/src/lib/tools/random.ts +15 -0
  500. package/ui/src/lib/tools/search.ts +25 -0
  501. package/ui/src/lib/tools/timeout.ts +26 -0
  502. package/ui/src/lib/tools/transition.ts +207 -0
  503. package/ui/src/lib/tools/types.ts +3 -0
  504. package/ui/src/lib/tools/uuid.test.ts +28 -0
  505. package/ui/src/lib/tools/uuid.ts +9 -0
  506. package/ui/src/lib/typeset.css +502 -0
  507. package/ui/src/lib/utils.ts +12 -0
  508. package/ui/src/routes/(private)/+layout.svelte +112 -0
  509. package/ui/src/routes/(private)/+page.svelte +7 -0
  510. package/ui/src/routes/(private)/[component]/+page.svelte +77 -0
  511. package/ui/src/routes/+layout.svelte +25 -0
  512. package/ui/src/routes/+layout.ts +14 -0
  513. package/ui/src/routes/layout.css +232 -0
  514. package/ui/static/robots.txt +3 -0
  515. package/ui/svelte.config.js +36 -0
  516. package/ui/tools/feat.js +43 -0
  517. package/ui/tools/hooks/README.md +13 -0
  518. package/ui/tools/hooks/guard-intl.sh +40 -0
  519. package/ui/tools/shad.js +7 -0
  520. package/ui/tsconfig.json +20 -0
  521. package/ui/vite.config.ts +8 -0
@@ -0,0 +1,234 @@
1
+ # Forms & Inputs
2
+
3
+ ## Contents
4
+
5
+ - Forms use Field.FieldGroup + Field.Field
6
+ - InputGroup requires InputGroup.Input/InputGroup.Textarea
7
+ - Buttons inside inputs use InputGroup.Root + InputGroup.Addon
8
+ - Option sets (2–7 choices) use ToggleGroup.Root + ToggleGroup.Item
9
+ - Field.FieldSet + Field.FieldLegend for grouping related fields
10
+ - Field validation and disabled states
11
+
12
+ ---
13
+
14
+ ## Forms use Field.FieldGroup + Field.Field
15
+
16
+ Always use `Field.FieldGroup` + `Field.Field` — never raw `div` with `space-y-*`:
17
+
18
+ ```svelte
19
+ <script lang="ts">
20
+ import * as Field from "$lib/components/ui/field";
21
+ import { Input } from "$lib/components/ui/input";
22
+ </script>
23
+
24
+ <Field.FieldGroup>
25
+ <Field.Field>
26
+ <Field.FieldLabel for="email">Email</Field.FieldLabel>
27
+ <Input id="email" type="email" />
28
+ </Field.Field>
29
+ <Field.Field>
30
+ <Field.FieldLabel for="password">Password</Field.FieldLabel>
31
+ <Input id="password" type="password" />
32
+ </Field.Field>
33
+ </Field.FieldGroup>
34
+ ```
35
+
36
+ Use `Field` with `orientation="horizontal"` for settings pages. Use `Field.FieldLabel` with `class="sr-only"` for visually hidden labels.
37
+
38
+ **Choosing form controls:**
39
+
40
+ - Simple text input → `Input`
41
+ - Dropdown with predefined options → `Select`
42
+ - Searchable dropdown → `Combobox`
43
+ - Native HTML select (no JS) → `native-select`
44
+ - Boolean toggle → `Switch` (for settings) or `Checkbox` (for forms)
45
+ - Single choice from few options → `RadioGroup`
46
+ - Toggle between 2–5 options → `ToggleGroup.Root` + `ToggleGroup.Item`
47
+ - OTP/verification code → `InputOTP`
48
+ - Multi-line text → `Textarea`
49
+
50
+ ---
51
+
52
+ ## InputGroup requires InputGroup.Input/InputGroup.Textarea
53
+
54
+ Never use raw `Input` or `Textarea` inside an `InputGroup.Root`.
55
+
56
+ **Incorrect:**
57
+
58
+ ```svelte
59
+ <script lang="ts">
60
+ import * as InputGroup from "$lib/components/ui/input-group";
61
+ import { Input } from "$lib/components/ui/input";
62
+ </script>
63
+
64
+ <InputGroup.Root>
65
+ <Input placeholder="Search..." />
66
+ </InputGroup.Root>
67
+ ```
68
+
69
+ **Correct:**
70
+
71
+ ```svelte
72
+ <script lang="ts">
73
+ import * as InputGroup from "$lib/components/ui/input-group";
74
+ </script>
75
+
76
+ <InputGroup.Root>
77
+ <InputGroup.Input placeholder="Search..." />
78
+ </InputGroup.Root>
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Buttons inside inputs use InputGroup.Root + InputGroup.Addon
84
+
85
+ Never place a `Button` directly inside or adjacent to an `Input` with custom positioning.
86
+
87
+ **Incorrect:**
88
+
89
+ ```svelte
90
+ <script lang="ts">
91
+ import { Input } from "$lib/components/ui/input";
92
+ import { Button } from "$lib/components/ui/button";
93
+ import SearchIcon from "@lucide/svelte/icons/search";
94
+ </script>
95
+
96
+ <div class="relative">
97
+ <Input placeholder="Search..." class="pr-10" />
98
+ <Button class="absolute top-0 right-0" size="icon">
99
+ <SearchIcon />
100
+ </Button>
101
+ </div>
102
+ ```
103
+
104
+ **Correct:**
105
+
106
+ ```svelte
107
+ <script lang="ts">
108
+ import * as InputGroup from "$lib/components/ui/input-group";
109
+ import { Button } from "$lib/components/ui/button";
110
+ import SearchIcon from "@lucide/svelte/icons/search";
111
+ </script>
112
+
113
+ <InputGroup.Root>
114
+ <InputGroup.Input placeholder="Search..." />
115
+ <InputGroup.Addon>
116
+ <Button size="icon">
117
+ <SearchIcon data-icon="inline-start" />
118
+ </Button>
119
+ </InputGroup.Addon>
120
+ </InputGroup.Root>
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Option sets (2–7 choices) use ToggleGroup.Root + ToggleGroup.Item
126
+
127
+ Don't manually loop `Button` components with active state.
128
+
129
+ **Incorrect:**
130
+
131
+ ```svelte
132
+ <script lang="ts">
133
+ import { Button } from "$lib/components/ui/button";
134
+ let selected = $state("daily");
135
+ </script>
136
+
137
+ <div class="flex gap-2">
138
+ {#each ["daily", "weekly", "monthly"] as option (option)}
139
+ <Button
140
+ variant={selected === option ? "default" : "outline"}
141
+ onclick={() => (selected = option)}
142
+ >
143
+ {option}
144
+ </Button>
145
+ {/each}
146
+ </div>
147
+ ```
148
+
149
+ **Correct:**
150
+
151
+ ```svelte
152
+ <script lang="ts">
153
+ import * as ToggleGroup from "$lib/components/ui/toggle-group";
154
+ let selected = $state("daily");
155
+ </script>
156
+
157
+ <ToggleGroup.Root bind:value={selected} spacing={2}>
158
+ <ToggleGroup.Item value="daily">Daily</ToggleGroup.Item>
159
+ <ToggleGroup.Item value="weekly">Weekly</ToggleGroup.Item>
160
+ <ToggleGroup.Item value="monthly">Monthly</ToggleGroup.Item>
161
+ </ToggleGroup.Root>
162
+ ```
163
+
164
+ Combine with `Field` for labelled toggle groups:
165
+
166
+ ```svelte
167
+ <script lang="ts">
168
+ import * as Field from "$lib/components/ui/field";
169
+ import * as ToggleGroup from "$lib/components/ui/toggle-group";
170
+ </script>
171
+
172
+ <Field.Field orientation="horizontal">
173
+ <Field.FieldTitle id="theme-label">Theme</Field.FieldTitle>
174
+ <ToggleGroup.Root aria-labelledby="theme-label" spacing={2}>
175
+ <ToggleGroup.Item value="light">Light</ToggleGroup.Item>
176
+ <ToggleGroup.Item value="dark">Dark</ToggleGroup.Item>
177
+ <ToggleGroup.Item value="system">System</ToggleGroup.Item>
178
+ </ToggleGroup.Root>
179
+ </Field.Field>
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Field.FieldSet + Field.FieldLegend for grouping related fields
185
+
186
+ Use `Field.FieldSet` + `Field.FieldLegend` for related checkboxes, radios, or switches — not `div` with a heading:
187
+
188
+ ```svelte
189
+ <script lang="ts">
190
+ import * as Field from "$lib/components/ui/field";
191
+ import { Checkbox } from "$lib/components/ui/checkbox";
192
+ </script>
193
+
194
+ <Field.FieldSet>
195
+ <Field.FieldLegend variant="label">Preferences</Field.FieldLegend>
196
+ <Field.FieldDescription>Select all that apply.</Field.FieldDescription>
197
+ <Field.FieldGroup class="gap-3">
198
+ <Field.Field orientation="horizontal">
199
+ <Checkbox id="dark" />
200
+ <Field.FieldLabel for="dark" class="font-normal"
201
+ >Dark mode</Field.FieldLabel
202
+ >
203
+ </Field.Field>
204
+ </Field.FieldGroup>
205
+ </Field.FieldSet>
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Field validation and disabled states
211
+
212
+ Both attributes are needed — `data-invalid`/`data-disabled` styles the field (label, description), while `aria-invalid`/`disabled` styles the control.
213
+
214
+ ```svelte
215
+ <script lang="ts">
216
+ import * as Field from "$lib/components/ui/field";
217
+ import { Input } from "$lib/components/ui/input";
218
+ </script>
219
+
220
+ <!-- Invalid. -->
221
+ <Field.Field data-invalid>
222
+ <Field.FieldLabel for="email">Email</Field.FieldLabel>
223
+ <Input id="email" aria-invalid />
224
+ <Field.FieldDescription>Invalid email address.</Field.FieldDescription>
225
+ </Field.Field>
226
+
227
+ <!-- Disabled. -->
228
+ <Field.Field data-disabled>
229
+ <Field.FieldLabel for="email">Email</Field.FieldLabel>
230
+ <Input id="email" disabled />
231
+ </Field.Field>
232
+ ```
233
+
234
+ Works for all controls: `Input`, `Textarea`, `Select`, `Checkbox`, `RadioGroupItem`, `Switch`, `Slider`, `NativeSelect`, `InputOTP`.
@@ -0,0 +1,107 @@
1
+ # Icons
2
+
3
+ **Always use the project's configured `iconLibrary` for imports.** Check the `iconLibrary` field in `components.json`: `lucide` → `@lucide/svelte`, `tabler` → `@tabler/icons-svelte`, etc. Never assume `@lucide/svelte`.
4
+
5
+ ---
6
+
7
+ ## Icons in Button use data-icon attribute
8
+
9
+ Add `data-icon="inline-start"` (prefix) or `data-icon="inline-end"` (suffix) to the icon. No sizing classes on the icon.
10
+
11
+ **Incorrect:**
12
+
13
+ ```svelte
14
+ <script lang="ts">
15
+ import { Button } from "$lib/components/ui/button";
16
+ import SearchIcon from "@lucide/svelte/icons/search";
17
+ </script>
18
+
19
+ <Button>
20
+ <SearchIcon class="mr-2 size-4" />
21
+ Search
22
+ </Button>
23
+ ```
24
+
25
+ **Correct:**
26
+
27
+ ```svelte
28
+ <script lang="ts">
29
+ import { Button } from "$lib/components/ui/button";
30
+ import SearchIcon from "@lucide/svelte/icons/search";
31
+ import ArrowRightIcon from "@lucide/svelte/icons/arrow-right";
32
+ </script>
33
+
34
+ <Button>
35
+ <SearchIcon data-icon="inline-start" />
36
+ Search
37
+ </Button>
38
+
39
+ <Button>
40
+ Next
41
+ <ArrowRightIcon data-icon="inline-end" />
42
+ </Button>
43
+ ```
44
+
45
+ ---
46
+
47
+ ## No sizing classes on icons inside components
48
+
49
+ Components handle icon sizing via CSS. Don't add `size-4`, `w-4 h-4`, or other sizing classes to icons inside `<Button>`, `DropdownMenu.Item`, `Alert.Root`, `Sidebar.*`, or other shadcn-svelte components — unless the user explicitly asks for custom icon sizes.
50
+
51
+ **Incorrect:**
52
+
53
+ ```svelte
54
+ <script lang="ts">
55
+ import { Button } from "$lib/components/ui/button";
56
+ import SearchIcon from "@lucide/svelte/icons/search";
57
+ </script>
58
+
59
+ <Button>
60
+ <SearchIcon class="size-4" data-icon="inline-start" />
61
+ Search
62
+ </Button>
63
+ ```
64
+
65
+ **Correct:**
66
+
67
+ ```svelte
68
+ <script lang="ts">
69
+ import { Button } from "$lib/components/ui/button";
70
+ import SearchIcon from "@lucide/svelte/icons/search";
71
+ </script>
72
+
73
+ <Button>
74
+ <SearchIcon data-icon="inline-start" />
75
+ Search
76
+ </Button>
77
+ ```
78
+
79
+ The same applies to icons inside `DropdownMenu.Item`, sidebar items, and other menu rows — no extra sizing classes on the icon component.
80
+
81
+ ---
82
+
83
+ ## Pass icons as components, not string keys
84
+
85
+ Use a component reference, not a string key to a lookup map.
86
+
87
+ **Incorrect:**
88
+
89
+ ```svelte
90
+ <!-- String key lookup — avoid -->
91
+ <DynamicIcon name="check" />
92
+ ```
93
+
94
+ **Correct:**
95
+
96
+ ```svelte
97
+ <script lang="ts">
98
+ import type { Component } from "svelte";
99
+ import CheckIcon from "@lucide/svelte/icons/check";
100
+
101
+ let { Icon }: { Icon: Component } = $props();
102
+ </script>
103
+
104
+ <Icon />
105
+
106
+ <!-- <StatusBadge Icon={CheckIcon} /> -->
107
+ ```
@@ -0,0 +1,195 @@
1
+ # Styling & Customization
2
+
3
+ See [customization.md](../customization.md) for theming, CSS variables, and adding custom colors.
4
+
5
+ ## Contents
6
+
7
+ - Semantic colors
8
+ - Built-in variants first
9
+ - class for layout only
10
+ - No space-x-_ / space-y-_
11
+ - Prefer size-_ over w-_ h-\* when equal
12
+ - Prefer truncate shorthand
13
+ - No manual dark: color overrides
14
+ - Use cn() for conditional classes
15
+ - No manual z-index on overlay components
16
+
17
+ ---
18
+
19
+ ## Semantic colors
20
+
21
+ **Incorrect:**
22
+
23
+ ```svelte
24
+ <div class="bg-blue-500 text-white">
25
+ <p class="text-gray-600">Secondary text</p>
26
+ </div>
27
+ ```
28
+
29
+ **Correct:**
30
+
31
+ ```svelte
32
+ <div class="bg-primary text-primary-foreground">
33
+ <p class="text-muted-foreground">Secondary text</p>
34
+ </div>
35
+ ```
36
+
37
+ ---
38
+
39
+ ## No raw color values for status/state indicators
40
+
41
+ For positive, negative, or status indicators, use Badge variants, semantic tokens like `text-destructive`, or define custom CSS variables — don't reach for raw Tailwind colors.
42
+
43
+ **Incorrect:**
44
+
45
+ ```svelte
46
+ <span class="text-emerald-600">+20.1%</span>
47
+ <span class="text-green-500">Active</span>
48
+ <span class="text-red-600">-3.2%</span>
49
+ ```
50
+
51
+ **Correct:**
52
+
53
+ ```svelte
54
+ <script lang="ts">
55
+ import { Badge } from "$lib/components/ui/badge";
56
+ </script>
57
+
58
+ <Badge variant="secondary">+20.1%</Badge>
59
+ <Badge>Active</Badge>
60
+ <span class="text-destructive">-3.2%</span>
61
+ ```
62
+
63
+ If you need a success/positive color that doesn't exist as a semantic token, use a Badge variant or ask the user about adding a custom CSS variable to the theme (see [customization.md](../customization.md)).
64
+
65
+ ---
66
+
67
+ ## Built-in variants first
68
+
69
+ **Incorrect:**
70
+
71
+ ```svelte
72
+ <script lang="ts">
73
+ import { Button } from "$lib/components/ui/button";
74
+ </script>
75
+
76
+ <Button class="border-input hover:bg-accent border bg-transparent"
77
+ >Click me</Button
78
+ >
79
+ ```
80
+
81
+ **Correct:**
82
+
83
+ ```svelte
84
+ <script lang="ts">
85
+ import { Button } from "$lib/components/ui/button";
86
+ </script>
87
+
88
+ <Button variant="outline">Click me</Button>
89
+ ```
90
+
91
+ ---
92
+
93
+ ## class for layout only
94
+
95
+ Use `class` for layout (e.g. `max-w-md`, `mx-auto`, `mt-4`), **not** for overriding component colors or typography. To change colors, use semantic tokens, built-in variants, or CSS variables.
96
+
97
+ **Incorrect:**
98
+
99
+ ```svelte
100
+ <script lang="ts">
101
+ import * as Card from "$lib/components/ui/card";
102
+ </script>
103
+
104
+ <Card.Root class="bg-blue-100 font-bold text-blue-900">
105
+ <Card.Content>Dashboard</Card.Content>
106
+ </Card.Root>
107
+ ```
108
+
109
+ **Correct:**
110
+
111
+ ```svelte
112
+ <script lang="ts">
113
+ import * as Card from "$lib/components/ui/card";
114
+ </script>
115
+
116
+ <Card.Root class="mx-auto max-w-md">
117
+ <Card.Content>Dashboard</Card.Content>
118
+ </Card.Root>
119
+ ```
120
+
121
+ To customize a component's appearance, prefer these approaches in order:
122
+
123
+ 1. **Built-in variants** — `variant="outline"`, `variant="destructive"`, etc.
124
+ 2. **Semantic color tokens** — `bg-primary`, `text-muted-foreground`.
125
+ 3. **CSS variables** — define custom colors in the global CSS file (see [customization.md](../customization.md)).
126
+
127
+ ---
128
+
129
+ ## No space-x-_ / space-y-_
130
+
131
+ Use `gap-*` instead. `space-y-4` → `flex flex-col gap-4`. `space-x-2` → `flex gap-2`.
132
+
133
+ ```svelte
134
+ <script lang="ts">
135
+ import { Input } from "$lib/components/ui/input";
136
+ import { Button } from "$lib/components/ui/button";
137
+ </script>
138
+
139
+ <div class="flex flex-col gap-4">
140
+ <Input />
141
+ <Input />
142
+ <Button>Submit</Button>
143
+ </div>
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Prefer size-_ over w-_ h-\* when equal
149
+
150
+ `size-10` not `w-10 h-10`. Applies to icons, avatars, skeletons, etc.
151
+
152
+ ---
153
+
154
+ ## Prefer truncate shorthand
155
+
156
+ `truncate` not `overflow-hidden text-ellipsis whitespace-nowrap`.
157
+
158
+ ---
159
+
160
+ ## No manual dark: color overrides
161
+
162
+ Use semantic tokens — they handle light/dark via CSS variables. `bg-background text-foreground` not `bg-white dark:bg-gray-950`.
163
+
164
+ ---
165
+
166
+ ## Use cn() for conditional classes
167
+
168
+ Use the `cn()` utility from the project for conditional or merged class names. Don't write manual ternaries in `class` strings.
169
+
170
+ **Incorrect:**
171
+
172
+ ```svelte
173
+ <script lang="ts">
174
+ let isActive = $state(false);
175
+ </script>
176
+
177
+ <div class={`flex items-center ${isActive ? "bg-primary text-primary-foreground" : "bg-muted"}`}>
178
+ ```
179
+
180
+ **Correct:**
181
+
182
+ ```svelte
183
+ <script lang="ts">
184
+ import { cn } from "$lib/utils";
185
+ let isActive = $state(false);
186
+ </script>
187
+
188
+ <div class={cn("flex items-center", isActive ? "bg-primary text-primary-foreground" : "bg-muted")}>
189
+ ```
190
+
191
+ ---
192
+
193
+ ## No manual z-index on overlay components
194
+
195
+ `Dialog`, `Sheet`, `Drawer`, `AlertDialog`, `DropdownMenu`, `Popover`, `Tooltip`, `HoverCard` handle their own stacking. Never add `z-50` or `z-[999]`.
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: svas
3
+ description: >
4
+ Async Svelte stores (svas): fetching, caching, revalidation, persistence.
5
+ Use when UI presents data from the API.
6
+ ---
7
+
8
+ # svas — Svelte Async Stores
9
+
10
+ Stores that fetch lazily, cache, revalidate, and persist. Every store emits one of three types:
11
+
12
+ ```ts
13
+ type Maybe<T, E extends Error = Error> = null | T | E
14
+ // null → no data yet (loading / cleared / not fetched)
15
+ // T → resolved value
16
+ // E → fetch error (errors are values, never thrown)
17
+ ```
18
+
19
+ ```ts
20
+ import {
21
+ value, values, collection, // stores
22
+ ok, ensure, having, awaited, once, // guards & awaiting
23
+ combined, sync, Async, // compose & render
24
+ type Maybe
25
+ } from 'svas'
26
+ ```
27
+
28
+ ## Shared lifecycle
29
+
30
+ Every store fetches on **first subscribe**, then auto-revalidates. Common options:
31
+
32
+ | Option | Meaning |
33
+ |--------|---------|
34
+ | `get` | fetcher returning `Promise<T \| Error>` |
35
+ | `revalidate` | ms before re-fetch (default `300_000`; `Infinity` disables) |
36
+ | `persist` | mirror into local storage under this key |
37
+ | `session` | use `sessionStorage` instead of `localStorage` |
38
+ | `stale` | keep previous value visible while revalidating (default `false`) |
39
+ | `bind` | `Readable<unknown \| null>` — reset/clear store when bound store is `null` (tie data to a user) |
40
+ | `default` | initial value when nothing is persisted |
41
+
42
+ ## Stores
43
+
44
+ All stores implements Readable interface from svelte/store.
45
+
46
+ Use `persist` whenever it makes sense to persist the data, it will vastly speed up the initial load.
47
+ If store contains user-bound data, use `bind` to reset the store when the user is logged out.
48
+
49
+ ### `value<T>` — one async value
50
+
51
+ `Writable<T | null>`. For single fetched values, auth tokens, transient UI flags.
52
+
53
+ ```ts
54
+ const me = value<User>({ get: () => api.me(), persist: 'user' })
55
+ const seen = value<number>({ persist: 'seen', default: 0 }) // transient/local-only
56
+ ```
57
+
58
+ Methods: `set(v)`, `update(fn)`, `extract(): T | null` (sync read), `sync()` (revalidate if stale).
59
+
60
+ ### `values<T>` — keyed cache
61
+
62
+ A map of independent `Readable<Maybe<T>>` lifecycles, one per key.
63
+
64
+ ```ts
65
+ const products = values<Product>({ get: (id) => api.product(id), stale: true, persist: 'products' })
66
+
67
+ const one = products.get('42') // Readable<Maybe<Product>>, fetches if missing
68
+ products.set('42', next) // write by key
69
+ products.extract('42') // Product | null, sync
70
+ ```
71
+
72
+ Methods: `get(key, { fetch? })` · `set(key, v, { stash? })` · `reset(key)` (restore stashed value) · `extract(key)` · `delete(key)` · `clear()`.
73
+
74
+ Extra options: `permanent` (don't revalidate persisted entries on startup). `stash: true` on `set` remembers the prior persisted value so `reset(key)` can roll back — use for optimistic updates.
75
+
76
+ ### `collection<T>` — list of `Identifiable` items
77
+
78
+ `Readable<Maybe<T[]>>`. Items must have `{ id: string }`. Pass a `values` store to also observe items individually via `get(id)`.
79
+
80
+ ```ts
81
+ const todos = collection<Todo>({
82
+ get: () => api.todos(),
83
+ values: values<Todo>(), // enables todos.get(id) / extract(id)
84
+ stale: true,
85
+ persist: 'todos',
86
+ bind: session
87
+ })
88
+ ```
89
+
90
+ Methods: `subscribe` · `add(item)` · `set(item, { add? })` (replace by id; `add` inserts if absent) · `update(id, fn, opts?)` · `delete(id)` · `replace(items)` · `get(id)`/`extract(id)` (require `values`) · `sync(): this` · `fetch(): Promise<this>`.
91
+
92
+ Mutations mirror into the `values` store, so components subscribed via `get(id)` update without re-fetching.
93
+
94
+ ## Guards & extraction
95
+
96
+ Never use `?.` on a `Maybe<T>` — an `Error` has no domain properties. Narrow first.
97
+
98
+ ```ts
99
+ ok($store) // boolean type guard: narrows Maybe<T> → T (excludes null | Error)
100
+ ensure(store) // sync read, THROWS if null/Error — use when value must exist now (e.g. unsafe net requests in response to user action)
101
+ store.extract(key?) // sync read, T | null (ignores errors) — never throws
102
+ ```
103
+
104
+ ```ts
105
+ if (ok($todos)) $todos.length // typed as T
106
+ items.filter((i) => ok(i.account) && !i.account.deleted) // ✅ guard before access
107
+ ```
108
+
109
+ ## Awaiting
110
+
111
+ ```ts
112
+ await having(store) // first non-null value; REJECTS on Error — services needing auth
113
+ await awaited(store) // first non-null value; returns Error as a value (never rejects)
114
+ await once(store, (v) => v === 'ready') // first value satisfying a condition
115
+ ```
116
+
117
+ ## Compose & render
118
+
119
+ ### `<Async>` — render a `Maybe`
120
+
121
+ ```svelte
122
+ <Async store={todos}>
123
+ {#snippet awaited(todos)}
124
+ <!-- here todos are T[] -->
125
+ {#each todos as t}<Row {t} />{/each}
126
+ {/snippet}
127
+ {#snippet waiting()}<Spinner />{/snippet} <!-- optional; default loader otherwise -->
128
+ {#snippet error(e)}<Err {e} />{/snippet} <!-- optional; default error UI otherwise -->
129
+ </Async>
130
+ ```
131
+
132
+ Props: `store` (required), `awaited` snippet (required), optional `waiting` / `error` snippets, `silent` (suppress default loader/error chrome). Combine with `combined` to await several at once.
133
+
134
+ ### `combined(...stores)`
135
+
136
+ One `Maybe` from many: tuple when **all** resolve, first `Error`, else `null`. Spreadable.
137
+
138
+ ```svelte
139
+ <Async store={combined(account, todos)}>
140
+ {#snippet awaited([account, todos])}
141
+ <!-- here account is U and todos is T[] -->
142
+ <Profile {account} />
143
+ {#each todos as t}<Row {t} />{/each}
144
+ {/snippet}
145
+ </Async>
146
+ ```
147
+
148
+ ### `sync(store, item, { delete? })`
149
+
150
+ Conflict-free update.
151
+
152
+ T must implement interface Comparable { id: string; _version: number;_deleted?: number | null }
153
+
154
+ Merge a versioned item into a `collection` or `value`, respecting `_version`; removes on `_deleted` (unless `delete: false`). For applying server/realtime events.
155
+
156
+ ```ts
157
+ events.on('todos.sync', (todo) => sync(todos, todo))
158
+ ```
159
+
160
+ ## Rules
161
+
162
+ - **Errors are values** — fetchers and services return `T | Error`; check `instanceof Error`, never `try/catch` for expected failures.
163
+ - **Guard before access** — `ok()`/`ensure()`/`extract()`, never `?.` on `Maybe<T>`.
164
+ - **One store per source** — derive everything else; don't duplicate fetched data into local state.
165
+ - **Lazy by design** — a store does nothing until subscribed; `$store`, `<Async>`, `get`, `having`, or `.subscribe` triggers it.
166
+
167
+ ## Advanced
168
+
169
+ For derived `Maybe` stores with live subscriptions/cleanup, realtime event wiring, linked/enriched entities, and optimistic update patterns, see [references/patterns.md](references/patterns.md).