@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.
- 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,119 +1,119 @@
|
|
|
1
|
-
<!-- File: packages/vue/src/components/OcCookieConsent.vue | Map: props -> storage helpers -> reopen button -> popover (title, text, categories, actions) -->
|
|
2
|
-
<script setup lang="ts">
|
|
3
|
-
/**
|
|
4
|
-
* Cookie banner on popover="manual" (same markup as snippets/cookie-consent.html). Like the snippet script it shows itself
|
|
5
|
-
* when no choice is stored, saves { necessary, <categories>, date } in localStorage and fires "oc-consent" on document.
|
|
6
|
-
* Emits: consent (the choice, also on load when one is stored). Slot: text (replaces the paragraph content).
|
|
7
|
-
* Classes: .oc-cookie-consent(--bar) __title __text __prefs __category __category-name __category-text __actions
|
|
8
|
-
*/
|
|
9
|
-
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
|
10
|
-
|
|
11
|
-
export interface CookieCategory {
|
|
12
|
-
name: string
|
|
13
|
-
label: string
|
|
14
|
-
text?: string
|
|
15
|
-
required?: boolean
|
|
16
|
-
}
|
|
17
|
-
export type ConsentChoice = { necessary: boolean; date: string } & Record<string, boolean | string>
|
|
18
|
-
|
|
19
|
-
const props = withDefaults(
|
|
20
|
-
defineProps<{
|
|
21
|
-
categories?: CookieCategory[]
|
|
22
|
-
title?: string
|
|
23
|
-
policyHref?: string
|
|
24
|
-
customizeLabel?: string
|
|
25
|
-
necessaryLabel?: string
|
|
26
|
-
selectedLabel?: string
|
|
27
|
-
allLabel?: string
|
|
28
|
-
/** Text of the "Cookie settings" button; empty string hides it. */
|
|
29
|
-
openLabel?: string
|
|
30
|
-
bar?: boolean
|
|
31
|
-
manual?: boolean
|
|
32
|
-
storageKey?: string
|
|
33
|
-
id?: string
|
|
34
|
-
}>(),
|
|
35
|
-
{
|
|
36
|
-
categories: () => [
|
|
37
|
-
{ name: 'necessary', label: 'Necessary', text: 'Session, security and your cookie choice. Always on.', required: true },
|
|
38
|
-
{ name: 'statistics', label: 'Statistics', text: 'Anonymous visit counts.' },
|
|
39
|
-
{ name: 'marketing', label: 'Marketing', text: 'Embedded videos and ads that track you.' },
|
|
40
|
-
],
|
|
41
|
-
title: 'We use cookies',
|
|
42
|
-
policyHref: '#cookie-policy',
|
|
43
|
-
customizeLabel: 'Customize',
|
|
44
|
-
necessaryLabel: 'Only necessary',
|
|
45
|
-
selectedLabel: 'Save choice',
|
|
46
|
-
allLabel: 'Accept all',
|
|
47
|
-
openLabel: 'Cookie settings',
|
|
48
|
-
storageKey: 'oc-consent',
|
|
49
|
-
id: 'oc-cookie-consent',
|
|
50
|
-
},
|
|
51
|
-
)
|
|
52
|
-
const emit = defineEmits<{ consent: [choice: ConsentChoice] }>()
|
|
53
|
-
defineOptions({ inheritAttrs: false })
|
|
54
|
-
const box = ref<HTMLElement | null>(null)
|
|
55
|
-
|
|
56
|
-
const read = (): ConsentChoice | null => {
|
|
57
|
-
try { return JSON.parse(localStorage.getItem(props.storageKey) ?? 'null') } catch { return null }
|
|
58
|
-
}
|
|
59
|
-
const inputs = () => Array.from(box.value?.querySelectorAll<HTMLInputElement>('input[name]') ?? [])
|
|
60
|
-
function tell(choice: ConsentChoice) {
|
|
61
|
-
document.dispatchEvent(new CustomEvent('oc-consent', { detail: choice }))
|
|
62
|
-
emit('consent', choice)
|
|
63
|
-
}
|
|
64
|
-
// Any [data-oc-consent-open] (also outside this component) opens the banner with the stored choice.
|
|
65
|
-
function reopen(e: Event) {
|
|
66
|
-
if (!(e.target as Element | null)?.closest?.('[data-oc-consent-open]')) return
|
|
67
|
-
const choice = read()
|
|
68
|
-
for (const i of inputs()) if (!i.disabled) i.checked = !!choice?.[i.name]
|
|
69
|
-
box.value?.showPopover?.()
|
|
70
|
-
}
|
|
71
|
-
function choose(e: MouseEvent) {
|
|
72
|
-
const mode = (e.target as HTMLElement).closest<HTMLElement>('[data-oc-consent]')?.dataset.ocConsent
|
|
73
|
-
if (!mode) return
|
|
74
|
-
const choice: ConsentChoice = { necessary: true, date: new Date().toISOString() }
|
|
75
|
-
for (const i of inputs()) if (!i.disabled) choice[i.name] = mode === 'all' || (mode === 'selected' && i.checked)
|
|
76
|
-
try { localStorage.setItem(props.storageKey, JSON.stringify(choice)) } catch { /* storage blocked */ }
|
|
77
|
-
box.value?.hidePopover?.()
|
|
78
|
-
tell(choice)
|
|
79
|
-
}
|
|
80
|
-
onMounted(() => {
|
|
81
|
-
const stored = read()
|
|
82
|
-
if (stored) tell(stored)
|
|
83
|
-
else if (!props.manual) box.value?.showPopover?.()
|
|
84
|
-
document.addEventListener('click', reopen)
|
|
85
|
-
})
|
|
86
|
-
onBeforeUnmount(() => document.removeEventListener('click', reopen))
|
|
87
|
-
</script>
|
|
88
|
-
|
|
89
|
-
<template>
|
|
90
|
-
<button v-if="openLabel" type="button" class="oc-btn oc-btn--outline oc-btn--sm" data-oc-consent-open>{{ openLabel }}</button>
|
|
91
|
-
<aside
|
|
92
|
-
:id="id"
|
|
93
|
-
ref="box"
|
|
94
|
-
v-bind="$attrs"
|
|
95
|
-
:class="['oc-cookie-consent', bar && 'oc-cookie-consent--bar']"
|
|
96
|
-
popover="manual"
|
|
97
|
-
:data-oc-consent-manual="manual ? '' : undefined"
|
|
98
|
-
:aria-labelledby="`${id}-title`"
|
|
99
|
-
@click="choose"
|
|
100
|
-
>
|
|
101
|
-
<h2 :id="`${id}-title`" class="oc-cookie-consent__title"><span aria-hidden="true">🍪</span> {{ title }}</h2>
|
|
102
|
-
<p class="oc-cookie-consent__text">
|
|
103
|
-
<slot name="text">Necessary cookies keep the site working. With your permission we also measure visits to improve the site. Read the <a :href="policyHref">cookie policy</a>.</slot>
|
|
104
|
-
</p>
|
|
105
|
-
<details class="oc-cookie-consent__prefs">
|
|
106
|
-
<summary>{{ customizeLabel }}</summary>
|
|
107
|
-
<div v-for="c in categories" :key="c.name" class="oc-cookie-consent__category">
|
|
108
|
-
<span class="oc-cookie-consent__category-name">{{ c.label }}</span>
|
|
109
|
-
<span v-if="c.text" class="oc-cookie-consent__category-text">{{ c.text }}</span>
|
|
110
|
-
<label class="oc-switch"><input type="checkbox" role="switch" :name="c.name" :checked="c.required" :disabled="c.required" :aria-label="`${c.label} cookies`" /><span class="oc-switch-track"></span></label>
|
|
111
|
-
</div>
|
|
112
|
-
</details>
|
|
113
|
-
<div class="oc-cookie-consent__actions">
|
|
114
|
-
<button type="button" class="oc-btn oc-btn--outline" data-oc-consent="necessary">{{ necessaryLabel }}</button>
|
|
115
|
-
<button type="button" class="oc-btn oc-btn--secondary" data-oc-consent="selected">{{ selectedLabel }}</button>
|
|
116
|
-
<button type="button" class="oc-btn" data-oc-consent="all">{{ allLabel }}</button>
|
|
117
|
-
</div>
|
|
118
|
-
</aside>
|
|
119
|
-
</template>
|
|
1
|
+
<!-- File: packages/vue/src/components/OcCookieConsent.vue | Map: props -> storage helpers -> reopen button -> popover (title, text, categories, actions) -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* Cookie banner on popover="manual" (same markup as snippets/cookie-consent.html). Like the snippet script it shows itself
|
|
5
|
+
* when no choice is stored, saves { necessary, <categories>, date } in localStorage and fires "oc-consent" on document.
|
|
6
|
+
* Emits: consent (the choice, also on load when one is stored). Slot: text (replaces the paragraph content).
|
|
7
|
+
* Classes: .oc-cookie-consent(--bar) __title __text __prefs __category __category-name __category-text __actions
|
|
8
|
+
*/
|
|
9
|
+
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
|
10
|
+
|
|
11
|
+
export interface CookieCategory {
|
|
12
|
+
name: string
|
|
13
|
+
label: string
|
|
14
|
+
text?: string
|
|
15
|
+
required?: boolean
|
|
16
|
+
}
|
|
17
|
+
export type ConsentChoice = { necessary: boolean; date: string } & Record<string, boolean | string>
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(
|
|
20
|
+
defineProps<{
|
|
21
|
+
categories?: CookieCategory[]
|
|
22
|
+
title?: string
|
|
23
|
+
policyHref?: string
|
|
24
|
+
customizeLabel?: string
|
|
25
|
+
necessaryLabel?: string
|
|
26
|
+
selectedLabel?: string
|
|
27
|
+
allLabel?: string
|
|
28
|
+
/** Text of the "Cookie settings" button; empty string hides it. */
|
|
29
|
+
openLabel?: string
|
|
30
|
+
bar?: boolean
|
|
31
|
+
manual?: boolean
|
|
32
|
+
storageKey?: string
|
|
33
|
+
id?: string
|
|
34
|
+
}>(),
|
|
35
|
+
{
|
|
36
|
+
categories: () => [
|
|
37
|
+
{ name: 'necessary', label: 'Necessary', text: 'Session, security and your cookie choice. Always on.', required: true },
|
|
38
|
+
{ name: 'statistics', label: 'Statistics', text: 'Anonymous visit counts.' },
|
|
39
|
+
{ name: 'marketing', label: 'Marketing', text: 'Embedded videos and ads that track you.' },
|
|
40
|
+
],
|
|
41
|
+
title: 'We use cookies',
|
|
42
|
+
policyHref: '#cookie-policy',
|
|
43
|
+
customizeLabel: 'Customize',
|
|
44
|
+
necessaryLabel: 'Only necessary',
|
|
45
|
+
selectedLabel: 'Save choice',
|
|
46
|
+
allLabel: 'Accept all',
|
|
47
|
+
openLabel: 'Cookie settings',
|
|
48
|
+
storageKey: 'oc-consent',
|
|
49
|
+
id: 'oc-cookie-consent',
|
|
50
|
+
},
|
|
51
|
+
)
|
|
52
|
+
const emit = defineEmits<{ consent: [choice: ConsentChoice] }>()
|
|
53
|
+
defineOptions({ inheritAttrs: false })
|
|
54
|
+
const box = ref<HTMLElement | null>(null)
|
|
55
|
+
|
|
56
|
+
const read = (): ConsentChoice | null => {
|
|
57
|
+
try { return JSON.parse(localStorage.getItem(props.storageKey) ?? 'null') } catch { return null }
|
|
58
|
+
}
|
|
59
|
+
const inputs = () => Array.from(box.value?.querySelectorAll<HTMLInputElement>('input[name]') ?? [])
|
|
60
|
+
function tell(choice: ConsentChoice) {
|
|
61
|
+
document.dispatchEvent(new CustomEvent('oc-consent', { detail: choice }))
|
|
62
|
+
emit('consent', choice)
|
|
63
|
+
}
|
|
64
|
+
// Any [data-oc-consent-open] (also outside this component) opens the banner with the stored choice.
|
|
65
|
+
function reopen(e: Event) {
|
|
66
|
+
if (!(e.target as Element | null)?.closest?.('[data-oc-consent-open]')) return
|
|
67
|
+
const choice = read()
|
|
68
|
+
for (const i of inputs()) if (!i.disabled) i.checked = !!choice?.[i.name]
|
|
69
|
+
box.value?.showPopover?.()
|
|
70
|
+
}
|
|
71
|
+
function choose(e: MouseEvent) {
|
|
72
|
+
const mode = (e.target as HTMLElement).closest<HTMLElement>('[data-oc-consent]')?.dataset.ocConsent
|
|
73
|
+
if (!mode) return
|
|
74
|
+
const choice: ConsentChoice = { necessary: true, date: new Date().toISOString() }
|
|
75
|
+
for (const i of inputs()) if (!i.disabled) choice[i.name] = mode === 'all' || (mode === 'selected' && i.checked)
|
|
76
|
+
try { localStorage.setItem(props.storageKey, JSON.stringify(choice)) } catch { /* storage blocked */ }
|
|
77
|
+
box.value?.hidePopover?.()
|
|
78
|
+
tell(choice)
|
|
79
|
+
}
|
|
80
|
+
onMounted(() => {
|
|
81
|
+
const stored = read()
|
|
82
|
+
if (stored) tell(stored)
|
|
83
|
+
else if (!props.manual) box.value?.showPopover?.()
|
|
84
|
+
document.addEventListener('click', reopen)
|
|
85
|
+
})
|
|
86
|
+
onBeforeUnmount(() => document.removeEventListener('click', reopen))
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<template>
|
|
90
|
+
<button v-if="openLabel" type="button" class="oc-btn oc-btn--outline oc-btn--sm" data-oc-consent-open>{{ openLabel }}</button>
|
|
91
|
+
<aside
|
|
92
|
+
:id="id"
|
|
93
|
+
ref="box"
|
|
94
|
+
v-bind="$attrs"
|
|
95
|
+
:class="['oc-cookie-consent', bar && 'oc-cookie-consent--bar']"
|
|
96
|
+
popover="manual"
|
|
97
|
+
:data-oc-consent-manual="manual ? '' : undefined"
|
|
98
|
+
:aria-labelledby="`${id}-title`"
|
|
99
|
+
@click="choose"
|
|
100
|
+
>
|
|
101
|
+
<h2 :id="`${id}-title`" class="oc-cookie-consent__title"><span aria-hidden="true">🍪</span> {{ title }}</h2>
|
|
102
|
+
<p class="oc-cookie-consent__text">
|
|
103
|
+
<slot name="text">Necessary cookies keep the site working. With your permission we also measure visits to improve the site. Read the <a :href="policyHref">cookie policy</a>.</slot>
|
|
104
|
+
</p>
|
|
105
|
+
<details class="oc-cookie-consent__prefs">
|
|
106
|
+
<summary>{{ customizeLabel }}</summary>
|
|
107
|
+
<div v-for="c in categories" :key="c.name" class="oc-cookie-consent__category">
|
|
108
|
+
<span class="oc-cookie-consent__category-name">{{ c.label }}</span>
|
|
109
|
+
<span v-if="c.text" class="oc-cookie-consent__category-text">{{ c.text }}</span>
|
|
110
|
+
<label class="oc-switch"><input type="checkbox" role="switch" :name="c.name" :checked="c.required" :disabled="c.required" :aria-label="`${c.label} cookies`" /><span class="oc-switch-track"></span></label>
|
|
111
|
+
</div>
|
|
112
|
+
</details>
|
|
113
|
+
<div class="oc-cookie-consent__actions">
|
|
114
|
+
<button type="button" class="oc-btn oc-btn--outline" data-oc-consent="necessary">{{ necessaryLabel }}</button>
|
|
115
|
+
<button type="button" class="oc-btn oc-btn--secondary" data-oc-consent="selected">{{ selectedLabel }}</button>
|
|
116
|
+
<button type="button" class="oc-btn" data-oc-consent="all">{{ allLabel }}</button>
|
|
117
|
+
</div>
|
|
118
|
+
</aside>
|
|
119
|
+
</template>
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Read-only monospace value with a copy button. Copies via navigator.clipboard and
|
|
4
|
-
* adds .is-copied for 2 seconds. Emits `copy` with the value.
|
|
5
|
-
*/
|
|
6
|
-
import { onBeforeUnmount, ref } from 'vue'
|
|
7
|
-
|
|
8
|
-
const props = withDefaults(
|
|
9
|
-
defineProps<{
|
|
10
|
-
value: string
|
|
11
|
-
label?: string
|
|
12
|
-
buttonLabel?: string
|
|
13
|
-
}>(),
|
|
14
|
-
{ label: 'Value', buttonLabel: 'Copy' },
|
|
15
|
-
)
|
|
16
|
-
const emit = defineEmits<{ copy: [value: string] }>()
|
|
17
|
-
|
|
18
|
-
const copied = ref(false)
|
|
19
|
-
let timer: ReturnType<typeof setTimeout> | undefined
|
|
20
|
-
|
|
21
|
-
async function copy() {
|
|
22
|
-
await navigator.clipboard.writeText(props.value)
|
|
23
|
-
copied.value = true
|
|
24
|
-
emit('copy', props.value)
|
|
25
|
-
clearTimeout(timer)
|
|
26
|
-
timer = setTimeout(() => (copied.value = false), 2000)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
onBeforeUnmount(() => clearTimeout(timer))
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<template>
|
|
33
|
-
<div class="oc-copy-field">
|
|
34
|
-
<input class="oc-copy-field-value" type="text" readonly :value="value" :aria-label="label" />
|
|
35
|
-
<button :class="['oc-copy-field-button', copied && 'is-copied']" type="button" @click="copy">{{ buttonLabel }}</button>
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Read-only monospace value with a copy button. Copies via navigator.clipboard and
|
|
4
|
+
* adds .is-copied for 2 seconds. Emits `copy` with the value.
|
|
5
|
+
*/
|
|
6
|
+
import { onBeforeUnmount, ref } from 'vue'
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
value: string
|
|
11
|
+
label?: string
|
|
12
|
+
buttonLabel?: string
|
|
13
|
+
}>(),
|
|
14
|
+
{ label: 'Value', buttonLabel: 'Copy' },
|
|
15
|
+
)
|
|
16
|
+
const emit = defineEmits<{ copy: [value: string] }>()
|
|
17
|
+
|
|
18
|
+
const copied = ref(false)
|
|
19
|
+
let timer: ReturnType<typeof setTimeout> | undefined
|
|
20
|
+
|
|
21
|
+
async function copy() {
|
|
22
|
+
await navigator.clipboard.writeText(props.value)
|
|
23
|
+
copied.value = true
|
|
24
|
+
emit('copy', props.value)
|
|
25
|
+
clearTimeout(timer)
|
|
26
|
+
timer = setTimeout(() => (copied.value = false), 2000)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
onBeforeUnmount(() => clearTimeout(timer))
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<div class="oc-copy-field">
|
|
34
|
+
<input class="oc-copy-field-value" type="text" readonly :value="value" :aria-label="label" />
|
|
35
|
+
<button :class="['oc-copy-field-button', copied && 'is-copied']" type="button" @click="copy">{{ buttonLabel }}</button>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/** Animated number (@property). Starts when scrolled into view unless `onView` is false. */
|
|
3
|
-
import { computed } from 'vue'
|
|
4
|
-
|
|
5
|
-
const props = withDefaults(defineProps<{ to: number; suffix?: string; onView?: boolean }>(), { onView: true })
|
|
6
|
-
const style = computed(() => {
|
|
7
|
-
const s: Record<string, string> = { '--oc-counter-to': String(props.to) }
|
|
8
|
-
if (props.suffix) s['--oc-counter-suffix'] = `'${props.suffix}'`
|
|
9
|
-
return s
|
|
10
|
-
})
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<template>
|
|
14
|
-
<strong :class="['oc-counter', onView && 'oc-counter--on-view']" :style="style"></strong>
|
|
15
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/** Animated number (@property). Starts when scrolled into view unless `onView` is false. */
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{ to: number; suffix?: string; onView?: boolean }>(), { onView: true })
|
|
6
|
+
const style = computed(() => {
|
|
7
|
+
const s: Record<string, string> = { '--oc-counter-to': String(props.to) }
|
|
8
|
+
if (props.suffix) s['--oc-counter-suffix'] = `'${props.suffix}'`
|
|
9
|
+
return s
|
|
10
|
+
})
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<strong :class="['oc-counter', onView && 'oc-counter--on-view']" :style="style"></strong>
|
|
15
|
+
</template>
|