@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.
- package/LICENSE +21 -0
- package/README.md +48 -2
- package/dist/blocks/OcBlockAboutTimeline.vue.d.ts +29 -0
- package/dist/blocks/OcBlockAppHeader.vue.d.ts +33 -0
- package/dist/blocks/OcBlockAppShell.vue.d.ts +33 -0
- package/dist/blocks/OcBlockAuth.vue.d.ts +28 -0
- package/dist/blocks/OcBlockAuthSplit.vue.d.ts +45 -0
- package/dist/blocks/OcBlockContactGrid.vue.d.ts +32 -0
- package/dist/blocks/OcBlockCta.vue.d.ts +17 -0
- package/dist/blocks/OcBlockDataTable.vue.d.ts +33 -0
- package/dist/blocks/OcBlockFaq.vue.d.ts +32 -0
- package/dist/blocks/OcBlockFeatures.vue.d.ts +25 -0
- package/dist/blocks/OcBlockFooter.vue.d.ts +27 -0
- package/dist/blocks/OcBlockFormPage.vue.d.ts +36 -0
- package/dist/blocks/OcBlockHero.vue.d.ts +18 -0
- package/dist/blocks/OcBlockHeroCode.vue.d.ts +32 -0
- package/dist/blocks/OcBlockHeroOrbit.vue.d.ts +36 -0
- package/dist/blocks/OcBlockHeroSplit.vue.d.ts +19 -0
- package/dist/blocks/OcBlockModuleHeader.vue.d.ts +24 -0
- package/dist/blocks/OcBlockPageHero.vue.d.ts +18 -0
- package/dist/blocks/OcBlockPortfolioGrid.vue.d.ts +34 -0
- package/dist/blocks/OcBlockPricing.vue.d.ts +38 -0
- package/dist/blocks/OcBlockProcess.vue.d.ts +18 -0
- package/dist/blocks/OcBlockProductGrid.vue.d.ts +25 -0
- package/dist/blocks/OcBlockProfileHeader.vue.d.ts +36 -0
- package/dist/blocks/OcBlockShowcase.vue.d.ts +23 -0
- package/dist/blocks/OcBlockSiteFooter.vue.d.ts +42 -0
- package/dist/blocks/OcBlockSiteHeader.vue.d.ts +32 -0
- package/dist/blocks/OcBlockSpotlight.vue.d.ts +32 -0
- package/dist/blocks/OcBlockStats.vue.d.ts +10 -0
- package/dist/blocks/OcBlockStatsCounter.vue.d.ts +10 -0
- package/dist/blocks/OcBlockTeamList.vue.d.ts +42 -0
- package/dist/blocks/OcBlockTwoFactor.vue.d.ts +38 -0
- package/dist/blocks/OcBlockWizardDialog.vue.d.ts +52 -0
- package/dist/components/OcAccordion.vue.d.ts +15 -0
- package/dist/components/OcAccordionAccent.vue.d.ts +20 -0
- package/dist/components/OcAccordionItem.vue.d.ts +24 -0
- package/dist/components/OcAffixInput.vue.d.ts +31 -0
- package/dist/components/OcAlert.vue.d.ts +21 -0
- package/dist/components/OcAlertDialog.vue.d.ts +48 -0
- package/dist/components/OcAlphaTabs.vue.d.ts +23 -0
- package/dist/components/OcAspectRatio.vue.d.ts +16 -0
- package/dist/components/OcAttachment.vue.d.ts +26 -0
- package/dist/components/OcAttachmentImage.vue.d.ts +10 -0
- package/dist/components/OcAttachmentList.vue.d.ts +31 -0
- package/dist/components/OcAttachmentThumb.vue.d.ts +16 -0
- package/dist/components/OcAvatar.vue.d.ts +21 -0
- package/dist/components/OcAvatarGroup.vue.d.ts +12 -0
- package/dist/components/OcBackLink.vue.d.ts +18 -0
- package/dist/components/OcBadge.vue.d.ts +18 -0
- package/dist/components/OcBarcodeInput.vue.d.ts +27 -0
- package/dist/components/OcBreadcrumb.vue.d.ts +24 -0
- package/dist/components/OcBrowserFrame.vue.d.ts +35 -0
- package/dist/components/OcBusyOverlay.vue.d.ts +30 -0
- package/dist/components/OcButton.vue.d.ts +31 -0
- package/dist/components/OcButtonGroup.vue.d.ts +17 -0
- package/dist/components/OcButtonGroupText.vue.d.ts +12 -0
- package/dist/components/OcCard.vue.d.ts +27 -0
- package/dist/components/OcChartLine.vue.d.ts +28 -0
- package/dist/components/OcChatComposer.vue.d.ts +33 -0
- package/dist/components/OcCheckbox.vue.d.ts +26 -0
- package/dist/components/OcChecklist.vue.d.ts +32 -0
- package/dist/components/OcChipFilter.vue.d.ts +24 -0
- package/dist/components/OcCollapsible.vue.d.ts +28 -0
- package/dist/components/OcColorField.vue.d.ts +17 -0
- package/dist/components/OcColorSelect.vue.d.ts +24 -0
- package/dist/components/OcColumnMenu.vue.d.ts +31 -0
- package/dist/components/OcCommand.vue.d.ts +28 -0
- package/dist/components/OcConfirmDialog.vue.d.ts +44 -0
- package/dist/components/OcCookieConsent.vue.d.ts +52 -0
- package/dist/components/OcCopyField.vue.d.ts +14 -0
- package/dist/components/OcCounter.vue.d.ts +9 -0
- package/dist/components/OcDataTable.vue.d.ts +37 -0
- package/dist/components/OcDecimalInput.vue.d.ts +19 -0
- package/dist/components/OcDefinitionList.vue.d.ts +34 -0
- package/dist/components/OcDocViewer.vue.d.ts +24 -0
- package/dist/components/OcDropdown.vue.d.ts +19 -0
- package/dist/components/OcDropdownItem.vue.d.ts +18 -0
- package/dist/components/OcDropdownLabel.vue.d.ts +12 -0
- package/dist/components/OcDropdownSeparator.vue.d.ts +2 -0
- package/dist/components/OcDropzone.vue.d.ts +29 -0
- package/dist/components/OcEmojiPicker.vue.d.ts +32 -0
- package/dist/components/OcEmptyState.vue.d.ts +24 -0
- package/dist/components/OcEntityCard.vue.d.ts +37 -0
- package/dist/components/OcFactList.vue.d.ts +29 -0
- package/dist/components/OcFilterCounts.vue.d.ts +25 -0
- package/dist/components/OcFlipCard.vue.d.ts +31 -0
- package/dist/components/OcFormField.vue.d.ts +26 -0
- package/dist/components/OcGreeting.vue.d.ts +26 -0
- package/dist/components/OcHeading.vue.d.ts +24 -0
- package/dist/components/OcHoverCard.vue.d.ts +22 -0
- package/dist/components/OcImageZoom.vue.d.ts +28 -0
- package/dist/components/OcInput.vue.d.ts +13 -0
- package/dist/components/OcInputGroup.vue.d.ts +21 -0
- package/dist/components/OcItem.vue.d.ts +39 -0
- package/dist/components/OcItemGroup.vue.d.ts +12 -0
- package/dist/components/OcItemSeparator.vue.d.ts +2 -0
- package/dist/components/OcKbd.vue.d.ts +12 -0
- package/dist/components/OcKbdGroup.vue.d.ts +17 -0
- package/dist/components/OcLabel.vue.d.ts +19 -0
- package/dist/components/OcLanguageSelect.vue.d.ts +32 -0
- package/dist/components/OcLauncherCard.vue.d.ts +26 -0
- package/dist/components/OcLightbox.vue.d.ts +45 -0
- package/dist/components/OcLinkArrow.vue.d.ts +23 -0
- package/dist/components/OcListToolbar.vue.d.ts +44 -0
- package/dist/components/OcMarquee.vue.d.ts +16 -0
- package/dist/components/OcMediaCard.vue.d.ts +24 -0
- package/dist/components/OcMediaRow.vue.d.ts +21 -0
- package/dist/components/OcMediaThumb.vue.d.ts +32 -0
- package/dist/components/OcMessage.vue.d.ts +63 -0
- package/dist/components/OcMessageList.vue.d.ts +35 -0
- package/dist/components/OcMessageThread.vue.d.ts +80 -0
- package/dist/components/OcModal.vue.d.ts +36 -0
- package/dist/components/OcNavmenu.vue.d.ts +24 -0
- package/dist/components/OcNavmenuList.vue.d.ts +29 -0
- package/dist/components/OcNextTeaser.vue.d.ts +29 -0
- package/dist/components/OcNumberInput.vue.d.ts +25 -0
- package/dist/components/OcOtpInput.vue.d.ts +19 -0
- package/dist/components/OcPageHeader.vue.d.ts +36 -0
- package/dist/components/OcPagination.vue.d.ts +20 -0
- package/dist/components/OcPasswordInput.vue.d.ts +18 -0
- package/dist/components/OcPasswordRequirements.vue.d.ts +19 -0
- package/dist/components/OcPhoneInput.vue.d.ts +25 -0
- package/dist/components/OcPopover.vue.d.ts +24 -0
- package/dist/components/OcPriceCard.vue.d.ts +41 -0
- package/dist/components/OcProductMark.vue.d.ts +25 -0
- package/dist/components/OcProgress.vue.d.ts +11 -0
- package/dist/components/OcProjectCard.vue.d.ts +35 -0
- package/dist/components/OcProse.vue.d.ts +25 -0
- package/dist/components/OcRadio.vue.d.ts +27 -0
- package/dist/components/OcRadioGroup.vue.d.ts +32 -0
- package/dist/components/OcRecoveryCodes.vue.d.ts +36 -0
- package/dist/components/OcScrollArea.vue.d.ts +18 -0
- package/dist/components/OcSegmented.vue.d.ts +21 -0
- package/dist/components/OcSelect.vue.d.ts +28 -0
- package/dist/components/OcSeparator.vue.d.ts +21 -0
- package/dist/components/OcSeverityCard.vue.d.ts +36 -0
- package/dist/components/OcSheet.vue.d.ts +37 -0
- package/dist/components/OcSidebar.vue.d.ts +28 -0
- package/dist/components/OcSidebarCollapsible.vue.d.ts +27 -0
- package/dist/components/OcSidebarGroup.vue.d.ts +16 -0
- package/dist/components/OcSidebarMenu.vue.d.ts +12 -0
- package/dist/components/OcSidebarMenuButton.vue.d.ts +21 -0
- package/dist/components/OcSidebarSeparator.vue.d.ts +2 -0
- package/dist/components/OcSkeleton.vue.d.ts +8 -0
- package/dist/components/OcSlider.vue.d.ts +18 -0
- package/dist/components/OcSortableRow.vue.d.ts +32 -0
- package/dist/components/OcSpinner.vue.d.ts +8 -0
- package/dist/components/OcStackCard.vue.d.ts +22 -0
- package/dist/components/OcStackList.vue.d.ts +28 -0
- package/dist/components/OcStatCard.vue.d.ts +25 -0
- package/dist/components/OcStepper.vue.d.ts +24 -0
- package/dist/components/OcSwitch.vue.d.ts +9 -0
- package/dist/components/OcTable.vue.d.ts +61 -0
- package/dist/components/OcTableActions.vue.d.ts +18 -0
- package/dist/components/OcTableCompact.vue.d.ts +37 -0
- package/dist/components/OcTabs.vue.d.ts +28 -0
- package/dist/components/OcTagInput.vue.d.ts +18 -0
- package/dist/components/OcTerminalLog.vue.d.ts +20 -0
- package/dist/components/OcTextarea.vue.d.ts +13 -0
- package/dist/components/OcThemeSwitch.vue.d.ts +20 -0
- package/dist/components/OcTimeInput.vue.d.ts +14 -0
- package/dist/components/OcTimeline.vue.d.ts +33 -0
- package/dist/components/OcToast.vue.d.ts +31 -0
- package/dist/components/OcToastContainer.vue.d.ts +8 -0
- package/dist/components/OcToggle.vue.d.ts +29 -0
- package/dist/components/OcToggleField.vue.d.ts +27 -0
- package/dist/components/OcToggleGroup.vue.d.ts +27 -0
- package/dist/components/OcTooltip.vue.d.ts +16 -0
- package/dist/components/OcTopProgress.vue.d.ts +18 -0
- package/dist/components/OcTree.vue.d.ts +40 -0
- package/dist/components/OcUpgradeBanner.vue.d.ts +41 -0
- package/dist/components/OcUser.vue.d.ts +20 -0
- package/dist/components/OcVersionBanner.vue.d.ts +32 -0
- package/dist/composables/chartLine.d.ts +6 -0
- package/dist/composables/keys.d.ts +19 -0
- package/dist/composables/useAttrsSplit.d.ts +14 -0
- package/dist/composables/useDialog.d.ts +9 -0
- package/dist/composables/useToast.d.ts +34 -0
- package/dist/composables/useUid.d.ts +5 -0
- package/dist/index.d.ts +233 -0
- package/dist/omniaui-vue.js +8811 -0
- package/dist/omniaui-vue.js.map +1 -0
- package/manifest.json +1036 -0
- package/package.json +67 -4
- package/src/blocks/OcBlockAboutTimeline.vue +44 -0
- package/src/blocks/OcBlockAppHeader.vue +36 -0
- package/src/blocks/OcBlockAppShell.vue +29 -0
- package/src/blocks/OcBlockAuth.vue +24 -0
- package/src/blocks/OcBlockAuthSplit.vue +47 -0
- package/src/blocks/OcBlockContactGrid.vue +53 -0
- package/src/blocks/OcBlockCta.vue +12 -0
- package/src/blocks/OcBlockDataTable.vue +27 -0
- package/src/blocks/OcBlockFaq.vue +49 -0
- package/src/blocks/OcBlockFeatures.vue +23 -0
- package/src/blocks/OcBlockFooter.vue +25 -0
- package/src/blocks/OcBlockFormPage.vue +24 -0
- package/src/blocks/OcBlockHero.vue +13 -0
- package/src/blocks/OcBlockHeroCode.vue +42 -0
- package/src/blocks/OcBlockHeroOrbit.vue +69 -0
- package/src/blocks/OcBlockHeroSplit.vue +15 -0
- package/src/blocks/OcBlockModuleHeader.vue +21 -0
- package/src/blocks/OcBlockPageHero.vue +13 -0
- package/src/blocks/OcBlockPortfolioGrid.vue +63 -0
- package/src/blocks/OcBlockPricing.vue +39 -0
- package/src/blocks/OcBlockProcess.vue +39 -0
- package/src/blocks/OcBlockProductGrid.vue +41 -0
- package/src/blocks/OcBlockProfileHeader.vue +50 -0
- package/src/blocks/OcBlockShowcase.vue +43 -0
- package/src/blocks/OcBlockSiteFooter.vue +54 -0
- package/src/blocks/OcBlockSiteHeader.vue +34 -0
- package/src/blocks/OcBlockSpotlight.vue +47 -0
- package/src/blocks/OcBlockStats.vue +17 -0
- package/src/blocks/OcBlockStatsCounter.vue +20 -0
- package/src/blocks/OcBlockTeamList.vue +53 -0
- package/src/blocks/OcBlockTwoFactor.vue +61 -0
- package/src/blocks/OcBlockWizardDialog.vue +67 -0
- package/src/components/OcAccordion.vue +12 -0
- package/src/components/OcAccordionAccent.vue +27 -0
- package/src/components/OcAccordionItem.vue +19 -0
- package/src/components/OcAffixInput.vue +40 -0
- package/src/components/OcAlert.vue +17 -0
- package/src/components/OcAlertDialog.vue +66 -0
- package/src/components/OcAlphaTabs.vue +54 -0
- package/src/components/OcAspectRatio.vue +21 -0
- package/src/components/OcAttachment.vue +59 -0
- package/src/components/OcAttachmentImage.vue +13 -0
- package/src/components/OcAttachmentList.vue +31 -0
- package/src/components/OcAttachmentThumb.vue +14 -0
- package/src/components/OcAvatar.vue +18 -0
- package/src/components/OcAvatarGroup.vue +7 -0
- package/src/components/OcBackLink.vue +8 -0
- package/src/components/OcBadge.vue +13 -0
- package/src/components/OcBarcodeInput.vue +51 -0
- package/src/components/OcBreadcrumb.vue +22 -0
- package/src/components/OcBrowserFrame.vue +33 -0
- package/src/components/OcBusyOverlay.vue +32 -0
- package/src/components/OcButton.vue +47 -0
- package/src/components/OcButtonGroup.vue +10 -0
- package/src/components/OcButtonGroupText.vue +7 -0
- package/src/components/OcCard.vue +20 -0
- package/src/components/OcChartLine.vue +80 -0
- package/src/components/OcChatComposer.vue +42 -0
- package/src/components/OcCheckbox.vue +26 -0
- package/src/components/OcChecklist.vue +29 -0
- package/src/components/OcChipFilter.vue +48 -0
- package/src/components/OcCollapsible.vue +19 -0
- package/src/components/OcColorField.vue +15 -0
- package/src/components/OcColorSelect.vue +33 -0
- package/src/components/OcColumnMenu.vue +50 -0
- package/src/components/OcCommand.vue +119 -0
- package/src/components/OcConfirmDialog.vue +65 -0
- package/src/components/OcCookieConsent.vue +119 -0
- package/src/components/OcCopyField.vue +37 -0
- package/src/components/OcCounter.vue +15 -0
- package/src/components/OcDataTable.vue +144 -0
- package/src/components/OcDecimalInput.vue +53 -0
- package/src/components/OcDefinitionList.vue +35 -0
- package/src/components/OcDocViewer.vue +79 -0
- package/src/components/OcDropdown.vue +23 -0
- package/src/components/OcDropdownItem.vue +9 -0
- package/src/components/OcDropdownLabel.vue +7 -0
- package/src/components/OcDropdownSeparator.vue +7 -0
- package/src/components/OcDropzone.vue +36 -0
- package/src/components/OcEmojiPicker.vue +45 -0
- package/src/components/OcEmptyState.vue +13 -0
- package/src/components/OcEntityCard.vue +47 -0
- package/src/components/OcFactList.vue +37 -0
- package/src/components/OcFilterCounts.vue +38 -0
- package/src/components/OcFlipCard.vue +36 -0
- package/src/components/OcFormField.vue +36 -0
- package/src/components/OcGreeting.vue +52 -0
- package/src/components/OcHeading.vue +19 -0
- package/src/components/OcHoverCard.vue +25 -0
- package/src/components/OcImageZoom.vue +39 -0
- package/src/components/OcInput.vue +9 -0
- package/src/components/OcInputGroup.vue +12 -0
- package/src/components/OcItem.vue +40 -0
- package/src/components/OcItemGroup.vue +7 -0
- package/src/components/OcItemSeparator.vue +7 -0
- package/src/components/OcKbd.vue +7 -0
- package/src/components/OcKbdGroup.vue +15 -0
- package/src/components/OcLabel.vue +10 -0
- package/src/components/OcLanguageSelect.vue +40 -0
- package/src/components/OcLauncherCard.vue +34 -0
- package/src/components/OcLightbox.vue +63 -0
- package/src/components/OcLinkArrow.vue +25 -0
- package/src/components/OcListToolbar.vue +44 -0
- package/src/components/OcMarquee.vue +36 -0
- package/src/components/OcMediaCard.vue +28 -0
- package/src/components/OcMediaRow.vue +28 -0
- package/src/components/OcMediaThumb.vue +38 -0
- package/src/components/OcMessage.vue +91 -0
- package/src/components/OcMessageList.vue +43 -0
- package/src/components/OcMessageThread.vue +155 -0
- package/src/components/OcModal.vue +42 -0
- package/src/components/OcNavmenu.vue +18 -0
- package/src/components/OcNavmenuList.vue +38 -0
- package/src/components/OcNextTeaser.vue +25 -0
- package/src/components/OcNumberInput.vue +47 -0
- package/src/components/OcOtpInput.vue +34 -0
- package/src/components/OcPageHeader.vue +34 -0
- package/src/components/OcPagination.vue +33 -0
- package/src/components/OcPasswordInput.vue +27 -0
- package/src/components/OcPasswordRequirements.vue +28 -0
- package/src/components/OcPhoneInput.vue +72 -0
- package/src/components/OcPopover.vue +25 -0
- package/src/components/OcPriceCard.vue +69 -0
- package/src/components/OcProductMark.vue +31 -0
- package/src/components/OcProgress.vue +21 -0
- package/src/components/OcProjectCard.vue +36 -0
- package/src/components/OcProse.vue +57 -0
- package/src/components/OcRadio.vue +40 -0
- package/src/components/OcRadioGroup.vue +32 -0
- package/src/components/OcRecoveryCodes.vue +55 -0
- package/src/components/OcScrollArea.vue +15 -0
- package/src/components/OcSegmented.vue +28 -0
- package/src/components/OcSelect.vue +21 -0
- package/src/components/OcSeparator.vue +18 -0
- package/src/components/OcSeverityCard.vue +46 -0
- package/src/components/OcSheet.vue +49 -0
- package/src/components/OcSidebar.vue +16 -0
- package/src/components/OcSidebarCollapsible.vue +19 -0
- package/src/components/OcSidebarGroup.vue +11 -0
- package/src/components/OcSidebarMenu.vue +7 -0
- package/src/components/OcSidebarMenuButton.vue +31 -0
- package/src/components/OcSidebarSeparator.vue +7 -0
- package/src/components/OcSkeleton.vue +8 -0
- package/src/components/OcSlider.vue +27 -0
- package/src/components/OcSortableRow.vue +40 -0
- package/src/components/OcSpinner.vue +13 -0
- package/src/components/OcStackCard.vue +24 -0
- package/src/components/OcStackList.vue +31 -0
- package/src/components/OcStatCard.vue +39 -0
- package/src/components/OcStepper.vue +34 -0
- package/src/components/OcSwitch.vue +15 -0
- package/src/components/OcTable.vue +115 -0
- package/src/components/OcTableActions.vue +26 -0
- package/src/components/OcTableCompact.vue +46 -0
- package/src/components/OcTabs.vue +37 -0
- package/src/components/OcTagInput.vue +50 -0
- package/src/components/OcTerminalLog.vue +50 -0
- package/src/components/OcTextarea.vue +9 -0
- package/src/components/OcThemeSwitch.vue +31 -0
- package/src/components/OcTimeInput.vue +50 -0
- package/src/components/OcTimeline.vue +36 -0
- package/src/components/OcToast.vue +31 -0
- package/src/components/OcToastContainer.vue +21 -0
- package/src/components/OcToggle.vue +63 -0
- package/src/components/OcToggleField.vue +28 -0
- package/src/components/OcToggleGroup.vue +40 -0
- package/src/components/OcTooltip.vue +8 -0
- package/src/components/OcTopProgress.vue +54 -0
- package/src/components/OcTree.vue +70 -0
- package/src/components/OcUpgradeBanner.vue +42 -0
- package/src/components/OcUser.vue +25 -0
- package/src/components/OcVersionBanner.vue +34 -0
- package/src/composables/chartLine.ts +28 -0
- package/src/composables/keys.ts +22 -0
- package/src/composables/useAttrsSplit.ts +16 -0
- package/src/composables/useDialog.ts +21 -0
- package/src/composables/useToast.ts +66 -0
- package/src/composables/useUid.ts +12 -0
- package/src/index.ts +589 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- File: packages/vue/src/components/OcTopProgress.vue | Map: progress.oc-top-progress -> phase (hidden / active / done) -> fade-out timer -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* Thin page-top loading bar. `active` shows it; when `active` turns false the bar fades out (.is-done)
|
|
5
|
+
* and is hidden after `fadeMs`. Without `value` it is indeterminate.
|
|
6
|
+
* Classes: progress.oc-top-progress(--success/--warning/--danger/--brand/--lg/--static), .is-done, [hidden]
|
|
7
|
+
*/
|
|
8
|
+
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(
|
|
11
|
+
defineProps<{
|
|
12
|
+
active?: boolean
|
|
13
|
+
value?: number
|
|
14
|
+
max?: number
|
|
15
|
+
tone?: 'default' | 'success' | 'warning' | 'danger' | 'brand'
|
|
16
|
+
large?: boolean
|
|
17
|
+
/** In the normal flow (inside a card) instead of fixed at the top. */
|
|
18
|
+
static?: boolean
|
|
19
|
+
fadeMs?: number
|
|
20
|
+
}>(),
|
|
21
|
+
{ active: true, tone: 'default', fadeMs: 400, value: undefined, max: undefined },
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const phase = ref<'hidden' | 'active' | 'done'>(props.active ? 'active' : 'hidden')
|
|
25
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
26
|
+
|
|
27
|
+
watch(
|
|
28
|
+
() => props.active,
|
|
29
|
+
(on) => {
|
|
30
|
+
clearTimeout(timer)
|
|
31
|
+
if (on) {
|
|
32
|
+
phase.value = 'active'
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
// Only fade out when the bar was visible.
|
|
36
|
+
if (phase.value === 'hidden') return
|
|
37
|
+
phase.value = 'done'
|
|
38
|
+
timer = setTimeout(() => (phase.value = 'hidden'), props.fadeMs)
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
onBeforeUnmount(() => clearTimeout(timer))
|
|
42
|
+
|
|
43
|
+
const classes = computed(() => [
|
|
44
|
+
'oc-top-progress',
|
|
45
|
+
props.tone !== 'default' && `oc-top-progress--${props.tone}`,
|
|
46
|
+
props.large && 'oc-top-progress--lg',
|
|
47
|
+
props.static && 'oc-top-progress--static',
|
|
48
|
+
phase.value === 'done' && 'is-done',
|
|
49
|
+
])
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<template>
|
|
53
|
+
<progress :class="classes" :value="value" :max="max" :hidden="phase === 'hidden'"></progress>
|
|
54
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<!-- File: packages/vue/src/components/OcTree.vue | Map: box (+ head row) -> list -> item: folder (details/summary + nested OcTree) or leaf (div row) -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* Nested tree list on details / summary. Renders itself recursively for child lists (`nested`).
|
|
5
|
+
* Slots (scoped, { item }): icon, actions; plus `head-actions` for the head row.
|
|
6
|
+
* Classes: .oc-tree(--quiet/--flush), .oc-tree-head, ul.oc-tree-list, details.oc-tree-node, .oc-tree-row(.is-muted),
|
|
7
|
+
* .oc-tree-icon, .oc-tree-label, .oc-tree-count, .oc-tree-actions
|
|
8
|
+
*/
|
|
9
|
+
export interface OcTreeItem {
|
|
10
|
+
label: string
|
|
11
|
+
href?: string
|
|
12
|
+
count?: string | number
|
|
13
|
+
children?: OcTreeItem[]
|
|
14
|
+
open?: boolean
|
|
15
|
+
current?: boolean
|
|
16
|
+
muted?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
defineOptions({ name: 'OcTree' })
|
|
20
|
+
defineProps<{
|
|
21
|
+
items: OcTreeItem[]
|
|
22
|
+
head?: string
|
|
23
|
+
quiet?: boolean
|
|
24
|
+
flush?: boolean
|
|
25
|
+
/** Internal: render only the list (used for child lists). */
|
|
26
|
+
nested?: boolean
|
|
27
|
+
}>()
|
|
28
|
+
// Typed slots: the component renders itself, so TypeScript cannot infer these on its own.
|
|
29
|
+
defineSlots<{
|
|
30
|
+
icon?(props: { item: OcTreeItem }): unknown
|
|
31
|
+
actions?(props: { item: OcTreeItem }): unknown
|
|
32
|
+
'head-actions'?(): unknown
|
|
33
|
+
}>()
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<ul v-if="nested" class="oc-tree-list">
|
|
38
|
+
<li v-for="(item, i) in items" :key="i">
|
|
39
|
+
<details v-if="item.children?.length" class="oc-tree-node" :open="item.open">
|
|
40
|
+
<summary :class="['oc-tree-row', item.muted && 'is-muted']" :aria-current="item.current && !item.href ? 'true' : undefined">
|
|
41
|
+
<span v-if="$slots.icon" class="oc-tree-icon" aria-hidden="true"><slot name="icon" :item="item" /></span>
|
|
42
|
+
<span class="oc-tree-label">{{ item.label }}</span>
|
|
43
|
+
<span v-if="item.count != null" class="oc-tree-count">{{ item.count }}</span>
|
|
44
|
+
<span v-if="$slots.actions" class="oc-tree-actions"><slot name="actions" :item="item" /></span>
|
|
45
|
+
</summary>
|
|
46
|
+
<OcTree :items="item.children" nested>
|
|
47
|
+
<template v-if="$slots.icon" #icon="{ item: child }"><slot name="icon" :item="child" /></template>
|
|
48
|
+
<template v-if="$slots.actions" #actions="{ item: child }"><slot name="actions" :item="child" /></template>
|
|
49
|
+
</OcTree>
|
|
50
|
+
</details>
|
|
51
|
+
<div v-else :class="['oc-tree-row', item.muted && 'is-muted']" :aria-current="item.current && !item.href ? 'true' : undefined">
|
|
52
|
+
<span v-if="$slots.icon" class="oc-tree-icon" aria-hidden="true"><slot name="icon" :item="item" /></span>
|
|
53
|
+
<a v-if="item.href" class="oc-tree-label" :href="item.href" :aria-current="item.current ? 'true' : undefined">{{ item.label }}</a>
|
|
54
|
+
<span v-else class="oc-tree-label">{{ item.label }}</span>
|
|
55
|
+
<span v-if="item.count != null" class="oc-tree-count">{{ item.count }}</span>
|
|
56
|
+
<span v-if="$slots.actions" class="oc-tree-actions"><slot name="actions" :item="item" /></span>
|
|
57
|
+
</div>
|
|
58
|
+
</li>
|
|
59
|
+
</ul>
|
|
60
|
+
<div v-else :class="['oc-tree', quiet && 'oc-tree--quiet', flush && 'oc-tree--flush']">
|
|
61
|
+
<div v-if="head" class="oc-tree-row oc-tree-head">
|
|
62
|
+
<span class="oc-tree-label">{{ head }}</span>
|
|
63
|
+
<span v-if="$slots['head-actions']" class="oc-tree-actions"><slot name="head-actions" /></span>
|
|
64
|
+
</div>
|
|
65
|
+
<OcTree :items="items" nested>
|
|
66
|
+
<template v-if="$slots.icon" #icon="{ item: child }"><slot name="icon" :item="child" /></template>
|
|
67
|
+
<template v-if="$slots.actions" #actions="{ item: child }"><slot name="actions" :item="child" /></template>
|
|
68
|
+
</OcTree>
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<!-- File: packages/vue/src/components/OcUpgradeBanner.vue | Map: aside -> icon slot -> body (title + plan pill, text slot, usage meter) -> actions slot -> dismiss button -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* Free-plan limits callout. `dismissible` adds an X that emits `dismiss` (your app hides the banner).
|
|
5
|
+
* Slots: icon, default (text, may hold links), actions.
|
|
6
|
+
* Classes: .oc-upgrade-banner(--premium/--compact), -icon, -body, -title, -plan, -text, -usage, meter.oc-upgrade-banner-meter, -actions, -dismiss
|
|
7
|
+
*/
|
|
8
|
+
withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
title: string
|
|
11
|
+
plan?: string
|
|
12
|
+
text?: string
|
|
13
|
+
usage?: { label: string; value: number; max: number }
|
|
14
|
+
premium?: boolean
|
|
15
|
+
compact?: boolean
|
|
16
|
+
dismissible?: boolean
|
|
17
|
+
dismissLabel?: string
|
|
18
|
+
}>(),
|
|
19
|
+
{ dismissLabel: 'Dismiss' },
|
|
20
|
+
)
|
|
21
|
+
const emit = defineEmits<{ dismiss: [] }>()
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<aside :class="['oc-upgrade-banner', premium && 'oc-upgrade-banner--premium', compact && 'oc-upgrade-banner--compact']">
|
|
26
|
+
<span v-if="$slots.icon" class="oc-upgrade-banner-icon" aria-hidden="true"><slot name="icon" /></span>
|
|
27
|
+
<div class="oc-upgrade-banner-body">
|
|
28
|
+
<p class="oc-upgrade-banner-title">{{ title }} <span v-if="plan" class="oc-upgrade-banner-plan">{{ plan }}</span></p>
|
|
29
|
+
<p v-if="$slots.default || text" class="oc-upgrade-banner-text"><slot>{{ text }}</slot></p>
|
|
30
|
+
<div v-if="usage" class="oc-upgrade-banner-usage">
|
|
31
|
+
<span>{{ usage.label }}</span>
|
|
32
|
+
<!-- low / high make the meter turn "less good" near the limit. -->
|
|
33
|
+
<meter class="oc-upgrade-banner-meter" min="0" :max="usage.max" :low="usage.max * 0.6" :high="usage.max * 0.8" optimum="0" :value="usage.value">
|
|
34
|
+
{{ usage.value }} of {{ usage.max }}
|
|
35
|
+
</meter>
|
|
36
|
+
<span>{{ usage.value }} / {{ usage.max }}</span>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div v-if="$slots.actions" class="oc-upgrade-banner-actions"><slot name="actions" /></div>
|
|
40
|
+
<button v-if="dismissible" class="oc-upgrade-banner-dismiss" type="button" :aria-label="dismissLabel" @click="emit('dismiss')">×</button>
|
|
41
|
+
</aside>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Avatar with name and e-mail (truncating). `initials` or `src` fill the avatar; slot `avatar` replaces it. */
|
|
3
|
+
defineProps<{
|
|
4
|
+
name: string
|
|
5
|
+
email?: string
|
|
6
|
+
initials?: string
|
|
7
|
+
src?: string
|
|
8
|
+
avatarSize?: 'sm' | 'md' | 'lg' | 'xl'
|
|
9
|
+
}>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="oc-user">
|
|
14
|
+
<slot name="avatar">
|
|
15
|
+
<span :class="['oc-avatar', avatarSize && avatarSize !== 'md' && `oc-avatar--${avatarSize}`]">
|
|
16
|
+
<img v-if="src" :src="src" alt="" />
|
|
17
|
+
<template v-else>{{ initials }}</template>
|
|
18
|
+
</span>
|
|
19
|
+
</slot>
|
|
20
|
+
<span class="oc-user-text">
|
|
21
|
+
<span class="oc-user-name">{{ name }}</span>
|
|
22
|
+
<span v-if="email" class="oc-user-email">{{ email }}</span>
|
|
23
|
+
</span>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- File: packages/vue/src/components/OcVersionBanner.vue | Map: chip (role=status) -> dot -> long text -> short text -> reload action -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* "New version available - reload" chip. Renders nothing while `version` is empty.
|
|
5
|
+
* Without an @reload listener the action is a plain link to the current page; with one it is a button.
|
|
6
|
+
* Slots: default (long text). Classes: .oc-version-banner(--info/--success/--floating), -dot, -text, -short, -action
|
|
7
|
+
*/
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
version?: string | null
|
|
11
|
+
short?: string
|
|
12
|
+
actionLabel?: string
|
|
13
|
+
tone?: 'warning' | 'info' | 'success'
|
|
14
|
+
floating?: boolean
|
|
15
|
+
/** Declared as a prop so the component can see whether a listener is set. */
|
|
16
|
+
onReload?: () => void
|
|
17
|
+
}>(),
|
|
18
|
+
{ short: 'New version', actionLabel: 'Reload', tone: 'warning', version: null, onReload: undefined },
|
|
19
|
+
)
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<div
|
|
24
|
+
v-if="version"
|
|
25
|
+
:class="['oc-version-banner', tone !== 'warning' && `oc-version-banner--${tone}`, floating && 'oc-version-banner--floating']"
|
|
26
|
+
role="status"
|
|
27
|
+
>
|
|
28
|
+
<span class="oc-version-banner-dot" aria-hidden="true"></span>
|
|
29
|
+
<span class="oc-version-banner-text"><slot>New version ({{ version }}) available - reload the page</slot></span>
|
|
30
|
+
<span class="oc-version-banner-short">{{ short }}</span>
|
|
31
|
+
<button v-if="props.onReload" class="oc-version-banner-action" type="button" @click="props.onReload()">{{ actionLabel }}</button>
|
|
32
|
+
<a v-else class="oc-version-banner-action" href="">{{ actionLabel }}</a>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// File: packages/vue/src/composables/chartLine.ts
|
|
2
|
+
// Map: number format -> nice axis maximum -> smooth path (same geometry as the chart-line snippet and the React wrapper)
|
|
3
|
+
|
|
4
|
+
/** Number with at most 2 decimals and no trailing zeros ("75", "37.5", "4.69"). */
|
|
5
|
+
export const n2 = (n: number) => String(parseFloat(n.toFixed(2)))
|
|
6
|
+
|
|
7
|
+
/** Round axis maximum: step = max / rows rounded up to 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 or 10 x 10^k. */
|
|
8
|
+
export function niceMax(value: number, rows = 4) {
|
|
9
|
+
if (value <= 0) return rows
|
|
10
|
+
const raw = value / rows
|
|
11
|
+
const pow = 10 ** Math.floor(Math.log10(raw))
|
|
12
|
+
return ([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10].find((s) => s * pow >= raw) ?? 10) * pow * rows
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Smooth path through the points (x 0-100, y = 100 - value / max * 100); control points stay between their two ends. */
|
|
16
|
+
export function chartLinePath(values: number[], max: number) {
|
|
17
|
+
const pts = values.map((v, i) => [values.length > 1 ? (i / (values.length - 1)) * 100 : 50, 100 - (v / max) * 100])
|
|
18
|
+
if (!pts.length) return ''
|
|
19
|
+
const clamp = (v: number, a: number, b: number) => Math.min(Math.max(v, Math.min(a, b)), Math.max(a, b))
|
|
20
|
+
let d = `M${n2(pts[0][0])} ${n2(pts[0][1])}`
|
|
21
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
22
|
+
const p0 = pts[i - 1] ?? pts[i], p1 = pts[i], p2 = pts[i + 1], p3 = pts[i + 2] ?? p2
|
|
23
|
+
const c1 = [p1[0] + (p2[0] - p0[0]) / 6, clamp(p1[1] + (p2[1] - p0[1]) / 6, p1[1], p2[1])]
|
|
24
|
+
const c2 = [p2[0] - (p3[0] - p1[0]) / 6, clamp(p2[1] - (p3[1] - p1[1]) / 6, p1[1], p2[1])]
|
|
25
|
+
d += ` C${n2(c1[0])} ${n2(c1[1])} ${n2(c2[0])} ${n2(c2[1])} ${n2(p2[0])} ${n2(p2[1])}`
|
|
26
|
+
}
|
|
27
|
+
return d
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { InjectionKey, Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
/** Provided by OcRadioGroup, injected by OcRadio. */
|
|
4
|
+
export interface RadioGroupContext {
|
|
5
|
+
model: Ref<string | number | undefined>
|
|
6
|
+
name: Ref<string>
|
|
7
|
+
card: Ref<boolean>
|
|
8
|
+
}
|
|
9
|
+
export const radioGroupKey: InjectionKey<RadioGroupContext> = Symbol('oc-radio-group')
|
|
10
|
+
|
|
11
|
+
/** Provided by OcToggleGroup, injected by OcToggle. */
|
|
12
|
+
export interface ToggleGroupContext {
|
|
13
|
+
/** Currently pressed values. */
|
|
14
|
+
values: Ref<string[]>
|
|
15
|
+
type: Ref<'single' | 'multiple'>
|
|
16
|
+
name: Ref<string>
|
|
17
|
+
toggle: (value: string) => void
|
|
18
|
+
}
|
|
19
|
+
export const toggleGroupKey: InjectionKey<ToggleGroupContext> = Symbol('oc-toggle-group')
|
|
20
|
+
|
|
21
|
+
/** Provided by OcResizable, injected by OcResizablePanel. */
|
|
22
|
+
export const resizableVerticalKey: InjectionKey<Ref<boolean>> = Symbol('oc-resizable-vertical')
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { computed, useAttrs } from 'vue'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* For components whose root is a wrapper (label, div) around the real form control:
|
|
5
|
+
* `class` and `style` stay on the wrapper, every other attribute (id, name, disabled,
|
|
6
|
+
* autocomplete, aria-*, listeners) goes to the control. Use with defineOptions({ inheritAttrs: false }).
|
|
7
|
+
*/
|
|
8
|
+
export function useAttrsSplit() {
|
|
9
|
+
const attrs = useAttrs()
|
|
10
|
+
const root = computed(() => ({ class: attrs.class, style: attrs.style }))
|
|
11
|
+
const control = computed(() => {
|
|
12
|
+
const { class: _c, style: _s, ...rest } = attrs
|
|
13
|
+
return rest
|
|
14
|
+
})
|
|
15
|
+
return { root, control }
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { onMounted, watch, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Keeps a native <dialog> in sync with a boolean `open` model:
|
|
5
|
+
* open -> showModal(), closed -> close(). Native close (Esc, backdrop, form method=dialog)
|
|
6
|
+
* is reported through `onClose` so v-model:open stays correct.
|
|
7
|
+
*/
|
|
8
|
+
export function useDialog(open: Ref<boolean | undefined>, el: Ref<HTMLDialogElement | null>) {
|
|
9
|
+
function sync() {
|
|
10
|
+
const dialog = el.value
|
|
11
|
+
if (!dialog) return
|
|
12
|
+
if (open.value && !dialog.open) dialog.showModal()
|
|
13
|
+
else if (!open.value && dialog.open) dialog.close()
|
|
14
|
+
}
|
|
15
|
+
watch(open, sync, { flush: 'post' })
|
|
16
|
+
onMounted(sync)
|
|
17
|
+
function onClose() {
|
|
18
|
+
if (open.value) open.value = false
|
|
19
|
+
}
|
|
20
|
+
return { onClose }
|
|
21
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { reactive, readonly } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type ToastVariant = 'success' | 'error' | 'warning' | 'info'
|
|
4
|
+
|
|
5
|
+
export interface ToastOptions {
|
|
6
|
+
title: string
|
|
7
|
+
description?: string
|
|
8
|
+
variant?: ToastVariant
|
|
9
|
+
/** Milliseconds before auto-dismiss. 0 keeps the toast until dismissed. Default 5000. */
|
|
10
|
+
duration?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ToastItem extends Required<Pick<ToastOptions, 'title' | 'variant'>> {
|
|
14
|
+
id: number
|
|
15
|
+
description?: string
|
|
16
|
+
duration: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const state = reactive<{ toasts: ToastItem[] }>({ toasts: [] })
|
|
20
|
+
const timers = new Map<number, ReturnType<typeof setTimeout>>()
|
|
21
|
+
let nextId = 1
|
|
22
|
+
|
|
23
|
+
function dismiss(id: number) {
|
|
24
|
+
const timer = timers.get(id)
|
|
25
|
+
if (timer) clearTimeout(timer)
|
|
26
|
+
timers.delete(id)
|
|
27
|
+
const i = state.toasts.findIndex((t) => t.id === id)
|
|
28
|
+
if (i !== -1) state.toasts.splice(i, 1)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function push(options: ToastOptions): number {
|
|
32
|
+
const id = nextId++
|
|
33
|
+
const item: ToastItem = {
|
|
34
|
+
id,
|
|
35
|
+
title: options.title,
|
|
36
|
+
description: options.description,
|
|
37
|
+
variant: options.variant ?? 'info',
|
|
38
|
+
duration: options.duration ?? 5000,
|
|
39
|
+
}
|
|
40
|
+
state.toasts.push(item)
|
|
41
|
+
if (item.duration > 0) timers.set(id, setTimeout(() => dismiss(id), item.duration))
|
|
42
|
+
return id
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function clear() {
|
|
46
|
+
for (const t of [...state.toasts]) dismiss(t.id)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const shortcut =
|
|
50
|
+
(variant: ToastVariant) =>
|
|
51
|
+
(title: string, description?: string, options: Omit<ToastOptions, 'title' | 'description' | 'variant'> = {}) =>
|
|
52
|
+
push({ ...options, title, description, variant })
|
|
53
|
+
|
|
54
|
+
/** Shared toast queue. Render it once with <OcToastContainer />. */
|
|
55
|
+
export function useToast() {
|
|
56
|
+
return {
|
|
57
|
+
toasts: readonly(state).toasts,
|
|
58
|
+
push,
|
|
59
|
+
dismiss,
|
|
60
|
+
clear,
|
|
61
|
+
success: shortcut('success'),
|
|
62
|
+
error: shortcut('error'),
|
|
63
|
+
warning: shortcut('warning'),
|
|
64
|
+
info: shortcut('info'),
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as Vue from 'vue'
|
|
2
|
+
|
|
3
|
+
let counter = 0
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Stable unique id for aria-labelledby / popovertarget / label-for wiring.
|
|
7
|
+
* Uses Vue's built-in useId() when available (Vue >= 3.5, SSR safe), otherwise a counter.
|
|
8
|
+
*/
|
|
9
|
+
export function useUid(prefix = 'oc'): string {
|
|
10
|
+
const useId = (Vue as Record<string, unknown>)['useId'] as (() => string) | undefined
|
|
11
|
+
return `${prefix}-${useId ? useId() : ++counter}`
|
|
12
|
+
}
|