@dnax/ui 0.0.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/README.md +15 -0
- package/components/QAccordion.vue +68 -0
- package/components/QAccordionContent.vue +62 -0
- package/components/QAccordionItem.vue +24 -0
- package/components/QAccordionTrigger.vue +51 -0
- package/components/QActionSheet.vue +159 -0
- package/components/QApp.vue +8 -0
- package/components/QAutocomplete.vue +316 -0
- package/components/QAvatar.vue +92 -0
- package/components/QBackHeader.vue +69 -0
- package/components/QBackTop.vue +125 -0
- package/components/QBadge.vue +55 -0
- package/components/QBottomSheet.vue +177 -0
- package/components/QBottomSheetFooter.vue +9 -0
- package/components/QBottomSheetHeader.vue +35 -0
- package/components/QBottomSheetProvider.vue +62 -0
- package/components/QBottomSheetTrigger.vue +18 -0
- package/components/QBtn.vue +144 -0
- package/components/QBtnGroup.vue +31 -0
- package/components/QBubble.vue +36 -0
- package/components/QBubbleContent.vue +28 -0
- package/components/QBubbleGroup.vue +25 -0
- package/components/QBubbleReactions.vue +40 -0
- package/components/QCard.vue +63 -0
- package/components/QCardActions.vue +27 -0
- package/components/QCardContent.vue +29 -0
- package/components/QCarousel.vue +115 -0
- package/components/QCarouselContent.vue +23 -0
- package/components/QCarouselItem.vue +20 -0
- package/components/QCarouselNav.vue +51 -0
- package/components/QCheckbox.vue +146 -0
- package/components/QChip.vue +91 -0
- package/components/QCircularProgress.vue +122 -0
- package/components/QCol.vue +52 -0
- package/components/QCollapse.vue +141 -0
- package/components/QConfigProvider.vue +164 -0
- package/components/QContainer.vue +201 -0
- package/components/QCountDown.vue +164 -0
- package/components/QCountryPicker.vue +593 -0
- package/components/QDataGrid.vue +491 -0
- package/components/QDatePicker.vue +250 -0
- package/components/QDialog.vue +163 -0
- package/components/QDialogFooter.vue +9 -0
- package/components/QDialogHeader.vue +41 -0
- package/components/QDialogProvider.vue +65 -0
- package/components/QDialogTrigger.vue +18 -0
- package/components/QFab.vue +80 -0
- package/components/QFabAction.vue +48 -0
- package/components/QFilePicker.vue +294 -0
- package/components/QFooter.vue +72 -0
- package/components/QGallery.vue +280 -0
- package/components/QGrid.vue +54 -0
- package/components/QHeader.vue +38 -0
- package/components/QIcon.vue +53 -0
- package/components/QImagePicker.vue +248 -0
- package/components/QImagePreview.vue +225 -0
- package/components/QImagePreviewProvider.vue +35 -0
- package/components/QImg.vue +142 -0
- package/components/QInfiniteScroll.vue +109 -0
- package/components/QInnerLoading.vue +67 -0
- package/components/QInput.vue +289 -0
- package/components/QInputOtp.vue +238 -0
- package/components/QInputPassword.vue +67 -0
- package/components/QInputTag.vue +281 -0
- package/components/QIntersection.vue +119 -0
- package/components/QItem.vue +60 -0
- package/components/QItemSection.vue +47 -0
- package/components/QLinearProgress.vue +94 -0
- package/components/QList.vue +39 -0
- package/components/QLoading.vue +77 -0
- package/components/QLoadingProvider.vue +41 -0
- package/components/QMarquee.vue +56 -0
- package/components/QMessageScroller.vue +10 -0
- package/components/QMessageScrollerButton.vue +48 -0
- package/components/QMessageScrollerContent.vue +31 -0
- package/components/QMessageScrollerItem.vue +49 -0
- package/components/QMessageScrollerProvider.vue +198 -0
- package/components/QMessageScrollerViewport.vue +109 -0
- package/components/QNavMenu.vue +75 -0
- package/components/QNavMenuContent.vue +10 -0
- package/components/QNavMenuItem.vue +60 -0
- package/components/QNavMenuTrigger.vue +96 -0
- package/components/QNotifyProvider.vue +33 -0
- package/components/QNotifyToast.vue +60 -0
- package/components/QPage.vue +56 -0
- package/components/QPagination.vue +195 -0
- package/components/QParallax.vue +124 -0
- package/components/QPullToRefresh.vue +138 -0
- package/components/QRadio.vue +99 -0
- package/components/QRating.vue +105 -0
- package/components/QReorder.vue +191 -0
- package/components/QRollingText.vue +225 -0
- package/components/QRow.vue +23 -0
- package/components/QSafeArea.vue +39 -0
- package/components/QScrollArea.vue +118 -0
- package/components/QSelect.vue +698 -0
- package/components/QSeparator.vue +39 -0
- package/components/QSidebar.vue +153 -0
- package/components/QSidebarContent.vue +14 -0
- package/components/QSidebarFooter.vue +14 -0
- package/components/QSidebarHeader.vue +14 -0
- package/components/QSidebarMenu.vue +9 -0
- package/components/QSidebarMenuButton.vue +59 -0
- package/components/QSidebarMenuItem.vue +9 -0
- package/components/QSidebarTrigger.vue +32 -0
- package/components/QSkeleton.vue +95 -0
- package/components/QSlider.vue +205 -0
- package/components/QSpace.vue +10 -0
- package/components/QSpinner.vue +172 -0
- package/components/QSplitter.vue +145 -0
- package/components/QSticky.vue +181 -0
- package/components/QSwipeCell.vue +217 -0
- package/components/QSwiper.vue +102 -0
- package/components/QSwiperSlide.vue +19 -0
- package/components/QSyntax.vue +171 -0
- package/components/QTab.vue +175 -0
- package/components/QTabPanel.vue +50 -0
- package/components/QTabPanels.vue +106 -0
- package/components/QTable.vue +575 -0
- package/components/QTabs.vue +188 -0
- package/components/QText.vue +316 -0
- package/components/QTextCaption.vue +122 -0
- package/components/QToolbar.vue +28 -0
- package/components/QTooltip.vue +313 -0
- package/components/QUploader.vue +473 -0
- package/components/QVideo.vue +289 -0
- package/components/QVirtualScroll.vue +190 -0
- package/components/internal/QDateCalendar.vue +153 -0
- package/index.ts +151 -0
- package/lib/breakpoints.ts +44 -0
- package/lib/colors.ts +24 -0
- package/lib/config.ts +34 -0
- package/lib/countries.ts +261 -0
- package/lib/formula.ts +630 -0
- package/lib/icons.ts +38 -0
- package/lib/loading.ts +75 -0
- package/lib/overlayBack.ts +124 -0
- package/lib/platform.ts +146 -0
- package/lib/primitive.ts +25 -0
- package/lib/q.ts +287 -0
- package/lib/screen.ts +105 -0
- package/lib/search.ts +35 -0
- package/lib/themeVars.ts +22 -0
- package/lib/useComponentProps.ts +54 -0
- package/lib/utils.ts +7 -0
- package/module.ts +89 -0
- package/package.json +41 -0
- package/scripts/generate-exports.ts +56 -0
- package/styles/main.css +7627 -0
- package/tsconfig.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// QAccordion — accordéon type Accordion shadcn-vue (reka-ui), style Quasar.
|
|
3
|
+
// <q-accordion v-model type="single|multiple" collapsible> + QAccordionItem/Trigger/Content
|
|
4
|
+
import type { InjectionKey } from "vue"
|
|
5
|
+
|
|
6
|
+
export interface AccordionContext {
|
|
7
|
+
isOpen: (value: string) => boolean
|
|
8
|
+
toggle: (value: string) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const qAccordionKey: InjectionKey<AccordionContext> = Symbol("q-accordion")
|
|
12
|
+
|
|
13
|
+
export interface AccordionItemContext {
|
|
14
|
+
value: string
|
|
15
|
+
uid: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const qAccordionItemKey: InjectionKey<AccordionItemContext> = Symbol("q-accordion-item")
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { provide } from "vue"
|
|
23
|
+
|
|
24
|
+
interface Props {
|
|
25
|
+
/** Valeur(s) ouverte(s) : string (single) ou string[] (multiple) */
|
|
26
|
+
modelValue?: string | string[]
|
|
27
|
+
/** single (un seul ouvert) | multiple */
|
|
28
|
+
type?: "single" | "multiple"
|
|
29
|
+
/** En single : permet de refermer l'item ouvert */
|
|
30
|
+
collapsible?: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
34
|
+
type: "single",
|
|
35
|
+
collapsible: false,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const emit = defineEmits<{ "update:modelValue": [value: string | string[] | undefined] }>()
|
|
39
|
+
|
|
40
|
+
const isOpen = (value: string): boolean => {
|
|
41
|
+
if (props.type === "multiple") return (props.modelValue as string[] | undefined)?.includes(value) ?? false
|
|
42
|
+
return props.modelValue === value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const toggle = (value: string) => {
|
|
46
|
+
if (props.type === "multiple") {
|
|
47
|
+
const list = (props.modelValue as string[] | undefined) ?? []
|
|
48
|
+
emit(
|
|
49
|
+
"update:modelValue",
|
|
50
|
+
list.includes(value) ? list.filter((v) => v !== value) : [...list, value],
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
else if (props.modelValue === value) {
|
|
54
|
+
if (props.collapsible) emit("update:modelValue", undefined)
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
emit("update:modelValue", value)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
provide<AccordionContext>(qAccordionKey, { isOpen, toggle })
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<div class="q-accordion">
|
|
66
|
+
<slot />
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// QAccordionContent — contenu repliable animé (pattern shadcn/reka-ui).
|
|
3
|
+
// Animation de hauteur mesurée (scrollHeight) : height 0 ↔ hauteur du contenu,
|
|
4
|
+
// overflow hidden → contenu invisible quand réduit (aucun débordement).
|
|
5
|
+
import { computed, inject, nextTick, onMounted, ref, watch } from "vue"
|
|
6
|
+
import { qAccordionItemKey, qAccordionKey } from "./QAccordion.vue"
|
|
7
|
+
|
|
8
|
+
const accordion = inject(qAccordionKey, null)
|
|
9
|
+
const item = inject(qAccordionItemKey, null)
|
|
10
|
+
|
|
11
|
+
const isOpen = computed(() => accordion?.isOpen(item?.value ?? "") ?? false)
|
|
12
|
+
|
|
13
|
+
const rootEl = ref<HTMLElement | null>(null)
|
|
14
|
+
const innerEl = ref<HTMLElement | null>(null)
|
|
15
|
+
const contentHeight = ref(0)
|
|
16
|
+
const measured = ref(false)
|
|
17
|
+
|
|
18
|
+
// Hauteur mesurée du contenu (padding compris)
|
|
19
|
+
const measure = () => {
|
|
20
|
+
const inner = innerEl.value
|
|
21
|
+
if (inner) {
|
|
22
|
+
contentHeight.value = inner.scrollHeight
|
|
23
|
+
measured.value = true
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const rootStyle = computed<Record<string, string> | undefined>(() => {
|
|
28
|
+
if (!isOpen.value) return { height: "0px" }
|
|
29
|
+
return measured.value ? { height: `${contentHeight.value}px` } : undefined
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// À l'ouverture : mesurer puis animer 0 → hauteur
|
|
33
|
+
watch(isOpen, async (open) => {
|
|
34
|
+
if (open) {
|
|
35
|
+
await nextTick()
|
|
36
|
+
measure()
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// À la fin de l'animation d'ouverture : height auto (le contenu peut grandir)
|
|
41
|
+
const onTransitionEnd = () => {
|
|
42
|
+
if (isOpen.value && rootEl.value) rootEl.value.style.height = "auto"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
onMounted(measure)
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<div
|
|
50
|
+
ref="rootEl"
|
|
51
|
+
:id="item?.uid"
|
|
52
|
+
class="q-accordion__content"
|
|
53
|
+
:class="{ 'q-accordion__content--open': isOpen }"
|
|
54
|
+
:style="rootStyle"
|
|
55
|
+
role="region"
|
|
56
|
+
@transitionend="onTransitionEnd"
|
|
57
|
+
>
|
|
58
|
+
<div ref="innerEl" class="q-accordion__content-inner">
|
|
59
|
+
<slot />
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// QAccordionItem — item de l'accordéon (équivalent AccordionItem). Fournit value + uid aux enfants.
|
|
3
|
+
import { provide } from "vue"
|
|
4
|
+
import { qAccordionItemKey, type AccordionItemContext } from "./QAccordion.vue"
|
|
5
|
+
|
|
6
|
+
let itemSeq = 0
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
/** Identifiant de l'item (lié au v-model de l'accordéon) */
|
|
10
|
+
value: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const props = defineProps<Props>()
|
|
14
|
+
|
|
15
|
+
const uid = `q-acc-${itemSeq++}`
|
|
16
|
+
|
|
17
|
+
provide<AccordionItemContext>(qAccordionItemKey, { value: props.value, uid })
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<div class="q-accordion__item">
|
|
22
|
+
<slot />
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// QAccordionTrigger — bouton d'ouverture (équivalent AccordionTrigger).
|
|
3
|
+
import { computed, inject } from "vue"
|
|
4
|
+
import { Icon } from "@iconify/vue"
|
|
5
|
+
import { icons } from "../lib/icons"
|
|
6
|
+
import { qAccordionItemKey, qAccordionKey } from "./QAccordion.vue"
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
label?: string
|
|
10
|
+
/** Icône Iconify du chevron (défaut : lucide:chevron-down) */
|
|
11
|
+
expandIcon?: string
|
|
12
|
+
disable?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
disable: false,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const accordion = inject(qAccordionKey, null)
|
|
20
|
+
const item = inject(qAccordionItemKey, null)
|
|
21
|
+
|
|
22
|
+
const isOpen = computed(() => accordion?.isOpen(item?.value ?? "") ?? false)
|
|
23
|
+
|
|
24
|
+
const toggle = () => {
|
|
25
|
+
if (props.disable || !item) return
|
|
26
|
+
accordion?.toggle(item.value)
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
class="q-accordion__trigger"
|
|
34
|
+
:class="{ 'q-accordion__trigger--open': isOpen }"
|
|
35
|
+
:disabled="disable"
|
|
36
|
+
:aria-expanded="isOpen ? 'true' : 'false'"
|
|
37
|
+
:aria-controls="item?.uid"
|
|
38
|
+
@click="toggle"
|
|
39
|
+
>
|
|
40
|
+
<span class="q-accordion__trigger-content">
|
|
41
|
+
<span v-if="label" class="q-accordion__trigger-label">{{ label }}</span>
|
|
42
|
+
<slot />
|
|
43
|
+
</span>
|
|
44
|
+
<Icon
|
|
45
|
+
:icon="expandIcon || icons.chevronDown"
|
|
46
|
+
class="q-accordion__trigger-icon"
|
|
47
|
+
:class="{ 'q-accordion__trigger-icon--rotated': isOpen }"
|
|
48
|
+
aria-hidden="true"
|
|
49
|
+
/>
|
|
50
|
+
</button>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// QActionSheet — action sheet type iOS : <q-action-sheet v-model="open" :options="opts" @select="onSelect" />
|
|
3
|
+
// Options passées en props, événement select à la sélection (ferme puis émet).
|
|
4
|
+
|
|
5
|
+
export interface ActionSheetOption {
|
|
6
|
+
/** Libellé affiché */
|
|
7
|
+
label: string
|
|
8
|
+
/** Valeur émise par @select ; si absente, l'option elle-même est émise */
|
|
9
|
+
value?: any
|
|
10
|
+
/** Icône Iconify à gauche (ex. : "lucide:star") */
|
|
11
|
+
icon?: string
|
|
12
|
+
/** Icône Iconify à droite */
|
|
13
|
+
iconRight?: string
|
|
14
|
+
/** Couleur du texte (token ou hex) */
|
|
15
|
+
color?: string
|
|
16
|
+
/** Sous-texte descriptif */
|
|
17
|
+
description?: string
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { computed, onBeforeUnmount, onMounted, watch } from "vue"
|
|
23
|
+
import { Icon } from "@iconify/vue"
|
|
24
|
+
import { colorValue } from "../lib/colors"
|
|
25
|
+
import { useOverlayBack } from "../lib/overlayBack"
|
|
26
|
+
|
|
27
|
+
interface Props {
|
|
28
|
+
/** Ouvert (v-model) */
|
|
29
|
+
modelValue?: boolean
|
|
30
|
+
/** Options de l'action sheet */
|
|
31
|
+
options?: ActionSheetOption[]
|
|
32
|
+
/** Titre discret au-dessus des options */
|
|
33
|
+
title?: string
|
|
34
|
+
/** Bouton Annuler : false pour masquer, string pour le libellé */
|
|
35
|
+
cancel?: boolean | string
|
|
36
|
+
/** Ne se ferme ni au backdrop ni à Échap */
|
|
37
|
+
persistent?: boolean
|
|
38
|
+
dark?: boolean
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
42
|
+
modelValue: false,
|
|
43
|
+
options: () => [],
|
|
44
|
+
cancel: true,
|
|
45
|
+
persistent: false,
|
|
46
|
+
dark: false,
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const emit = defineEmits<{
|
|
50
|
+
"update:modelValue": [value: boolean]
|
|
51
|
+
/** Valeur de l'option sélectionnée (ou l'option si pas de value) */
|
|
52
|
+
select: [value: any]
|
|
53
|
+
/** Fermeture sans sélection (backdrop, Échap, Annuler) */
|
|
54
|
+
cancel: []
|
|
55
|
+
}>()
|
|
56
|
+
|
|
57
|
+
const open = computed({
|
|
58
|
+
get: () => props.modelValue,
|
|
59
|
+
set: (v) => emit("update:modelValue", v),
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// « Retour » navigateur → ferme l'action sheet au lieu de naviguer
|
|
63
|
+
useOverlayBack(open, () => { open.value = false }, "QActionSheet")
|
|
64
|
+
|
|
65
|
+
const cancelLabel = computed(() => (typeof props.cancel === "string" ? props.cancel : "Annuler"))
|
|
66
|
+
|
|
67
|
+
// Échap + verrouillage du scroll du body
|
|
68
|
+
const onDocKeydown = (e: KeyboardEvent) => {
|
|
69
|
+
if (e.key === "Escape" && open.value && !props.persistent) dismiss()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
watch(open, (v) => {
|
|
73
|
+
if (typeof document !== "undefined") document.body.style.overflow = v ? "hidden" : ""
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
onMounted(() => {
|
|
77
|
+
if (typeof document !== "undefined") document.addEventListener("keydown", onDocKeydown)
|
|
78
|
+
})
|
|
79
|
+
onBeforeUnmount(() => {
|
|
80
|
+
if (typeof document !== "undefined") {
|
|
81
|
+
document.removeEventListener("keydown", onDocKeydown)
|
|
82
|
+
document.body.style.overflow = ""
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const onSelect = (opt: ActionSheetOption) => {
|
|
87
|
+
open.value = false
|
|
88
|
+
emit("select", opt.value !== undefined ? opt.value : opt)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const dismiss = () => {
|
|
92
|
+
open.value = false
|
|
93
|
+
emit("cancel")
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const onOverlayClick = () => {
|
|
97
|
+
if (!props.persistent) dismiss()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const getKey = (opt: ActionSheetOption, i: number) => String(opt.value ?? `opt-${i}`)
|
|
101
|
+
|
|
102
|
+
const optionStyle = (opt: ActionSheetOption) =>
|
|
103
|
+
opt.color ? { color: colorValue(opt.color) } : undefined
|
|
104
|
+
|
|
105
|
+
const panelClasses = computed(() => [
|
|
106
|
+
"q-action-sheet__panel",
|
|
107
|
+
props.dark && "q-action-sheet__panel--dark",
|
|
108
|
+
])
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<template>
|
|
112
|
+
<Teleport to="body">
|
|
113
|
+
<Transition name="q-bs">
|
|
114
|
+
<div
|
|
115
|
+
v-if="open"
|
|
116
|
+
class="q-action-sheet__overlay"
|
|
117
|
+
@click="onOverlayClick"
|
|
118
|
+
>
|
|
119
|
+
<div
|
|
120
|
+
class="q-action-sheet__panel"
|
|
121
|
+
:class="panelClasses"
|
|
122
|
+
role="dialog"
|
|
123
|
+
aria-modal="true"
|
|
124
|
+
@click.stop
|
|
125
|
+
>
|
|
126
|
+
<h2 v-if="title" class="q-action-sheet__title">{{ title }}</h2>
|
|
127
|
+
|
|
128
|
+
<div class="q-action-sheet__options" role="listbox">
|
|
129
|
+
<button
|
|
130
|
+
v-for="(opt, i) in options"
|
|
131
|
+
:key="getKey(opt, i)"
|
|
132
|
+
type="button"
|
|
133
|
+
role="option"
|
|
134
|
+
class="q-action-sheet__option"
|
|
135
|
+
:style="optionStyle(opt)"
|
|
136
|
+
@click="onSelect(opt)"
|
|
137
|
+
>
|
|
138
|
+
<Icon :icon="opt.icon" v-if="opt.icon" class="q-action-sheet__option-icon" aria-hidden="true" />
|
|
139
|
+
<span class="q-action-sheet__option-text">
|
|
140
|
+
<span class="q-action-sheet__option-label">{{ opt.label }}</span>
|
|
141
|
+
<span v-if="opt.description" class="q-action-sheet__option-description">{{ opt.description }}</span>
|
|
142
|
+
</span>
|
|
143
|
+
<Icon :icon="opt.iconRight" v-if="opt.iconRight" class="q-action-sheet__option-icon" aria-hidden="true" />
|
|
144
|
+
</button>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<button
|
|
148
|
+
v-if="cancel !== false"
|
|
149
|
+
type="button"
|
|
150
|
+
class="q-action-sheet__cancel"
|
|
151
|
+
@click="dismiss"
|
|
152
|
+
>
|
|
153
|
+
{{ cancelLabel }}
|
|
154
|
+
</button>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</Transition>
|
|
158
|
+
</Teleport>
|
|
159
|
+
</template>
|