@birdycom/omniaui-vue 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +49 -49
  3. package/dist/omniaui-vue.js.map +1 -1
  4. package/package.json +69 -69
  5. package/src/blocks/OcBlockAboutTimeline.vue +44 -44
  6. package/src/blocks/OcBlockAppHeader.vue +36 -36
  7. package/src/blocks/OcBlockAppShell.vue +29 -29
  8. package/src/blocks/OcBlockAuth.vue +24 -24
  9. package/src/blocks/OcBlockAuthSplit.vue +47 -47
  10. package/src/blocks/OcBlockContactGrid.vue +53 -53
  11. package/src/blocks/OcBlockCta.vue +12 -12
  12. package/src/blocks/OcBlockDataTable.vue +27 -27
  13. package/src/blocks/OcBlockFaq.vue +49 -49
  14. package/src/blocks/OcBlockFeatures.vue +23 -23
  15. package/src/blocks/OcBlockFooter.vue +25 -25
  16. package/src/blocks/OcBlockFormPage.vue +24 -24
  17. package/src/blocks/OcBlockHero.vue +13 -13
  18. package/src/blocks/OcBlockHeroCode.vue +42 -42
  19. package/src/blocks/OcBlockHeroOrbit.vue +69 -69
  20. package/src/blocks/OcBlockHeroSplit.vue +15 -15
  21. package/src/blocks/OcBlockModuleHeader.vue +21 -21
  22. package/src/blocks/OcBlockPageHero.vue +13 -13
  23. package/src/blocks/OcBlockPortfolioGrid.vue +63 -63
  24. package/src/blocks/OcBlockPricing.vue +39 -39
  25. package/src/blocks/OcBlockProcess.vue +39 -39
  26. package/src/blocks/OcBlockProductGrid.vue +41 -41
  27. package/src/blocks/OcBlockProfileHeader.vue +50 -50
  28. package/src/blocks/OcBlockShowcase.vue +43 -43
  29. package/src/blocks/OcBlockSiteFooter.vue +54 -54
  30. package/src/blocks/OcBlockSiteHeader.vue +34 -34
  31. package/src/blocks/OcBlockSpotlight.vue +47 -47
  32. package/src/blocks/OcBlockStats.vue +17 -17
  33. package/src/blocks/OcBlockStatsCounter.vue +20 -20
  34. package/src/blocks/OcBlockTeamList.vue +53 -53
  35. package/src/blocks/OcBlockTwoFactor.vue +61 -61
  36. package/src/blocks/OcBlockWizardDialog.vue +67 -67
  37. package/src/components/OcAccordion.vue +12 -12
  38. package/src/components/OcAccordionAccent.vue +27 -27
  39. package/src/components/OcAccordionItem.vue +19 -19
  40. package/src/components/OcAffixInput.vue +40 -40
  41. package/src/components/OcAlert.vue +17 -17
  42. package/src/components/OcAlertDialog.vue +66 -66
  43. package/src/components/OcAlphaTabs.vue +54 -54
  44. package/src/components/OcAspectRatio.vue +21 -21
  45. package/src/components/OcAttachment.vue +59 -59
  46. package/src/components/OcAttachmentImage.vue +13 -13
  47. package/src/components/OcAttachmentList.vue +31 -31
  48. package/src/components/OcAttachmentThumb.vue +14 -14
  49. package/src/components/OcAvatar.vue +18 -18
  50. package/src/components/OcAvatarGroup.vue +7 -7
  51. package/src/components/OcBackLink.vue +8 -8
  52. package/src/components/OcBadge.vue +13 -13
  53. package/src/components/OcBarcodeInput.vue +51 -51
  54. package/src/components/OcBreadcrumb.vue +22 -22
  55. package/src/components/OcBrowserFrame.vue +33 -33
  56. package/src/components/OcBusyOverlay.vue +32 -32
  57. package/src/components/OcButton.vue +47 -47
  58. package/src/components/OcButtonGroup.vue +10 -10
  59. package/src/components/OcButtonGroupText.vue +7 -7
  60. package/src/components/OcCard.vue +20 -20
  61. package/src/components/OcChartLine.vue +80 -80
  62. package/src/components/OcChatComposer.vue +42 -42
  63. package/src/components/OcCheckbox.vue +26 -26
  64. package/src/components/OcChecklist.vue +29 -29
  65. package/src/components/OcCollapsible.vue +19 -19
  66. package/src/components/OcColorField.vue +15 -15
  67. package/src/components/OcColorSelect.vue +33 -33
  68. package/src/components/OcColumnMenu.vue +50 -50
  69. package/src/components/OcCommand.vue +119 -119
  70. package/src/components/OcConfirmDialog.vue +65 -65
  71. package/src/components/OcCookieConsent.vue +119 -119
  72. package/src/components/OcCopyField.vue +37 -37
  73. package/src/components/OcCounter.vue +15 -15
  74. package/src/components/OcDataTable.vue +144 -144
  75. package/src/components/OcDefinitionList.vue +35 -35
  76. package/src/components/OcDropdown.vue +23 -23
  77. package/src/components/OcDropdownItem.vue +9 -9
  78. package/src/components/OcDropdownLabel.vue +7 -7
  79. package/src/components/OcDropdownSeparator.vue +7 -7
  80. package/src/components/OcDropzone.vue +36 -36
  81. package/src/components/OcEmojiPicker.vue +45 -45
  82. package/src/components/OcEmptyState.vue +13 -13
  83. package/src/components/OcEntityCard.vue +47 -47
  84. package/src/components/OcFactList.vue +37 -37
  85. package/src/components/OcFilterCounts.vue +38 -38
  86. package/src/components/OcFlipCard.vue +36 -36
  87. package/src/components/OcFormField.vue +36 -36
  88. package/src/components/OcGreeting.vue +52 -52
  89. package/src/components/OcHeading.vue +19 -19
  90. package/src/components/OcHoverCard.vue +25 -25
  91. package/src/components/OcImageZoom.vue +39 -39
  92. package/src/components/OcInput.vue +9 -9
  93. package/src/components/OcInputGroup.vue +12 -12
  94. package/src/components/OcItem.vue +40 -40
  95. package/src/components/OcItemGroup.vue +7 -7
  96. package/src/components/OcItemSeparator.vue +7 -7
  97. package/src/components/OcKbd.vue +7 -7
  98. package/src/components/OcKbdGroup.vue +15 -15
  99. package/src/components/OcLabel.vue +10 -10
  100. package/src/components/OcLanguageSelect.vue +40 -40
  101. package/src/components/OcLauncherCard.vue +34 -34
  102. package/src/components/OcLightbox.vue +63 -63
  103. package/src/components/OcLinkArrow.vue +25 -25
  104. package/src/components/OcListToolbar.vue +44 -44
  105. package/src/components/OcMarquee.vue +36 -36
  106. package/src/components/OcMediaCard.vue +28 -28
  107. package/src/components/OcMediaRow.vue +28 -28
  108. package/src/components/OcMediaThumb.vue +38 -38
  109. package/src/components/OcMessage.vue +91 -91
  110. package/src/components/OcMessageList.vue +43 -43
  111. package/src/components/OcMessageThread.vue +155 -155
  112. package/src/components/OcModal.vue +42 -42
  113. package/src/components/OcNavmenu.vue +18 -18
  114. package/src/components/OcNavmenuList.vue +38 -38
  115. package/src/components/OcNextTeaser.vue +25 -25
  116. package/src/components/OcNumberInput.vue +47 -47
  117. package/src/components/OcOtpInput.vue +34 -34
  118. package/src/components/OcPageHeader.vue +34 -34
  119. package/src/components/OcPagination.vue +33 -33
  120. package/src/components/OcPasswordInput.vue +27 -27
  121. package/src/components/OcPasswordRequirements.vue +28 -28
  122. package/src/components/OcPhoneInput.vue +72 -72
  123. package/src/components/OcPopover.vue +25 -25
  124. package/src/components/OcPriceCard.vue +69 -69
  125. package/src/components/OcProductMark.vue +31 -31
  126. package/src/components/OcProgress.vue +21 -21
  127. package/src/components/OcProjectCard.vue +36 -36
  128. package/src/components/OcProse.vue +57 -57
  129. package/src/components/OcRadio.vue +40 -40
  130. package/src/components/OcRadioGroup.vue +32 -32
  131. package/src/components/OcRecoveryCodes.vue +55 -55
  132. package/src/components/OcScrollArea.vue +15 -15
  133. package/src/components/OcSegmented.vue +28 -28
  134. package/src/components/OcSelect.vue +21 -21
  135. package/src/components/OcSeparator.vue +18 -18
  136. package/src/components/OcSeverityCard.vue +46 -46
  137. package/src/components/OcSheet.vue +49 -49
  138. package/src/components/OcSidebarCollapsible.vue +19 -19
  139. package/src/components/OcSidebarGroup.vue +11 -11
  140. package/src/components/OcSidebarMenu.vue +7 -7
  141. package/src/components/OcSidebarMenuButton.vue +31 -31
  142. package/src/components/OcSidebarSeparator.vue +7 -7
  143. package/src/components/OcSkeleton.vue +8 -8
  144. package/src/components/OcSlider.vue +27 -27
  145. package/src/components/OcSortableRow.vue +40 -40
  146. package/src/components/OcSpinner.vue +13 -13
  147. package/src/components/OcStackCard.vue +24 -24
  148. package/src/components/OcStackList.vue +31 -31
  149. package/src/components/OcStatCard.vue +39 -39
  150. package/src/components/OcStepper.vue +34 -34
  151. package/src/components/OcSwitch.vue +15 -15
  152. package/src/components/OcTable.vue +115 -115
  153. package/src/components/OcTableActions.vue +26 -26
  154. package/src/components/OcTableCompact.vue +46 -46
  155. package/src/components/OcTabs.vue +37 -37
  156. package/src/components/OcTagInput.vue +50 -50
  157. package/src/components/OcTerminalLog.vue +50 -50
  158. package/src/components/OcTextarea.vue +9 -9
  159. package/src/components/OcThemeSwitch.vue +31 -31
  160. package/src/components/OcTimeInput.vue +50 -50
  161. package/src/components/OcTimeline.vue +36 -36
  162. package/src/components/OcToast.vue +31 -31
  163. package/src/components/OcToastContainer.vue +21 -21
  164. package/src/components/OcToggle.vue +63 -63
  165. package/src/components/OcToggleField.vue +28 -28
  166. package/src/components/OcToggleGroup.vue +40 -40
  167. package/src/components/OcTooltip.vue +8 -8
  168. package/src/components/OcTopProgress.vue +54 -54
  169. package/src/components/OcTree.vue +70 -70
  170. package/src/components/OcUpgradeBanner.vue +42 -42
  171. package/src/components/OcUser.vue +25 -25
  172. package/src/components/OcVersionBanner.vue +34 -34
  173. package/src/composables/chartLine.ts +28 -28
  174. package/src/composables/keys.ts +22 -22
  175. package/src/composables/useAttrsSplit.ts +16 -16
  176. package/src/composables/useDialog.ts +21 -21
  177. package/src/composables/useToast.ts +66 -66
  178. package/src/composables/useUid.ts +12 -12
@@ -1,27 +1,27 @@
1
- <script setup lang="ts">
2
- /**
3
- * Card with title, actions, toolbar, table, bulk bar and footer. Put an <OcTable> in the default slot.
4
- * Slots: actions (header buttons), toolbar (.oc-table-toolbar content: search, filter pills, columns popover),
5
- * bulk (selection bar, shown when `selectedCount` > 0), default (table), footer (.oc-table-footer: entries text, page size, pagination).
6
- * Classes: .oc-card.oc-block-datatable, -head, -title, -description, -body, -bulk, .oc-table-toolbar, .oc-table-footer
7
- */
8
- defineProps<{ title?: string; description?: string; selectedCount?: number }>()
9
- </script>
10
-
11
- <template>
12
- <section class="oc-card oc-block-datatable">
13
- <header v-if="title || description || $slots.actions" class="oc-block-datatable-head">
14
- <div>
15
- <h2 v-if="title" class="oc-block-datatable-title">{{ title }}</h2>
16
- <p v-if="description" class="oc-block-datatable-description">{{ description }}</p>
17
- </div>
18
- <div v-if="$slots.actions"><slot name="actions" /></div>
19
- </header>
20
- <div class="oc-block-datatable-body">
21
- <div v-if="$slots.toolbar" class="oc-table-toolbar"><slot name="toolbar" /></div>
22
- <div v-if="$slots.bulk && selectedCount" class="oc-block-datatable-bulk"><slot name="bulk" :count="selectedCount" /></div>
23
- <slot />
24
- <div v-if="$slots.footer" class="oc-table-footer"><slot name="footer" /></div>
25
- </div>
26
- </section>
27
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * Card with title, actions, toolbar, table, bulk bar and footer. Put an <OcTable> in the default slot.
4
+ * Slots: actions (header buttons), toolbar (.oc-table-toolbar content: search, filter pills, columns popover),
5
+ * bulk (selection bar, shown when `selectedCount` > 0), default (table), footer (.oc-table-footer: entries text, page size, pagination).
6
+ * Classes: .oc-card.oc-block-datatable, -head, -title, -description, -body, -bulk, .oc-table-toolbar, .oc-table-footer
7
+ */
8
+ defineProps<{ title?: string; description?: string; selectedCount?: number }>()
9
+ </script>
10
+
11
+ <template>
12
+ <section class="oc-card oc-block-datatable">
13
+ <header v-if="title || description || $slots.actions" class="oc-block-datatable-head">
14
+ <div>
15
+ <h2 v-if="title" class="oc-block-datatable-title">{{ title }}</h2>
16
+ <p v-if="description" class="oc-block-datatable-description">{{ description }}</p>
17
+ </div>
18
+ <div v-if="$slots.actions"><slot name="actions" /></div>
19
+ </header>
20
+ <div class="oc-block-datatable-body">
21
+ <div v-if="$slots.toolbar" class="oc-table-toolbar"><slot name="toolbar" /></div>
22
+ <div v-if="$slots.bulk && selectedCount" class="oc-block-datatable-bulk"><slot name="bulk" :count="selectedCount" /></div>
23
+ <slot />
24
+ <div v-if="$slots.footer" class="oc-table-footer"><slot name="footer" /></div>
25
+ </div>
26
+ </section>
27
+ </template>
@@ -1,49 +1,49 @@
1
- <!-- File: packages/vue/src/blocks/OcBlockFaq.vue | Map: props -> section.oc-block-faq -> head -> accordion (details name) -> more slot -->
2
- <script setup lang="ts">
3
- /**
4
- * FAQ section: title + exclusive accordion on native <details name> (no JavaScript).
5
- * Slots: lead, default (own details items), more. Classes: .oc-block-faq (--split), -inner, -head, -title, -lead, -list, -more
6
- */
7
- import { useUid } from '../composables/useUid'
8
-
9
- export interface FaqItem {
10
- question: string
11
- answer: string
12
- }
13
- const props = withDefaults(
14
- defineProps<{
15
- eyebrow?: string
16
- title: string
17
- lead?: string
18
- items?: FaqItem[]
19
- openIndex?: number
20
- split?: boolean
21
- name?: string
22
- }>(),
23
- { items: () => [], openIndex: 0 },
24
- )
25
- const titleId = useUid('oc-faq-title')
26
- const autoGroup = useUid('oc-faq')
27
- const group = props.name ?? autoGroup
28
- </script>
29
-
30
- <template>
31
- <section :class="['oc-block-faq', split && 'oc-block-faq--split']" :aria-labelledby="titleId">
32
- <div class="oc-block-faq-inner">
33
- <div class="oc-block-faq-head">
34
- <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
35
- <h2 :id="titleId" class="oc-block-faq-title">{{ title }}</h2>
36
- <p v-if="lead || $slots.lead" class="oc-block-faq-lead"><slot name="lead">{{ lead }}</slot></p>
37
- </div>
38
- <div class="oc-accordion oc-block-faq-list">
39
- <slot>
40
- <details v-for="(item, i) in items" :key="i" class="oc-accordion-item" :name="group" :open="i === openIndex">
41
- <summary class="oc-accordion-trigger">{{ item.question }}</summary>
42
- <div class="oc-accordion-content">{{ item.answer }}</div>
43
- </details>
44
- </slot>
45
- </div>
46
- <p v-if="$slots.more" class="oc-block-faq-more"><slot name="more" /></p>
47
- </div>
48
- </section>
49
- </template>
1
+ <!-- File: packages/vue/src/blocks/OcBlockFaq.vue | Map: props -> section.oc-block-faq -> head -> accordion (details name) -> more slot -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * FAQ section: title + exclusive accordion on native <details name> (no JavaScript).
5
+ * Slots: lead, default (own details items), more. Classes: .oc-block-faq (--split), -inner, -head, -title, -lead, -list, -more
6
+ */
7
+ import { useUid } from '../composables/useUid'
8
+
9
+ export interface FaqItem {
10
+ question: string
11
+ answer: string
12
+ }
13
+ const props = withDefaults(
14
+ defineProps<{
15
+ eyebrow?: string
16
+ title: string
17
+ lead?: string
18
+ items?: FaqItem[]
19
+ openIndex?: number
20
+ split?: boolean
21
+ name?: string
22
+ }>(),
23
+ { items: () => [], openIndex: 0 },
24
+ )
25
+ const titleId = useUid('oc-faq-title')
26
+ const autoGroup = useUid('oc-faq')
27
+ const group = props.name ?? autoGroup
28
+ </script>
29
+
30
+ <template>
31
+ <section :class="['oc-block-faq', split && 'oc-block-faq--split']" :aria-labelledby="titleId">
32
+ <div class="oc-block-faq-inner">
33
+ <div class="oc-block-faq-head">
34
+ <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
35
+ <h2 :id="titleId" class="oc-block-faq-title">{{ title }}</h2>
36
+ <p v-if="lead || $slots.lead" class="oc-block-faq-lead"><slot name="lead">{{ lead }}</slot></p>
37
+ </div>
38
+ <div class="oc-accordion oc-block-faq-list">
39
+ <slot>
40
+ <details v-for="(item, i) in items" :key="i" class="oc-accordion-item" :name="group" :open="i === openIndex">
41
+ <summary class="oc-accordion-trigger">{{ item.question }}</summary>
42
+ <div class="oc-accordion-content">{{ item.answer }}</div>
43
+ </details>
44
+ </slot>
45
+ </div>
46
+ <p v-if="$slots.more" class="oc-block-faq-more"><slot name="more" /></p>
47
+ </div>
48
+ </section>
49
+ </template>
@@ -1,23 +1,23 @@
1
- <script setup lang="ts">
2
- /** Feature grid with icons. Slot `icon` (scoped: { item }) overrides the glyph. Classes: .oc-block-features, -grid, .oc-block-feature-card, -icon */
3
- export interface FeatureItem {
4
- icon?: string
5
- title: string
6
- text: string
7
- }
8
- defineProps<{ title?: string; description?: string; items: FeatureItem[] }>()
9
- </script>
10
-
11
- <template>
12
- <div class="oc-block-features">
13
- <h2 v-if="title">{{ title }}</h2>
14
- <p v-if="description">{{ description }}</p>
15
- <div class="oc-block-features-grid">
16
- <div v-for="(item, i) in items" :key="i" class="oc-block-feature-card">
17
- <div class="oc-block-feature-icon"><slot name="icon" :item="item">{{ item.icon }}</slot></div>
18
- <h3>{{ item.title }}</h3>
19
- <p>{{ item.text }}</p>
20
- </div>
21
- </div>
22
- </div>
23
- </template>
1
+ <script setup lang="ts">
2
+ /** Feature grid with icons. Slot `icon` (scoped: { item }) overrides the glyph. Classes: .oc-block-features, -grid, .oc-block-feature-card, -icon */
3
+ export interface FeatureItem {
4
+ icon?: string
5
+ title: string
6
+ text: string
7
+ }
8
+ defineProps<{ title?: string; description?: string; items: FeatureItem[] }>()
9
+ </script>
10
+
11
+ <template>
12
+ <div class="oc-block-features">
13
+ <h2 v-if="title">{{ title }}</h2>
14
+ <p v-if="description">{{ description }}</p>
15
+ <div class="oc-block-features-grid">
16
+ <div v-for="(item, i) in items" :key="i" class="oc-block-feature-card">
17
+ <div class="oc-block-feature-icon"><slot name="icon" :item="item">{{ item.icon }}</slot></div>
18
+ <h3>{{ item.title }}</h3>
19
+ <p>{{ item.text }}</p>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </template>
@@ -1,25 +1,25 @@
1
- <script setup lang="ts">
2
- /** Multi-column site footer. Slots: bottom-start, bottom-end (default text via `copyright` / `credit`). Classes: .oc-block-footer, -grid, -col, -bottom */
3
- export interface FooterColumn {
4
- title: string
5
- links: { label: string; href: string }[]
6
- }
7
- defineProps<{ columns: FooterColumn[]; copyright?: string; credit?: string }>()
8
- </script>
9
-
10
- <template>
11
- <div class="oc-block-footer">
12
- <div class="oc-block-footer-grid">
13
- <div v-for="col in columns" :key="col.title" class="oc-block-footer-col">
14
- <h4>{{ col.title }}</h4>
15
- <ul>
16
- <li v-for="link in col.links" :key="link.href + link.label"><a :href="link.href">{{ link.label }}</a></li>
17
- </ul>
18
- </div>
19
- </div>
20
- <div v-if="copyright || credit || $slots['bottom-start'] || $slots['bottom-end']" class="oc-block-footer-bottom">
21
- <span><slot name="bottom-start">{{ copyright }}</slot></span>
22
- <span><slot name="bottom-end">{{ credit }}</slot></span>
23
- </div>
24
- </div>
25
- </template>
1
+ <script setup lang="ts">
2
+ /** Multi-column site footer. Slots: bottom-start, bottom-end (default text via `copyright` / `credit`). Classes: .oc-block-footer, -grid, -col, -bottom */
3
+ export interface FooterColumn {
4
+ title: string
5
+ links: { label: string; href: string }[]
6
+ }
7
+ defineProps<{ columns: FooterColumn[]; copyright?: string; credit?: string }>()
8
+ </script>
9
+
10
+ <template>
11
+ <div class="oc-block-footer">
12
+ <div class="oc-block-footer-grid">
13
+ <div v-for="col in columns" :key="col.title" class="oc-block-footer-col">
14
+ <h4>{{ col.title }}</h4>
15
+ <ul>
16
+ <li v-for="link in col.links" :key="link.href + link.label"><a :href="link.href">{{ link.label }}</a></li>
17
+ </ul>
18
+ </div>
19
+ </div>
20
+ <div v-if="copyright || credit || $slots['bottom-start'] || $slots['bottom-end']" class="oc-block-footer-bottom">
21
+ <span><slot name="bottom-start">{{ copyright }}</slot></span>
22
+ <span><slot name="bottom-end">{{ credit }}</slot></span>
23
+ </div>
24
+ </div>
25
+ </template>
@@ -1,24 +1,24 @@
1
- <script setup lang="ts">
2
- /**
3
- * Collapsible form sections with a sticky action bar. Default slot = sections (OcCollapsible containing a
4
- * `<div class="oc-block-formpage-grid">` for the two-column field grid). Emits `submit`.
5
- * Slot `actions` replaces the default Cancel / Save buttons. Classes: .oc-block-formpage, -grid, -actions
6
- */
7
- withDefaults(
8
- defineProps<{ cancelLabel?: string; submitLabel?: string; action?: string; method?: string }>(),
9
- { cancelLabel: 'Cancel', submitLabel: 'Save', action: '#', method: 'post' },
10
- )
11
- defineEmits<{ submit: [event: SubmitEvent]; cancel: [] }>()
12
- </script>
13
-
14
- <template>
15
- <form class="oc-block-formpage" :action="action" :method="method" @submit="$emit('submit', $event)">
16
- <slot />
17
- <div class="oc-block-formpage-actions">
18
- <slot name="actions">
19
- <button class="oc-btn oc-btn--outline" type="button" @click="$emit('cancel')">{{ cancelLabel }}</button>
20
- <button class="oc-btn" type="submit">{{ submitLabel }}</button>
21
- </slot>
22
- </div>
23
- </form>
24
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * Collapsible form sections with a sticky action bar. Default slot = sections (OcCollapsible containing a
4
+ * `<div class="oc-block-formpage-grid">` for the two-column field grid). Emits `submit`.
5
+ * Slot `actions` replaces the default Cancel / Save buttons. Classes: .oc-block-formpage, -grid, -actions
6
+ */
7
+ withDefaults(
8
+ defineProps<{ cancelLabel?: string; submitLabel?: string; action?: string; method?: string }>(),
9
+ { cancelLabel: 'Cancel', submitLabel: 'Save', action: '#', method: 'post' },
10
+ )
11
+ defineEmits<{ submit: [event: SubmitEvent]; cancel: [] }>()
12
+ </script>
13
+
14
+ <template>
15
+ <form class="oc-block-formpage" :action="action" :method="method" @submit="$emit('submit', $event)">
16
+ <slot />
17
+ <div class="oc-block-formpage-actions">
18
+ <slot name="actions">
19
+ <button class="oc-btn oc-btn--outline" type="button" @click="$emit('cancel')">{{ cancelLabel }}</button>
20
+ <button class="oc-btn" type="submit">{{ submitLabel }}</button>
21
+ </slot>
22
+ </div>
23
+ </form>
24
+ </template>
@@ -1,13 +1,13 @@
1
- <script setup lang="ts">
2
- /** Centered hero with badge, headline, text and actions. Classes: .oc-block-hero, -badge, -actions */
3
- defineProps<{ badge?: string; title?: string; text?: string }>()
4
- </script>
5
-
6
- <template>
7
- <div class="oc-block-hero">
8
- <span v-if="badge" class="oc-block-hero-badge">{{ badge }}</span>
9
- <h1 v-if="title">{{ title }}</h1>
10
- <p v-if="text">{{ text }}</p>
11
- <div v-if="$slots.actions" class="oc-block-hero-actions"><slot name="actions" /></div>
12
- </div>
13
- </template>
1
+ <script setup lang="ts">
2
+ /** Centered hero with badge, headline, text and actions. Classes: .oc-block-hero, -badge, -actions */
3
+ defineProps<{ badge?: string; title?: string; text?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <div class="oc-block-hero">
8
+ <span v-if="badge" class="oc-block-hero-badge">{{ badge }}</span>
9
+ <h1 v-if="title">{{ title }}</h1>
10
+ <p v-if="text">{{ text }}</p>
11
+ <div v-if="$slots.actions" class="oc-block-hero-actions"><slot name="actions" /></div>
12
+ </div>
13
+ </template>
@@ -1,42 +1,42 @@
1
- <script setup lang="ts">
2
- /**
3
- * Landing hero: eyebrow, display title with a gradient word, lead, buttons and a code window with floating icon tiles.
4
- * `title` + `highlight` (gradient word) + `titleEnd`, or the `title` slot. Slots: lead, actions, visual (replaces the code window).
5
- * Classes: .oc-section-pad, .oc-container, .oc-split, .oc-eyebrow, .oc-display, .oc-text-gradient, .oc-lead, .oc-code-window
6
- */
7
- defineProps<{
8
- eyebrow?: string
9
- title?: string
10
- highlight?: string
11
- titleEnd?: string
12
- lead?: string
13
- code?: string
14
- codeTitle?: string
15
- }>()
16
- </script>
17
-
18
- <template>
19
- <section class="oc-section-pad">
20
- <div class="oc-container oc-split">
21
- <div>
22
- <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
23
- <h1 class="oc-display">
24
- <slot name="title">{{ title }} <span v-if="highlight" class="oc-text-gradient">{{ highlight }}</span>{{ titleEnd }}</slot>
25
- </h1>
26
- <p v-if="lead || $slots.lead" class="oc-lead"><slot name="lead">{{ lead }}</slot></p>
27
- <div v-if="$slots.actions" class="flex flex-wrap gap-1 mt-2"><slot name="actions" /></div>
28
- </div>
29
- <div class="relative p-2">
30
- <slot name="visual">
31
- <span class="oc-icon-tile oc-icon-tile--float oc-accent--green absolute" style="inset: -0.5rem auto auto 8%" aria-hidden="true">&#9670;</span>
32
- <span class="oc-icon-tile oc-icon-tile--float oc-accent--violet absolute" style="inset: 0 6% auto auto; animation-delay: -2s" aria-hidden="true">&#9673;</span>
33
- <span class="oc-icon-tile oc-icon-tile--float oc-accent--orange absolute" style="inset: auto 10% -0.5rem auto; animation-delay: -4s" aria-hidden="true">&#9650;</span>
34
- <div class="oc-code-window">
35
- <div class="oc-code-window__bar"><i></i><i></i><i></i><span v-if="codeTitle" class="oc-code-window__title">{{ codeTitle }}</span></div>
36
- <pre class="oc-code-window__body">{{ code }}</pre>
37
- </div>
38
- </slot>
39
- </div>
40
- </div>
41
- </section>
42
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * Landing hero: eyebrow, display title with a gradient word, lead, buttons and a code window with floating icon tiles.
4
+ * `title` + `highlight` (gradient word) + `titleEnd`, or the `title` slot. Slots: lead, actions, visual (replaces the code window).
5
+ * Classes: .oc-section-pad, .oc-container, .oc-split, .oc-eyebrow, .oc-display, .oc-text-gradient, .oc-lead, .oc-code-window
6
+ */
7
+ defineProps<{
8
+ eyebrow?: string
9
+ title?: string
10
+ highlight?: string
11
+ titleEnd?: string
12
+ lead?: string
13
+ code?: string
14
+ codeTitle?: string
15
+ }>()
16
+ </script>
17
+
18
+ <template>
19
+ <section class="oc-section-pad">
20
+ <div class="oc-container oc-split">
21
+ <div>
22
+ <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
23
+ <h1 class="oc-display">
24
+ <slot name="title">{{ title }} <span v-if="highlight" class="oc-text-gradient">{{ highlight }}</span>{{ titleEnd }}</slot>
25
+ </h1>
26
+ <p v-if="lead || $slots.lead" class="oc-lead"><slot name="lead">{{ lead }}</slot></p>
27
+ <div v-if="$slots.actions" class="flex flex-wrap gap-1 mt-2"><slot name="actions" /></div>
28
+ </div>
29
+ <div class="relative p-2">
30
+ <slot name="visual">
31
+ <span class="oc-icon-tile oc-icon-tile--float oc-accent--green absolute" style="inset: -0.5rem auto auto 8%" aria-hidden="true">&#9670;</span>
32
+ <span class="oc-icon-tile oc-icon-tile--float oc-accent--violet absolute" style="inset: 0 6% auto auto; animation-delay: -2s" aria-hidden="true">&#9673;</span>
33
+ <span class="oc-icon-tile oc-icon-tile--float oc-accent--orange absolute" style="inset: auto 10% -0.5rem auto; animation-delay: -4s" aria-hidden="true">&#9650;</span>
34
+ <div class="oc-code-window">
35
+ <div class="oc-code-window__bar"><i></i><i></i><i></i><span v-if="codeTitle" class="oc-code-window__title">{{ codeTitle }}</span></div>
36
+ <pre class="oc-code-window__body">{{ code }}</pre>
37
+ </div>
38
+ </slot>
39
+ </div>
40
+ </div>
41
+ </section>
42
+ </template>
@@ -1,69 +1,69 @@
1
- <!-- File: packages/vue/src/blocks/OcBlockHeroOrbit.vue | Map: props + default marks -> copy -> visual (ring with marks + center slot / code window) -->
2
- <script setup lang="ts">
3
- /**
4
- * Hero with a code window and product marks that orbit around it (reduced motion: they stand still).
5
- * `title` + `highlight` + `titleEnd`, or the `title` slot. Slots: lead, actions, center (replaces the code window;
6
- * give it class="oc-block-orbit-center"). Classes: .oc-block-orbit-visual, -ring, -mark (--oc-orbit-angle), -center
7
- */
8
- import { computed } from 'vue'
9
-
10
- export interface HeroOrbitMark {
11
- glyph: string
12
- accent: string
13
- }
14
- const props = withDefaults(
15
- defineProps<{
16
- eyebrow?: string
17
- title?: string
18
- highlight?: string
19
- titleEnd?: string
20
- lead?: string
21
- code?: string
22
- codeTitle?: string
23
- marks?: HeroOrbitMark[]
24
- duration?: string
25
- }>(),
26
- {
27
- code: '',
28
- marks: () => [
29
- { glyph: '◆', accent: 'green' },
30
- { glyph: '◉', accent: 'violet' },
31
- { glyph: '▲', accent: 'orange' },
32
- { glyph: '★', accent: 'cyan' },
33
- { glyph: '♥', accent: 'red' },
34
- { glyph: '☀', accent: 'yellow' },
35
- ],
36
- },
37
- )
38
- // Spread the marks evenly over the ring.
39
- const angle = (i: number) => `--oc-orbit-angle: ${(360 / props.marks.length) * i}deg`
40
- const visualStyle = computed(() => (props.duration ? `--oc-orbit-duration: ${props.duration}` : undefined))
41
- </script>
42
-
43
- <template>
44
- <section class="oc-block-orbit oc-section-pad">
45
- <div class="oc-container oc-split">
46
- <div>
47
- <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
48
- <h1 class="oc-display">
49
- <slot name="title">{{ title }} <span v-if="highlight" class="oc-text-gradient">{{ highlight }}</span>{{ titleEnd }}</slot>
50
- </h1>
51
- <p v-if="lead || $slots.lead" class="oc-lead"><slot name="lead">{{ lead }}</slot></p>
52
- <div v-if="$slots.actions" class="flex flex-wrap gap-1 mt-2"><slot name="actions" /></div>
53
- </div>
54
- <div class="oc-block-orbit-visual" :style="visualStyle">
55
- <div class="oc-block-orbit-ring" aria-hidden="true">
56
- <span v-for="(mark, i) in marks" :key="i" class="oc-block-orbit-mark" :style="angle(i)">
57
- <span :class="['oc-product-mark oc-product-mark--sm', `oc-accent--${mark.accent}`]">{{ mark.glyph }}</span>
58
- </span>
59
- </div>
60
- <slot name="center">
61
- <div class="oc-code-window oc-block-orbit-center">
62
- <div class="oc-code-window__bar"><i></i><i></i><i></i><span v-if="codeTitle" class="oc-code-window__title">{{ codeTitle }}</span></div>
63
- <pre class="oc-code-window__body">{{ code }}</pre>
64
- </div>
65
- </slot>
66
- </div>
67
- </div>
68
- </section>
69
- </template>
1
+ <!-- File: packages/vue/src/blocks/OcBlockHeroOrbit.vue | Map: props + default marks -> copy -> visual (ring with marks + center slot / code window) -->
2
+ <script setup lang="ts">
3
+ /**
4
+ * Hero with a code window and product marks that orbit around it (reduced motion: they stand still).
5
+ * `title` + `highlight` + `titleEnd`, or the `title` slot. Slots: lead, actions, center (replaces the code window;
6
+ * give it class="oc-block-orbit-center"). Classes: .oc-block-orbit-visual, -ring, -mark (--oc-orbit-angle), -center
7
+ */
8
+ import { computed } from 'vue'
9
+
10
+ export interface HeroOrbitMark {
11
+ glyph: string
12
+ accent: string
13
+ }
14
+ const props = withDefaults(
15
+ defineProps<{
16
+ eyebrow?: string
17
+ title?: string
18
+ highlight?: string
19
+ titleEnd?: string
20
+ lead?: string
21
+ code?: string
22
+ codeTitle?: string
23
+ marks?: HeroOrbitMark[]
24
+ duration?: string
25
+ }>(),
26
+ {
27
+ code: '',
28
+ marks: () => [
29
+ { glyph: '◆', accent: 'green' },
30
+ { glyph: '◉', accent: 'violet' },
31
+ { glyph: '▲', accent: 'orange' },
32
+ { glyph: '★', accent: 'cyan' },
33
+ { glyph: '♥', accent: 'red' },
34
+ { glyph: '☀', accent: 'yellow' },
35
+ ],
36
+ },
37
+ )
38
+ // Spread the marks evenly over the ring.
39
+ const angle = (i: number) => `--oc-orbit-angle: ${(360 / props.marks.length) * i}deg`
40
+ const visualStyle = computed(() => (props.duration ? `--oc-orbit-duration: ${props.duration}` : undefined))
41
+ </script>
42
+
43
+ <template>
44
+ <section class="oc-block-orbit oc-section-pad">
45
+ <div class="oc-container oc-split">
46
+ <div>
47
+ <p v-if="eyebrow" class="oc-eyebrow">{{ eyebrow }}</p>
48
+ <h1 class="oc-display">
49
+ <slot name="title">{{ title }} <span v-if="highlight" class="oc-text-gradient">{{ highlight }}</span>{{ titleEnd }}</slot>
50
+ </h1>
51
+ <p v-if="lead || $slots.lead" class="oc-lead"><slot name="lead">{{ lead }}</slot></p>
52
+ <div v-if="$slots.actions" class="flex flex-wrap gap-1 mt-2"><slot name="actions" /></div>
53
+ </div>
54
+ <div class="oc-block-orbit-visual" :style="visualStyle">
55
+ <div class="oc-block-orbit-ring" aria-hidden="true">
56
+ <span v-for="(mark, i) in marks" :key="i" class="oc-block-orbit-mark" :style="angle(i)">
57
+ <span :class="['oc-product-mark oc-product-mark--sm', `oc-accent--${mark.accent}`]">{{ mark.glyph }}</span>
58
+ </span>
59
+ </div>
60
+ <slot name="center">
61
+ <div class="oc-code-window oc-block-orbit-center">
62
+ <div class="oc-code-window__bar"><i></i><i></i><i></i><span v-if="codeTitle" class="oc-code-window__title">{{ codeTitle }}</span></div>
63
+ <pre class="oc-code-window__body">{{ code }}</pre>
64
+ </div>
65
+ </slot>
66
+ </div>
67
+ </div>
68
+ </section>
69
+ </template>
@@ -1,15 +1,15 @@
1
- <script setup lang="ts">
2
- /** Hero with text left and visual right. Slots: actions, visual. Classes: .oc-block-hero-split, -actions, -visual */
3
- defineProps<{ title?: string; text?: string }>()
4
- </script>
5
-
6
- <template>
7
- <div class="oc-block-hero-split">
8
- <div>
9
- <h1 v-if="title">{{ title }}</h1>
10
- <p v-if="text">{{ text }}</p>
11
- <div v-if="$slots.actions" class="oc-block-hero-actions justify-start"><slot name="actions" /></div>
12
- </div>
13
- <div class="oc-block-hero-visual"><slot name="visual" /></div>
14
- </div>
15
- </template>
1
+ <script setup lang="ts">
2
+ /** Hero with text left and visual right. Slots: actions, visual. Classes: .oc-block-hero-split, -actions, -visual */
3
+ defineProps<{ title?: string; text?: string }>()
4
+ </script>
5
+
6
+ <template>
7
+ <div class="oc-block-hero-split">
8
+ <div>
9
+ <h1 v-if="title">{{ title }}</h1>
10
+ <p v-if="text">{{ text }}</p>
11
+ <div v-if="$slots.actions" class="oc-block-hero-actions justify-start"><slot name="actions" /></div>
12
+ </div>
13
+ <div class="oc-block-hero-visual"><slot name="visual" /></div>
14
+ </div>
15
+ </template>
@@ -1,21 +1,21 @@
1
- <script setup lang="ts">
2
- /**
3
- * Page header with icon tile, title, intro, meta badges and an action row.
4
- * Slots: icon, meta (badges), actions. Classes: .oc-block-modulehead, -band, -icon, -body, -title, -intro, -meta, -actions
5
- */
6
- defineProps<{ title: string; intro?: string }>()
7
- </script>
8
-
9
- <template>
10
- <header class="oc-block-modulehead">
11
- <div class="oc-block-modulehead-band">
12
- <span v-if="$slots.icon" class="oc-block-modulehead-icon" aria-hidden="true"><slot name="icon" /></span>
13
- <div class="oc-block-modulehead-body">
14
- <h1 class="oc-block-modulehead-title">{{ title }}</h1>
15
- <p v-if="intro" class="oc-block-modulehead-intro">{{ intro }}</p>
16
- <div v-if="$slots.meta" class="oc-block-modulehead-meta"><slot name="meta" /></div>
17
- </div>
18
- </div>
19
- <div v-if="$slots.actions" class="oc-block-modulehead-actions"><slot name="actions" /></div>
20
- </header>
21
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * Page header with icon tile, title, intro, meta badges and an action row.
4
+ * Slots: icon, meta (badges), actions. Classes: .oc-block-modulehead, -band, -icon, -body, -title, -intro, -meta, -actions
5
+ */
6
+ defineProps<{ title: string; intro?: string }>()
7
+ </script>
8
+
9
+ <template>
10
+ <header class="oc-block-modulehead">
11
+ <div class="oc-block-modulehead-band">
12
+ <span v-if="$slots.icon" class="oc-block-modulehead-icon" aria-hidden="true"><slot name="icon" /></span>
13
+ <div class="oc-block-modulehead-body">
14
+ <h1 class="oc-block-modulehead-title">{{ title }}</h1>
15
+ <p v-if="intro" class="oc-block-modulehead-intro">{{ intro }}</p>
16
+ <div v-if="$slots.meta" class="oc-block-modulehead-meta"><slot name="meta" /></div>
17
+ </div>
18
+ </div>
19
+ <div v-if="$slots.actions" class="oc-block-modulehead-actions"><slot name="actions" /></div>
20
+ </header>
21
+ </template>