@birdycom/omniaui-vue 0.0.0-stage → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +48 -2
  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 +67 -4
  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,12 @@
1
+ <script setup lang="ts">
2
+ /** Exclusive accordion on <details name>. Put OcAccordionItem children inside; they share one group name. */
3
+ import { provide } from 'vue'
4
+ import { useUid } from '../composables/useUid'
5
+
6
+ const props = defineProps<{ name?: string }>()
7
+ provide('oc-accordion-name', props.name ?? useUid('oc-accordion'))
8
+ </script>
9
+
10
+ <template>
11
+ <div class="oc-accordion"><slot /></div>
12
+ </template>
@@ -0,0 +1,27 @@
1
+ <!-- File: packages/vue/src/components/OcAccordionAccent.vue | Map: div.oc-accordion.oc-accordion--accent (+ color classes) -> OcAccordionItem children -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Accent accordion: separate item cards with a colored start edge. Put OcAccordionItem children inside;
5
+ * they share one group name (like OcAccordion). Color one item with class "oc-accent--violet" or "oc-accordion-item--warning".
6
+ * Classes: .oc-accordion--accent, .oc-accent--*, .oc-accordion--success/--warning/--danger, .oc-accordion--flush, .oc-accordion-accent-meta
7
+ */
8
+ import { provide } from 'vue'
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ const props = defineProps<{
12
+ name?: string
13
+ /** Color preset for all items. */
14
+ accent?: 'blue' | 'cyan' | 'green' | 'orange' | 'red' | 'violet' | 'yellow'
15
+ /** Semantic color for all items. */
16
+ tone?: 'success' | 'warning' | 'danger'
17
+ flush?: boolean
18
+ }>()
19
+ // Same key as OcAccordion, so OcAccordionItem picks up the group name.
20
+ provide('oc-accordion-name', props.name ?? useUid('oc-accordion'))
21
+ </script>
22
+
23
+ <template>
24
+ <div :class="['oc-accordion', 'oc-accordion--accent', flush && 'oc-accordion--flush', accent && `oc-accent--${accent}`, tone && `oc-accordion--${tone}`]">
25
+ <slot />
26
+ </div>
27
+ </template>
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ /** One accordion section (details/summary). v-model:open; default slot = content, `title` prop or slot = trigger. */
3
+ import { inject } from 'vue'
4
+
5
+ defineProps<{ title?: string }>()
6
+ const open = defineModel<boolean>('open', { default: false })
7
+ const name = inject<string | undefined>('oc-accordion-name', undefined)
8
+
9
+ function onToggle(e: Event) {
10
+ open.value = (e.target as HTMLDetailsElement).open
11
+ }
12
+ </script>
13
+
14
+ <template>
15
+ <details class="oc-accordion-item" :name="name" :open="open" @toggle="onToggle">
16
+ <summary class="oc-accordion-trigger"><slot name="title">{{ title }}</slot></summary>
17
+ <div class="oc-accordion-content"><slot /></div>
18
+ </details>
19
+ </template>
@@ -0,0 +1,40 @@
1
+ <!-- File: packages/vue/src/components/OcAffixInput.vue | Map: props -> variant presets -> template (input group --affix with inline symbol) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Input with a symbol inside the frame. variant: currency (€), percent (%) or email (@); or own prefix / suffix (props or slots).
5
+ * Same markup as packages/ui/snippets/affix-input.html. v-model: string.
6
+ * class/style stay on the wrapper, other attributes go to the input.
7
+ */
8
+ import { computed } from 'vue'
9
+ import { useAttrsSplit } from '../composables/useAttrsSplit'
10
+
11
+ export type AffixInputKind = 'currency' | 'percent' | 'email'
12
+
13
+ defineOptions({ inheritAttrs: false })
14
+ // alignEnd defaults to undefined (not false), so the variant preset can decide.
15
+ const props = withDefaults(defineProps<{ variant?: AffixInputKind; prefix?: string; suffix?: string; alignEnd?: boolean; error?: boolean }>(), {
16
+ alignEnd: undefined,
17
+ })
18
+ const model = defineModel<string>({ default: '' })
19
+ const { root, control } = useAttrsSplit()
20
+
21
+ // Preset per variant. Email uses type="email" so :user-invalid checks the address.
22
+ const PRESETS = {
23
+ currency: { prefix: '\u20AC', suffix: undefined, end: false, input: { type: 'text', inputmode: 'decimal' } },
24
+ percent: { prefix: '%', suffix: undefined, end: false, input: { type: 'text', inputmode: 'decimal' } },
25
+ email: { prefix: '@', suffix: undefined, end: false, input: { type: 'email', autocomplete: 'email' } },
26
+ } as const
27
+
28
+ const preset = computed(() => (props.variant ? PRESETS[props.variant] : undefined))
29
+ const before = computed(() => props.prefix ?? preset.value?.prefix)
30
+ const after = computed(() => props.suffix ?? preset.value?.suffix)
31
+ const end = computed(() => props.alignEnd ?? preset.value?.end ?? false)
32
+ </script>
33
+
34
+ <template>
35
+ <div v-bind="root" :class="['oc-input-group', 'oc-input-group--affix', end && 'oc-input-group--end', error && 'oc-input-group--error']">
36
+ <span v-if="before || $slots.prefix" class="oc-input-addon" aria-hidden="true"><slot name="prefix">{{ before }}</slot></span>
37
+ <input v-bind="{ type: 'text', ...preset?.input, ...control }" v-model="model" class="oc-input" :aria-invalid="error ? 'true' : undefined" />
38
+ <span v-if="after || $slots.suffix" class="oc-input-addon" aria-hidden="true"><slot name="suffix">{{ after }}</slot></span>
39
+ </div>
40
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ /** Alert. Classes: .oc-alert--info/success/warning/danger. Default slot = description. */
3
+ withDefaults(
4
+ defineProps<{
5
+ variant?: 'info' | 'success' | 'warning' | 'danger'
6
+ title?: string
7
+ }>(),
8
+ { variant: 'info' },
9
+ )
10
+ </script>
11
+
12
+ <template>
13
+ <div :class="['oc-alert', `oc-alert--${variant}`]" role="status">
14
+ <h4 v-if="title || $slots.title" class="oc-alert-title"><slot name="title">{{ title }}</slot></h4>
15
+ <p v-if="$slots.default" class="oc-alert-description"><slot /></p>
16
+ </div>
17
+ </template>
@@ -0,0 +1,66 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Confirmation modal with a status icon. v-model:open. Emits `confirm` / `cancel` (both close the dialog).
4
+ * Slots: icon, title, default (message), footer (scoped: { close }).
5
+ * Classes: .oc-alert-dialog(--success/--error/--warning/--info/--question), .oc-alert-dialog-icon
6
+ */
7
+ import { computed, ref } from 'vue'
8
+ import { useDialog } from '../composables/useDialog'
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ const props = withDefaults(
12
+ defineProps<{
13
+ type?: 'success' | 'error' | 'warning' | 'info' | 'question'
14
+ title?: string
15
+ message?: string
16
+ confirmLabel?: string
17
+ cancelLabel?: string
18
+ /** Variant of the confirm button; defaults to destructive for warning/error. */
19
+ confirmVariant?: 'default' | 'destructive' | 'success'
20
+ }>(),
21
+ { type: 'warning', confirmLabel: 'Confirm', cancelLabel: 'Cancel' },
22
+ )
23
+ const emit = defineEmits<{ confirm: []; cancel: [] }>()
24
+ const open = defineModel<boolean>('open', { default: false })
25
+ const el = ref<HTMLDialogElement | null>(null)
26
+ const { onClose } = useDialog(open, el)
27
+ const titleId = useUid('oc-alert-dialog-title')
28
+ const textId = `${titleId}-text`
29
+
30
+ const glyphs = { success: '✓', error: '×', warning: '!', info: 'i', question: '?' } as const
31
+ const variant = computed(() => props.confirmVariant ?? (props.type === 'warning' || props.type === 'error' ? 'destructive' : 'default'))
32
+ const close = () => (open.value = false)
33
+
34
+ function confirm() {
35
+ emit('confirm')
36
+ close()
37
+ }
38
+ function cancel() {
39
+ emit('cancel')
40
+ close()
41
+ }
42
+ </script>
43
+
44
+ <template>
45
+ <dialog
46
+ ref="el"
47
+ class="oc-modal"
48
+ closedby="closerequest"
49
+ role="alertdialog"
50
+ :aria-labelledby="titleId"
51
+ :aria-describedby="textId"
52
+ @close="onClose"
53
+ >
54
+ <div :class="['oc-modal-content', 'oc-modal-content--sm', 'oc-alert-dialog', `oc-alert-dialog--${type}`]">
55
+ <span class="oc-alert-dialog-icon" aria-hidden="true"><slot name="icon">{{ glyphs[type] }}</slot></span>
56
+ <h2 :id="titleId" class="oc-modal-title"><slot name="title">{{ title }}</slot></h2>
57
+ <div :id="textId" class="oc-modal-body"><slot>{{ message }}</slot></div>
58
+ <div class="oc-modal-footer">
59
+ <slot name="footer" :close="close" :confirm="confirm" :cancel="cancel">
60
+ <button class="oc-btn oc-btn--outline" type="button" @click="cancel">{{ cancelLabel }}</button>
61
+ <button :class="['oc-btn', variant !== 'default' && `oc-btn--${variant}`]" type="button" @click="confirm">{{ confirmLabel }}</button>
62
+ </slot>
63
+ </div>
64
+ </div>
65
+ </dialog>
66
+ </template>
@@ -0,0 +1,54 @@
1
+ <!-- File: packages/vue/src/components/OcAlphaTabs.vue | Map: nav -> "All" item -> one item per letter (current / disabled) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * All + A-Z letter filter. v-model = current letter ("all" by default).
5
+ * With `href` (e.g. "?letter={letter}") the items are links; otherwise buttons that update v-model.
6
+ * Classes: nav.oc-alpha-tabs(--wrap/--sm/--plain), .oc-alpha-tabs-item(--all), aria-current, aria-disabled
7
+ */
8
+ import { computed } from 'vue'
9
+
10
+ const props = withDefaults(
11
+ defineProps<{
12
+ letters?: string[]
13
+ /** Letters with entries; the others are disabled. Default: all. */
14
+ available?: string[]
15
+ /** Link pattern; "{letter}" is replaced, e.g. "?letter={letter}". */
16
+ href?: string
17
+ allLabel?: string
18
+ wrap?: boolean
19
+ size?: 'sm'
20
+ plain?: boolean
21
+ }>(),
22
+ { letters: () => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), allLabel: 'All' },
23
+ )
24
+ const current = defineModel<string>({ default: 'all' })
25
+
26
+ const items = computed(() => [
27
+ { key: 'all', label: props.allLabel, all: true },
28
+ ...props.letters.map((l) => ({ key: l, label: l, all: false })),
29
+ ])
30
+ const isDisabled = (key: string) => key !== 'all' && props.available !== undefined && !props.available.includes(key)
31
+ const link = (key: string) => props.href?.replace('{letter}', key)
32
+ </script>
33
+
34
+ <template>
35
+ <nav :class="['oc-alpha-tabs', wrap && 'oc-alpha-tabs--wrap', size && `oc-alpha-tabs--${size}`, plain && 'oc-alpha-tabs--plain']" aria-label="Filter by letter">
36
+ <template v-for="item in items" :key="item.key">
37
+ <a
38
+ v-if="href"
39
+ :class="['oc-alpha-tabs-item', item.all && 'oc-alpha-tabs-item--all']"
40
+ :href="isDisabled(item.key) ? undefined : link(item.key)"
41
+ :aria-current="current === item.key ? 'true' : undefined"
42
+ :aria-disabled="isDisabled(item.key) ? 'true' : undefined"
43
+ >{{ item.label }}</a>
44
+ <button
45
+ v-else
46
+ type="button"
47
+ :class="['oc-alpha-tabs-item', item.all && 'oc-alpha-tabs-item--all']"
48
+ :aria-current="current === item.key ? 'true' : undefined"
49
+ :disabled="isDisabled(item.key)"
50
+ @click="current = item.key"
51
+ >{{ item.label }}</button>
52
+ </template>
53
+ </nav>
54
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Aspect-ratio box. `ratio` is a preset (square | photo | portrait | wide), a number (1.5) or a CSS ratio ("5 / 2");
4
+ * default 16 / 9. `center` centers the content. Classes: .oc-aspect(--square/--photo/--portrait/--wide/--center), --oc-aspect
5
+ */
6
+ import { computed } from 'vue'
7
+
8
+ const presets = ['square', 'photo', 'portrait', 'wide']
9
+ const props = defineProps<{ ratio?: 'square' | 'photo' | 'portrait' | 'wide' | number | string; center?: boolean }>()
10
+ const preset = computed(() => (typeof props.ratio === 'string' && presets.includes(props.ratio) ? props.ratio : undefined))
11
+ const custom = computed(() => (props.ratio !== undefined && !preset.value ? String(props.ratio) : undefined))
12
+ </script>
13
+
14
+ <template>
15
+ <div
16
+ :class="['oc-aspect', preset && `oc-aspect--${preset}`, center && 'oc-aspect--center']"
17
+ :style="custom ? { '--oc-aspect': custom } : undefined"
18
+ >
19
+ <slot />
20
+ </div>
21
+ </template>
@@ -0,0 +1,59 @@
1
+ <!-- File: packages/vue/src/components/OcAttachment.vue | Map: type / extension helpers -> props -> a[download] or div chip (icon, name, size, remove) -->
2
+ <script lang="ts">
3
+ export type AttachmentType = 'pdf' | 'doc' | 'sheet' | 'zip' | 'image'
4
+ export interface AttachmentFile {
5
+ name: string
6
+ size?: string
7
+ type?: AttachmentType
8
+ ext?: string
9
+ href?: string
10
+ image?: string
11
+ state?: 'uploading' | 'error'
12
+ progress?: number
13
+ removable?: boolean
14
+ removeLabel?: string
15
+ }
16
+ const TYPES: Record<string, AttachmentType> = {
17
+ pdf: 'pdf', doc: 'doc', docx: 'doc', odt: 'doc', rtf: 'doc', txt: 'doc', xls: 'sheet', xlsx: 'sheet', csv: 'sheet', ods: 'sheet',
18
+ zip: 'zip', rar: 'zip', '7z': 'zip', gz: 'zip', jpg: 'image', jpeg: 'image', png: 'image', gif: 'image', webp: 'image', heic: 'image', avif: 'image',
19
+ }
20
+ const extOf = (name: string) => (name.includes('.') ? name.split('.').pop()!.toLowerCase() : '')
21
+ /** Icon text and tint of a file name (Plan.xlsx -> XLS, sheet). */
22
+ export const attachmentMeta = (f: AttachmentFile) => ({
23
+ ext: f.ext ?? extOf(f.name).toUpperCase().replace(/^(DOC|XLS|PPT)X$/, '$1'),
24
+ type: f.type ?? TYPES[extOf(f.name)],
25
+ })
26
+ </script>
27
+
28
+ <script setup lang="ts">
29
+ /**
30
+ * File chip (same markup as snippets/attachment.html): icon tile by type, name, size, upload / error state and remove button.
31
+ * With href (and not removable) it is an <a download>. Emits: remove. Classes: .oc-attachment(--pdf/--doc/--sheet/--zip/--image,
32
+ * --uploading/--error) __icon __body __name __size __remove; --oc-attachment-progress while uploading.
33
+ */
34
+ import { computed } from 'vue'
35
+
36
+ const props = withDefaults(defineProps<AttachmentFile>(), { progress: 0 })
37
+ const emit = defineEmits<{ remove: [] }>()
38
+ const meta = computed(() => attachmentMeta(props))
39
+ const uploading = computed(() => props.state === 'uploading')
40
+ const link = computed(() => !!props.href && !props.removable)
41
+ </script>
42
+
43
+ <template>
44
+ <component
45
+ :is="link ? 'a' : 'div'"
46
+ :class="['oc-attachment', meta.type && `oc-attachment--${meta.type}`, state && `oc-attachment--${state}`]"
47
+ :href="link ? href : undefined"
48
+ :download="link ? '' : undefined"
49
+ :style="uploading ? `--oc-attachment-progress:${progress}%` : undefined"
50
+ >
51
+ <span class="oc-attachment__icon" aria-hidden="true"><img v-if="image" :src="image" alt="" /><template v-else>{{ meta.ext }}</template></span>
52
+ <span class="oc-attachment__body">
53
+ <span class="oc-attachment__name">{{ name }}</span>
54
+ <span v-if="uploading" class="oc-attachment__size" role="status">{{ size ?? `Uploading… ${progress}%` }}</span>
55
+ <span v-else-if="size" class="oc-attachment__size">{{ size }}</span>
56
+ </span>
57
+ <button v-if="removable" type="button" class="oc-attachment__remove" :aria-label="removeLabel ?? (uploading ? `Cancel upload of ${name}` : `Remove ${name}`)" @click="emit('remove')">&#10005;</button>
58
+ </component>
59
+ </template>
@@ -0,0 +1,13 @@
1
+ <!-- File: packages/vue/src/components/OcAttachmentImage.vue | Map: props -> a.oc-attachment-image (img or placeholder art, caption) -->
2
+ <script setup lang="ts">
3
+ /** Image preview inside a message (4 : 3, same markup as snippets/attachment.html). No src = placeholder art. Classes: .oc-attachment-image, __caption */
4
+ defineProps<{ href?: string; src?: string; alt: string; art?: number; caption?: string }>()
5
+ </script>
6
+
7
+ <template>
8
+ <a class="oc-attachment-image" :href="href">
9
+ <img v-if="src" :src="src" :alt="alt" />
10
+ <span v-else :class="['oc-media-art', art != null && `oc-media-art--${art}`]" role="img" :aria-label="alt"></span>
11
+ <span v-if="caption" class="oc-attachment-image__caption">{{ caption }}</span>
12
+ </a>
13
+ </template>
@@ -0,0 +1,31 @@
1
+ <!-- File: packages/vue/src/components/OcAttachmentList.vue | Map: props + demo files -> ul (li > chip) or div of chips -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Wrapping row of file chips (snippets/attachment.html). items = AttachmentFile[] (demo files when empty); slot default replaces them.
5
+ * stack = one per line. as = ul (default) or div. Emits: remove(file, index). Classes: .oc-attachment-list(--stack)
6
+ */
7
+ import OcAttachment, { type AttachmentFile } from './OcAttachment.vue'
8
+
9
+ withDefaults(defineProps<{ items?: AttachmentFile[]; stack?: boolean; as?: 'ul' | 'div'; label?: string }>(), {
10
+ as: 'ul',
11
+ label: 'Files in this message',
12
+ items: () => [
13
+ { name: 'Quote kitchen Dewitte v2.pdf', size: '1.2 MB', href: '#quote.pdf' },
14
+ { name: 'Measurements ground floor.xlsx', size: '86 KB', href: '#measurements.xlsx' },
15
+ { name: 'Contract addendum.docx', size: '240 KB', href: '#contract.docx' },
16
+ { name: 'Plans architect.zip', size: '14.8 MB', href: '#plans.zip' },
17
+ ],
18
+ })
19
+ const emit = defineEmits<{ remove: [file: AttachmentFile, index: number] }>()
20
+ </script>
21
+
22
+ <template>
23
+ <component :is="as" :class="['oc-attachment-list', stack && 'oc-attachment-list--stack']" :aria-label="label">
24
+ <slot>
25
+ <template v-for="(f, i) in items" :key="i">
26
+ <li v-if="as === 'ul'"><OcAttachment v-bind="f" @remove="emit('remove', f, i)" /></li>
27
+ <OcAttachment v-else v-bind="f" @remove="emit('remove', f, i)" />
28
+ </template>
29
+ </slot>
30
+ </component>
31
+ </template>
@@ -0,0 +1,14 @@
1
+ <!-- File: packages/vue/src/components/OcAttachmentThumb.vue | Map: props -> .oc-attachment-thumb (img or placeholder art, remove button) -->
2
+ <script setup lang="ts">
3
+ /** Square thumbnail of a pasted screenshot (snippets/attachment.html). removeLabel adds the remove button. Emits: remove. */
4
+ withDefaults(defineProps<{ src?: string; alt: string; art?: number; removeLabel?: string; as?: 'div' | 'span' }>(), { as: 'div' })
5
+ const emit = defineEmits<{ remove: [] }>()
6
+ </script>
7
+
8
+ <template>
9
+ <component :is="as" class="oc-attachment-thumb">
10
+ <img v-if="src" :src="src" :alt="alt" />
11
+ <span v-else :class="['oc-media-art', art != null && `oc-media-art--${art}`]" role="img" :aria-label="alt"></span>
12
+ <button v-if="removeLabel" type="button" class="oc-attachment__remove" :aria-label="removeLabel" @click="emit('remove')">&#10005;</button>
13
+ </component>
14
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ /** Avatar (initials via the default slot, or an image via `src`). Classes: .oc-avatar--sm/lg/xl */
3
+ withDefaults(
4
+ defineProps<{
5
+ size?: 'sm' | 'md' | 'lg' | 'xl'
6
+ src?: string
7
+ alt?: string
8
+ }>(),
9
+ { size: 'md', alt: '' },
10
+ )
11
+ </script>
12
+
13
+ <template>
14
+ <span :class="['oc-avatar', size !== 'md' && `oc-avatar--${size}`]">
15
+ <img v-if="src" :src="src" :alt="alt" />
16
+ <slot v-else />
17
+ </span>
18
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** Overlapping avatars. Put <OcAvatar> elements in the default slot. */
3
+ </script>
4
+
5
+ <template>
6
+ <div class="oc-avatar-group"><slot /></div>
7
+ </template>
@@ -0,0 +1,8 @@
1
+ <script setup lang="ts">
2
+ /** Outline link that names its destination (Back to Products). */
3
+ withDefaults(defineProps<{ href?: string }>(), { href: '#' })
4
+ </script>
5
+
6
+ <template>
7
+ <a class="oc-back-link" :href="href"><slot /></a>
8
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ /** Badge. Classes: .oc-badge + --secondary/--outline/--destructive/--success/--warning/--info */
3
+ withDefaults(
4
+ defineProps<{
5
+ variant?: 'default' | 'secondary' | 'outline' | 'destructive' | 'success' | 'warning' | 'info'
6
+ }>(),
7
+ { variant: 'default' },
8
+ )
9
+ </script>
10
+
11
+ <template>
12
+ <span :class="['oc-badge', variant !== 'default' && `oc-badge--${variant}`]"><slot /></span>
13
+ </template>
@@ -0,0 +1,51 @@
1
+ <!-- File: packages/vue/src/components/OcBarcodeInput.vue | Map: props + model -> template (label, digits-only field, preview figure + slot) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Barcode / EAN field with a preview. v-model: string (digits only).
5
+ * Slot `preview`: your own <svg>/<canvas> barcode; default = decorative placeholder bars.
6
+ * Same markup as packages/ui/snippets/barcode-input.html. class/style on the wrapper, other attributes on the input.
7
+ */
8
+ import { computed } from 'vue'
9
+ import { useAttrsSplit } from '../composables/useAttrsSplit'
10
+ import { useUid } from '../composables/useUid'
11
+
12
+ defineOptions({ inheritAttrs: false })
13
+ const props = withDefaults(defineProps<{ label?: string; id?: string; emptyText?: string; error?: boolean }>(), { emptyText: 'No code yet' })
14
+ const model = defineModel<string>({ default: '' })
15
+ const { root, control } = useAttrsSplit()
16
+ const auto = useUid('oc-barcode')
17
+ const inputId = computed(() => props.id ?? auto)
18
+
19
+ function onInput(e: Event) {
20
+ const input = e.target as HTMLInputElement
21
+ model.value = input.value
22
+ }
23
+ </script>
24
+
25
+ <template>
26
+ <div v-bind="root" class="oc-barcode-input">
27
+ <label v-if="label" class="oc-field-label" :for="inputId">{{ label }}</label>
28
+ <div class="oc-input-group oc-input-group--affix">
29
+ <span class="oc-input-addon" aria-hidden="true">
30
+ <svg viewBox="0 0 16 16"><path fill="currentColor" d="M1 1h1.4v14H1zm2.2 0h.7v14h-.7zm1.6 0h1.5v14H4.8zm2.4 0h.7v14H7.2zm1.6 0h.7v14H8.8zm1.5 0h1.4v14h-1.4zm2.2 0H15v14h-.9z" /></svg>
31
+ </span>
32
+ <input
33
+ v-bind="control"
34
+ :id="inputId"
35
+ class="oc-input oc-barcode-input-field"
36
+ type="text"
37
+ autocomplete="off"
38
+ spellcheck="false"
39
+ maxlength="80"
40
+ placeholder="EAN-13 or internal code"
41
+ :aria-invalid="error ? 'true' : undefined"
42
+ :value="model"
43
+ @input="onInput"
44
+ />
45
+ </div>
46
+ <figure :class="['oc-barcode-preview', !model && 'oc-barcode-preview--empty']" aria-label="Barcode preview">
47
+ <slot name="preview"><div class="oc-barcode-preview-bars" aria-hidden="true"></div></slot>
48
+ <figcaption class="oc-barcode-preview-code">{{ model || emptyText }}</figcaption>
49
+ </figure>
50
+ </div>
51
+ </template>
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ /** Breadcrumb. Pass `items` (the last one is the current page) or use the default slot. */
3
+ export interface BreadcrumbItem {
4
+ label: string
5
+ href?: string
6
+ }
7
+ withDefaults(defineProps<{ items?: BreadcrumbItem[]; label?: string }>(), {
8
+ items: () => [],
9
+ label: 'Breadcrumb',
10
+ })
11
+ </script>
12
+
13
+ <template>
14
+ <nav class="oc-breadcrumb" :aria-label="label">
15
+ <slot>
16
+ <template v-for="(item, i) in items" :key="i">
17
+ <a v-if="item.href && i < items.length - 1" class="oc-breadcrumb-item" :href="item.href">{{ item.label }}</a>
18
+ <span v-else class="oc-breadcrumb-item" aria-current="page">{{ item.label }}</span>
19
+ </template>
20
+ </slot>
21
+ </nav>
22
+ </template>
@@ -0,0 +1,33 @@
1
+ <!-- File: packages/vue/src/components/OcBrowserFrame.vue | Map: props -> figure -> bar (dots, address, actions) -> view (slot or img) -> caption -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Fake browser chrome (same markup as snippets/browser-frame.html).
5
+ * Props: url (address pill), src / alt (screenshot), caption, minimal, dark, tilt, auto (free height), ratio ("16 / 9").
6
+ * Slots: default (live content, replaces the screenshot), actions (glyphs right in the bar), caption.
7
+ * Classes: .oc-browser-frame(--minimal/--dark/--tilt/--auto), __bar, __address, __actions, __view, __caption
8
+ */
9
+ withDefaults(
10
+ defineProps<{ url?: string; src?: string; alt?: string; caption?: string; minimal?: boolean; dark?: boolean; tilt?: boolean; auto?: boolean; ratio?: string }>(),
11
+ { alt: '' },
12
+ )
13
+ </script>
14
+
15
+ <template>
16
+ <figure
17
+ :class="['oc-browser-frame', minimal && 'oc-browser-frame--minimal', dark && 'oc-browser-frame--dark', tilt && 'oc-browser-frame--tilt', auto && 'oc-browser-frame--auto']"
18
+ :style="ratio ? { '--oc-browser-frame-ratio': ratio } : undefined"
19
+ >
20
+ <div class="oc-browser-frame__bar">
21
+ <i /><i /><i />
22
+ <span v-if="url" class="oc-browser-frame__address">{{ url }}</span>
23
+ <span v-if="$slots.actions" class="oc-browser-frame__actions" aria-hidden="true"><slot name="actions" /></span>
24
+ </div>
25
+ <div class="oc-browser-frame__view">
26
+ <slot>
27
+ <img v-if="src" :src="src" :alt="alt" />
28
+ <div v-else class="oc-media-art" role="img" :aria-label="alt" />
29
+ </slot>
30
+ </div>
31
+ <figcaption v-if="caption || $slots.caption" class="oc-browser-frame__caption"><slot name="caption">{{ caption }}</slot></figcaption>
32
+ </figure>
33
+ </template>
@@ -0,0 +1,32 @@
1
+ <!-- File: packages/vue/src/components/OcBusyOverlay.vue | Map: props + model -> <dialog closedby="none"> (spinner or progress, title, text) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Modal "please wait" overlay (same markup as snippets/busy-overlay.html). v-model:open shows it while a long submit or
5
+ * upload runs; the page is inert and Esc does not close it. `progress` (0-100) swaps the spinner for a progress bar.
6
+ * Slot: default (replaces the text). Classes: .oc-busy-overlay __title __text; .oc-spinner / .oc-progress
7
+ */
8
+ import { ref } from 'vue'
9
+ import { useDialog } from '../composables/useDialog'
10
+ import { useUid } from '../composables/useUid'
11
+ import OcProgress from './OcProgress.vue'
12
+
13
+ const props = withDefaults(defineProps<{ title?: string; text?: string; progress?: number; label?: string; id?: string }>(), {
14
+ title: 'Saving…',
15
+ text: 'The photos are being processed. This can take a minute; please keep this page open.',
16
+ label: 'Busy',
17
+ })
18
+ const open = defineModel<boolean>('open', { default: false })
19
+ const el = ref<HTMLDialogElement | null>(null)
20
+ const { onClose } = useDialog(open, el)
21
+ const auto = useUid('oc-busy-overlay')
22
+ const base = props.id ?? auto
23
+ </script>
24
+
25
+ <template>
26
+ <dialog :id="base" ref="el" class="oc-busy-overlay" closedby="none" :aria-labelledby="`${base}-title`" :aria-describedby="`${base}-text`" @close="onClose">
27
+ <span v-if="progress == null" class="oc-spinner" role="status" :aria-label="label"></span>
28
+ <OcProgress v-else :value="progress" :label="label" />
29
+ <h2 :id="`${base}-title`" class="oc-busy-overlay__title">{{ title }}</h2>
30
+ <p :id="`${base}-text`" class="oc-busy-overlay__text"><slot>{{ text }}</slot></p>
31
+ </dialog>
32
+ </template>
@@ -0,0 +1,47 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Button. Renders <a> when `href` is set, otherwise <button>.
4
+ * Classes: .oc-btn + --secondary/--outline/--ghost/--link/--destructive/--success/--gradient/--glass,
5
+ * --xs/--sm/--lg, --icon, --pill
6
+ */
7
+ withDefaults(
8
+ defineProps<{
9
+ variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'link' | 'destructive' | 'success' | 'gradient' | 'glass'
10
+ size?: 'xs' | 'sm' | 'md' | 'lg'
11
+ icon?: boolean
12
+ pill?: boolean
13
+ href?: string
14
+ type?: 'button' | 'submit' | 'reset'
15
+ }>(),
16
+ { variant: 'default', size: 'md', type: 'button' },
17
+ )
18
+ </script>
19
+
20
+ <template>
21
+ <a
22
+ v-if="href"
23
+ :href="href"
24
+ :class="[
25
+ 'oc-btn',
26
+ variant !== 'default' && `oc-btn--${variant}`,
27
+ size !== 'md' && `oc-btn--${size}`,
28
+ icon && 'oc-btn--icon',
29
+ pill && 'oc-btn--pill',
30
+ ]"
31
+ >
32
+ <slot />
33
+ </a>
34
+ <button
35
+ v-else
36
+ :type="type"
37
+ :class="[
38
+ 'oc-btn',
39
+ variant !== 'default' && `oc-btn--${variant}`,
40
+ size !== 'md' && `oc-btn--${size}`,
41
+ icon && 'oc-btn--icon',
42
+ pill && 'oc-btn--pill',
43
+ ]"
44
+ >
45
+ <slot />
46
+ </button>
47
+ </template>
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ /** Joined buttons with shared borders. `label` becomes aria-label. Put OcButton (usually variant outline) and OcButtonGroupText inside. Classes: .oc-btn-group(--vertical) */
3
+ defineProps<{ vertical?: boolean; label?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <div :class="['oc-btn-group', vertical && 'oc-btn-group--vertical']" role="group" :aria-label="label">
8
+ <slot />
9
+ </div>
10
+ </template>