@birdycom/omniaui-vue 0.11.0 → 0.11.2
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 -21
- package/README.md +49 -49
- package/dist/omniaui-vue.js.map +1 -1
- package/package.json +69 -69
- package/src/blocks/OcBlockAboutTimeline.vue +44 -44
- package/src/blocks/OcBlockAppHeader.vue +36 -36
- package/src/blocks/OcBlockAppShell.vue +29 -29
- package/src/blocks/OcBlockAuth.vue +24 -24
- package/src/blocks/OcBlockAuthSplit.vue +47 -47
- package/src/blocks/OcBlockContactGrid.vue +53 -53
- package/src/blocks/OcBlockCta.vue +12 -12
- package/src/blocks/OcBlockDataTable.vue +27 -27
- package/src/blocks/OcBlockFaq.vue +49 -49
- package/src/blocks/OcBlockFeatures.vue +23 -23
- package/src/blocks/OcBlockFooter.vue +25 -25
- package/src/blocks/OcBlockFormPage.vue +24 -24
- package/src/blocks/OcBlockHero.vue +13 -13
- package/src/blocks/OcBlockHeroCode.vue +42 -42
- package/src/blocks/OcBlockHeroOrbit.vue +69 -69
- package/src/blocks/OcBlockHeroSplit.vue +15 -15
- package/src/blocks/OcBlockModuleHeader.vue +21 -21
- package/src/blocks/OcBlockPageHero.vue +13 -13
- package/src/blocks/OcBlockPortfolioGrid.vue +63 -63
- package/src/blocks/OcBlockPricing.vue +39 -39
- package/src/blocks/OcBlockProcess.vue +39 -39
- package/src/blocks/OcBlockProductGrid.vue +41 -41
- package/src/blocks/OcBlockProfileHeader.vue +50 -50
- package/src/blocks/OcBlockShowcase.vue +43 -43
- package/src/blocks/OcBlockSiteFooter.vue +54 -54
- package/src/blocks/OcBlockSiteHeader.vue +34 -34
- package/src/blocks/OcBlockSpotlight.vue +47 -47
- package/src/blocks/OcBlockStats.vue +17 -17
- package/src/blocks/OcBlockStatsCounter.vue +20 -20
- package/src/blocks/OcBlockTeamList.vue +53 -53
- package/src/blocks/OcBlockTwoFactor.vue +61 -61
- package/src/blocks/OcBlockWizardDialog.vue +67 -67
- package/src/components/OcAccordion.vue +12 -12
- package/src/components/OcAccordionAccent.vue +27 -27
- package/src/components/OcAccordionItem.vue +19 -19
- package/src/components/OcAffixInput.vue +40 -40
- package/src/components/OcAlert.vue +17 -17
- package/src/components/OcAlertDialog.vue +66 -66
- package/src/components/OcAlphaTabs.vue +54 -54
- package/src/components/OcAspectRatio.vue +21 -21
- package/src/components/OcAttachment.vue +59 -59
- package/src/components/OcAttachmentImage.vue +13 -13
- package/src/components/OcAttachmentList.vue +31 -31
- package/src/components/OcAttachmentThumb.vue +14 -14
- package/src/components/OcAvatar.vue +18 -18
- package/src/components/OcAvatarGroup.vue +7 -7
- package/src/components/OcBackLink.vue +8 -8
- package/src/components/OcBadge.vue +13 -13
- package/src/components/OcBarcodeInput.vue +51 -51
- package/src/components/OcBreadcrumb.vue +22 -22
- package/src/components/OcBrowserFrame.vue +33 -33
- package/src/components/OcBusyOverlay.vue +32 -32
- package/src/components/OcButton.vue +47 -47
- package/src/components/OcButtonGroup.vue +10 -10
- package/src/components/OcButtonGroupText.vue +7 -7
- package/src/components/OcCard.vue +20 -20
- package/src/components/OcChartLine.vue +80 -80
- package/src/components/OcChatComposer.vue +42 -42
- package/src/components/OcCheckbox.vue +26 -26
- package/src/components/OcChecklist.vue +29 -29
- package/src/components/OcCollapsible.vue +19 -19
- package/src/components/OcColorField.vue +15 -15
- package/src/components/OcColorSelect.vue +33 -33
- package/src/components/OcColumnMenu.vue +50 -50
- package/src/components/OcCommand.vue +119 -119
- package/src/components/OcConfirmDialog.vue +65 -65
- package/src/components/OcCookieConsent.vue +119 -119
- package/src/components/OcCopyField.vue +37 -37
- package/src/components/OcCounter.vue +15 -15
- package/src/components/OcDataTable.vue +144 -144
- package/src/components/OcDefinitionList.vue +35 -35
- package/src/components/OcDropdown.vue +23 -23
- package/src/components/OcDropdownItem.vue +9 -9
- package/src/components/OcDropdownLabel.vue +7 -7
- package/src/components/OcDropdownSeparator.vue +7 -7
- package/src/components/OcDropzone.vue +36 -36
- package/src/components/OcEmojiPicker.vue +45 -45
- package/src/components/OcEmptyState.vue +13 -13
- package/src/components/OcEntityCard.vue +47 -47
- package/src/components/OcFactList.vue +37 -37
- package/src/components/OcFilterCounts.vue +38 -38
- package/src/components/OcFlipCard.vue +36 -36
- package/src/components/OcFormField.vue +36 -36
- package/src/components/OcGreeting.vue +52 -52
- package/src/components/OcHeading.vue +19 -19
- package/src/components/OcHoverCard.vue +25 -25
- package/src/components/OcImageZoom.vue +39 -39
- package/src/components/OcInput.vue +9 -9
- package/src/components/OcInputGroup.vue +12 -12
- package/src/components/OcItem.vue +40 -40
- package/src/components/OcItemGroup.vue +7 -7
- package/src/components/OcItemSeparator.vue +7 -7
- package/src/components/OcKbd.vue +7 -7
- package/src/components/OcKbdGroup.vue +15 -15
- package/src/components/OcLabel.vue +10 -10
- package/src/components/OcLanguageSelect.vue +40 -40
- package/src/components/OcLauncherCard.vue +34 -34
- package/src/components/OcLightbox.vue +63 -63
- package/src/components/OcLinkArrow.vue +25 -25
- package/src/components/OcListToolbar.vue +44 -44
- package/src/components/OcMarquee.vue +36 -36
- package/src/components/OcMediaCard.vue +28 -28
- package/src/components/OcMediaRow.vue +28 -28
- package/src/components/OcMediaThumb.vue +38 -38
- package/src/components/OcMessage.vue +91 -91
- package/src/components/OcMessageList.vue +43 -43
- package/src/components/OcMessageThread.vue +155 -155
- package/src/components/OcModal.vue +42 -42
- package/src/components/OcNavmenu.vue +18 -18
- package/src/components/OcNavmenuList.vue +38 -38
- package/src/components/OcNextTeaser.vue +25 -25
- package/src/components/OcNumberInput.vue +47 -47
- package/src/components/OcOtpInput.vue +34 -34
- package/src/components/OcPageHeader.vue +34 -34
- package/src/components/OcPagination.vue +33 -33
- package/src/components/OcPasswordInput.vue +27 -27
- package/src/components/OcPasswordRequirements.vue +28 -28
- package/src/components/OcPhoneInput.vue +72 -72
- package/src/components/OcPopover.vue +25 -25
- package/src/components/OcPriceCard.vue +69 -69
- package/src/components/OcProductMark.vue +31 -31
- package/src/components/OcProgress.vue +21 -21
- package/src/components/OcProjectCard.vue +36 -36
- package/src/components/OcProse.vue +57 -57
- package/src/components/OcRadio.vue +40 -40
- package/src/components/OcRadioGroup.vue +32 -32
- package/src/components/OcRecoveryCodes.vue +55 -55
- package/src/components/OcScrollArea.vue +15 -15
- package/src/components/OcSegmented.vue +28 -28
- package/src/components/OcSelect.vue +21 -21
- package/src/components/OcSeparator.vue +18 -18
- package/src/components/OcSeverityCard.vue +46 -46
- package/src/components/OcSheet.vue +49 -49
- package/src/components/OcSidebarCollapsible.vue +19 -19
- package/src/components/OcSidebarGroup.vue +11 -11
- package/src/components/OcSidebarMenu.vue +7 -7
- package/src/components/OcSidebarMenuButton.vue +31 -31
- package/src/components/OcSidebarSeparator.vue +7 -7
- package/src/components/OcSkeleton.vue +8 -8
- package/src/components/OcSlider.vue +27 -27
- package/src/components/OcSortableRow.vue +40 -40
- package/src/components/OcSpinner.vue +13 -13
- package/src/components/OcStackCard.vue +24 -24
- package/src/components/OcStackList.vue +31 -31
- package/src/components/OcStatCard.vue +39 -39
- package/src/components/OcStepper.vue +34 -34
- package/src/components/OcSwitch.vue +15 -15
- package/src/components/OcTable.vue +115 -115
- package/src/components/OcTableActions.vue +26 -26
- package/src/components/OcTableCompact.vue +46 -46
- package/src/components/OcTabs.vue +37 -37
- package/src/components/OcTagInput.vue +50 -50
- package/src/components/OcTerminalLog.vue +50 -50
- package/src/components/OcTextarea.vue +9 -9
- package/src/components/OcThemeSwitch.vue +31 -31
- package/src/components/OcTimeInput.vue +50 -50
- package/src/components/OcTimeline.vue +36 -36
- package/src/components/OcToast.vue +31 -31
- package/src/components/OcToastContainer.vue +21 -21
- package/src/components/OcToggle.vue +63 -63
- package/src/components/OcToggleField.vue +28 -28
- package/src/components/OcToggleGroup.vue +40 -40
- package/src/components/OcTooltip.vue +8 -8
- package/src/components/OcTopProgress.vue +54 -54
- package/src/components/OcTree.vue +70 -70
- package/src/components/OcUpgradeBanner.vue +42 -42
- package/src/components/OcUser.vue +25 -25
- package/src/components/OcVersionBanner.vue +34 -34
- package/src/composables/chartLine.ts +28 -28
- package/src/composables/keys.ts +22 -22
- package/src/composables/useAttrsSplit.ts +16 -16
- package/src/composables/useDialog.ts +21 -21
- package/src/composables/useToast.ts +66 -66
- package/src/composables/useUid.ts +12 -12
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Radio group (fieldset). v-model = value of the checked radio. Pass `options` or put OcRadio items in the default slot.
|
|
4
|
-
* `legend` renders a legend; `row` lays the items out horizontally; `card` makes the option items bordered cards.
|
|
5
|
-
* Classes: .oc-radio-group(--row)
|
|
6
|
-
*/
|
|
7
|
-
import { computed, provide } from 'vue'
|
|
8
|
-
import { useUid } from '../composables/useUid'
|
|
9
|
-
import { radioGroupKey } from '../composables/keys'
|
|
10
|
-
import OcRadio from './OcRadio.vue'
|
|
11
|
-
|
|
12
|
-
export interface RadioOption {
|
|
13
|
-
value: string | number
|
|
14
|
-
label: string
|
|
15
|
-
description?: string
|
|
16
|
-
disabled?: boolean
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const props = defineProps<{ legend?: string; options?: RadioOption[]; name?: string; row?: boolean; card?: boolean }>()
|
|
20
|
-
const model = defineModel<string | number>()
|
|
21
|
-
const uid = useUid('oc-radio')
|
|
22
|
-
provide(radioGroupKey, { model, name: computed(() => props.name ?? uid), card: computed(() => !!props.card) })
|
|
23
|
-
</script>
|
|
24
|
-
|
|
25
|
-
<template>
|
|
26
|
-
<fieldset :class="['oc-radio-group', row && 'oc-radio-group--row']">
|
|
27
|
-
<legend v-if="legend" class="oc-label">{{ legend }}</legend>
|
|
28
|
-
<slot>
|
|
29
|
-
<OcRadio v-for="o in options" :key="o.value" :value="o.value" :disabled="o.disabled" :description="o.description">{{ o.label }}</OcRadio>
|
|
30
|
-
</slot>
|
|
31
|
-
</fieldset>
|
|
32
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Radio group (fieldset). v-model = value of the checked radio. Pass `options` or put OcRadio items in the default slot.
|
|
4
|
+
* `legend` renders a legend; `row` lays the items out horizontally; `card` makes the option items bordered cards.
|
|
5
|
+
* Classes: .oc-radio-group(--row)
|
|
6
|
+
*/
|
|
7
|
+
import { computed, provide } from 'vue'
|
|
8
|
+
import { useUid } from '../composables/useUid'
|
|
9
|
+
import { radioGroupKey } from '../composables/keys'
|
|
10
|
+
import OcRadio from './OcRadio.vue'
|
|
11
|
+
|
|
12
|
+
export interface RadioOption {
|
|
13
|
+
value: string | number
|
|
14
|
+
label: string
|
|
15
|
+
description?: string
|
|
16
|
+
disabled?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const props = defineProps<{ legend?: string; options?: RadioOption[]; name?: string; row?: boolean; card?: boolean }>()
|
|
20
|
+
const model = defineModel<string | number>()
|
|
21
|
+
const uid = useUid('oc-radio')
|
|
22
|
+
provide(radioGroupKey, { model, name: computed(() => props.name ?? uid), card: computed(() => !!props.card) })
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<fieldset :class="['oc-radio-group', row && 'oc-radio-group--row']">
|
|
27
|
+
<legend v-if="legend" class="oc-label">{{ legend }}</legend>
|
|
28
|
+
<slot>
|
|
29
|
+
<OcRadio v-for="o in options" :key="o.value" :value="o.value" :disabled="o.disabled" :description="o.description">{{ o.label }}</OcRadio>
|
|
30
|
+
</slot>
|
|
31
|
+
</fieldset>
|
|
32
|
+
</template>
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Warning panel with a code grid plus "copy all" and "download .txt" actions (handled here).
|
|
4
|
-
* Emits `copy` and `download`. Slot: actions (replaces the two buttons).
|
|
5
|
-
*/
|
|
6
|
-
const props = withDefaults(
|
|
7
|
-
defineProps<{
|
|
8
|
-
codes: string[]
|
|
9
|
-
title?: string
|
|
10
|
-
warning?: string
|
|
11
|
-
copyLabel?: string
|
|
12
|
-
downloadLabel?: string
|
|
13
|
-
filename?: string
|
|
14
|
-
}>(),
|
|
15
|
-
{
|
|
16
|
-
title: 'Recovery codes',
|
|
17
|
-
warning: 'Store these codes somewhere safe. Each code works once.',
|
|
18
|
-
copyLabel: 'Copy all',
|
|
19
|
-
downloadLabel: 'Download .txt',
|
|
20
|
-
filename: 'recovery-codes.txt',
|
|
21
|
-
},
|
|
22
|
-
)
|
|
23
|
-
const emit = defineEmits<{ copy: []; download: [] }>()
|
|
24
|
-
|
|
25
|
-
async function copyAll() {
|
|
26
|
-
await navigator.clipboard.writeText(props.codes.join('\n'))
|
|
27
|
-
emit('copy')
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function download() {
|
|
31
|
-
const url = URL.createObjectURL(new Blob([props.codes.join('\n') + '\n'], { type: 'text/plain' }))
|
|
32
|
-
const a = document.createElement('a')
|
|
33
|
-
a.href = url
|
|
34
|
-
a.download = props.filename
|
|
35
|
-
a.click()
|
|
36
|
-
URL.revokeObjectURL(url)
|
|
37
|
-
emit('download')
|
|
38
|
-
}
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<template>
|
|
42
|
-
<div class="oc-recovery-codes">
|
|
43
|
-
<h3 class="oc-recovery-codes-title">{{ title }}</h3>
|
|
44
|
-
<p class="oc-recovery-codes-warning">{{ warning }}</p>
|
|
45
|
-
<ul class="oc-recovery-codes-list">
|
|
46
|
-
<li v-for="code in codes" :key="code">{{ code }}</li>
|
|
47
|
-
</ul>
|
|
48
|
-
<div class="oc-recovery-codes-actions">
|
|
49
|
-
<slot name="actions">
|
|
50
|
-
<button class="oc-btn oc-btn--outline oc-btn--sm" type="button" @click="copyAll">{{ copyLabel }}</button>
|
|
51
|
-
<button class="oc-btn oc-btn--outline oc-btn--sm" type="button" @click="download">{{ downloadLabel }}</button>
|
|
52
|
-
</slot>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Warning panel with a code grid plus "copy all" and "download .txt" actions (handled here).
|
|
4
|
+
* Emits `copy` and `download`. Slot: actions (replaces the two buttons).
|
|
5
|
+
*/
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
codes: string[]
|
|
9
|
+
title?: string
|
|
10
|
+
warning?: string
|
|
11
|
+
copyLabel?: string
|
|
12
|
+
downloadLabel?: string
|
|
13
|
+
filename?: string
|
|
14
|
+
}>(),
|
|
15
|
+
{
|
|
16
|
+
title: 'Recovery codes',
|
|
17
|
+
warning: 'Store these codes somewhere safe. Each code works once.',
|
|
18
|
+
copyLabel: 'Copy all',
|
|
19
|
+
downloadLabel: 'Download .txt',
|
|
20
|
+
filename: 'recovery-codes.txt',
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
const emit = defineEmits<{ copy: []; download: [] }>()
|
|
24
|
+
|
|
25
|
+
async function copyAll() {
|
|
26
|
+
await navigator.clipboard.writeText(props.codes.join('\n'))
|
|
27
|
+
emit('copy')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function download() {
|
|
31
|
+
const url = URL.createObjectURL(new Blob([props.codes.join('\n') + '\n'], { type: 'text/plain' }))
|
|
32
|
+
const a = document.createElement('a')
|
|
33
|
+
a.href = url
|
|
34
|
+
a.download = props.filename
|
|
35
|
+
a.click()
|
|
36
|
+
URL.revokeObjectURL(url)
|
|
37
|
+
emit('download')
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div class="oc-recovery-codes">
|
|
43
|
+
<h3 class="oc-recovery-codes-title">{{ title }}</h3>
|
|
44
|
+
<p class="oc-recovery-codes-warning">{{ warning }}</p>
|
|
45
|
+
<ul class="oc-recovery-codes-list">
|
|
46
|
+
<li v-for="code in codes" :key="code">{{ code }}</li>
|
|
47
|
+
</ul>
|
|
48
|
+
<div class="oc-recovery-codes-actions">
|
|
49
|
+
<slot name="actions">
|
|
50
|
+
<button class="oc-btn oc-btn--outline oc-btn--sm" type="button" @click="copyAll">{{ copyLabel }}</button>
|
|
51
|
+
<button class="oc-btn oc-btn--outline oc-btn--sm" type="button" @click="download">{{ downloadLabel }}</button>
|
|
52
|
+
</slot>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Bounded scroll region (focusable, role=region) with themed scrollbar. `label` = aria-label. Classes: .oc-scroll-area(--x/--shadows) */
|
|
3
|
-
defineProps<{ horizontal?: boolean; shadows?: boolean; label?: string }>()
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<template>
|
|
7
|
-
<div
|
|
8
|
-
:class="['oc-scroll-area', horizontal && 'oc-scroll-area--x', shadows && 'oc-scroll-area--shadows']"
|
|
9
|
-
tabindex="0"
|
|
10
|
-
role="region"
|
|
11
|
-
:aria-label="label"
|
|
12
|
-
>
|
|
13
|
-
<slot />
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Bounded scroll region (focusable, role=region) with themed scrollbar. `label` = aria-label. Classes: .oc-scroll-area(--x/--shadows) */
|
|
3
|
+
defineProps<{ horizontal?: boolean; shadows?: boolean; label?: string }>()
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<div
|
|
8
|
+
:class="['oc-scroll-area', horizontal && 'oc-scroll-area--x', shadows && 'oc-scroll-area--shadows']"
|
|
9
|
+
tabindex="0"
|
|
10
|
+
role="region"
|
|
11
|
+
:aria-label="label"
|
|
12
|
+
>
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Radio group as a pill switcher. v-model = selected value. Classes: .oc-segmented(--block/--sm), -item */
|
|
3
|
-
import { useUid } from '../composables/useUid'
|
|
4
|
-
|
|
5
|
-
export interface SegmentedOption {
|
|
6
|
-
value: string
|
|
7
|
-
label: string
|
|
8
|
-
}
|
|
9
|
-
defineProps<{
|
|
10
|
-
options: SegmentedOption[]
|
|
11
|
-
/** aria-label of the group */
|
|
12
|
-
label?: string
|
|
13
|
-
block?: boolean
|
|
14
|
-
size?: 'sm' | 'md'
|
|
15
|
-
name?: string
|
|
16
|
-
}>()
|
|
17
|
-
const model = defineModel<string>()
|
|
18
|
-
const uid = useUid('oc-segmented')
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<template>
|
|
22
|
-
<div :class="['oc-segmented', block && 'oc-segmented--block', size === 'sm' && 'oc-segmented--sm']" role="radiogroup" :aria-label="label">
|
|
23
|
-
<label v-for="option in options" :key="option.value" class="oc-segmented-item">
|
|
24
|
-
<input v-model="model" type="radio" :name="name ?? uid" :value="option.value" />
|
|
25
|
-
{{ option.label }}
|
|
26
|
-
</label>
|
|
27
|
-
</div>
|
|
28
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Radio group as a pill switcher. v-model = selected value. Classes: .oc-segmented(--block/--sm), -item */
|
|
3
|
+
import { useUid } from '../composables/useUid'
|
|
4
|
+
|
|
5
|
+
export interface SegmentedOption {
|
|
6
|
+
value: string
|
|
7
|
+
label: string
|
|
8
|
+
}
|
|
9
|
+
defineProps<{
|
|
10
|
+
options: SegmentedOption[]
|
|
11
|
+
/** aria-label of the group */
|
|
12
|
+
label?: string
|
|
13
|
+
block?: boolean
|
|
14
|
+
size?: 'sm' | 'md'
|
|
15
|
+
name?: string
|
|
16
|
+
}>()
|
|
17
|
+
const model = defineModel<string>()
|
|
18
|
+
const uid = useUid('oc-segmented')
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<div :class="['oc-segmented', block && 'oc-segmented--block', size === 'sm' && 'oc-segmented--sm']" role="radiogroup" :aria-label="label">
|
|
23
|
+
<label v-for="option in options" :key="option.value" class="oc-segmented-item">
|
|
24
|
+
<input v-model="model" type="radio" :name="name ?? uid" :value="option.value" />
|
|
25
|
+
{{ option.label }}
|
|
26
|
+
</label>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Native select. v-model. Pass `options` (strings or { value, label }) or <option> elements in the default slot. */
|
|
3
|
-
export interface SelectOption {
|
|
4
|
-
value: string | number
|
|
5
|
-
label: string
|
|
6
|
-
disabled?: boolean
|
|
7
|
-
}
|
|
8
|
-
defineProps<{ options?: (string | SelectOption)[] }>()
|
|
9
|
-
const model = defineModel<any>()
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<template>
|
|
13
|
-
<select v-model="model" class="oc-select">
|
|
14
|
-
<slot>
|
|
15
|
-
<template v-for="o in options" :key="typeof o === 'string' ? o : o.value">
|
|
16
|
-
<option v-if="typeof o === 'string'" :value="o">{{ o }}</option>
|
|
17
|
-
<option v-else :value="o.value" :disabled="o.disabled">{{ o.label }}</option>
|
|
18
|
-
</template>
|
|
19
|
-
</slot>
|
|
20
|
-
</select>
|
|
21
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Native select. v-model. Pass `options` (strings or { value, label }) or <option> elements in the default slot. */
|
|
3
|
+
export interface SelectOption {
|
|
4
|
+
value: string | number
|
|
5
|
+
label: string
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
}
|
|
8
|
+
defineProps<{ options?: (string | SelectOption)[] }>()
|
|
9
|
+
const model = defineModel<any>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<select v-model="model" class="oc-select">
|
|
14
|
+
<slot>
|
|
15
|
+
<template v-for="o in options" :key="typeof o === 'string' ? o : o.value">
|
|
16
|
+
<option v-if="typeof o === 'string'" :value="o">{{ o }}</option>
|
|
17
|
+
<option v-else :value="o.value" :disabled="o.disabled">{{ o.label }}</option>
|
|
18
|
+
</template>
|
|
19
|
+
</slot>
|
|
20
|
+
</select>
|
|
21
|
+
</template>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Divider. Default = <hr>. `vertical` = inline separator for flex rows. `label` (or the default slot) renders the
|
|
4
|
-
* line-text-line form. Classes: .oc-separator(--vertical/--strong), .oc-separator-text
|
|
5
|
-
*/
|
|
6
|
-
defineProps<{ vertical?: boolean; strong?: boolean; label?: string }>()
|
|
7
|
-
</script>
|
|
8
|
-
|
|
9
|
-
<template>
|
|
10
|
-
<div v-if="label || $slots.default" class="oc-separator-text" role="separator"><span><slot>{{ label }}</slot></span></div>
|
|
11
|
-
<span
|
|
12
|
-
v-else-if="vertical"
|
|
13
|
-
:class="['oc-separator', 'oc-separator--vertical', strong && 'oc-separator--strong']"
|
|
14
|
-
role="separator"
|
|
15
|
-
aria-orientation="vertical"
|
|
16
|
-
></span>
|
|
17
|
-
<hr v-else :class="['oc-separator', strong && 'oc-separator--strong']" />
|
|
18
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Divider. Default = <hr>. `vertical` = inline separator for flex rows. `label` (or the default slot) renders the
|
|
4
|
+
* line-text-line form. Classes: .oc-separator(--vertical/--strong), .oc-separator-text
|
|
5
|
+
*/
|
|
6
|
+
defineProps<{ vertical?: boolean; strong?: boolean; label?: string }>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div v-if="label || $slots.default" class="oc-separator-text" role="separator"><span><slot>{{ label }}</slot></span></div>
|
|
11
|
+
<span
|
|
12
|
+
v-else-if="vertical"
|
|
13
|
+
:class="['oc-separator', 'oc-separator--vertical', strong && 'oc-separator--strong']"
|
|
14
|
+
role="separator"
|
|
15
|
+
aria-orientation="vertical"
|
|
16
|
+
></span>
|
|
17
|
+
<hr v-else :class="['oc-separator', strong && 'oc-separator--strong']" />
|
|
18
|
+
</template>
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
<!-- File: packages/vue/src/components/OcSeverityCard.vue | Map: details -> summary head (icon, title + tags, level badge) -> body (default slot, actions slot) -->
|
|
2
|
-
<script setup lang="ts">
|
|
3
|
-
/**
|
|
4
|
-
* Expandable card colored by risk level. v-model:open. Cards with the same `name` open one at a time.
|
|
5
|
-
* Slots: icon, default (body), actions.
|
|
6
|
-
* Classes: details.oc-severity-card(--low/--medium/--high/--critical, .is-resolved), -head, -icon, -main, -title, -tags, -tag, -level, -body, -actions
|
|
7
|
-
*/
|
|
8
|
-
const props = defineProps<{
|
|
9
|
-
level: 'low' | 'medium' | 'high' | 'critical'
|
|
10
|
-
title: string
|
|
11
|
-
tags?: string[]
|
|
12
|
-
levelLabel?: string
|
|
13
|
-
resolved?: boolean
|
|
14
|
-
name?: string
|
|
15
|
-
}>()
|
|
16
|
-
const open = defineModel<boolean>('open', { default: false })
|
|
17
|
-
const LEVEL_TEXT = { low: 'Low', medium: 'Medium', high: 'High', critical: 'Critical' } as const
|
|
18
|
-
|
|
19
|
-
function onToggle(e: Event) {
|
|
20
|
-
open.value = (e.target as HTMLDetailsElement).open
|
|
21
|
-
}
|
|
22
|
-
</script>
|
|
23
|
-
|
|
24
|
-
<template>
|
|
25
|
-
<details
|
|
26
|
-
:class="['oc-severity-card', `oc-severity-card--${level}`, resolved && 'is-resolved']"
|
|
27
|
-
:name="name"
|
|
28
|
-
:open="open"
|
|
29
|
-
@toggle="onToggle"
|
|
30
|
-
>
|
|
31
|
-
<summary class="oc-severity-card-head">
|
|
32
|
-
<span v-if="$slots.icon" class="oc-severity-card-icon" aria-hidden="true"><slot name="icon" /></span>
|
|
33
|
-
<span class="oc-severity-card-main">
|
|
34
|
-
<span class="oc-severity-card-title">{{ title }}</span>
|
|
35
|
-
<span v-if="tags?.length" class="oc-severity-card-tags">
|
|
36
|
-
<span v-for="t in tags" :key="t" class="oc-severity-card-tag">{{ t }}</span>
|
|
37
|
-
</span>
|
|
38
|
-
</span>
|
|
39
|
-
<span class="oc-severity-card-level">{{ levelLabel ?? LEVEL_TEXT[props.level] }}</span>
|
|
40
|
-
</summary>
|
|
41
|
-
<div class="oc-severity-card-body">
|
|
42
|
-
<slot />
|
|
43
|
-
<div v-if="$slots.actions" class="oc-severity-card-actions"><slot name="actions" /></div>
|
|
44
|
-
</div>
|
|
45
|
-
</details>
|
|
46
|
-
</template>
|
|
1
|
+
<!-- File: packages/vue/src/components/OcSeverityCard.vue | Map: details -> summary head (icon, title + tags, level badge) -> body (default slot, actions slot) -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* Expandable card colored by risk level. v-model:open. Cards with the same `name` open one at a time.
|
|
5
|
+
* Slots: icon, default (body), actions.
|
|
6
|
+
* Classes: details.oc-severity-card(--low/--medium/--high/--critical, .is-resolved), -head, -icon, -main, -title, -tags, -tag, -level, -body, -actions
|
|
7
|
+
*/
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
level: 'low' | 'medium' | 'high' | 'critical'
|
|
10
|
+
title: string
|
|
11
|
+
tags?: string[]
|
|
12
|
+
levelLabel?: string
|
|
13
|
+
resolved?: boolean
|
|
14
|
+
name?: string
|
|
15
|
+
}>()
|
|
16
|
+
const open = defineModel<boolean>('open', { default: false })
|
|
17
|
+
const LEVEL_TEXT = { low: 'Low', medium: 'Medium', high: 'High', critical: 'Critical' } as const
|
|
18
|
+
|
|
19
|
+
function onToggle(e: Event) {
|
|
20
|
+
open.value = (e.target as HTMLDetailsElement).open
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<details
|
|
26
|
+
:class="['oc-severity-card', `oc-severity-card--${level}`, resolved && 'is-resolved']"
|
|
27
|
+
:name="name"
|
|
28
|
+
:open="open"
|
|
29
|
+
@toggle="onToggle"
|
|
30
|
+
>
|
|
31
|
+
<summary class="oc-severity-card-head">
|
|
32
|
+
<span v-if="$slots.icon" class="oc-severity-card-icon" aria-hidden="true"><slot name="icon" /></span>
|
|
33
|
+
<span class="oc-severity-card-main">
|
|
34
|
+
<span class="oc-severity-card-title">{{ title }}</span>
|
|
35
|
+
<span v-if="tags?.length" class="oc-severity-card-tags">
|
|
36
|
+
<span v-for="t in tags" :key="t" class="oc-severity-card-tag">{{ t }}</span>
|
|
37
|
+
</span>
|
|
38
|
+
</span>
|
|
39
|
+
<span class="oc-severity-card-level">{{ levelLabel ?? LEVEL_TEXT[props.level] }}</span>
|
|
40
|
+
</summary>
|
|
41
|
+
<div class="oc-severity-card-body">
|
|
42
|
+
<slot />
|
|
43
|
+
<div v-if="$slots.actions" class="oc-severity-card-actions"><slot name="actions" /></div>
|
|
44
|
+
</div>
|
|
45
|
+
</details>
|
|
46
|
+
</template>
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Side panel on a native <dialog>. v-model:open. Slots: header (replaces title + description),
|
|
4
|
-
* default (body), footer (scoped: { close }). Classes: dialog.oc-sheet(--left/--top/--bottom),
|
|
5
|
-
* .oc-sheet-content(--wide), -header, -title, -description, -body, -footer, -close.
|
|
6
|
-
*/
|
|
7
|
-
import { ref } from 'vue'
|
|
8
|
-
import { useDialog } from '../composables/useDialog'
|
|
9
|
-
import { useUid } from '../composables/useUid'
|
|
10
|
-
|
|
11
|
-
withDefaults(
|
|
12
|
-
defineProps<{
|
|
13
|
-
side?: 'right' | 'left' | 'top' | 'bottom'
|
|
14
|
-
wide?: boolean
|
|
15
|
-
title?: string
|
|
16
|
-
description?: string
|
|
17
|
-
closeLabel?: string
|
|
18
|
-
}>(),
|
|
19
|
-
{ side: 'right', closeLabel: 'Close' },
|
|
20
|
-
)
|
|
21
|
-
const open = defineModel<boolean>('open', { default: false })
|
|
22
|
-
const el = ref<HTMLDialogElement | null>(null)
|
|
23
|
-
const { onClose } = useDialog(open, el)
|
|
24
|
-
const titleId = useUid('oc-sheet-title')
|
|
25
|
-
const close = () => (open.value = false)
|
|
26
|
-
defineExpose({ close })
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<template>
|
|
30
|
-
<dialog
|
|
31
|
-
ref="el"
|
|
32
|
-
:class="['oc-sheet', side !== 'right' && `oc-sheet--${side}`]"
|
|
33
|
-
closedby="any"
|
|
34
|
-
:aria-labelledby="title ? titleId : undefined"
|
|
35
|
-
@close="onClose"
|
|
36
|
-
>
|
|
37
|
-
<div :class="['oc-sheet-content', wide && 'oc-sheet-content--wide']">
|
|
38
|
-
<button class="oc-sheet-close" type="button" :aria-label="closeLabel" @click="close">×</button>
|
|
39
|
-
<div v-if="title || description || $slots.header" class="oc-sheet-header">
|
|
40
|
-
<slot name="header">
|
|
41
|
-
<h2 v-if="title" :id="titleId" class="oc-sheet-title">{{ title }}</h2>
|
|
42
|
-
<p v-if="description" class="oc-sheet-description">{{ description }}</p>
|
|
43
|
-
</slot>
|
|
44
|
-
</div>
|
|
45
|
-
<div v-if="$slots.default" class="oc-sheet-body"><slot /></div>
|
|
46
|
-
<div v-if="$slots.footer" class="oc-sheet-footer"><slot name="footer" :close="close" /></div>
|
|
47
|
-
</div>
|
|
48
|
-
</dialog>
|
|
49
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Side panel on a native <dialog>. v-model:open. Slots: header (replaces title + description),
|
|
4
|
+
* default (body), footer (scoped: { close }). Classes: dialog.oc-sheet(--left/--top/--bottom),
|
|
5
|
+
* .oc-sheet-content(--wide), -header, -title, -description, -body, -footer, -close.
|
|
6
|
+
*/
|
|
7
|
+
import { ref } from 'vue'
|
|
8
|
+
import { useDialog } from '../composables/useDialog'
|
|
9
|
+
import { useUid } from '../composables/useUid'
|
|
10
|
+
|
|
11
|
+
withDefaults(
|
|
12
|
+
defineProps<{
|
|
13
|
+
side?: 'right' | 'left' | 'top' | 'bottom'
|
|
14
|
+
wide?: boolean
|
|
15
|
+
title?: string
|
|
16
|
+
description?: string
|
|
17
|
+
closeLabel?: string
|
|
18
|
+
}>(),
|
|
19
|
+
{ side: 'right', closeLabel: 'Close' },
|
|
20
|
+
)
|
|
21
|
+
const open = defineModel<boolean>('open', { default: false })
|
|
22
|
+
const el = ref<HTMLDialogElement | null>(null)
|
|
23
|
+
const { onClose } = useDialog(open, el)
|
|
24
|
+
const titleId = useUid('oc-sheet-title')
|
|
25
|
+
const close = () => (open.value = false)
|
|
26
|
+
defineExpose({ close })
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<dialog
|
|
31
|
+
ref="el"
|
|
32
|
+
:class="['oc-sheet', side !== 'right' && `oc-sheet--${side}`]"
|
|
33
|
+
closedby="any"
|
|
34
|
+
:aria-labelledby="title ? titleId : undefined"
|
|
35
|
+
@close="onClose"
|
|
36
|
+
>
|
|
37
|
+
<div :class="['oc-sheet-content', wide && 'oc-sheet-content--wide']">
|
|
38
|
+
<button class="oc-sheet-close" type="button" :aria-label="closeLabel" @click="close">×</button>
|
|
39
|
+
<div v-if="title || description || $slots.header" class="oc-sheet-header">
|
|
40
|
+
<slot name="header">
|
|
41
|
+
<h2 v-if="title" :id="titleId" class="oc-sheet-title">{{ title }}</h2>
|
|
42
|
+
<p v-if="description" class="oc-sheet-description">{{ description }}</p>
|
|
43
|
+
</slot>
|
|
44
|
+
</div>
|
|
45
|
+
<div v-if="$slots.default" class="oc-sheet-body"><slot /></div>
|
|
46
|
+
<div v-if="$slots.footer" class="oc-sheet-footer"><slot name="footer" :close="close" /></div>
|
|
47
|
+
</div>
|
|
48
|
+
</dialog>
|
|
49
|
+
</template>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Expandable sidebar item (details). v-model:open. Slots: icon, label (or `label` prop), default (sub items as <li>). */
|
|
3
|
-
defineProps<{ label?: string }>()
|
|
4
|
-
const open = defineModel<boolean>('open', { default: false })
|
|
5
|
-
|
|
6
|
-
function onToggle(e: Event) {
|
|
7
|
-
open.value = (e.target as HTMLDetailsElement).open
|
|
8
|
-
}
|
|
9
|
-
</script>
|
|
10
|
-
|
|
11
|
-
<template>
|
|
12
|
-
<details class="oc-sidebar-collapsible" :open="open" @toggle="onToggle">
|
|
13
|
-
<summary class="oc-sidebar-menu-button">
|
|
14
|
-
<slot name="icon" />
|
|
15
|
-
<span class="oc-sidebar-menu-label"><slot name="label">{{ label }}</slot></span>
|
|
16
|
-
</summary>
|
|
17
|
-
<ul class="oc-sidebar-menu-sub"><slot /></ul>
|
|
18
|
-
</details>
|
|
19
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Expandable sidebar item (details). v-model:open. Slots: icon, label (or `label` prop), default (sub items as <li>). */
|
|
3
|
+
defineProps<{ label?: string }>()
|
|
4
|
+
const open = defineModel<boolean>('open', { default: false })
|
|
5
|
+
|
|
6
|
+
function onToggle(e: Event) {
|
|
7
|
+
open.value = (e.target as HTMLDetailsElement).open
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<details class="oc-sidebar-collapsible" :open="open" @toggle="onToggle">
|
|
13
|
+
<summary class="oc-sidebar-menu-button">
|
|
14
|
+
<slot name="icon" />
|
|
15
|
+
<span class="oc-sidebar-menu-label"><slot name="label">{{ label }}</slot></span>
|
|
16
|
+
</summary>
|
|
17
|
+
<ul class="oc-sidebar-menu-sub"><slot /></ul>
|
|
18
|
+
</details>
|
|
19
|
+
</template>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Group of sidebar items with an optional heading (`label`). */
|
|
3
|
-
defineProps<{ label?: string }>()
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<template>
|
|
7
|
-
<div class="oc-sidebar-group">
|
|
8
|
-
<div v-if="label" class="oc-sidebar-group-label">{{ label }}</div>
|
|
9
|
-
<slot />
|
|
10
|
-
</div>
|
|
11
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Group of sidebar items with an optional heading (`label`). */
|
|
3
|
+
defineProps<{ label?: string }>()
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<div class="oc-sidebar-group">
|
|
8
|
+
<div v-if="label" class="oc-sidebar-group-label">{{ label }}</div>
|
|
9
|
+
<slot />
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** The <ul class="oc-sidebar-menu">; put <li> elements (each with an OcSidebarMenuButton or OcSidebarCollapsible) inside. */
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
|
-
<template>
|
|
6
|
-
<ul class="oc-sidebar-menu"><slot /></ul>
|
|
7
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** The <ul class="oc-sidebar-menu">; put <li> elements (each with an OcSidebarMenuButton or OcSidebarCollapsible) inside. */
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<ul class="oc-sidebar-menu"><slot /></ul>
|
|
7
|
+
</template>
|