@ternent/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +17 -0
  3. package/.github/workflows/deploy-armour.yml +42 -0
  4. package/.github/workflows/deploy-identity.yml +42 -0
  5. package/.github/workflows/deploy-seal.yml +42 -0
  6. package/.github/workflows/deploy-ui.yml +42 -0
  7. package/.github/workflows/deploy-utils.yml +42 -0
  8. package/.github/workflows/release-create.yml +59 -0
  9. package/.github/workflows/release-publish.yml +54 -0
  10. package/.nvmrc +1 -0
  11. package/.ops/publish.mjs +31 -0
  12. package/package.json +16 -0
  13. package/packages/README.md +0 -0
  14. package/packages/armour/CHANGELOG.md +66 -0
  15. package/packages/armour/CLAUDE.md +8 -0
  16. package/packages/armour/README.md +103 -0
  17. package/packages/armour/SPEC.md +92 -0
  18. package/packages/armour/package.json +45 -0
  19. package/packages/armour/src/constants.ts +5 -0
  20. package/packages/armour/src/deps.d.ts +56 -0
  21. package/packages/armour/src/errors.ts +172 -0
  22. package/packages/armour/src/files.ts +73 -0
  23. package/packages/armour/src/identity.ts +72 -0
  24. package/packages/armour/src/index.ts +56 -0
  25. package/packages/armour/src/init.ts +10 -0
  26. package/packages/armour/src/passphrase.ts +33 -0
  27. package/packages/armour/src/recipients.ts +73 -0
  28. package/packages/armour/src/text.ts +68 -0
  29. package/packages/armour/src/types.ts +93 -0
  30. package/packages/armour/test/armour.test.ts +270 -0
  31. package/packages/armour/tsconfig.build.json +12 -0
  32. package/packages/armour/tsconfig.json +12 -0
  33. package/packages/armour/vite.config.ts +29 -0
  34. package/packages/concord/CHANGELOG.md +83 -0
  35. package/packages/concord/CLAUDE.md +9 -0
  36. package/packages/concord/README.md +146 -0
  37. package/packages/concord/SPEC.md +287 -0
  38. package/packages/concord/package.json +51 -0
  39. package/packages/concord/src/app.ts +717 -0
  40. package/packages/concord/src/errors.ts +9 -0
  41. package/packages/concord/src/index.ts +20 -0
  42. package/packages/concord/src/types.ts +127 -0
  43. package/packages/concord/test/concord.test.ts +978 -0
  44. package/packages/concord/tsconfig.json +12 -0
  45. package/packages/concord/vite.browser.config.ts +27 -0
  46. package/packages/concord/vite.config.ts +35 -0
  47. package/packages/concord/vite.config.ts.timestamp-1774262297922-ffd76e35ea668.mjs +83 -0
  48. package/packages/identity/CHANGELOG.md +47 -0
  49. package/packages/identity/README.md +236 -0
  50. package/packages/identity/package.json +41 -0
  51. package/packages/identity/src/index.ts +538 -0
  52. package/packages/identity/test/identity.test.ts +172 -0
  53. package/packages/identity/tsconfig.build.json +12 -0
  54. package/packages/identity/vite.config.ts +17 -0
  55. package/packages/ledger/CHANGELOG.md +69 -0
  56. package/packages/ledger/CLAUDE.md +9 -0
  57. package/packages/ledger/SPEC.md +304 -0
  58. package/packages/ledger/package.json +48 -0
  59. package/packages/ledger/src/index.ts +2 -0
  60. package/packages/ledger/src/ledger.ts +1286 -0
  61. package/packages/ledger/src/seal-cli.d.ts +25 -0
  62. package/packages/ledger/src/types.ts +294 -0
  63. package/packages/ledger/test/ledger.test.ts +838 -0
  64. package/packages/ledger/tsconfig.json +12 -0
  65. package/packages/ledger/vite.browser.config.ts +27 -0
  66. package/packages/ledger/vite.config.ts +39 -0
  67. package/packages/seal/CHANGELOG.md +137 -0
  68. package/packages/seal/CLAUDE.md +8 -0
  69. package/packages/seal/README.md +258 -0
  70. package/packages/seal/bin/seal +6 -0
  71. package/packages/seal/package.json +59 -0
  72. package/packages/seal/src/artifact.ts +380 -0
  73. package/packages/seal/src/cli.ts +372 -0
  74. package/packages/seal/src/commands/identity.ts +52 -0
  75. package/packages/seal/src/commands/manifest.ts +71 -0
  76. package/packages/seal/src/commands/publicKey.ts +7 -0
  77. package/packages/seal/src/commands/sign.ts +56 -0
  78. package/packages/seal/src/commands/verify.ts +54 -0
  79. package/packages/seal/src/crypto.ts +85 -0
  80. package/packages/seal/src/errors.ts +88 -0
  81. package/packages/seal/src/index.ts +5 -0
  82. package/packages/seal/src/manifest.ts +114 -0
  83. package/packages/seal/src/node.ts +18 -0
  84. package/packages/seal/src/proof.ts +344 -0
  85. package/packages/seal/test/artifact.test.ts +86 -0
  86. package/packages/seal/test/cli.test.ts +208 -0
  87. package/packages/seal/test/crypto.test.ts +21 -0
  88. package/packages/seal/test/manifest.test.ts +32 -0
  89. package/packages/seal/test/proof.test.ts +60 -0
  90. package/packages/seal/tsconfig.json +12 -0
  91. package/packages/seal/vite.config.ts +54 -0
  92. package/packages/ui/CHANGELOG.md +393 -0
  93. package/packages/ui/README.md +57 -0
  94. package/packages/ui/jsconfig.json +19 -0
  95. package/packages/ui/package.json +64 -0
  96. package/packages/ui/scripts/check-tokens.js +56 -0
  97. package/packages/ui/scripts/generate-theme-css.mjs +85 -0
  98. package/packages/ui/src/design-system/base.css +8 -0
  99. package/packages/ui/src/design-system/docs/ACCESSIBILITY_RULES.md +186 -0
  100. package/packages/ui/src/design-system/docs/AI_SYSTEM.md +281 -0
  101. package/packages/ui/src/design-system/docs/PATTERN_RULES.md +83 -0
  102. package/packages/ui/src/design-system/docs/PRIMITIVE_RULES.md +258 -0
  103. package/packages/ui/src/design-system/docs/TOKEN_RULES.md +235 -0
  104. package/packages/ui/src/design-system/docs/VISUAL_DIRECTION.md +68 -0
  105. package/packages/ui/src/design-system/foundation.js +420 -0
  106. package/packages/ui/src/design-system/tokens.css +140 -0
  107. package/packages/ui/src/design-system/tokens.js +327 -0
  108. package/packages/ui/src/design-system/utils.js +246 -0
  109. package/packages/ui/src/main.js +4 -0
  110. package/packages/ui/src/patterns/FeatureCard/FeatureCard.spec.md +24 -0
  111. package/packages/ui/src/patterns/FeatureCard/FeatureCard.types.ts +8 -0
  112. package/packages/ui/src/patterns/FeatureCard/FeatureCard.vue +175 -0
  113. package/packages/ui/src/patterns/FormField/FormField.spec.md +65 -0
  114. package/packages/ui/src/patterns/FormField/FormField.types.ts +11 -0
  115. package/packages/ui/src/patterns/FormField/FormField.vue +87 -0
  116. package/packages/ui/src/patterns/IdentityGlyph/IdentityGlyph.vue +61 -0
  117. package/packages/ui/src/patterns/IdentityGlyph/IdentityHandle.vue +58 -0
  118. package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.types.ts +36 -0
  119. package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.utils.ts +585 -0
  120. package/packages/ui/src/patterns/IdentityGlyph/index.ts +5 -0
  121. package/packages/ui/src/patterns/KeyValueList/KeyValueList.spec.md +28 -0
  122. package/packages/ui/src/patterns/KeyValueList/KeyValueList.types.ts +16 -0
  123. package/packages/ui/src/patterns/KeyValueList/KeyValueList.vue +50 -0
  124. package/packages/ui/src/patterns/LandingPage/LandingIcon.vue +90 -0
  125. package/packages/ui/src/patterns/LandingPage/LandingPage.spec.md +24 -0
  126. package/packages/ui/src/patterns/LandingPage/LandingPage.types.ts +212 -0
  127. package/packages/ui/src/patterns/LandingPage/LandingPage.vue +599 -0
  128. package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.test.ts +33 -0
  129. package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.vue +44 -0
  130. package/packages/ui/src/patterns/Logo/Logo.spec.md +22 -0
  131. package/packages/ui/src/patterns/Logo/Logo.vue +160 -0
  132. package/packages/ui/src/patterns/PageSurface/PageSurface.spec.md +15 -0
  133. package/packages/ui/src/patterns/PageSurface/PageSurface.vue +85 -0
  134. package/packages/ui/src/patterns/PanelChrome/PanelChrome.spec.md +39 -0
  135. package/packages/ui/src/patterns/PanelChrome/PanelChrome.types.ts +1 -0
  136. package/packages/ui/src/patterns/PanelChrome/PanelChrome.vue +187 -0
  137. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.spec.md +31 -0
  138. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.types.ts +23 -0
  139. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.vue +354 -0
  140. package/packages/ui/src/patterns/RecordList/RecordList.spec.md +35 -0
  141. package/packages/ui/src/patterns/RecordList/RecordList.test.ts +42 -0
  142. package/packages/ui/src/patterns/RecordList/RecordList.types.ts +9 -0
  143. package/packages/ui/src/patterns/RecordList/RecordList.utils.ts +5 -0
  144. package/packages/ui/src/patterns/RecordList/RecordList.vue +134 -0
  145. package/packages/ui/src/patterns/SectionClarifier/SectionClarifier.vue +85 -0
  146. package/packages/ui/src/patterns/SectionIntro/SectionIntro.spec.md +25 -0
  147. package/packages/ui/src/patterns/SectionIntro/SectionIntro.types.ts +7 -0
  148. package/packages/ui/src/patterns/SectionIntro/SectionIntro.vue +141 -0
  149. package/packages/ui/src/patterns/SidebarNav/SidebarNav.spec.md +34 -0
  150. package/packages/ui/src/patterns/SidebarNav/SidebarNav.types.ts +17 -0
  151. package/packages/ui/src/patterns/SidebarNav/SidebarNav.vue +110 -0
  152. package/packages/ui/src/patterns/SplitView/SplitView.spec.md +28 -0
  153. package/packages/ui/src/patterns/SplitView/SplitView.test.ts +22 -0
  154. package/packages/ui/src/patterns/SplitView/SplitView.types.ts +3 -0
  155. package/packages/ui/src/patterns/SplitView/SplitView.utils.ts +13 -0
  156. package/packages/ui/src/patterns/SplitView/SplitView.vue +39 -0
  157. package/packages/ui/src/patterns/StepList/StepList.spec.md +15 -0
  158. package/packages/ui/src/patterns/StepList/StepList.types.ts +4 -0
  159. package/packages/ui/src/patterns/StepList/StepList.vue +91 -0
  160. package/packages/ui/src/patterns/Verification/VerificationBadge.vue +97 -0
  161. package/packages/ui/src/patterns/Verification/VerificationComponents.test.ts +153 -0
  162. package/packages/ui/src/patterns/Verification/VerificationDetailsPanel.vue +270 -0
  163. package/packages/ui/src/patterns/Verification/VerificationSummary.vue +171 -0
  164. package/packages/ui/src/patterns/Verification/index.ts +6 -0
  165. package/packages/ui/src/patterns/Verification/verification.types.ts +8 -0
  166. package/packages/ui/src/patterns/Verification/verification.utils.test.ts +37 -0
  167. package/packages/ui/src/patterns/Verification/verification.utils.ts +75 -0
  168. package/packages/ui/src/patterns/index.ts +25 -0
  169. package/packages/ui/src/primitives/Accordian/Accordian.vue +11 -0
  170. package/packages/ui/src/primitives/Accordian/AccordianItem.vue +14 -0
  171. package/packages/ui/src/primitives/Accordion/Accordion.props.ts +21 -0
  172. package/packages/ui/src/primitives/Accordion/Accordion.spec.md +50 -0
  173. package/packages/ui/src/primitives/Accordion/Accordion.types.ts +4 -0
  174. package/packages/ui/src/primitives/Accordion/Accordion.variants.ts +12 -0
  175. package/packages/ui/src/primitives/Accordion/Accordion.vue +71 -0
  176. package/packages/ui/src/primitives/Accordion/AccordionItem.props.ts +14 -0
  177. package/packages/ui/src/primitives/Accordion/AccordionItem.vue +40 -0
  178. package/packages/ui/src/primitives/Badge/Badge.props.ts +17 -0
  179. package/packages/ui/src/primitives/Badge/Badge.spec.md +17 -0
  180. package/packages/ui/src/primitives/Badge/Badge.types.ts +15 -0
  181. package/packages/ui/src/primitives/Badge/Badge.variants.ts +48 -0
  182. package/packages/ui/src/primitives/Badge/Badge.vue +31 -0
  183. package/packages/ui/src/primitives/Button/Button.props.ts +29 -0
  184. package/packages/ui/src/primitives/Button/Button.spec.md +139 -0
  185. package/packages/ui/src/primitives/Button/Button.types.ts +19 -0
  186. package/packages/ui/src/primitives/Button/Button.variants.ts +72 -0
  187. package/packages/ui/src/primitives/Button/Button.vue +90 -0
  188. package/packages/ui/src/primitives/Card/Card.props.ts +17 -0
  189. package/packages/ui/src/primitives/Card/Card.spec.md +29 -0
  190. package/packages/ui/src/primitives/Card/Card.types.ts +12 -0
  191. package/packages/ui/src/primitives/Card/Card.variants.ts +27 -0
  192. package/packages/ui/src/primitives/Card/Card.vue +37 -0
  193. package/packages/ui/src/primitives/Checkbox/Checkbox.props.ts +21 -0
  194. package/packages/ui/src/primitives/Checkbox/Checkbox.spec.md +51 -0
  195. package/packages/ui/src/primitives/Checkbox/Checkbox.types.ts +4 -0
  196. package/packages/ui/src/primitives/Checkbox/Checkbox.variants.ts +34 -0
  197. package/packages/ui/src/primitives/Checkbox/Checkbox.vue +92 -0
  198. package/packages/ui/src/primitives/Dialog/Dialog.props.ts +29 -0
  199. package/packages/ui/src/primitives/Dialog/Dialog.spec.md +52 -0
  200. package/packages/ui/src/primitives/Dialog/Dialog.types.ts +3 -0
  201. package/packages/ui/src/primitives/Dialog/Dialog.variants.ts +27 -0
  202. package/packages/ui/src/primitives/Dialog/Dialog.vue +78 -0
  203. package/packages/ui/src/primitives/Drawer/Drawer.props.ts +33 -0
  204. package/packages/ui/src/primitives/Drawer/Drawer.spec.md +50 -0
  205. package/packages/ui/src/primitives/Drawer/Drawer.types.ts +5 -0
  206. package/packages/ui/src/primitives/Drawer/Drawer.variants.ts +35 -0
  207. package/packages/ui/src/primitives/Drawer/Drawer.vue +88 -0
  208. package/packages/ui/src/primitives/FieldMessage/FieldMessage.props.ts +17 -0
  209. package/packages/ui/src/primitives/FieldMessage/FieldMessage.spec.md +35 -0
  210. package/packages/ui/src/primitives/FieldMessage/FieldMessage.types.ts +5 -0
  211. package/packages/ui/src/primitives/FieldMessage/FieldMessage.variants.ts +14 -0
  212. package/packages/ui/src/primitives/FieldMessage/FieldMessage.vue +40 -0
  213. package/packages/ui/src/primitives/FileInput/FileInput.props.ts +41 -0
  214. package/packages/ui/src/primitives/FileInput/FileInput.types.ts +6 -0
  215. package/packages/ui/src/primitives/FileInput/FileInput.variants.ts +46 -0
  216. package/packages/ui/src/primitives/FileInput/FileInput.vue +163 -0
  217. package/packages/ui/src/primitives/Input/Input.props.ts +29 -0
  218. package/packages/ui/src/primitives/Input/Input.spec.md +79 -0
  219. package/packages/ui/src/primitives/Input/Input.types.ts +13 -0
  220. package/packages/ui/src/primitives/Input/Input.variants.ts +54 -0
  221. package/packages/ui/src/primitives/Input/Input.vue +99 -0
  222. package/packages/ui/src/primitives/Label/Label.props.ts +25 -0
  223. package/packages/ui/src/primitives/Label/Label.spec.md +31 -0
  224. package/packages/ui/src/primitives/Label/Label.types.ts +3 -0
  225. package/packages/ui/src/primitives/Label/Label.variants.ts +17 -0
  226. package/packages/ui/src/primitives/Label/Label.vue +38 -0
  227. package/packages/ui/src/primitives/Menu/Menu.props.ts +17 -0
  228. package/packages/ui/src/primitives/Menu/Menu.spec.md +38 -0
  229. package/packages/ui/src/primitives/Menu/Menu.types.ts +10 -0
  230. package/packages/ui/src/primitives/Menu/Menu.variants.ts +10 -0
  231. package/packages/ui/src/primitives/Menu/Menu.vue +57 -0
  232. package/packages/ui/src/primitives/Popover/Popover.props.ts +25 -0
  233. package/packages/ui/src/primitives/Popover/Popover.spec.md +49 -0
  234. package/packages/ui/src/primitives/Popover/Popover.types.ts +3 -0
  235. package/packages/ui/src/primitives/Popover/Popover.variants.ts +18 -0
  236. package/packages/ui/src/primitives/Popover/Popover.vue +74 -0
  237. package/packages/ui/src/primitives/RadioGroup/RadioGroup.props.ts +29 -0
  238. package/packages/ui/src/primitives/RadioGroup/RadioGroup.spec.md +50 -0
  239. package/packages/ui/src/primitives/RadioGroup/RadioGroup.types.ts +12 -0
  240. package/packages/ui/src/primitives/RadioGroup/RadioGroup.variants.ts +48 -0
  241. package/packages/ui/src/primitives/RadioGroup/RadioGroup.vue +87 -0
  242. package/packages/ui/src/primitives/Separator/Separator.props.ts +9 -0
  243. package/packages/ui/src/primitives/Separator/Separator.spec.md +15 -0
  244. package/packages/ui/src/primitives/Separator/Separator.types.ts +3 -0
  245. package/packages/ui/src/primitives/Separator/Separator.variants.ts +8 -0
  246. package/packages/ui/src/primitives/Separator/Separator.vue +23 -0
  247. package/packages/ui/src/primitives/Skeleton/Skeleton.props.ts +21 -0
  248. package/packages/ui/src/primitives/Skeleton/Skeleton.spec.md +18 -0
  249. package/packages/ui/src/primitives/Skeleton/Skeleton.types.ts +5 -0
  250. package/packages/ui/src/primitives/Skeleton/Skeleton.variants.ts +18 -0
  251. package/packages/ui/src/primitives/Skeleton/Skeleton.vue +37 -0
  252. package/packages/ui/src/primitives/Spinner/Spinner.props.ts +13 -0
  253. package/packages/ui/src/primitives/Spinner/Spinner.spec.md +16 -0
  254. package/packages/ui/src/primitives/Spinner/Spinner.types.ts +5 -0
  255. package/packages/ui/src/primitives/Spinner/Spinner.variants.ts +15 -0
  256. package/packages/ui/src/primitives/Spinner/Spinner.vue +33 -0
  257. package/packages/ui/src/primitives/SplitButton/SplitButton.vue +108 -0
  258. package/packages/ui/src/primitives/Switch/Switch.props.ts +21 -0
  259. package/packages/ui/src/primitives/Switch/Switch.spec.md +49 -0
  260. package/packages/ui/src/primitives/Switch/Switch.types.ts +3 -0
  261. package/packages/ui/src/primitives/Switch/Switch.variants.ts +34 -0
  262. package/packages/ui/src/primitives/Switch/Switch.vue +71 -0
  263. package/packages/ui/src/primitives/Tabs/Tabs.props.ts +25 -0
  264. package/packages/ui/src/primitives/Tabs/Tabs.spec.md +48 -0
  265. package/packages/ui/src/primitives/Tabs/Tabs.types.ts +11 -0
  266. package/packages/ui/src/primitives/Tabs/Tabs.variants.ts +28 -0
  267. package/packages/ui/src/primitives/Tabs/Tabs.vue +59 -0
  268. package/packages/ui/src/primitives/Textarea/Textarea.props.ts +33 -0
  269. package/packages/ui/src/primitives/Textarea/Textarea.spec.md +59 -0
  270. package/packages/ui/src/primitives/Textarea/Textarea.types.ts +5 -0
  271. package/packages/ui/src/primitives/Textarea/Textarea.variants.ts +27 -0
  272. package/packages/ui/src/primitives/Textarea/Textarea.vue +74 -0
  273. package/packages/ui/src/primitives/Tooltip/Tooltip.props.ts +21 -0
  274. package/packages/ui/src/primitives/Tooltip/Tooltip.spec.md +45 -0
  275. package/packages/ui/src/primitives/Tooltip/Tooltip.types.ts +3 -0
  276. package/packages/ui/src/primitives/Tooltip/Tooltip.variants.ts +4 -0
  277. package/packages/ui/src/primitives/Tooltip/Tooltip.vue +31 -0
  278. package/packages/ui/src/primitives/TreeView/TreeView.types.ts +10 -0
  279. package/packages/ui/src/primitives/TreeView/TreeView.vue +113 -0
  280. package/packages/ui/src/primitives/TreeView/TreeViewNode.vue +190 -0
  281. package/packages/ui/src/primitives/index.ts +29 -0
  282. package/packages/ui/src/style.css +7 -0
  283. package/packages/ui/src/style.js +1 -0
  284. package/packages/ui/src/themes/armour.css +147 -0
  285. package/packages/ui/src/themes/aurora.css +147 -0
  286. package/packages/ui/src/themes/citrine-ash.css +147 -0
  287. package/packages/ui/src/themes/concord.css +147 -0
  288. package/packages/ui/src/themes/garnet-honey.css +147 -0
  289. package/packages/ui/src/themes/harbor-rose.css +147 -0
  290. package/packages/ui/src/themes/ledger.css +147 -0
  291. package/packages/ui/src/themes/neon-noir.css +74 -0
  292. package/packages/ui/src/themes/obsidian-iris.css +147 -0
  293. package/packages/ui/src/themes/pixpax.css +147 -0
  294. package/packages/ui/src/themes/print.css +147 -0
  295. package/packages/ui/src/themes/prism.css +147 -0
  296. package/packages/ui/src/themes/proof.css +145 -0
  297. package/packages/ui/src/themes/semanticThemeContract.js +2256 -0
  298. package/packages/ui/src/themes/spruce-ink.css +147 -0
  299. package/packages/ui/src/themes/sunset.css +147 -0
  300. package/packages/ui/tailwind.config.js +64 -0
  301. package/packages/ui/vite.config.js +35 -0
  302. package/packages/ui/vite.config.js.timestamp-1780697224943-89fbc929987bc.mjs +38 -0
  303. package/packages/utils/CHANGELOG.md +111 -0
  304. package/packages/utils/README.md +3 -0
  305. package/packages/utils/package.json +46 -0
  306. package/packages/utils/src/index.test.js +39 -0
  307. package/packages/utils/src/index.ts +289 -0
  308. package/packages/utils/tsconfig.build.json +12 -0
  309. package/packages/utils/vite.config.js +28 -0
  310. package/pnpm-workspace.yaml +8 -0
  311. package/scripts/vite/package-lib-config.ts +59 -0
  312. package/tsconfig.json +24 -0
  313. package/tsconfig.node.json +9 -0
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ import { Popover as ArkPopover } from "@ark-ui/vue/popover";
3
+ import { computed, useSlots } from "vue";
4
+ import { popoverProps } from "./Popover.props";
5
+ import {
6
+ popoverArrowClass,
7
+ popoverBodyClass,
8
+ popoverCloseClass,
9
+ popoverContentClass,
10
+ popoverDescriptionClass,
11
+ popoverFooterClass,
12
+ popoverHeaderClass,
13
+ popoverPositionerClass,
14
+ popoverTitleClass,
15
+ } from "./Popover.variants";
16
+
17
+ const open = defineModel<boolean>("open", { default: false });
18
+ const props = defineProps(popoverProps);
19
+ const slots = useSlots();
20
+
21
+ const hasHeader = computed(() =>
22
+ Boolean(props.title || props.description || slots.header || props.showClose),
23
+ );
24
+ </script>
25
+
26
+ <template>
27
+ <ArkPopover.Root v-model:open="open" :positioning="{ placement: props.placement }">
28
+ <ArkPopover.Trigger v-if="$slots.trigger" as-child>
29
+ <slot name="trigger" />
30
+ </ArkPopover.Trigger>
31
+ <ArkPopover.Positioner :class="popoverPositionerClass">
32
+ <ArkPopover.Content :class="popoverContentClass">
33
+ <ArkPopover.Arrow v-if="props.showArrow" :class="popoverArrowClass">
34
+ <ArkPopover.ArrowTip />
35
+ </ArkPopover.Arrow>
36
+
37
+ <div v-if="hasHeader" :class="popoverHeaderClass">
38
+ <slot name="header">
39
+ <div class="min-w-0 flex-1">
40
+ <ArkPopover.Title v-if="props.title" :class="popoverTitleClass">
41
+ {{ props.title }}
42
+ </ArkPopover.Title>
43
+ <ArkPopover.Description v-if="props.description" :class="popoverDescriptionClass">
44
+ {{ props.description }}
45
+ </ArkPopover.Description>
46
+ </div>
47
+ </slot>
48
+ <ArkPopover.CloseTrigger
49
+ v-if="props.showClose"
50
+ :class="popoverCloseClass"
51
+ aria-label="Close popover"
52
+ >
53
+ <svg viewBox="0 0 24 24" fill="none" class="size-4" aria-hidden="true">
54
+ <path
55
+ d="M6 6l12 12M18 6 6 18"
56
+ stroke="currentColor"
57
+ stroke-width="1.75"
58
+ stroke-linecap="round"
59
+ />
60
+ </svg>
61
+ </ArkPopover.CloseTrigger>
62
+ </div>
63
+
64
+ <div :class="popoverBodyClass">
65
+ <slot />
66
+ </div>
67
+
68
+ <div v-if="$slots.footer" :class="popoverFooterClass">
69
+ <slot name="footer" />
70
+ </div>
71
+ </ArkPopover.Content>
72
+ </ArkPopover.Positioner>
73
+ </ArkPopover.Root>
74
+ </template>
@@ -0,0 +1,29 @@
1
+ import type { PropType } from "vue";
2
+ import type { RadioGroupOption, RadioGroupOrientation, RadioGroupSize } from "./RadioGroup.types";
3
+
4
+ export const radioGroupProps = {
5
+ modelValue: {
6
+ type: String,
7
+ default: "",
8
+ },
9
+ options: {
10
+ type: Array as PropType<RadioGroupOption[]>,
11
+ default: () => [],
12
+ },
13
+ orientation: {
14
+ type: String as PropType<RadioGroupOrientation>,
15
+ default: "vertical",
16
+ },
17
+ size: {
18
+ type: String as PropType<RadioGroupSize>,
19
+ default: "md",
20
+ },
21
+ disabled: {
22
+ type: Boolean,
23
+ default: false,
24
+ },
25
+ invalid: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+ };
@@ -0,0 +1,50 @@
1
+ # RadioGroup
2
+
3
+ ## Purpose
4
+
5
+ Single-selection choice primitive built on Ark UI.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `modelValue`: string
16
+ - `options`: `{ value, label, description?, disabled? }[]`
17
+ - `orientation`: `horizontal | vertical`
18
+ - `size`: `sm | md`
19
+ - `disabled`: boolean
20
+ - `invalid`: boolean
21
+
22
+ Events:
23
+
24
+ - `update:modelValue`
25
+
26
+ ## States
27
+
28
+ - unchecked
29
+ - checked
30
+ - focus-visible
31
+ - disabled
32
+ - invalid
33
+
34
+ ## Accessibility
35
+
36
+ - built on Ark `RadioGroup.Root`
37
+ - each option includes a hidden input and item control
38
+ - external group labelling can be passed through standard attrs such as `aria-label`
39
+
40
+ ## Example
41
+
42
+ ```vue
43
+ <RadioGroup
44
+ v-model="plan"
45
+ :options="[
46
+ { value: 'starter', label: 'Starter' },
47
+ { value: 'pro', label: 'Pro', description: 'Best for teams' },
48
+ ]"
49
+ />
50
+ ```
@@ -0,0 +1,12 @@
1
+ export const radioGroupSizeValues = ["sm", "md"] as const;
2
+ export const radioGroupOrientationValues = ["horizontal", "vertical"] as const;
3
+
4
+ export type RadioGroupSize = (typeof radioGroupSizeValues)[number];
5
+ export type RadioGroupOrientation = (typeof radioGroupOrientationValues)[number];
6
+
7
+ export type RadioGroupOption = {
8
+ description?: string;
9
+ disabled?: boolean;
10
+ label: string;
11
+ value: string;
12
+ };
@@ -0,0 +1,48 @@
1
+ import type { RadioGroupOrientation, RadioGroupSize } from "./RadioGroup.types";
2
+
3
+ export const radioGroupRootClass = "flex w-full";
4
+
5
+ export const radioGroupListOrientationClasses: Record<RadioGroupOrientation, string> = {
6
+ horizontal: "flex flex-wrap gap-3",
7
+ vertical: "flex flex-col gap-3",
8
+ };
9
+
10
+ export const radioGroupItemBaseClass =
11
+ "group flex items-start gap-3 rounded-[var(--ui-radius-md)] border border-[var(--ui-border)] " +
12
+ "bg-[var(--ui-surface)] px-3 transition-[border-color,background-color,box-shadow] " +
13
+ "duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)] " +
14
+ "hover:border-[var(--ui-primary-muted)] focus-within:ring-2 focus-within:ring-[var(--ui-ring)] " +
15
+ "data-[state=checked]:border-[var(--ui-primary)] data-[state=checked]:bg-[var(--ui-primary-muted)]";
16
+
17
+ export const radioGroupItemStateClasses = {
18
+ default: "",
19
+ invalid:
20
+ "border-[var(--ui-critical)] data-[state=checked]:border-[var(--ui-critical)] data-[state=checked]:bg-[var(--ui-critical-muted)]",
21
+ disabled: "opacity-50",
22
+ } as const;
23
+
24
+ export const radioGroupItemSizeClasses: Record<RadioGroupSize, string> = {
25
+ sm: "py-2",
26
+ md: "py-3",
27
+ };
28
+
29
+ export const radioGroupControlBaseClass =
30
+ "mt-0.5 inline-flex shrink-0 items-center justify-center rounded-full border border-[var(--ui-border)] " +
31
+ "bg-[var(--ui-bg)] transition-[border-color,box-shadow] duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)] " +
32
+ "group-data-[state=checked]:border-[var(--ui-primary)]";
33
+
34
+ export const radioGroupControlSizeClasses: Record<RadioGroupSize, string> = {
35
+ sm: "size-4",
36
+ md: "size-5",
37
+ };
38
+
39
+ export const radioGroupIndicatorBaseClass =
40
+ "rounded-full bg-[var(--ui-primary)] group-data-[state=checked]:bg-[var(--ui-primary)]";
41
+
42
+ export const radioGroupIndicatorSizeClasses: Record<RadioGroupSize, string> = {
43
+ sm: "size-2",
44
+ md: "size-2.5",
45
+ };
46
+
47
+ export const radioGroupLabelClass = "text-[var(--ui-fg)]";
48
+ export const radioGroupDescriptionClass = "text-sm text-[var(--ui-fg-muted)]";
@@ -0,0 +1,87 @@
1
+ <script setup lang="ts">
2
+ import { RadioGroup } from "@ark-ui/vue/radio-group";
3
+ import { computed, normalizeClass, useAttrs } from "vue";
4
+ import { twMerge } from "tailwind-merge";
5
+ import { radioGroupProps } from "./RadioGroup.props";
6
+ import {
7
+ radioGroupControlBaseClass,
8
+ radioGroupControlSizeClasses,
9
+ radioGroupDescriptionClass,
10
+ radioGroupIndicatorBaseClass,
11
+ radioGroupIndicatorSizeClasses,
12
+ radioGroupItemBaseClass,
13
+ radioGroupItemSizeClasses,
14
+ radioGroupItemStateClasses,
15
+ radioGroupLabelClass,
16
+ radioGroupListOrientationClasses,
17
+ radioGroupRootClass,
18
+ } from "./RadioGroup.variants";
19
+
20
+ defineOptions({ inheritAttrs: false });
21
+
22
+ const emit = defineEmits<{
23
+ "update:modelValue": [value: string];
24
+ }>();
25
+
26
+ const attrs = useAttrs();
27
+ const props = defineProps(radioGroupProps);
28
+
29
+ const model = computed({
30
+ get: () => props.modelValue,
31
+ set: (value: string) => emit("update:modelValue", value),
32
+ });
33
+
34
+ const rootClass = computed(() => twMerge(radioGroupRootClass, normalizeClass(attrs.class)));
35
+
36
+ const rootAttrs = computed(() => {
37
+ const { class: _class, ...rest } = attrs;
38
+ return rest;
39
+ });
40
+
41
+ function itemClass(disabled?: boolean) {
42
+ return twMerge(
43
+ radioGroupItemBaseClass,
44
+ radioGroupItemSizeClasses[props.size],
45
+ props.invalid ? radioGroupItemStateClasses.invalid : radioGroupItemStateClasses.default,
46
+ props.disabled || disabled ? radioGroupItemStateClasses.disabled : "",
47
+ );
48
+ }
49
+ </script>
50
+
51
+ <template>
52
+ <RadioGroup.Root
53
+ v-model="model"
54
+ :orientation="props.orientation"
55
+ :disabled="props.disabled"
56
+ :invalid="props.invalid"
57
+ :class="rootClass"
58
+ v-bind="rootAttrs"
59
+ >
60
+ <div :class="radioGroupListOrientationClasses[props.orientation]">
61
+ <RadioGroup.Item
62
+ v-for="option in props.options"
63
+ :key="option.value"
64
+ :value="option.value"
65
+ :disabled="option.disabled"
66
+ :class="itemClass(option.disabled)"
67
+ >
68
+ <RadioGroup.ItemHiddenInput />
69
+ <RadioGroup.ItemControl
70
+ :class="[radioGroupControlBaseClass, radioGroupControlSizeClasses[props.size]]"
71
+ >
72
+ <RadioGroup.Indicator
73
+ :class="[radioGroupIndicatorBaseClass, radioGroupIndicatorSizeClasses[props.size]]"
74
+ />
75
+ </RadioGroup.ItemControl>
76
+ <div class="flex flex-col gap-1">
77
+ <RadioGroup.ItemText :class="radioGroupLabelClass">
78
+ {{ option.label }}
79
+ </RadioGroup.ItemText>
80
+ <div v-if="option.description" :class="radioGroupDescriptionClass">
81
+ {{ option.description }}
82
+ </div>
83
+ </div>
84
+ </RadioGroup.Item>
85
+ </div>
86
+ </RadioGroup.Root>
87
+ </template>
@@ -0,0 +1,9 @@
1
+ import type { PropType } from "vue";
2
+ import type { SeparatorOrientation } from "./Separator.types";
3
+
4
+ export const separatorProps = {
5
+ orientation: {
6
+ type: String as PropType<SeparatorOrientation>,
7
+ default: "horizontal",
8
+ },
9
+ };
@@ -0,0 +1,15 @@
1
+ # Separator
2
+
3
+ ## Purpose
4
+
5
+ Low-emphasis structural divider primitive.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `orientation`
@@ -0,0 +1,3 @@
1
+ export const separatorOrientationValues = ["horizontal", "vertical"] as const;
2
+
3
+ export type SeparatorOrientation = (typeof separatorOrientationValues)[number];
@@ -0,0 +1,8 @@
1
+ import type { SeparatorOrientation } from "./Separator.types";
2
+
3
+ export const separatorBaseClass = "shrink-0 bg-[var(--ui-border)]";
4
+
5
+ export const separatorOrientationClasses: Record<SeparatorOrientation, string> = {
6
+ horizontal: "h-px w-full",
7
+ vertical: "h-full min-h-4 w-px",
8
+ };
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ import { computed, normalizeClass, useAttrs } from "vue";
3
+ import { twMerge } from "tailwind-merge";
4
+ import { separatorProps } from "./Separator.props";
5
+ import { separatorBaseClass, separatorOrientationClasses } from "./Separator.variants";
6
+
7
+ defineOptions({ inheritAttrs: false });
8
+
9
+ const attrs = useAttrs();
10
+ const props = defineProps(separatorProps);
11
+
12
+ const classes = computed(() =>
13
+ twMerge(
14
+ separatorBaseClass,
15
+ separatorOrientationClasses[props.orientation],
16
+ normalizeClass(attrs.class),
17
+ ),
18
+ );
19
+ </script>
20
+
21
+ <template>
22
+ <div :class="classes" :aria-orientation="props.orientation" role="separator" />
23
+ </template>
@@ -0,0 +1,21 @@
1
+ import type { PropType } from "vue";
2
+ import type { SkeletonShape, SkeletonSize } from "./Skeleton.types";
3
+
4
+ export const skeletonProps = {
5
+ shape: {
6
+ type: String as PropType<SkeletonShape>,
7
+ default: "line",
8
+ },
9
+ size: {
10
+ type: String as PropType<SkeletonSize>,
11
+ default: "md",
12
+ },
13
+ lines: {
14
+ type: Number,
15
+ default: 1,
16
+ },
17
+ animated: {
18
+ type: Boolean,
19
+ default: true,
20
+ },
21
+ };
@@ -0,0 +1,18 @@
1
+ # Skeleton
2
+
3
+ ## Purpose
4
+
5
+ Loading placeholder primitive.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `shape`
16
+ - `size`
17
+ - `lines`
18
+ - `animated`
@@ -0,0 +1,5 @@
1
+ export const skeletonShapeValues = ["line", "block", "circle"] as const;
2
+ export const skeletonSizeValues = ["sm", "md", "lg"] as const;
3
+
4
+ export type SkeletonShape = (typeof skeletonShapeValues)[number];
5
+ export type SkeletonSize = (typeof skeletonSizeValues)[number];
@@ -0,0 +1,18 @@
1
+ import type { SkeletonShape, SkeletonSize } from "./Skeleton.types";
2
+
3
+ export const skeletonBaseClass =
4
+ "bg-[linear-gradient(90deg,var(--ui-tonal-secondary),var(--ui-surface-hover),var(--ui-tonal-secondary))] bg-[length:200%_100%]";
5
+
6
+ export const skeletonShapeClasses: Record<SkeletonShape, string> = {
7
+ line: "w-full rounded-[var(--ui-radius-sm)]",
8
+ block: "w-full rounded-[var(--ui-radius-md)]",
9
+ circle: "aspect-square rounded-full",
10
+ };
11
+
12
+ export const skeletonSizeClasses: Record<SkeletonSize, string> = {
13
+ sm: "h-4",
14
+ md: "h-5",
15
+ lg: "h-6",
16
+ };
17
+
18
+ export const skeletonAnimatedClass = "animate-[skeleton-shimmer_1.6s_linear_infinite]";
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { skeletonProps } from "./Skeleton.props";
3
+ import {
4
+ skeletonAnimatedClass,
5
+ skeletonBaseClass,
6
+ skeletonShapeClasses,
7
+ skeletonSizeClasses,
8
+ } from "./Skeleton.variants";
9
+
10
+ const props = defineProps(skeletonProps);
11
+ </script>
12
+
13
+ <template>
14
+ <div class="space-y-2">
15
+ <div
16
+ v-for="line in Math.max(props.lines, 1)"
17
+ :key="line"
18
+ :class="[
19
+ skeletonBaseClass,
20
+ skeletonShapeClasses[props.shape],
21
+ skeletonSizeClasses[props.size],
22
+ props.animated ? skeletonAnimatedClass : '',
23
+ ]"
24
+ />
25
+ </div>
26
+ </template>
27
+
28
+ <style scoped>
29
+ @keyframes skeleton-shimmer {
30
+ 0% {
31
+ background-position: 200% 0;
32
+ }
33
+ 100% {
34
+ background-position: -200% 0;
35
+ }
36
+ }
37
+ </style>
@@ -0,0 +1,13 @@
1
+ import type { PropType } from "vue";
2
+ import type { SpinnerSize, SpinnerTone } from "./Spinner.types";
3
+
4
+ export const spinnerProps = {
5
+ size: {
6
+ type: String as PropType<SpinnerSize>,
7
+ default: "md",
8
+ },
9
+ tone: {
10
+ type: String as PropType<SpinnerTone>,
11
+ default: "primary",
12
+ },
13
+ };
@@ -0,0 +1,16 @@
1
+ # Spinner
2
+
3
+ ## Purpose
4
+
5
+ Loading indicator primitive.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `size`
16
+ - `tone`
@@ -0,0 +1,5 @@
1
+ export const spinnerSizeValues = ["sm", "md", "lg"] as const;
2
+ export const spinnerToneValues = ["primary", "muted", "critical"] as const;
3
+
4
+ export type SpinnerSize = (typeof spinnerSizeValues)[number];
5
+ export type SpinnerTone = (typeof spinnerToneValues)[number];
@@ -0,0 +1,15 @@
1
+ import type { SpinnerSize, SpinnerTone } from "./Spinner.types";
2
+
3
+ export const spinnerBaseClass = "animate-spin";
4
+
5
+ export const spinnerSizeClasses: Record<SpinnerSize, string> = {
6
+ sm: "size-4",
7
+ md: "size-6",
8
+ lg: "size-8",
9
+ };
10
+
11
+ export const spinnerToneClasses: Record<SpinnerTone, string> = {
12
+ primary: "text-[var(--ui-primary)]",
13
+ muted: "text-[var(--ui-fg-muted)]",
14
+ critical: "text-[var(--ui-critical)]",
15
+ };
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import { computed, normalizeClass, useAttrs } from "vue";
3
+ import { twMerge } from "tailwind-merge";
4
+ import { spinnerProps } from "./Spinner.props";
5
+ import { spinnerBaseClass, spinnerSizeClasses, spinnerToneClasses } from "./Spinner.variants";
6
+
7
+ defineOptions({ inheritAttrs: false });
8
+
9
+ const attrs = useAttrs();
10
+ const props = defineProps(spinnerProps);
11
+
12
+ const classes = computed(() =>
13
+ twMerge(
14
+ spinnerBaseClass,
15
+ spinnerSizeClasses[props.size],
16
+ spinnerToneClasses[props.tone],
17
+ normalizeClass(attrs.class),
18
+ ),
19
+ );
20
+ </script>
21
+
22
+ <template>
23
+ <svg viewBox="0 0 24 24" fill="none" :class="classes" aria-hidden="true">
24
+ <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="3" class="opacity-25" />
25
+ <path
26
+ d="M21 12a9 9 0 0 0-9-9"
27
+ stroke="currentColor"
28
+ stroke-width="3"
29
+ stroke-linecap="round"
30
+ class="opacity-90"
31
+ />
32
+ </svg>
33
+ </template>
@@ -0,0 +1,108 @@
1
+ <script setup lang="ts">
2
+ import { computed, shallowRef } from "vue";
3
+ import { onClickOutside } from "@vueuse/core";
4
+
5
+ const props = defineProps({
6
+ disabled: {
7
+ type: Boolean,
8
+ default: false,
9
+ },
10
+ menuWidth: {
11
+ type: String,
12
+ default: "w-48",
13
+ },
14
+ menuAlign: {
15
+ type: String,
16
+ default: "right", // right, left
17
+ },
18
+ menuOffset: {
19
+ type: String,
20
+ default: "mt-2",
21
+ },
22
+ menuClass: {
23
+ type: String,
24
+ default: "",
25
+ },
26
+ containerClass: {
27
+ type: String,
28
+ default: "",
29
+ },
30
+ toggleClass: {
31
+ type: String,
32
+ default: "",
33
+ },
34
+ });
35
+
36
+ const wrapperRef = shallowRef<HTMLElement | null>(null);
37
+ const isOpen = shallowRef(false);
38
+
39
+ const alignClass = computed(() => (props.menuAlign === "left" ? "left-0" : "right-0"));
40
+
41
+ function toggleMenu() {
42
+ if (props.disabled) return;
43
+ isOpen.value = !isOpen.value;
44
+ }
45
+
46
+ function closeMenu() {
47
+ isOpen.value = false;
48
+ }
49
+
50
+ onClickOutside(wrapperRef, () => {
51
+ isOpen.value = false;
52
+ });
53
+ </script>
54
+
55
+ <template>
56
+ <div ref="wrapperRef" class="relative w-full" :class="containerClass">
57
+ <div
58
+ class="flex w-full items-center overflow-hidden rounded-full border border-[var(--ui-border)] bg-[var(--ui-bg)]/30"
59
+ >
60
+ <slot name="primary" :closeMenu="closeMenu" :isOpen="isOpen" />
61
+ <button
62
+ type="button"
63
+ class="border-l border-[var(--ui-border)] px-3 py-2 transition-colors hover:bg-[var(--ui-fg)]/5"
64
+ :class="toggleClass"
65
+ :disabled="disabled"
66
+ :aria-expanded="isOpen"
67
+ aria-haspopup="menu"
68
+ @click="toggleMenu"
69
+ >
70
+ <slot name="toggle" :isOpen="isOpen">
71
+ <svg
72
+ class="h-4 w-4 transition-transform"
73
+ :class="{ 'rotate-180': isOpen }"
74
+ viewBox="0 0 20 20"
75
+ fill="currentColor"
76
+ >
77
+ <path
78
+ fill-rule="evenodd"
79
+ d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 10.94l3.71-3.71a.75.75 0 1 1 1.06 1.06l-4.24 4.24a.75.75 0 0 1-1.06 0L5.25 8.29a.75.75 0 0 1-.02-1.08Z"
80
+ clip-rule="evenodd"
81
+ />
82
+ </svg>
83
+ </slot>
84
+ </button>
85
+ </div>
86
+ <Transition
87
+ enter-active-class="transition duration-200 ease-out"
88
+ enter-from-class="opacity-0 scale-95 -translate-y-1"
89
+ enter-to-class="opacity-100 scale-100 translate-y-0"
90
+ leave-active-class="transition duration-150 ease-in"
91
+ leave-from-class="opacity-100 scale-100 translate-y-0"
92
+ leave-to-class="opacity-0 scale-95 -translate-y-1"
93
+ >
94
+ <div
95
+ v-if="isOpen"
96
+ :class="[
97
+ 'absolute z-50 rounded-xl border border-[var(--ui-border)] bg-[var(--ui-bg)] p-1 shadow-lg',
98
+ alignClass,
99
+ menuOffset,
100
+ menuWidth,
101
+ menuClass,
102
+ ]"
103
+ >
104
+ <slot name="menu" :closeMenu="closeMenu" :isOpen="isOpen" />
105
+ </div>
106
+ </Transition>
107
+ </div>
108
+ </template>