@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,119 @@
1
+ <!-- File: packages/vue/src/components/OcCookieConsent.vue | Map: props -> storage helpers -> reopen button -> popover (title, text, categories, actions) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Cookie banner on popover="manual" (same markup as snippets/cookie-consent.html). Like the snippet script it shows itself
5
+ * when no choice is stored, saves { necessary, <categories>, date } in localStorage and fires "oc-consent" on document.
6
+ * Emits: consent (the choice, also on load when one is stored). Slot: text (replaces the paragraph content).
7
+ * Classes: .oc-cookie-consent(--bar) __title __text __prefs __category __category-name __category-text __actions
8
+ */
9
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
10
+
11
+ export interface CookieCategory {
12
+ name: string
13
+ label: string
14
+ text?: string
15
+ required?: boolean
16
+ }
17
+ export type ConsentChoice = { necessary: boolean; date: string } & Record<string, boolean | string>
18
+
19
+ const props = withDefaults(
20
+ defineProps<{
21
+ categories?: CookieCategory[]
22
+ title?: string
23
+ policyHref?: string
24
+ customizeLabel?: string
25
+ necessaryLabel?: string
26
+ selectedLabel?: string
27
+ allLabel?: string
28
+ /** Text of the "Cookie settings" button; empty string hides it. */
29
+ openLabel?: string
30
+ bar?: boolean
31
+ manual?: boolean
32
+ storageKey?: string
33
+ id?: string
34
+ }>(),
35
+ {
36
+ categories: () => [
37
+ { name: 'necessary', label: 'Necessary', text: 'Session, security and your cookie choice. Always on.', required: true },
38
+ { name: 'statistics', label: 'Statistics', text: 'Anonymous visit counts.' },
39
+ { name: 'marketing', label: 'Marketing', text: 'Embedded videos and ads that track you.' },
40
+ ],
41
+ title: 'We use cookies',
42
+ policyHref: '#cookie-policy',
43
+ customizeLabel: 'Customize',
44
+ necessaryLabel: 'Only necessary',
45
+ selectedLabel: 'Save choice',
46
+ allLabel: 'Accept all',
47
+ openLabel: 'Cookie settings',
48
+ storageKey: 'oc-consent',
49
+ id: 'oc-cookie-consent',
50
+ },
51
+ )
52
+ const emit = defineEmits<{ consent: [choice: ConsentChoice] }>()
53
+ defineOptions({ inheritAttrs: false })
54
+ const box = ref<HTMLElement | null>(null)
55
+
56
+ const read = (): ConsentChoice | null => {
57
+ try { return JSON.parse(localStorage.getItem(props.storageKey) ?? 'null') } catch { return null }
58
+ }
59
+ const inputs = () => Array.from(box.value?.querySelectorAll<HTMLInputElement>('input[name]') ?? [])
60
+ function tell(choice: ConsentChoice) {
61
+ document.dispatchEvent(new CustomEvent('oc-consent', { detail: choice }))
62
+ emit('consent', choice)
63
+ }
64
+ // Any [data-oc-consent-open] (also outside this component) opens the banner with the stored choice.
65
+ function reopen(e: Event) {
66
+ if (!(e.target as Element | null)?.closest?.('[data-oc-consent-open]')) return
67
+ const choice = read()
68
+ for (const i of inputs()) if (!i.disabled) i.checked = !!choice?.[i.name]
69
+ box.value?.showPopover?.()
70
+ }
71
+ function choose(e: MouseEvent) {
72
+ const mode = (e.target as HTMLElement).closest<HTMLElement>('[data-oc-consent]')?.dataset.ocConsent
73
+ if (!mode) return
74
+ const choice: ConsentChoice = { necessary: true, date: new Date().toISOString() }
75
+ for (const i of inputs()) if (!i.disabled) choice[i.name] = mode === 'all' || (mode === 'selected' && i.checked)
76
+ try { localStorage.setItem(props.storageKey, JSON.stringify(choice)) } catch { /* storage blocked */ }
77
+ box.value?.hidePopover?.()
78
+ tell(choice)
79
+ }
80
+ onMounted(() => {
81
+ const stored = read()
82
+ if (stored) tell(stored)
83
+ else if (!props.manual) box.value?.showPopover?.()
84
+ document.addEventListener('click', reopen)
85
+ })
86
+ onBeforeUnmount(() => document.removeEventListener('click', reopen))
87
+ </script>
88
+
89
+ <template>
90
+ <button v-if="openLabel" type="button" class="oc-btn oc-btn--outline oc-btn--sm" data-oc-consent-open>{{ openLabel }}</button>
91
+ <aside
92
+ :id="id"
93
+ ref="box"
94
+ v-bind="$attrs"
95
+ :class="['oc-cookie-consent', bar && 'oc-cookie-consent--bar']"
96
+ popover="manual"
97
+ :data-oc-consent-manual="manual ? '' : undefined"
98
+ :aria-labelledby="`${id}-title`"
99
+ @click="choose"
100
+ >
101
+ <h2 :id="`${id}-title`" class="oc-cookie-consent__title"><span aria-hidden="true">&#127850;</span> {{ title }}</h2>
102
+ <p class="oc-cookie-consent__text">
103
+ <slot name="text">Necessary cookies keep the site working. With your permission we also measure visits to improve the site. Read the <a :href="policyHref">cookie policy</a>.</slot>
104
+ </p>
105
+ <details class="oc-cookie-consent__prefs">
106
+ <summary>{{ customizeLabel }}</summary>
107
+ <div v-for="c in categories" :key="c.name" class="oc-cookie-consent__category">
108
+ <span class="oc-cookie-consent__category-name">{{ c.label }}</span>
109
+ <span v-if="c.text" class="oc-cookie-consent__category-text">{{ c.text }}</span>
110
+ <label class="oc-switch"><input type="checkbox" role="switch" :name="c.name" :checked="c.required" :disabled="c.required" :aria-label="`${c.label} cookies`" /><span class="oc-switch-track"></span></label>
111
+ </div>
112
+ </details>
113
+ <div class="oc-cookie-consent__actions">
114
+ <button type="button" class="oc-btn oc-btn--outline" data-oc-consent="necessary">{{ necessaryLabel }}</button>
115
+ <button type="button" class="oc-btn oc-btn--secondary" data-oc-consent="selected">{{ selectedLabel }}</button>
116
+ <button type="button" class="oc-btn" data-oc-consent="all">{{ allLabel }}</button>
117
+ </div>
118
+ </aside>
119
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Read-only monospace value with a copy button. Copies via navigator.clipboard and
4
+ * adds .is-copied for 2 seconds. Emits `copy` with the value.
5
+ */
6
+ import { onBeforeUnmount, ref } from 'vue'
7
+
8
+ const props = withDefaults(
9
+ defineProps<{
10
+ value: string
11
+ label?: string
12
+ buttonLabel?: string
13
+ }>(),
14
+ { label: 'Value', buttonLabel: 'Copy' },
15
+ )
16
+ const emit = defineEmits<{ copy: [value: string] }>()
17
+
18
+ const copied = ref(false)
19
+ let timer: ReturnType<typeof setTimeout> | undefined
20
+
21
+ async function copy() {
22
+ await navigator.clipboard.writeText(props.value)
23
+ copied.value = true
24
+ emit('copy', props.value)
25
+ clearTimeout(timer)
26
+ timer = setTimeout(() => (copied.value = false), 2000)
27
+ }
28
+
29
+ onBeforeUnmount(() => clearTimeout(timer))
30
+ </script>
31
+
32
+ <template>
33
+ <div class="oc-copy-field">
34
+ <input class="oc-copy-field-value" type="text" readonly :value="value" :aria-label="label" />
35
+ <button :class="['oc-copy-field-button', copied && 'is-copied']" type="button" @click="copy">{{ buttonLabel }}</button>
36
+ </div>
37
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ /** Animated number (@property). Starts when scrolled into view unless `onView` is false. */
3
+ import { computed } from 'vue'
4
+
5
+ const props = withDefaults(defineProps<{ to: number; suffix?: string; onView?: boolean }>(), { onView: true })
6
+ const style = computed(() => {
7
+ const s: Record<string, string> = { '--oc-counter-to': String(props.to) }
8
+ if (props.suffix) s['--oc-counter-suffix'] = `'${props.suffix}'`
9
+ return s
10
+ })
11
+ </script>
12
+
13
+ <template>
14
+ <strong :class="['oc-counter', onView && 'oc-counter--on-view']" :style="style"></strong>
15
+ </template>
@@ -0,0 +1,144 @@
1
+ <!-- File: packages/vue/src/components/OcDataTable.vue | Map: props -> markup (toolbar, table, footer) -> bind the list-table script on mount -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Korrekt / OmniaDesk list table. Same markup as packages/ui/snippets/data-table.html.
5
+ * Search, sort, pages, columns, resize, drag and bulk actions come from data-table.js.
6
+ * Listen on the root for oc-datatable-bulk, oc-datatable-reorder, oc-datatable-search, oc-datatable-import.
7
+ */
8
+ import { onMounted, useTemplateRef } from 'vue'
9
+ import { bindDataTable } from '../../../ui/src/data-table.js'
10
+
11
+ export interface DataTableColumn {
12
+ key: string
13
+ header: string
14
+ numeric?: boolean
15
+ sortable?: boolean
16
+ hideable?: boolean
17
+ defaultHidden?: boolean
18
+ }
19
+ export interface DataTableRow {
20
+ key: string
21
+ status?: 'active' | 'deleted' | 'archived'
22
+ cells: Record<string, string>
23
+ values?: Record<string, string>
24
+ href?: string
25
+ }
26
+
27
+ const props = withDefaults(
28
+ defineProps<{
29
+ tableId?: string
30
+ title?: string
31
+ columns: DataTableColumn[]
32
+ rows: DataTableRow[]
33
+ pageSize?: number
34
+ searchPlaceholder?: string
35
+ selectable?: boolean
36
+ draggable?: boolean
37
+ filters?: boolean
38
+ live?: boolean
39
+ }>(),
40
+ { title: 'List', pageSize: 15, searchPlaceholder: 'Search...', selectable: true, draggable: true, filters: true, live: false },
41
+ )
42
+
43
+ const root = useTemplateRef<HTMLElement>('root')
44
+ const sizes = [...new Set([10, 15, 20, 50, 100, props.pageSize])].sort((a, b) => a - b)
45
+ const lead = (props.selectable ? 1 : 0) + (props.draggable ? 1 : 0)
46
+ const id = props.tableId || `oc-dt-${Math.random().toString(36).slice(2, 8)}`
47
+
48
+ onMounted(() => {
49
+ if (root.value) bindDataTable(root.value)
50
+ })
51
+ </script>
52
+
53
+ <template>
54
+ <div ref="root" class="oc-data-table oc-column-menu-scope" :id="id" :data-page-size="pageSize" :data-oc-live="live ? 'true' : undefined">
55
+ <div class="oc-data-table-toolbar">
56
+ <div class="oc-data-table-heading">
57
+ <span class="oc-data-table-title">{{ title }}</span>
58
+ <button class="oc-btn oc-btn--outline oc-btn--icon oc-btn--sm" type="button" :popovertarget="`${id}-menu`" aria-label="Table actions">⚙</button>
59
+ <div class="oc-dropdown-menu" :id="`${id}-menu`" popover>
60
+ <button class="oc-dropdown-item" type="button" data-oc-export>Export CSV</button>
61
+ <button class="oc-dropdown-item" type="button" data-oc-import>Import CSV</button>
62
+ <input class="oc-data-table-file" type="file" accept=".csv,text/csv" data-oc-file>
63
+ <div class="oc-dropdown-separator"></div>
64
+ <button class="oc-dropdown-item" type="button" data-oc-density="comfortable">Comfortable rows</button>
65
+ <button class="oc-dropdown-item" type="button" data-oc-density="compact">Compact rows</button>
66
+ <button class="oc-dropdown-item" type="button" data-oc-reset-widths>Reset column widths</button>
67
+ </div>
68
+ </div>
69
+ <input class="oc-input oc-data-table-search" type="search" :placeholder="searchPlaceholder" :aria-label="`Search ${title}`">
70
+ <div v-if="filters" class="oc-filter-pills" role="group" aria-label="Trash filter">
71
+ <button class="oc-filter-pill" type="button" data-oc-filter="active" aria-current="true">Active only</button>
72
+ <button class="oc-filter-pill" type="button" data-oc-filter="all">Including trash</button>
73
+ <button class="oc-filter-pill" type="button" data-oc-filter="deleted">Trash only</button>
74
+ <button class="oc-filter-pill" type="button" data-oc-filter="archived">Archive only</button>
75
+ </div>
76
+ <div class="oc-data-table-view" role="group" aria-label="View">
77
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-view="table" aria-pressed="true">Table</button>
78
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-view="grid">Cards</button>
79
+ </div>
80
+ <p class="oc-data-table-sort-summary" data-oc-sort-summary role="status"></p>
81
+ </div>
82
+ <div class="oc-table-toolbar">
83
+ <span class="oc-table-toolbar-spacer"></span>
84
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" :popovertarget="`${id}-columns`">Columns</button>
85
+ </div>
86
+ <div class="oc-column-menu" :id="`${id}-columns`" popover>
87
+ <p class="oc-column-menu-title">Visible columns</p>
88
+ <form class="oc-column-menu-list">
89
+ <template v-for="(col, index) in columns" :key="col.key">
90
+ <label v-if="col.hideable !== false" class="oc-column-menu-item">
91
+ <input type="checkbox" :data-col="lead + index + 1" :checked="!col.defaultHidden"> {{ col.header }}
92
+ </label>
93
+ </template>
94
+ </form>
95
+ </div>
96
+ <div class="oc-data-table-bulk" hidden>
97
+ <span data-oc-selected-count>0 selected</span>
98
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="export">Export selection</button>
99
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="duplicate">Duplicate</button>
100
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="archive">Move to trash</button>
101
+ <button class="oc-btn oc-btn--outline oc-btn--sm" type="button" data-oc-bulk="restore">Restore</button>
102
+ <button class="oc-btn oc-btn--destructive oc-btn--sm" type="button" data-oc-bulk="delete">Delete permanently</button>
103
+ <button class="oc-btn oc-btn--ghost oc-btn--sm" type="button" data-oc-bulk="clear">Clear</button>
104
+ </div>
105
+ <div class="oc-data-table-frame">
106
+ <div class="oc-data-table-scroll">
107
+ <table class="oc-table oc-data-table-table">
108
+ <thead>
109
+ <tr>
110
+ <th v-if="selectable" data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select-all aria-label="Select all"></th>
111
+ <th v-if="draggable" data-oc-col="order"><span class="oc-visually-hidden">Order</span></th>
112
+ <th v-for="col in columns" :key="col.key" :data-oc-col="col.key" :data-oc-sort="col.numeric ? 'numeric' : 'text'" :data-numeric="col.numeric ? '' : undefined">
113
+ <span class="oc-data-table-th">
114
+ <button v-if="col.sortable !== false" class="oc-table-sort" type="button">{{ col.header }}</button>
115
+ <template v-else>{{ col.header }}</template>
116
+ <span class="oc-data-table-resize" role="separator" aria-orientation="vertical" :aria-label="`Resize ${col.header}`"></span>
117
+ </span>
118
+ </th>
119
+ <th data-oc-col="actions"><span class="oc-visually-hidden">Actions</span></th>
120
+ </tr>
121
+ </thead>
122
+ <tbody>
123
+ <tr v-for="row in rows" :key="row.key" data-oc-row :data-oc-key="row.key" :data-oc-status="row.status || 'active'" :data-oc-href="row.href">
124
+ <td v-if="selectable" data-oc-col="select"><input class="oc-checkbox" type="checkbox" data-oc-select :aria-label="`Select ${row.cells.name || row.key}`"></td>
125
+ <td v-if="draggable" data-oc-col="order" class="oc-sortable-row-grip-cell"><button class="oc-sortable-row-grip" type="button" :aria-label="`Move ${row.cells.name || row.key}`"></button></td>
126
+ <td v-for="col in columns" :key="col.key" :data-oc-col="col.key" :data-numeric="col.numeric ? '' : undefined" :data-oc-value="row.values?.[col.key]">{{ row.cells[col.key] ?? '' }}</td>
127
+ <td data-oc-col="actions" class="oc-table-actions"><button class="oc-table-row-action" type="button">Edit</button></td>
128
+ </tr>
129
+ </tbody>
130
+ </table>
131
+ </div>
132
+ <p class="oc-data-table-empty" hidden>No results</p>
133
+ </div>
134
+ <div class="oc-data-table-footer">
135
+ <p class="oc-data-table-summary" data-oc-summary></p>
136
+ <label class="oc-data-table-per-page">Rows per page
137
+ <select class="oc-select" data-oc-page-size aria-label="Rows per page">
138
+ <option v-for="n in sizes" :key="n" :value="n" :selected="n === pageSize">{{ n }}</option>
139
+ </select>
140
+ </label>
141
+ <nav class="oc-data-table-pager" data-oc-pager aria-label="Pagination"></nav>
142
+ </div>
143
+ </div>
144
+ </template>
@@ -0,0 +1,53 @@
1
+ <!-- File: packages/vue/src/components/OcDecimalInput.vue | Map: props + model -> locale helpers (parse / format) -> template (field, optional unit frame) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Locale decimal field (1.234,56). v-model: number | null. Formats on blur with Intl.NumberFormat.
5
+ * Same markup as packages/ui/snippets/decimal-input.html. All attributes (also class) go to the input.
6
+ */
7
+ import { ref, watch } from 'vue'
8
+
9
+ defineOptions({ inheritAttrs: false })
10
+ const props = withDefaults(defineProps<{ locale?: string; decimals?: number; unit?: string; alignStart?: boolean; error?: boolean }>(), {
11
+ locale: 'nl-BE',
12
+ decimals: 2,
13
+ })
14
+ const model = defineModel<number | null>({ default: null })
15
+
16
+ /** Group and decimal separator of the locale, e.g. nl-BE -> "." and ",". */
17
+ function separators() {
18
+ const parts = new Intl.NumberFormat(props.locale).formatToParts(1234.5)
19
+ return { group: parts.find((p) => p.type === 'group')?.value ?? ',', decimal: parts.find((p) => p.type === 'decimal')?.value ?? '.' }
20
+ }
21
+ function parse(text: string): number | null {
22
+ const { group, decimal } = separators()
23
+ const clean = text.trim().split(group).join('').replace(decimal, '.').replace(/\s/g, '')
24
+ const n = Number(clean)
25
+ return clean && Number.isFinite(n) ? n : null
26
+ }
27
+ function format(n: number | null): string {
28
+ return n == null ? '' : new Intl.NumberFormat(props.locale, { minimumFractionDigits: props.decimals, maximumFractionDigits: props.decimals }).format(n)
29
+ }
30
+
31
+ const text = ref(format(model.value))
32
+ const focused = ref(false)
33
+ // Show outside changes, but never while the user is typing.
34
+ watch(model, (n) => { if (!focused.value) text.value = format(n) })
35
+
36
+ function onInput(e: Event) {
37
+ text.value = (e.target as HTMLInputElement).value
38
+ model.value = parse(text.value)
39
+ }
40
+ function onBlur() {
41
+ focused.value = false
42
+ const n = parse(text.value)
43
+ if (n != null || !text.value.trim()) text.value = format(n)
44
+ }
45
+ </script>
46
+
47
+ <template>
48
+ <div v-if="unit" class="oc-decimal-field">
49
+ <input v-bind="$attrs" :class="['oc-input', 'oc-decimal-input', alignStart && 'oc-decimal-input--start']" type="text" inputmode="decimal" :aria-invalid="error ? 'true' : undefined" :value="text" @focus="focused = true" @input="onInput" @blur="onBlur" />
50
+ <span class="oc-decimal-field-unit">{{ unit }}</span>
51
+ </div>
52
+ <input v-else v-bind="$attrs" :class="['oc-input', 'oc-decimal-input', alignStart && 'oc-decimal-input--start']" type="text" inputmode="decimal" :aria-invalid="error ? 'true' : undefined" :value="text" @focus="focused = true" @input="onInput" @blur="onBlur" />
53
+ </template>
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Label / value rows in a panel (dl). Pass `rows`, or put your own .oc-dl-row elements in the default slot.
4
+ * Slots: title, description, default (rows), footer.
5
+ */
6
+ export interface DefinitionRow {
7
+ term: string
8
+ detail: string
9
+ }
10
+ withDefaults(
11
+ defineProps<{
12
+ title?: string
13
+ description?: string
14
+ rows?: DefinitionRow[]
15
+ label?: string
16
+ }>(),
17
+ { rows: () => [] },
18
+ )
19
+ </script>
20
+
21
+ <template>
22
+ <div class="oc-dl-panel" role="region" :aria-label="label ?? title">
23
+ <h3 v-if="title || $slots.title" class="oc-dl-title"><slot name="title">{{ title }}</slot></h3>
24
+ <p v-if="description || $slots.description" class="oc-dl-description"><slot name="description">{{ description }}</slot></p>
25
+ <dl class="oc-dl">
26
+ <slot>
27
+ <div v-for="(row, i) in rows" :key="i" class="oc-dl-row">
28
+ <dt class="oc-dl-term">{{ row.term }}</dt>
29
+ <dd class="oc-dl-detail">{{ row.detail }}</dd>
30
+ </div>
31
+ </slot>
32
+ </dl>
33
+ <div v-if="$slots.footer" class="oc-dl-footer"><slot name="footer" /></div>
34
+ </div>
35
+ </template>
@@ -0,0 +1,79 @@
1
+ <!-- File: packages/vue/src/components/OcDocViewer.vue | Map: props + demo items -> grid of cards (bar, frame) -> one full-screen <dialog> per card -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * PDF, video or image cards with a full-screen view (same markup as snippets/doc-viewer.html). No JavaScript:
5
+ * the buttons open the dialog with invoker commands (command="show-modal" commandfor), closedby="any" closes it.
6
+ * items: { label, meta?, src?, type?: pdf|video|image, id?, alt?, art?, download?, open?: bar|frame, fullscreen? }[]
7
+ * Classes: .oc-doc-viewer-grid, .oc-doc-viewer(--video/--image) __bar __label __meta __expand __frame __open;
8
+ * .oc-doc-viewer-dialog(--video) __bar __title __actions __close __body
9
+ */
10
+ import { useUid } from '../composables/useUid'
11
+
12
+ export interface DocViewerItem {
13
+ label: string
14
+ meta?: string
15
+ src?: string
16
+ type?: 'pdf' | 'video' | 'image'
17
+ id?: string
18
+ alt?: string
19
+ art?: number
20
+ download?: string
21
+ open?: 'bar' | 'frame'
22
+ fullscreen?: boolean
23
+ }
24
+ const props = withDefaults(
25
+ defineProps<{ items?: DocViewerItem[]; openText?: string; downloadText?: string; idPrefix?: string }>(),
26
+ {
27
+ items: () => [
28
+ { label: 'Brochure 2026', meta: 'PDF · 2.4 MB', alt: 'First page of Brochure 2026', art: 2, download: '#brochure.pdf' },
29
+ { label: 'Site visit', meta: '1:42', type: 'video', alt: 'Video still: site visit', art: 5 },
30
+ ],
31
+ openText: 'Click for full screen',
32
+ downloadText: 'Download',
33
+ },
34
+ )
35
+ defineOptions({ inheritAttrs: false })
36
+ const auto = useUid('oc-doc-viewer')
37
+ const idOf = (doc: DocViewerItem, i: number) => doc.id ?? `${props.idPrefix ?? auto}-${i + 1}`
38
+ const full = (doc: DocViewerItem) => doc.fullscreen !== false
39
+ const inFrame = (doc: DocViewerItem) => full(doc) && (doc.open ?? (doc.type === 'video' ? 'frame' : 'bar')) === 'frame'
40
+ const art = (doc: DocViewerItem) => ['oc-media-art', doc.art != null && `oc-media-art--${doc.art}`]
41
+ const dialogAlt = (doc: DocViewerItem) => (doc.type === 'video' ? `${doc.label} video` : doc.label)
42
+ </script>
43
+
44
+ <template>
45
+ <div class="oc-doc-viewer-grid" v-bind="$attrs">
46
+ <figure v-for="(doc, i) in items" :key="i" :class="['oc-doc-viewer', doc.type === 'video' && 'oc-doc-viewer--video', doc.type === 'image' && 'oc-doc-viewer--image']">
47
+ <figcaption class="oc-doc-viewer__bar">
48
+ <span class="oc-doc-viewer__label">{{ doc.label }}</span>
49
+ <span v-if="doc.meta" class="oc-doc-viewer__meta">{{ doc.meta }}</span>
50
+ <button v-if="full(doc) && !inFrame(doc)" type="button" class="oc-doc-viewer__expand" command="show-modal" :commandfor="idOf(doc, i)" :aria-label="`Open ${doc.label} full screen`">&#10530;</button>
51
+ </figcaption>
52
+ <div class="oc-doc-viewer__frame">
53
+ <div v-if="!doc.src" :class="art(doc)" role="img" :aria-label="doc.alt ?? doc.label"></div>
54
+ <video v-else-if="doc.type === 'video'" :src="doc.src" controls preload="metadata" :aria-label="doc.alt ?? doc.label"></video>
55
+ <img v-else-if="doc.type === 'image'" :src="doc.src" :alt="doc.alt ?? doc.label" />
56
+ <iframe v-else :src="`${doc.src}#toolbar=0&view=FitH`" :title="doc.alt ?? doc.label" loading="lazy"></iframe>
57
+ <button v-if="inFrame(doc)" type="button" class="oc-doc-viewer__open" command="show-modal" :commandfor="idOf(doc, i)">{{ openText }}</button>
58
+ </div>
59
+ </figure>
60
+ </div>
61
+ <template v-for="(doc, i) in items" :key="i">
62
+ <dialog v-if="full(doc)" :id="idOf(doc, i)" :class="['oc-doc-viewer-dialog', doc.type === 'video' && 'oc-doc-viewer-dialog--video']" closedby="any" :aria-labelledby="`${idOf(doc, i)}-title`">
63
+ <div class="oc-doc-viewer-dialog__bar">
64
+ <h2 :id="`${idOf(doc, i)}-title`" class="oc-doc-viewer-dialog__title">{{ doc.label }}</h2>
65
+ <div v-if="doc.download" class="oc-doc-viewer-dialog__actions">
66
+ <a class="oc-btn oc-btn--outline oc-btn--sm" :href="doc.download" download>{{ downloadText }}</a>
67
+ <button type="button" class="oc-doc-viewer-dialog__close" command="close" :commandfor="idOf(doc, i)" aria-label="Close">&#10005;</button>
68
+ </div>
69
+ <button v-else type="button" class="oc-doc-viewer-dialog__close" command="close" :commandfor="idOf(doc, i)" aria-label="Close">&#10005;</button>
70
+ </div>
71
+ <div class="oc-doc-viewer-dialog__body">
72
+ <div v-if="!doc.src" :class="art(doc)" role="img" :aria-label="dialogAlt(doc)"></div>
73
+ <video v-else-if="doc.type === 'video'" :src="doc.src" controls preload="metadata" :aria-label="dialogAlt(doc)"></video>
74
+ <img v-else-if="doc.type === 'image'" :src="doc.src" :alt="dialogAlt(doc)" />
75
+ <iframe v-else :src="`${doc.src}#toolbar=0&view=FitH`" :title="dialogAlt(doc)" loading="lazy"></iframe>
76
+ </div>
77
+ </dialog>
78
+ </template>
79
+ </template>
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Dropdown menu on the popover attribute + anchor positioning. The trigger is the `trigger` slot
4
+ * (scoped: { id }) or a default outline button showing `label`. Default slot = menu content
5
+ * (OcDropdownLabel / OcDropdownItem / OcDropdownSeparator). Attributes land on the menu element.
6
+ */
7
+ import { useAttrs } from 'vue'
8
+ import { useUid } from '../composables/useUid'
9
+
10
+ defineOptions({ inheritAttrs: false })
11
+ defineProps<{ label?: string }>()
12
+ const attrs = useAttrs()
13
+ const id = (attrs.id as string | undefined) ?? useUid('oc-menu')
14
+ </script>
15
+
16
+ <template>
17
+ <slot name="trigger" :id="id">
18
+ <button class="oc-btn oc-btn--outline" type="button" :popovertarget="id">{{ label }}</button>
19
+ </slot>
20
+ <div v-bind="attrs" :id="id" class="oc-dropdown-menu" popover>
21
+ <slot />
22
+ </div>
23
+ </template>
@@ -0,0 +1,9 @@
1
+ <script setup lang="ts">
2
+ /** Menu item: <a> with `href`, otherwise <button>. */
3
+ defineProps<{ href?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <a v-if="href" class="oc-dropdown-item" :href="href"><slot /></a>
8
+ <button v-else class="oc-dropdown-item" type="button"><slot /></button>
9
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** Heading inside a dropdown menu. */
3
+ </script>
4
+
5
+ <template>
6
+ <div class="oc-dropdown-label"><slot /></div>
7
+ </template>
@@ -0,0 +1,7 @@
1
+ <script setup lang="ts">
2
+ /** Divider inside a dropdown menu. */
3
+ </script>
4
+
5
+ <template>
6
+ <div class="oc-dropdown-separator"></div>
7
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * File upload target: a label around a real file input. v-model: File[].
4
+ * .is-dragover is toggled while dragging over. Slots: icon, default (text), hint.
5
+ */
6
+ import { ref } from 'vue'
7
+ import { useAttrsSplit } from '../composables/useAttrsSplit'
8
+
9
+ defineOptions({ inheritAttrs: false })
10
+ defineProps<{ accept?: string; multiple?: boolean; disabled?: boolean; hint?: string }>()
11
+ const model = defineModel<File[]>({ default: () => [] })
12
+ const { root, control } = useAttrsSplit()
13
+ const dragover = ref(false)
14
+
15
+ function onChange(e: Event) {
16
+ model.value = Array.from((e.target as HTMLInputElement).files ?? [])
17
+ }
18
+ function onDrop() {
19
+ dragover.value = false
20
+ }
21
+ </script>
22
+
23
+ <template>
24
+ <label
25
+ v-bind="root"
26
+ :class="['oc-dropzone', dragover && 'is-dragover']"
27
+ @dragover.prevent="dragover = true"
28
+ @dragleave="dragover = false"
29
+ @drop="onDrop"
30
+ >
31
+ <input v-bind="control" type="file" :accept="accept" :multiple="multiple" :disabled="disabled" @change="onChange" />
32
+ <span v-if="$slots.icon" class="oc-dropzone-icon" aria-hidden="true"><slot name="icon" /></span>
33
+ <span><slot /></span>
34
+ <span v-if="hint || $slots.hint" class="oc-dropzone-hint"><slot name="hint">{{ hint }}</slot></span>
35
+ </label>
36
+ </template>
@@ -0,0 +1,45 @@
1
+ <!-- File: packages/vue/src/components/OcEmojiPicker.vue | Map: props + emit -> trigger button -> popover panel -> groups (label + grid) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Emoji picker on the popover attribute (same markup as snippets/emoji-picker.html).
5
+ * Props: groups ({ label?, emojis[] }[]), inline (always visible, no popover), triggerLabel, label.
6
+ * Emits: select(emoji) and then closes the popover. Slot: trigger (button content, default 🙂).
7
+ * Classes: .oc-emoji-picker(--inline), __trigger, __label, __grid, __item
8
+ */
9
+ import { useUid } from '../composables/useUid'
10
+
11
+ withDefaults(
12
+ defineProps<{ groups?: { label?: string; emojis: string[] }[]; inline?: boolean; triggerLabel?: string; label?: string }>(),
13
+ {
14
+ groups: () => [
15
+ { label: 'Smileys', emojis: ['😀', '😃', '😄', '😁', '😂', '🙂', '😉', '😍', '🤔', '😎', '😢', '😴', '😯', '🥳', '😤', '🤗'] },
16
+ { label: 'Gestures', emojis: ['👍', '👎', '👏', '🙌', '👋', '🙏', '✌️', '💪'] },
17
+ { label: 'Objects', emojis: ['❤️', '⭐', '🔥', '🎉', '✅', '🚀', '💡', '☕'] },
18
+ ],
19
+ triggerLabel: 'Insert emoji',
20
+ label: 'Emoji',
21
+ },
22
+ )
23
+ const emit = defineEmits<{ select: [emoji: string] }>()
24
+ const id = useUid('oc-emoji')
25
+
26
+ function pick(e: MouseEvent, emoji: string) {
27
+ emit('select', emoji)
28
+ const panel = (e.currentTarget as HTMLElement).closest('[popover]') as (HTMLElement & { hidePopover?: () => void }) | null
29
+ panel?.hidePopover?.()
30
+ }
31
+ </script>
32
+
33
+ <template>
34
+ <button v-if="!inline" type="button" class="oc-emoji-picker__trigger" :popovertarget="id" :aria-label="triggerLabel">
35
+ <slot name="trigger">🙂</slot>
36
+ </button>
37
+ <div :id="id" :class="['oc-emoji-picker', inline && 'oc-emoji-picker--inline']" :popover="inline ? undefined : ''" :role="inline ? 'group' : undefined" :aria-label="label">
38
+ <div v-for="(g, gi) in groups" :key="gi">
39
+ <p v-if="g.label" class="oc-emoji-picker__label">{{ g.label }}</p>
40
+ <div class="oc-emoji-picker__grid">
41
+ <button v-for="emoji in g.emojis" :key="emoji" type="button" class="oc-emoji-picker__item" @click="pick($event, emoji)">{{ emoji }}</button>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ /** Icon, title, text and actions for lists without data. Slots: icon, title, default (text), actions. */
3
+ defineProps<{ icon?: string; title?: string; text?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <div class="oc-empty">
8
+ <span v-if="icon || $slots.icon" class="oc-empty-icon" aria-hidden="true"><slot name="icon">{{ icon }}</slot></span>
9
+ <h3 v-if="title || $slots.title" class="oc-empty-title"><slot name="title">{{ title }}</slot></h3>
10
+ <p v-if="text || $slots.default" class="oc-empty-text"><slot>{{ text }}</slot></p>
11
+ <div v-if="$slots.actions" class="oc-empty-actions"><slot name="actions" /></div>
12
+ </div>
13
+ </template>