@birdycom/omniaui-vue 0.0.0-stage → 0.11.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 (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -3
  3. package/dist/blocks/OcBlockAboutTimeline.vue.d.ts +29 -0
  4. package/dist/blocks/OcBlockAppHeader.vue.d.ts +33 -0
  5. package/dist/blocks/OcBlockAppShell.vue.d.ts +33 -0
  6. package/dist/blocks/OcBlockAuth.vue.d.ts +28 -0
  7. package/dist/blocks/OcBlockAuthSplit.vue.d.ts +45 -0
  8. package/dist/blocks/OcBlockContactGrid.vue.d.ts +32 -0
  9. package/dist/blocks/OcBlockCta.vue.d.ts +17 -0
  10. package/dist/blocks/OcBlockDataTable.vue.d.ts +33 -0
  11. package/dist/blocks/OcBlockFaq.vue.d.ts +32 -0
  12. package/dist/blocks/OcBlockFeatures.vue.d.ts +25 -0
  13. package/dist/blocks/OcBlockFooter.vue.d.ts +27 -0
  14. package/dist/blocks/OcBlockFormPage.vue.d.ts +36 -0
  15. package/dist/blocks/OcBlockHero.vue.d.ts +18 -0
  16. package/dist/blocks/OcBlockHeroCode.vue.d.ts +32 -0
  17. package/dist/blocks/OcBlockHeroOrbit.vue.d.ts +36 -0
  18. package/dist/blocks/OcBlockHeroSplit.vue.d.ts +19 -0
  19. package/dist/blocks/OcBlockModuleHeader.vue.d.ts +24 -0
  20. package/dist/blocks/OcBlockPageHero.vue.d.ts +18 -0
  21. package/dist/blocks/OcBlockPortfolioGrid.vue.d.ts +34 -0
  22. package/dist/blocks/OcBlockPricing.vue.d.ts +38 -0
  23. package/dist/blocks/OcBlockProcess.vue.d.ts +18 -0
  24. package/dist/blocks/OcBlockProductGrid.vue.d.ts +25 -0
  25. package/dist/blocks/OcBlockProfileHeader.vue.d.ts +36 -0
  26. package/dist/blocks/OcBlockShowcase.vue.d.ts +23 -0
  27. package/dist/blocks/OcBlockSiteFooter.vue.d.ts +42 -0
  28. package/dist/blocks/OcBlockSiteHeader.vue.d.ts +32 -0
  29. package/dist/blocks/OcBlockSpotlight.vue.d.ts +32 -0
  30. package/dist/blocks/OcBlockStats.vue.d.ts +10 -0
  31. package/dist/blocks/OcBlockStatsCounter.vue.d.ts +10 -0
  32. package/dist/blocks/OcBlockTeamList.vue.d.ts +42 -0
  33. package/dist/blocks/OcBlockTwoFactor.vue.d.ts +38 -0
  34. package/dist/blocks/OcBlockWizardDialog.vue.d.ts +52 -0
  35. package/dist/components/OcAccordion.vue.d.ts +15 -0
  36. package/dist/components/OcAccordionAccent.vue.d.ts +20 -0
  37. package/dist/components/OcAccordionItem.vue.d.ts +24 -0
  38. package/dist/components/OcAffixInput.vue.d.ts +31 -0
  39. package/dist/components/OcAlert.vue.d.ts +21 -0
  40. package/dist/components/OcAlertDialog.vue.d.ts +48 -0
  41. package/dist/components/OcAlphaTabs.vue.d.ts +23 -0
  42. package/dist/components/OcAspectRatio.vue.d.ts +16 -0
  43. package/dist/components/OcAttachment.vue.d.ts +26 -0
  44. package/dist/components/OcAttachmentImage.vue.d.ts +10 -0
  45. package/dist/components/OcAttachmentList.vue.d.ts +31 -0
  46. package/dist/components/OcAttachmentThumb.vue.d.ts +16 -0
  47. package/dist/components/OcAvatar.vue.d.ts +21 -0
  48. package/dist/components/OcAvatarGroup.vue.d.ts +12 -0
  49. package/dist/components/OcBackLink.vue.d.ts +18 -0
  50. package/dist/components/OcBadge.vue.d.ts +18 -0
  51. package/dist/components/OcBarcodeInput.vue.d.ts +27 -0
  52. package/dist/components/OcBreadcrumb.vue.d.ts +24 -0
  53. package/dist/components/OcBrowserFrame.vue.d.ts +35 -0
  54. package/dist/components/OcBusyOverlay.vue.d.ts +30 -0
  55. package/dist/components/OcButton.vue.d.ts +31 -0
  56. package/dist/components/OcButtonGroup.vue.d.ts +17 -0
  57. package/dist/components/OcButtonGroupText.vue.d.ts +12 -0
  58. package/dist/components/OcCard.vue.d.ts +27 -0
  59. package/dist/components/OcChartLine.vue.d.ts +28 -0
  60. package/dist/components/OcChatComposer.vue.d.ts +33 -0
  61. package/dist/components/OcCheckbox.vue.d.ts +26 -0
  62. package/dist/components/OcChecklist.vue.d.ts +32 -0
  63. package/dist/components/OcChipFilter.vue.d.ts +24 -0
  64. package/dist/components/OcCollapsible.vue.d.ts +28 -0
  65. package/dist/components/OcColorField.vue.d.ts +17 -0
  66. package/dist/components/OcColorSelect.vue.d.ts +24 -0
  67. package/dist/components/OcColumnMenu.vue.d.ts +31 -0
  68. package/dist/components/OcCommand.vue.d.ts +28 -0
  69. package/dist/components/OcConfirmDialog.vue.d.ts +44 -0
  70. package/dist/components/OcCookieConsent.vue.d.ts +52 -0
  71. package/dist/components/OcCopyField.vue.d.ts +14 -0
  72. package/dist/components/OcCounter.vue.d.ts +9 -0
  73. package/dist/components/OcDataTable.vue.d.ts +37 -0
  74. package/dist/components/OcDecimalInput.vue.d.ts +19 -0
  75. package/dist/components/OcDefinitionList.vue.d.ts +34 -0
  76. package/dist/components/OcDocViewer.vue.d.ts +24 -0
  77. package/dist/components/OcDropdown.vue.d.ts +19 -0
  78. package/dist/components/OcDropdownItem.vue.d.ts +18 -0
  79. package/dist/components/OcDropdownLabel.vue.d.ts +12 -0
  80. package/dist/components/OcDropdownSeparator.vue.d.ts +2 -0
  81. package/dist/components/OcDropzone.vue.d.ts +29 -0
  82. package/dist/components/OcEmojiPicker.vue.d.ts +32 -0
  83. package/dist/components/OcEmptyState.vue.d.ts +24 -0
  84. package/dist/components/OcEntityCard.vue.d.ts +37 -0
  85. package/dist/components/OcFactList.vue.d.ts +29 -0
  86. package/dist/components/OcFilterCounts.vue.d.ts +25 -0
  87. package/dist/components/OcFlipCard.vue.d.ts +31 -0
  88. package/dist/components/OcFormField.vue.d.ts +26 -0
  89. package/dist/components/OcGreeting.vue.d.ts +26 -0
  90. package/dist/components/OcHeading.vue.d.ts +24 -0
  91. package/dist/components/OcHoverCard.vue.d.ts +22 -0
  92. package/dist/components/OcImageZoom.vue.d.ts +28 -0
  93. package/dist/components/OcInput.vue.d.ts +13 -0
  94. package/dist/components/OcInputGroup.vue.d.ts +21 -0
  95. package/dist/components/OcItem.vue.d.ts +39 -0
  96. package/dist/components/OcItemGroup.vue.d.ts +12 -0
  97. package/dist/components/OcItemSeparator.vue.d.ts +2 -0
  98. package/dist/components/OcKbd.vue.d.ts +12 -0
  99. package/dist/components/OcKbdGroup.vue.d.ts +17 -0
  100. package/dist/components/OcLabel.vue.d.ts +19 -0
  101. package/dist/components/OcLanguageSelect.vue.d.ts +32 -0
  102. package/dist/components/OcLauncherCard.vue.d.ts +26 -0
  103. package/dist/components/OcLightbox.vue.d.ts +45 -0
  104. package/dist/components/OcLinkArrow.vue.d.ts +23 -0
  105. package/dist/components/OcListToolbar.vue.d.ts +44 -0
  106. package/dist/components/OcMarquee.vue.d.ts +16 -0
  107. package/dist/components/OcMediaCard.vue.d.ts +24 -0
  108. package/dist/components/OcMediaRow.vue.d.ts +21 -0
  109. package/dist/components/OcMediaThumb.vue.d.ts +32 -0
  110. package/dist/components/OcMessage.vue.d.ts +63 -0
  111. package/dist/components/OcMessageList.vue.d.ts +35 -0
  112. package/dist/components/OcMessageThread.vue.d.ts +80 -0
  113. package/dist/components/OcModal.vue.d.ts +36 -0
  114. package/dist/components/OcNavmenu.vue.d.ts +24 -0
  115. package/dist/components/OcNavmenuList.vue.d.ts +29 -0
  116. package/dist/components/OcNextTeaser.vue.d.ts +29 -0
  117. package/dist/components/OcNumberInput.vue.d.ts +25 -0
  118. package/dist/components/OcOtpInput.vue.d.ts +19 -0
  119. package/dist/components/OcPageHeader.vue.d.ts +36 -0
  120. package/dist/components/OcPagination.vue.d.ts +20 -0
  121. package/dist/components/OcPasswordInput.vue.d.ts +18 -0
  122. package/dist/components/OcPasswordRequirements.vue.d.ts +19 -0
  123. package/dist/components/OcPhoneInput.vue.d.ts +25 -0
  124. package/dist/components/OcPopover.vue.d.ts +24 -0
  125. package/dist/components/OcPriceCard.vue.d.ts +41 -0
  126. package/dist/components/OcProductMark.vue.d.ts +25 -0
  127. package/dist/components/OcProgress.vue.d.ts +11 -0
  128. package/dist/components/OcProjectCard.vue.d.ts +35 -0
  129. package/dist/components/OcProse.vue.d.ts +25 -0
  130. package/dist/components/OcRadio.vue.d.ts +27 -0
  131. package/dist/components/OcRadioGroup.vue.d.ts +32 -0
  132. package/dist/components/OcRecoveryCodes.vue.d.ts +36 -0
  133. package/dist/components/OcScrollArea.vue.d.ts +18 -0
  134. package/dist/components/OcSegmented.vue.d.ts +21 -0
  135. package/dist/components/OcSelect.vue.d.ts +28 -0
  136. package/dist/components/OcSeparator.vue.d.ts +21 -0
  137. package/dist/components/OcSeverityCard.vue.d.ts +36 -0
  138. package/dist/components/OcSheet.vue.d.ts +37 -0
  139. package/dist/components/OcSidebar.vue.d.ts +28 -0
  140. package/dist/components/OcSidebarCollapsible.vue.d.ts +27 -0
  141. package/dist/components/OcSidebarGroup.vue.d.ts +16 -0
  142. package/dist/components/OcSidebarMenu.vue.d.ts +12 -0
  143. package/dist/components/OcSidebarMenuButton.vue.d.ts +21 -0
  144. package/dist/components/OcSidebarSeparator.vue.d.ts +2 -0
  145. package/dist/components/OcSkeleton.vue.d.ts +8 -0
  146. package/dist/components/OcSlider.vue.d.ts +18 -0
  147. package/dist/components/OcSortableRow.vue.d.ts +32 -0
  148. package/dist/components/OcSpinner.vue.d.ts +8 -0
  149. package/dist/components/OcStackCard.vue.d.ts +22 -0
  150. package/dist/components/OcStackList.vue.d.ts +28 -0
  151. package/dist/components/OcStatCard.vue.d.ts +25 -0
  152. package/dist/components/OcStepper.vue.d.ts +24 -0
  153. package/dist/components/OcSwitch.vue.d.ts +9 -0
  154. package/dist/components/OcTable.vue.d.ts +61 -0
  155. package/dist/components/OcTableActions.vue.d.ts +18 -0
  156. package/dist/components/OcTableCompact.vue.d.ts +37 -0
  157. package/dist/components/OcTabs.vue.d.ts +28 -0
  158. package/dist/components/OcTagInput.vue.d.ts +18 -0
  159. package/dist/components/OcTerminalLog.vue.d.ts +20 -0
  160. package/dist/components/OcTextarea.vue.d.ts +13 -0
  161. package/dist/components/OcThemeSwitch.vue.d.ts +20 -0
  162. package/dist/components/OcTimeInput.vue.d.ts +14 -0
  163. package/dist/components/OcTimeline.vue.d.ts +33 -0
  164. package/dist/components/OcToast.vue.d.ts +31 -0
  165. package/dist/components/OcToastContainer.vue.d.ts +8 -0
  166. package/dist/components/OcToggle.vue.d.ts +29 -0
  167. package/dist/components/OcToggleField.vue.d.ts +27 -0
  168. package/dist/components/OcToggleGroup.vue.d.ts +27 -0
  169. package/dist/components/OcTooltip.vue.d.ts +16 -0
  170. package/dist/components/OcTopProgress.vue.d.ts +18 -0
  171. package/dist/components/OcTree.vue.d.ts +40 -0
  172. package/dist/components/OcUpgradeBanner.vue.d.ts +41 -0
  173. package/dist/components/OcUser.vue.d.ts +20 -0
  174. package/dist/components/OcVersionBanner.vue.d.ts +32 -0
  175. package/dist/composables/chartLine.d.ts +6 -0
  176. package/dist/composables/keys.d.ts +19 -0
  177. package/dist/composables/useAttrsSplit.d.ts +14 -0
  178. package/dist/composables/useDialog.d.ts +9 -0
  179. package/dist/composables/useToast.d.ts +34 -0
  180. package/dist/composables/useUid.d.ts +5 -0
  181. package/dist/index.d.ts +233 -0
  182. package/dist/omniaui-vue.js +8811 -0
  183. package/dist/omniaui-vue.js.map +1 -0
  184. package/manifest.json +1036 -0
  185. package/package.json +69 -6
  186. package/src/blocks/OcBlockAboutTimeline.vue +44 -0
  187. package/src/blocks/OcBlockAppHeader.vue +36 -0
  188. package/src/blocks/OcBlockAppShell.vue +29 -0
  189. package/src/blocks/OcBlockAuth.vue +24 -0
  190. package/src/blocks/OcBlockAuthSplit.vue +47 -0
  191. package/src/blocks/OcBlockContactGrid.vue +53 -0
  192. package/src/blocks/OcBlockCta.vue +12 -0
  193. package/src/blocks/OcBlockDataTable.vue +27 -0
  194. package/src/blocks/OcBlockFaq.vue +49 -0
  195. package/src/blocks/OcBlockFeatures.vue +23 -0
  196. package/src/blocks/OcBlockFooter.vue +25 -0
  197. package/src/blocks/OcBlockFormPage.vue +24 -0
  198. package/src/blocks/OcBlockHero.vue +13 -0
  199. package/src/blocks/OcBlockHeroCode.vue +42 -0
  200. package/src/blocks/OcBlockHeroOrbit.vue +69 -0
  201. package/src/blocks/OcBlockHeroSplit.vue +15 -0
  202. package/src/blocks/OcBlockModuleHeader.vue +21 -0
  203. package/src/blocks/OcBlockPageHero.vue +13 -0
  204. package/src/blocks/OcBlockPortfolioGrid.vue +63 -0
  205. package/src/blocks/OcBlockPricing.vue +39 -0
  206. package/src/blocks/OcBlockProcess.vue +39 -0
  207. package/src/blocks/OcBlockProductGrid.vue +41 -0
  208. package/src/blocks/OcBlockProfileHeader.vue +50 -0
  209. package/src/blocks/OcBlockShowcase.vue +43 -0
  210. package/src/blocks/OcBlockSiteFooter.vue +54 -0
  211. package/src/blocks/OcBlockSiteHeader.vue +34 -0
  212. package/src/blocks/OcBlockSpotlight.vue +47 -0
  213. package/src/blocks/OcBlockStats.vue +17 -0
  214. package/src/blocks/OcBlockStatsCounter.vue +20 -0
  215. package/src/blocks/OcBlockTeamList.vue +53 -0
  216. package/src/blocks/OcBlockTwoFactor.vue +61 -0
  217. package/src/blocks/OcBlockWizardDialog.vue +67 -0
  218. package/src/components/OcAccordion.vue +12 -0
  219. package/src/components/OcAccordionAccent.vue +27 -0
  220. package/src/components/OcAccordionItem.vue +19 -0
  221. package/src/components/OcAffixInput.vue +40 -0
  222. package/src/components/OcAlert.vue +17 -0
  223. package/src/components/OcAlertDialog.vue +66 -0
  224. package/src/components/OcAlphaTabs.vue +54 -0
  225. package/src/components/OcAspectRatio.vue +21 -0
  226. package/src/components/OcAttachment.vue +59 -0
  227. package/src/components/OcAttachmentImage.vue +13 -0
  228. package/src/components/OcAttachmentList.vue +31 -0
  229. package/src/components/OcAttachmentThumb.vue +14 -0
  230. package/src/components/OcAvatar.vue +18 -0
  231. package/src/components/OcAvatarGroup.vue +7 -0
  232. package/src/components/OcBackLink.vue +8 -0
  233. package/src/components/OcBadge.vue +13 -0
  234. package/src/components/OcBarcodeInput.vue +51 -0
  235. package/src/components/OcBreadcrumb.vue +22 -0
  236. package/src/components/OcBrowserFrame.vue +33 -0
  237. package/src/components/OcBusyOverlay.vue +32 -0
  238. package/src/components/OcButton.vue +47 -0
  239. package/src/components/OcButtonGroup.vue +10 -0
  240. package/src/components/OcButtonGroupText.vue +7 -0
  241. package/src/components/OcCard.vue +20 -0
  242. package/src/components/OcChartLine.vue +80 -0
  243. package/src/components/OcChatComposer.vue +42 -0
  244. package/src/components/OcCheckbox.vue +26 -0
  245. package/src/components/OcChecklist.vue +29 -0
  246. package/src/components/OcChipFilter.vue +48 -0
  247. package/src/components/OcCollapsible.vue +19 -0
  248. package/src/components/OcColorField.vue +15 -0
  249. package/src/components/OcColorSelect.vue +33 -0
  250. package/src/components/OcColumnMenu.vue +50 -0
  251. package/src/components/OcCommand.vue +119 -0
  252. package/src/components/OcConfirmDialog.vue +65 -0
  253. package/src/components/OcCookieConsent.vue +119 -0
  254. package/src/components/OcCopyField.vue +37 -0
  255. package/src/components/OcCounter.vue +15 -0
  256. package/src/components/OcDataTable.vue +144 -0
  257. package/src/components/OcDecimalInput.vue +53 -0
  258. package/src/components/OcDefinitionList.vue +35 -0
  259. package/src/components/OcDocViewer.vue +79 -0
  260. package/src/components/OcDropdown.vue +23 -0
  261. package/src/components/OcDropdownItem.vue +9 -0
  262. package/src/components/OcDropdownLabel.vue +7 -0
  263. package/src/components/OcDropdownSeparator.vue +7 -0
  264. package/src/components/OcDropzone.vue +36 -0
  265. package/src/components/OcEmojiPicker.vue +45 -0
  266. package/src/components/OcEmptyState.vue +13 -0
  267. package/src/components/OcEntityCard.vue +47 -0
  268. package/src/components/OcFactList.vue +37 -0
  269. package/src/components/OcFilterCounts.vue +38 -0
  270. package/src/components/OcFlipCard.vue +36 -0
  271. package/src/components/OcFormField.vue +36 -0
  272. package/src/components/OcGreeting.vue +52 -0
  273. package/src/components/OcHeading.vue +19 -0
  274. package/src/components/OcHoverCard.vue +25 -0
  275. package/src/components/OcImageZoom.vue +39 -0
  276. package/src/components/OcInput.vue +9 -0
  277. package/src/components/OcInputGroup.vue +12 -0
  278. package/src/components/OcItem.vue +40 -0
  279. package/src/components/OcItemGroup.vue +7 -0
  280. package/src/components/OcItemSeparator.vue +7 -0
  281. package/src/components/OcKbd.vue +7 -0
  282. package/src/components/OcKbdGroup.vue +15 -0
  283. package/src/components/OcLabel.vue +10 -0
  284. package/src/components/OcLanguageSelect.vue +40 -0
  285. package/src/components/OcLauncherCard.vue +34 -0
  286. package/src/components/OcLightbox.vue +63 -0
  287. package/src/components/OcLinkArrow.vue +25 -0
  288. package/src/components/OcListToolbar.vue +44 -0
  289. package/src/components/OcMarquee.vue +36 -0
  290. package/src/components/OcMediaCard.vue +28 -0
  291. package/src/components/OcMediaRow.vue +28 -0
  292. package/src/components/OcMediaThumb.vue +38 -0
  293. package/src/components/OcMessage.vue +91 -0
  294. package/src/components/OcMessageList.vue +43 -0
  295. package/src/components/OcMessageThread.vue +155 -0
  296. package/src/components/OcModal.vue +42 -0
  297. package/src/components/OcNavmenu.vue +18 -0
  298. package/src/components/OcNavmenuList.vue +38 -0
  299. package/src/components/OcNextTeaser.vue +25 -0
  300. package/src/components/OcNumberInput.vue +47 -0
  301. package/src/components/OcOtpInput.vue +34 -0
  302. package/src/components/OcPageHeader.vue +34 -0
  303. package/src/components/OcPagination.vue +33 -0
  304. package/src/components/OcPasswordInput.vue +27 -0
  305. package/src/components/OcPasswordRequirements.vue +28 -0
  306. package/src/components/OcPhoneInput.vue +72 -0
  307. package/src/components/OcPopover.vue +25 -0
  308. package/src/components/OcPriceCard.vue +69 -0
  309. package/src/components/OcProductMark.vue +31 -0
  310. package/src/components/OcProgress.vue +21 -0
  311. package/src/components/OcProjectCard.vue +36 -0
  312. package/src/components/OcProse.vue +57 -0
  313. package/src/components/OcRadio.vue +40 -0
  314. package/src/components/OcRadioGroup.vue +32 -0
  315. package/src/components/OcRecoveryCodes.vue +55 -0
  316. package/src/components/OcScrollArea.vue +15 -0
  317. package/src/components/OcSegmented.vue +28 -0
  318. package/src/components/OcSelect.vue +21 -0
  319. package/src/components/OcSeparator.vue +18 -0
  320. package/src/components/OcSeverityCard.vue +46 -0
  321. package/src/components/OcSheet.vue +49 -0
  322. package/src/components/OcSidebar.vue +16 -0
  323. package/src/components/OcSidebarCollapsible.vue +19 -0
  324. package/src/components/OcSidebarGroup.vue +11 -0
  325. package/src/components/OcSidebarMenu.vue +7 -0
  326. package/src/components/OcSidebarMenuButton.vue +31 -0
  327. package/src/components/OcSidebarSeparator.vue +7 -0
  328. package/src/components/OcSkeleton.vue +8 -0
  329. package/src/components/OcSlider.vue +27 -0
  330. package/src/components/OcSortableRow.vue +40 -0
  331. package/src/components/OcSpinner.vue +13 -0
  332. package/src/components/OcStackCard.vue +24 -0
  333. package/src/components/OcStackList.vue +31 -0
  334. package/src/components/OcStatCard.vue +39 -0
  335. package/src/components/OcStepper.vue +34 -0
  336. package/src/components/OcSwitch.vue +15 -0
  337. package/src/components/OcTable.vue +115 -0
  338. package/src/components/OcTableActions.vue +26 -0
  339. package/src/components/OcTableCompact.vue +46 -0
  340. package/src/components/OcTabs.vue +37 -0
  341. package/src/components/OcTagInput.vue +50 -0
  342. package/src/components/OcTerminalLog.vue +50 -0
  343. package/src/components/OcTextarea.vue +9 -0
  344. package/src/components/OcThemeSwitch.vue +31 -0
  345. package/src/components/OcTimeInput.vue +50 -0
  346. package/src/components/OcTimeline.vue +36 -0
  347. package/src/components/OcToast.vue +31 -0
  348. package/src/components/OcToastContainer.vue +21 -0
  349. package/src/components/OcToggle.vue +63 -0
  350. package/src/components/OcToggleField.vue +28 -0
  351. package/src/components/OcToggleGroup.vue +40 -0
  352. package/src/components/OcTooltip.vue +8 -0
  353. package/src/components/OcTopProgress.vue +54 -0
  354. package/src/components/OcTree.vue +70 -0
  355. package/src/components/OcUpgradeBanner.vue +42 -0
  356. package/src/components/OcUser.vue +25 -0
  357. package/src/components/OcVersionBanner.vue +34 -0
  358. package/src/composables/chartLine.ts +28 -0
  359. package/src/composables/keys.ts +22 -0
  360. package/src/composables/useAttrsSplit.ts +16 -0
  361. package/src/composables/useDialog.ts +21 -0
  362. package/src/composables/useToast.ts +66 -0
  363. package/src/composables/useUid.ts +12 -0
  364. package/src/index.ts +589 -0
@@ -0,0 +1,47 @@
1
+ <!-- File: packages/vue/src/components/OcEntityCard.vue | Map: props -> article -> grid (frame | body: eyebrow, title, description, facts) -> footer -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Framed media cell + detail column (same markup as snippets/entity-card.html).
5
+ * Props: title, eyebrow, description, src / alt or glyph (frame content), contain, facts ([key, value][]), stacked, size (sm|md).
6
+ * Slots: media (frame content), default (extra body content), footer. Classes: .oc-entity-card(--stacked/--sm), __grid,
7
+ * __frame(--contain), __glyph, __body, __eyebrow, __title, __description, __facts, __footer
8
+ */
9
+ withDefaults(
10
+ defineProps<{
11
+ title: string
12
+ eyebrow?: string
13
+ description?: string
14
+ src?: string
15
+ alt?: string
16
+ glyph?: string
17
+ contain?: boolean
18
+ facts?: [string, string][]
19
+ stacked?: boolean
20
+ size?: 'sm' | 'md'
21
+ }>(),
22
+ { alt: '', size: 'md' },
23
+ )
24
+ </script>
25
+
26
+ <template>
27
+ <article :class="['oc-entity-card', stacked && 'oc-entity-card--stacked', size === 'sm' && 'oc-entity-card--sm']">
28
+ <div class="oc-entity-card__grid">
29
+ <div :class="['oc-entity-card__frame', contain && 'oc-entity-card__frame--contain']">
30
+ <slot name="media">
31
+ <img v-if="src" :src="src" :alt="alt" />
32
+ <span v-else-if="glyph" class="oc-entity-card__glyph" aria-hidden="true">{{ glyph }}</span>
33
+ </slot>
34
+ </div>
35
+ <div class="oc-entity-card__body">
36
+ <p v-if="eyebrow" class="oc-entity-card__eyebrow">{{ eyebrow }}</p>
37
+ <h3 class="oc-entity-card__title">{{ title }}</h3>
38
+ <p v-if="description" class="oc-entity-card__description">{{ description }}</p>
39
+ <dl v-if="facts?.length" class="oc-entity-card__facts">
40
+ <template v-for="([k, v], i) in facts" :key="i"><dt>{{ k }}</dt><dd>{{ v }}</dd></template>
41
+ </dl>
42
+ <slot />
43
+ </div>
44
+ </div>
45
+ <div v-if="$slots.footer" class="oc-entity-card__footer"><slot name="footer" /></div>
46
+ </article>
47
+ </template>
@@ -0,0 +1,37 @@
1
+ <!-- File: packages/vue/src/components/OcFactList.vue | Map: props (items + modifiers) -> dl.oc-fact-list -> div > dt + dd -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Key / value product facts (variant of the definition list). Pass `items`, or your own <div><dt><dd> rows in the slot.
5
+ * Classes: .oc-fact-list (--plain, --compact, --stacked, --accent)
6
+ */
7
+ export interface FactListRow {
8
+ label: string
9
+ value: string
10
+ }
11
+ withDefaults(
12
+ defineProps<{
13
+ items?: FactListRow[]
14
+ plain?: boolean
15
+ compact?: boolean
16
+ stacked?: boolean
17
+ accent?: boolean
18
+ }>(),
19
+ { items: () => [] },
20
+ )
21
+ </script>
22
+
23
+ <template>
24
+ <dl
25
+ :class="[
26
+ 'oc-fact-list',
27
+ plain && 'oc-fact-list--plain',
28
+ compact && 'oc-fact-list--compact',
29
+ stacked && 'oc-fact-list--stacked',
30
+ accent && 'oc-fact-list--accent',
31
+ ]"
32
+ >
33
+ <slot>
34
+ <div v-for="(row, i) in items" :key="i"><dt>{{ row.label }}</dt><dd>{{ row.value }}</dd></div>
35
+ </slot>
36
+ </dl>
37
+ </template>
@@ -0,0 +1,38 @@
1
+ <!-- File: packages/vue/src/components/OcFilterCounts.vue | Map: types + props -> template (fieldset radiogroup -> tile per view) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * View filter tiles with counts (Active / Deleted / All). v-model = selected value.
5
+ * Same markup as packages/ui/snippets/filter-counts.html. Classes: .oc-filter-counts(--compact), -item(--success/--destructive/--muted), -value, -label, -hint
6
+ */
7
+ import { useUid } from '../composables/useUid'
8
+
9
+ export interface FilterCountsItem {
10
+ value: string
11
+ label: string
12
+ count: number | string
13
+ hint?: string
14
+ /** Accent color of the tile; default primary. */
15
+ tone?: 'primary' | 'success' | 'destructive' | 'muted'
16
+ disabled?: boolean
17
+ }
18
+ defineProps<{
19
+ options: FilterCountsItem[]
20
+ /** aria-label of the group */
21
+ label?: string
22
+ compact?: boolean
23
+ name?: string
24
+ }>()
25
+ const model = defineModel<string>()
26
+ const uid = useUid('oc-filter')
27
+ </script>
28
+
29
+ <template>
30
+ <fieldset :class="['oc-filter-counts', compact && 'oc-filter-counts--compact']" role="radiogroup" :aria-label="label">
31
+ <label v-for="option in options" :key="option.value" :class="['oc-filter-counts-item', option.tone && option.tone !== 'primary' && `oc-filter-counts-item--${option.tone}`]">
32
+ <input v-model="model" type="radio" :name="name ?? uid" :value="option.value" :disabled="option.disabled" />
33
+ <span class="oc-filter-counts-value">{{ option.count }}</span>
34
+ <span class="oc-filter-counts-label">{{ option.label }}</span>
35
+ <span v-if="option.hint" class="oc-filter-counts-hint">{{ option.hint }}</span>
36
+ </label>
37
+ </fieldset>
38
+ </template>
@@ -0,0 +1,36 @@
1
+ <!-- File: packages/vue/src/components/OcFlipCard.vue | Map: props + v-model:flipped -> card -> checkbox (toggle) -> inner -> front / back faces -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * 3D flip card (same markup as snippets/flip-card.html). v-model:flipped. trigger: toggle (checkbox, default) |
5
+ * hover (--hover, tabindex 0) | manual (.is-flipped from the model only). Props: vertical, frontLabel, backLabel.
6
+ * Slots: front, back. Classes: .oc-flip-card(--hover/--vertical, .is-flipped), __toggle, __inner, __face(--front/--back),
7
+ * __title, __text, __flip
8
+ */
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ withDefaults(
12
+ defineProps<{ trigger?: 'toggle' | 'hover' | 'manual'; vertical?: boolean; frontLabel?: string; backLabel?: string }>(),
13
+ { trigger: 'toggle', frontLabel: 'Show answer', backLabel: 'Back' },
14
+ )
15
+ const flipped = defineModel<boolean>('flipped', { default: false })
16
+ const id = useUid('oc-flip')
17
+ </script>
18
+
19
+ <template>
20
+ <div
21
+ :class="['oc-flip-card', trigger === 'hover' && 'oc-flip-card--hover', vertical && 'oc-flip-card--vertical', trigger !== 'toggle' && flipped && 'is-flipped']"
22
+ :tabindex="trigger === 'hover' ? 0 : undefined"
23
+ >
24
+ <input v-if="trigger === 'toggle'" :id="id" v-model="flipped" type="checkbox" class="oc-flip-card__toggle" />
25
+ <div class="oc-flip-card__inner">
26
+ <div class="oc-flip-card__face oc-flip-card__face--front">
27
+ <slot name="front" />
28
+ <label v-if="trigger === 'toggle'" class="oc-flip-card__flip" :for="id">{{ frontLabel }}</label>
29
+ </div>
30
+ <div class="oc-flip-card__face oc-flip-card__face--back">
31
+ <slot name="back" />
32
+ <label v-if="trigger === 'toggle'" class="oc-flip-card__flip" :for="id">{{ backLabel }}</label>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Form field: label, control (default slot), description and error.
4
+ * The slot receives { id, describedBy, invalid } so the control can be wired:
5
+ * <OcFormField label="Email" description="..." v-slot="f"><OcInput :id="f.id" :aria-describedby="f.describedBy" /></OcFormField>
6
+ * Classes: .oc-field(--horizontal), .oc-field-label, .oc-field-description, .oc-field-error
7
+ */
8
+ import { computed } from 'vue'
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ const props = defineProps<{
12
+ label?: string
13
+ description?: string
14
+ error?: string
15
+ /** id of the control; generated when omitted */
16
+ for?: string
17
+ horizontal?: boolean
18
+ }>()
19
+ const generated = useUid('oc-field')
20
+ const id = computed(() => props.for ?? generated)
21
+ const helpId = computed(() => `${id.value}-help`)
22
+ const errorId = computed(() => `${id.value}-error`)
23
+ const describedBy = computed(() => {
24
+ const ids = [props.description && helpId.value, props.error && errorId.value].filter(Boolean)
25
+ return ids.length ? ids.join(' ') : undefined
26
+ })
27
+ </script>
28
+
29
+ <template>
30
+ <div :class="['oc-field', horizontal && 'oc-field--horizontal']">
31
+ <label v-if="label || $slots.label" class="oc-field-label" :for="id"><slot name="label">{{ label }}</slot></label>
32
+ <slot :id="id" :described-by="describedBy" :invalid="!!error" />
33
+ <p v-if="description" :id="helpId" class="oc-field-description">{{ description }}</p>
34
+ <p v-if="error" :id="errorId" class="oc-field-error" role="alert">{{ error }}</p>
35
+ </div>
36
+ </template>
@@ -0,0 +1,52 @@
1
+ <!-- File: packages/vue/src/components/OcGreeting.vue | Map: time-of-day logic -> header -> icon slot -> body (eyebrow, title + name, date) -> actions slot -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Dashboard greeting. The time of day comes from `date` (default now): morning 05-12, afternoon 12-18, evening otherwise.
5
+ * Slots: icon, actions. Classes: .oc-greeting(--morning/--afternoon/--evening/--lg), -icon, -body, -eyebrow, -title, -name, -date, -actions
6
+ */
7
+ import { computed } from 'vue'
8
+
9
+ type TimeOfDay = 'morning' | 'afternoon' | 'evening'
10
+
11
+ const props = defineProps<{
12
+ name?: string
13
+ date?: Date
14
+ timeOfDay?: TimeOfDay
15
+ /** Translated greetings, e.g. { morning: 'Goedemorgen' }. */
16
+ words?: Partial<Record<TimeOfDay, string>>
17
+ locale?: string
18
+ hideDate?: boolean
19
+ eyebrow?: string
20
+ size?: 'lg'
21
+ }>()
22
+
23
+ const WORDS: Record<TimeOfDay, string> = { morning: 'Good morning', afternoon: 'Good afternoon', evening: 'Good evening' }
24
+
25
+ const when = computed(() => props.date ?? new Date())
26
+ const tod = computed<TimeOfDay>(() => {
27
+ if (props.timeOfDay) return props.timeOfDay
28
+ const h = when.value.getHours()
29
+ return h >= 5 && h < 12 ? 'morning' : h >= 12 && h < 18 ? 'afternoon' : 'evening'
30
+ })
31
+ const word = computed(() => props.words?.[tod.value] ?? WORDS[tod.value])
32
+ const dateText = computed(() =>
33
+ new Intl.DateTimeFormat(props.locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }).format(when.value),
34
+ )
35
+ // Local YYYY-MM-DD for datetime (toISOString would use UTC).
36
+ const iso = computed(() => {
37
+ const d = when.value
38
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
39
+ })
40
+ </script>
41
+
42
+ <template>
43
+ <header :class="['oc-greeting', `oc-greeting--${tod}`, size && `oc-greeting--${size}`]">
44
+ <span v-if="$slots.icon" class="oc-greeting-icon" aria-hidden="true"><slot name="icon" /></span>
45
+ <div class="oc-greeting-body">
46
+ <p v-if="eyebrow" class="oc-greeting-eyebrow">{{ eyebrow }}</p>
47
+ <h2 class="oc-greeting-title">{{ word }}<template v-if="name">, <span class="oc-greeting-name">{{ name }}</span></template></h2>
48
+ <time v-if="!hideDate" class="oc-greeting-date" :datetime="iso">{{ dateText }}</time>
49
+ </div>
50
+ <div v-if="$slots.actions" class="oc-greeting-actions"><slot name="actions" /></div>
51
+ </header>
52
+ </template>
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ /** Page or section title with a muted description. Classes: .oc-heading(--sm). `as` picks the title tag. */
3
+ withDefaults(
4
+ defineProps<{
5
+ title?: string
6
+ description?: string
7
+ size?: 'sm' | 'md'
8
+ as?: 'h1' | 'h2' | 'h3' | 'h4'
9
+ }>(),
10
+ { size: 'md', as: 'h2' },
11
+ )
12
+ </script>
13
+
14
+ <template>
15
+ <div :class="['oc-heading', size === 'sm' && 'oc-heading--sm']">
16
+ <component :is="as" class="oc-heading-title"><slot name="title">{{ title }}</slot></component>
17
+ <p v-if="description || $slots.default" class="oc-heading-description"><slot>{{ description }}</slot></p>
18
+ </div>
19
+ </template>
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Preview on hover/focus (interestfor + popover, CSS hover fallback). The trigger is the `trigger` slot
4
+ * (scoped: { id }) or a link with `label` and `href`; default slot = card content.
5
+ * Classes: .oc-hover-card(--top), -trigger, -content(--sm). Attributes land on the content element.
6
+ */
7
+ import { useAttrs } from 'vue'
8
+ import { useUid } from '../composables/useUid'
9
+
10
+ defineOptions({ inheritAttrs: false })
11
+ defineProps<{ label?: string; href?: string; top?: boolean; small?: boolean }>()
12
+ const attrs = useAttrs()
13
+ const id = (attrs.id as string | undefined) ?? useUid('oc-hover-card')
14
+ </script>
15
+
16
+ <template>
17
+ <span :class="['oc-hover-card', top && 'oc-hover-card--top']">
18
+ <slot name="trigger" :id="id">
19
+ <a class="oc-hover-card-trigger" :href="href ?? '#'" :interestfor="id">{{ label }}</a>
20
+ </slot>
21
+ <div v-bind="attrs" :id="id" :class="['oc-hover-card-content', small && 'oc-hover-card-content--sm']" popover>
22
+ <slot />
23
+ </div>
24
+ </span>
25
+ </template>
@@ -0,0 +1,39 @@
1
+ <!-- File: packages/vue/src/components/OcImageZoom.vue | Map: props + v-model:zoom -> toolbar (radio levels) -> viewport -> canvas -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Zoom / pan viewport (same markup as snippets/image-zoom.html). v-model:zoom = current level (default 1).
5
+ * levels: toolbar values (default [1, 1.5, 2, 3]; [] = no toolbar). ratio: square | photo | CSS ratio.
6
+ * Default slot replaces the <img>. Classes: .oc-image-zoom(--square/--photo), __toolbar, __label, __level, __viewport, __canvas
7
+ */
8
+ import { computed } from 'vue'
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ const props = withDefaults(defineProps<{ src?: string; alt?: string; levels?: number[]; ratio?: string }>(), {
12
+ alt: '',
13
+ levels: () => [1, 1.5, 2, 3],
14
+ })
15
+ const zoom = defineModel<number>('zoom', { default: 1 })
16
+ const name = useUid('oc-zoom')
17
+ const preset = computed(() => (props.ratio === 'square' || props.ratio === 'photo' ? props.ratio : undefined))
18
+ // Writing --oc-zoom inline means any level works, not only the ones the CSS :has() rules know.
19
+ const vars = computed(() => ({ '--oc-zoom': String(zoom.value), ...(props.ratio && !preset.value ? { '--oc-image-zoom-ratio': props.ratio } : {}) }))
20
+ </script>
21
+
22
+ <template>
23
+ <div :class="['oc-image-zoom', preset && `oc-image-zoom--${preset}`]" :style="vars">
24
+ <div v-if="levels.length" class="oc-image-zoom__toolbar" role="radiogroup" aria-label="Zoom level">
25
+ <span class="oc-image-zoom__label">Zoom</span>
26
+ <label v-for="l in levels" :key="l" class="oc-image-zoom__level">
27
+ <input v-model="zoom" type="radio" :name="name" :value="l" />{{ Math.round(l * 100) }}%
28
+ </label>
29
+ </div>
30
+ <div class="oc-image-zoom__viewport" tabindex="0" role="region" :aria-label="alt ? `${alt}, scroll to pan` : 'Scroll to pan'">
31
+ <div class="oc-image-zoom__canvas">
32
+ <slot>
33
+ <img v-if="src" :src="src" :alt="alt" />
34
+ <div v-else class="oc-media-art" role="img" :aria-label="alt" />
35
+ </slot>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </template>
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ /** Text input. v-model. `error` sets .oc-input--error + aria-invalid. Any native attribute falls through. */
3
+ defineProps<{ error?: boolean }>()
4
+ const model = defineModel<string | number>()
5
+ </script>
6
+
7
+ <template>
8
+ <input v-model="model" :class="['oc-input', error && 'oc-input--error']" :aria-invalid="error ? 'true' : undefined" />
9
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ /** Input with prefix/suffix addon. Default slot = the input(s); `prefix` / `suffix` are text props or slots. */
3
+ defineProps<{ prefix?: string; suffix?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <div class="oc-input-group">
8
+ <span v-if="prefix || $slots.prefix" class="oc-input-addon"><slot name="prefix">{{ prefix }}</slot></span>
9
+ <slot />
10
+ <span v-if="suffix || $slots.suffix" class="oc-input-addon"><slot name="suffix">{{ suffix }}</slot></span>
11
+ </div>
12
+ </template>
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * List row. Renders <a> when `href` is set. Slots: media (left; `icon` boxes it, `image` makes it an image),
4
+ * default (replaces title + description), actions (right), header / footer (full-width rows).
5
+ * Classes: .oc-item(--outline/--muted/--sm/--interactive), -media(--icon/--image), -content, -title, -description,
6
+ * -actions, -header, -footer
7
+ */
8
+ withDefaults(
9
+ defineProps<{
10
+ variant?: 'default' | 'outline' | 'muted'
11
+ size?: 'sm' | 'md'
12
+ interactive?: boolean
13
+ href?: string
14
+ title?: string
15
+ description?: string
16
+ icon?: boolean
17
+ image?: boolean
18
+ }>(),
19
+ { variant: 'default', size: 'md' },
20
+ )
21
+ </script>
22
+
23
+ <template>
24
+ <component
25
+ :is="href ? 'a' : 'div'"
26
+ :href="href"
27
+ :class="['oc-item', variant !== 'default' && `oc-item--${variant}`, size === 'sm' && 'oc-item--sm', interactive && 'oc-item--interactive']"
28
+ >
29
+ <div v-if="$slots.header" class="oc-item-header"><slot name="header" /></div>
30
+ <div v-if="$slots.media" :class="['oc-item-media', icon && 'oc-item-media--icon', image && 'oc-item-media--image']"><slot name="media" /></div>
31
+ <div class="oc-item-content">
32
+ <slot>
33
+ <p v-if="title" class="oc-item-title">{{ title }}</p>
34
+ <p v-if="description" class="oc-item-description">{{ description }}</p>
35
+ </slot>
36
+ </div>
37
+ <div v-if="$slots.actions" class="oc-item-actions"><slot name="actions" /></div>
38
+ <div v-if="$slots.footer" class="oc-item-footer"><slot name="footer" /></div>
39
+ </component>
40
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** Vertical list of OcItem. `separated` puts a separator between the direct children is left to OcItemSeparator. Class: .oc-item-group */
3
+ </script>
4
+
5
+ <template>
6
+ <div class="oc-item-group"><slot /></div>
7
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** Divider between items in an OcItemGroup. Class: .oc-item-separator */
3
+ </script>
4
+
5
+ <template>
6
+ <hr class="oc-item-separator" />
7
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** One key. Class: .oc-kbd */
3
+ </script>
4
+
5
+ <template>
6
+ <kbd class="oc-kbd"><slot /></kbd>
7
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ /** Shortcut: `keys` ["Ctrl", "K"] renders one key per entry, with a "+" separator when `separator` is set. Or pass OcKbd in the slot. Classes: .oc-kbd-group, .oc-kbd-sep */
3
+ defineProps<{ keys?: string[]; separator?: boolean }>()
4
+ </script>
5
+
6
+ <template>
7
+ <span class="oc-kbd-group">
8
+ <slot>
9
+ <template v-for="(key, i) in keys" :key="key + i">
10
+ <span v-if="separator && i > 0" class="oc-kbd-sep">+</span>
11
+ <kbd class="oc-kbd">{{ key }}</kbd>
12
+ </template>
13
+ </slot>
14
+ </span>
15
+ </template>
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ /** Form label. `for` links it to a control. Classes: .oc-label(--required/--inline/--muted) */
3
+ defineProps<{ for?: string; required?: boolean; inline?: boolean; muted?: boolean }>()
4
+ </script>
5
+
6
+ <template>
7
+ <label :class="['oc-label', required && 'oc-label--required', inline && 'oc-label--inline', muted && 'oc-label--muted']" :for="$props.for">
8
+ <slot />
9
+ </label>
10
+ </template>
@@ -0,0 +1,40 @@
1
+ <!-- File: packages/vue/src/components/OcLanguageSelect.vue | Map: types + props -> template (label pill: icon slot + native select) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Compact language / currency switcher. v-model = selected value. Slot `icon` replaces the globe / symbol.
5
+ * Same markup as packages/ui/snippets/language-select.html. class/style on the pill, other attributes on the select.
6
+ */
7
+ import { useAttrsSplit } from '../composables/useAttrsSplit'
8
+
9
+ export interface LanguageSelectItem {
10
+ value: string
11
+ label: string
12
+ }
13
+
14
+ defineOptions({ inheritAttrs: false })
15
+ defineProps<{
16
+ options: LanguageSelectItem[]
17
+ /** aria-label of the select (default "Language" / "Currency") */
18
+ label?: string
19
+ currency?: boolean
20
+ ghost?: boolean
21
+ /** Text icon, e.g. "€" (default: globe, or € with `currency`) */
22
+ icon?: string
23
+ }>()
24
+ const model = defineModel<string>()
25
+ const { root, control } = useAttrsSplit()
26
+ </script>
27
+
28
+ <template>
29
+ <label v-bind="root" :class="['oc-language-select', ghost && 'oc-language-select--ghost', currency && 'oc-language-select--currency']">
30
+ <span class="oc-language-select-icon" aria-hidden="true">
31
+ <slot name="icon">
32
+ <template v-if="icon || currency">{{ icon ?? '€' }}</template>
33
+ <svg v-else viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9" /><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" /></svg>
34
+ </slot>
35
+ </span>
36
+ <select v-bind="control" v-model="model" class="oc-language-select-control" :aria-label="label ?? (currency ? 'Currency' : 'Language')">
37
+ <option v-for="option in options" :key="option.value" :value="option.value">{{ option.label }}</option>
38
+ </select>
39
+ </label>
40
+ </template>
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Large clickable card with icon, title and description. Renders <a> with `href`, <span> when disabled,
4
+ * otherwise <button>. State: `current` (aria-current), `disabled` (aria-disabled).
5
+ * Slots: icon, title (+ trailing badge), description, footer.
6
+ */
7
+ import { computed } from 'vue'
8
+
9
+ const props = defineProps<{
10
+ href?: string
11
+ title?: string
12
+ description?: string
13
+ footer?: string
14
+ current?: boolean
15
+ disabled?: boolean
16
+ }>()
17
+ const tag = computed(() => (props.disabled ? 'span' : props.href ? 'a' : 'button'))
18
+ </script>
19
+
20
+ <template>
21
+ <component
22
+ :is="tag"
23
+ class="oc-launcher"
24
+ :href="tag === 'a' ? href : undefined"
25
+ :type="tag === 'button' ? 'button' : undefined"
26
+ :aria-current="current ? 'true' : undefined"
27
+ :aria-disabled="disabled ? 'true' : undefined"
28
+ >
29
+ <span v-if="$slots.icon" class="oc-launcher-icon" aria-hidden="true"><slot name="icon" /></span>
30
+ <h3 class="oc-launcher-title"><slot name="title">{{ title }}</slot></h3>
31
+ <p v-if="description || $slots.description" class="oc-launcher-description"><slot name="description">{{ description }}</slot></p>
32
+ <span v-if="footer || $slots.footer" class="oc-launcher-footer"><slot name="footer">{{ footer }}</slot></span>
33
+ </component>
34
+ </template>
@@ -0,0 +1,63 @@
1
+ <!-- File: packages/vue/src/components/OcLightbox.vue | Map: props + model -> open at photo -> thumbnails -> <dialog> (bar, track of slides) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Lightbox on a native <dialog> (same markup as snippets/lightbox.html). v-model:open controls it.
5
+ * images: { src?, alt, caption?, thumb? }[] (no src = placeholder art). Prev / next are anchor links.
6
+ * Slot: caption (scoped: { image, index }). Classes: .oc-lightbox(--single), __bar, __title, __close, __track,
7
+ * __slide, __media, __nav(--prev/--next), __caption, __counter; .oc-lightbox-thumbs / -thumb.
8
+ */
9
+ import { nextTick, ref } from 'vue'
10
+ import { useDialog } from '../composables/useDialog'
11
+ import { useUid } from '../composables/useUid'
12
+
13
+ const props = withDefaults(
14
+ defineProps<{ images: { src?: string; alt: string; caption?: string; thumb?: string }[]; title?: string; label?: string; thumbnails?: boolean }>(),
15
+ { label: 'Photo viewer', thumbnails: true },
16
+ )
17
+ const open = defineModel<boolean>('open', { default: false })
18
+ const el = ref<HTMLDialogElement | null>(null)
19
+ const { onClose } = useDialog(open, el)
20
+ const base = useUid('oc-lightbox')
21
+ const n = () => props.images.length
22
+ const slideId = (i: number) => `${base}-${((i % n()) + n()) % n() + 1}`
23
+
24
+ // Open the viewer and jump (without animation) to photo i.
25
+ async function show(i: number) {
26
+ open.value = true
27
+ await nextTick()
28
+ document.getElementById(slideId(i))?.scrollIntoView?.({ behavior: 'instant' as ScrollBehavior, block: 'nearest', inline: 'center' })
29
+ }
30
+ defineExpose({ show, close: () => (open.value = false) })
31
+ </script>
32
+
33
+ <template>
34
+ <div v-if="thumbnails" class="oc-lightbox-thumbs">
35
+ <button v-for="(img, i) in images" :key="i" type="button" class="oc-lightbox-thumb" :aria-label="`Open photo ${i + 1}: ${img.alt}`" @click="show(i)">
36
+ <img v-if="img.thumb || img.src" :src="img.thumb || img.src" :alt="img.alt" />
37
+ <span v-else class="oc-media-art" />
38
+ </button>
39
+ </div>
40
+ <dialog ref="el" :class="['oc-lightbox', images.length === 1 && 'oc-lightbox--single']" closedby="any" :aria-label="label" @close="onClose">
41
+ <div class="oc-lightbox__bar">
42
+ <h2 v-if="title" class="oc-lightbox__title">{{ title }}</h2>
43
+ <span v-else />
44
+ <button type="button" class="oc-lightbox__close" aria-label="Close" @click="open = false">&#10005;</button>
45
+ </div>
46
+ <div class="oc-lightbox__track" tabindex="0" aria-label="Photos, use the arrow keys">
47
+ <figure v-for="(img, i) in images" :id="slideId(i)" :key="i" class="oc-lightbox__slide">
48
+ <div class="oc-lightbox__media">
49
+ <img v-if="img.src" :src="img.src" :alt="img.alt" />
50
+ <span v-else class="oc-media-art" role="img" :aria-label="img.alt" />
51
+ </div>
52
+ <template v-if="images.length > 1">
53
+ <a class="oc-lightbox__nav oc-lightbox__nav--prev" :href="`#${slideId(i - 1)}`" aria-label="Previous photo">&#8592;</a>
54
+ <a class="oc-lightbox__nav oc-lightbox__nav--next" :href="`#${slideId(i + 1)}`" aria-label="Next photo">&#8594;</a>
55
+ </template>
56
+ <figcaption class="oc-lightbox__caption">
57
+ <span v-if="images.length > 1" class="oc-lightbox__counter">{{ i + 1 }} / {{ images.length }}</span>
58
+ <slot name="caption" :image="img" :index="i">{{ img.caption ?? img.alt }}</slot>
59
+ </figcaption>
60
+ </figure>
61
+ </div>
62
+ </dialog>
63
+ </template>
@@ -0,0 +1,25 @@
1
+ <!-- File: packages/vue/src/components/OcLinkArrow.vue | Map: props (direction, tone, size) -> a.oc-link-arrow -->
2
+ <script setup lang="ts">
3
+ /** Text link with a moving arrow. Classes: .oc-link-arrow + --back/--external, --accent/--muted, --sm/--lg */
4
+ withDefaults(
5
+ defineProps<{
6
+ href: string
7
+ direction?: 'forward' | 'back' | 'external'
8
+ tone?: 'default' | 'accent' | 'muted'
9
+ size?: 'sm' | 'default' | 'lg'
10
+ }>(),
11
+ { direction: 'forward', tone: 'default', size: 'default' },
12
+ )
13
+ </script>
14
+
15
+ <template>
16
+ <a
17
+ :class="[
18
+ 'oc-link-arrow',
19
+ direction !== 'forward' && `oc-link-arrow--${direction}`,
20
+ tone !== 'default' && `oc-link-arrow--${tone}`,
21
+ size !== 'default' && `oc-link-arrow--${size}`,
22
+ ]"
23
+ :href="href"
24
+ ><slot /></a>
25
+ </template>