feat(popper): arrow option & docs consistency across components (#875)

This commit is contained in:
Conner
2023-10-27 08:03:06 -05:00
committed by GitHub
parent 4ce23746da
commit f785ecd46f
22 changed files with 412 additions and 101 deletions

View File

@@ -0,0 +1,35 @@
<script setup>
const { x, y } = useMouse()
const { y: windowY } = useWindowScroll()
const isOpen = ref(false)
const virtualElement = ref({ getBoundingClientRect: () => ({}) })
function onContextMenu () {
const top = unref(y) - unref(windowY)
const left = unref(x)
virtualElement.value.getBoundingClientRect = () => ({
width: 0,
height: 0,
top,
left
})
isOpen.value = true
}
</script>
<template>
<div class="w-full" @contextmenu.prevent="onContextMenu">
<Placeholder class="h-96 select-none w-full flex items-center justify-center">
Right click here
</Placeholder>
<UContextMenu v-model="isOpen" :virtual-element="virtualElement" :popper="{ arrow: true, placement: 'right' }">
<div class="p-4">
Menu
</div>
</UContextMenu>
</div>
</template>

View File

@@ -0,0 +1,35 @@
<script setup>
const { x, y } = useMouse()
const { y: windowY } = useWindowScroll()
const isOpen = ref(false)
const virtualElement = ref({ getBoundingClientRect: () => ({}) })
function onContextMenu () {
const top = unref(y) - unref(windowY)
const left = unref(x)
virtualElement.value.getBoundingClientRect = () => ({
width: 0,
height: 0,
top,
left
})
isOpen.value = true
}
</script>
<template>
<div class="w-full" @contextmenu.prevent="onContextMenu">
<Placeholder class="h-96 select-none w-full flex items-center justify-center">
Right click here
</Placeholder>
<UContextMenu v-model="isOpen" :virtual-element="virtualElement" :popper="{ offset: 0 }">
<div class="p-4">
Menu
</div>
</UContextMenu>
</div>
</template>

View File

@@ -0,0 +1,35 @@
<script setup>
const { x, y } = useMouse()
const { y: windowY } = useWindowScroll()
const isOpen = ref(false)
const virtualElement = ref({ getBoundingClientRect: () => ({}) })
function onContextMenu () {
const top = unref(y) - unref(windowY)
const left = unref(x)
virtualElement.value.getBoundingClientRect = () => ({
width: 0,
height: 0,
top,
left
})
isOpen.value = true
}
</script>
<template>
<div class="w-full" @contextmenu.prevent="onContextMenu">
<Placeholder class="h-96 select-none w-full flex items-center justify-center">
Right click here
</Placeholder>
<UContextMenu v-model="isOpen" :virtual-element="virtualElement" :popper="{ placement: 'right-start' }">
<div class="p-4">
Menu
</div>
</UContextMenu>
</div>
</template>

View File

@@ -0,0 +1,16 @@
<script setup>
const items = [
[{
label: 'Profile',
avatar: {
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
}
}]
]
</script>
<template>
<UDropdown :items="items" :popper="{ arrow: true }">
<UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
</UDropdown>
</template>

View File

@@ -0,0 +1,16 @@
<script setup>
const items = [
[{
label: 'Profile',
avatar: {
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
}
}]
]
</script>
<template>
<UDropdown :items="items" :popper="{ offsetDistance: 0, placement: 'right-start' }">
<UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
</UDropdown>
</template>

View File

@@ -0,0 +1,16 @@
<script setup>
const items = [
[{
label: 'Profile',
avatar: {
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
}
}]
]
</script>
<template>
<UDropdown :items="items" :popper="{ placement: 'right-start' }">
<UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
</UDropdown>
</template>

View File

@@ -0,0 +1,11 @@
<template>
<UPopover :popper="{ arrow: true }">
<UButton color="white" label="Open" trailing-icon="i-heroicons-chevron-down-20-solid" />
<template #panel>
<div class="p-4">
<Placeholder class="h-20 w-48" />
</div>
</template>
</UPopover>
</template>

View File

@@ -0,0 +1,11 @@
<template>
<UPopover :popper="{ offsetDistance: 0 }">
<UButton color="white" label="Open" trailing-icon="i-heroicons-chevron-down-20-solid" />
<template #panel>
<div class="p-4">
<Placeholder class="h-20 w-48" />
</div>
</template>
</UPopover>
</template>

View File

@@ -0,0 +1,11 @@
<template>
<UPopover :popper="{ placement: 'top-end' }">
<UButton color="white" label="Open" trailing-icon="i-heroicons-chevron-down-20-solid" />
<template #panel>
<div class="p-4">
<Placeholder class="h-20 w-48" />
</div>
</template>
</UPopover>
</template>

View File

@@ -0,0 +1,9 @@
<script setup>
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
const selected = ref(people[0])
</script>
<template>
<USelectMenu v-model="selected" :options="people" :popper="{ arrow: true }" />
</template>

View File

@@ -0,0 +1,9 @@
<script setup>
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
const selected = ref(people[0])
</script>
<template>
<USelectMenu v-model="selected" :options="people" :popper="{ offsetDistance: 0 }" />
</template>

View File

@@ -0,0 +1,9 @@
<script setup>
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
const selected = ref(people[0])
</script>
<template>
<USelectMenu v-model="selected" :options="people" :popper="{ placement: 'left-end' }" />
</template>

View File

@@ -32,6 +32,22 @@ Use the `mode` prop to switch between `click` and `hover` modes.
:component-example{component="dropdown-example-mode"} :component-example{component="dropdown-example-mode"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="dropdown-example-arrow"}
### Placement
:component-example{component="dropdown-example-placement"}
### Offset
:component-example{component="dropdown-example-offset"}
## Slots ## Slots
### `item` ### `item`

View File

@@ -91,6 +91,22 @@ Try to search for something that doesn't exist in the example below.
:component-example{component="select-menu-example-creatable" :componentProps='{"class": "w-full lg:w-40"}'} :component-example{component="select-menu-example-creatable" :componentProps='{"class": "w-full lg:w-40"}'}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="select-menu-example-arrow"}
### Placement
:component-example{component="select-menu-example-placement"}
### Offset
:component-example{component="select-menu-example-offset"}
## Slots ## Slots
### `label` ### `label`

View File

@@ -25,6 +25,22 @@ Use the `open` prop to manually control showing the panel.
:component-example{component="popover-example-open"} :component-example{component="popover-example-open"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="popover-example-arrow"}
### Placement
:component-example{component="popover-example-placement"}
### Offset
:component-example{component="popover-example-offset"}
## Slots ## Slots
### `panel` ### `panel`

View File

@@ -12,7 +12,7 @@ links:
## Popper ## Popper
Use the `popper` prop to customize the tootip. Use the `popper` prop to customize the popper instance.
### Arrow ### Arrow

View File

@@ -11,6 +11,22 @@ links:
:component-example{component="context-menu-example"} :component-example{component="context-menu-example"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="context-menu-example-arrow"}
### Placement
:component-example{component="context-menu-example-placement"}
### Offset
:component-example{component="context-menu-example-offset"}
## Props ## Props
:component-props :component-props

View File

@@ -17,28 +17,31 @@
<div v-if="open && items.length" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver"> <div v-if="open && items.length" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver">
<Transition appear v-bind="ui.transition"> <Transition appear v-bind="ui.transition">
<HMenuItems :class="[ui.base, ui.divide, ui.ring, ui.rounded, ui.shadow, ui.background, ui.height]" static> <div>
<div v-for="(subItems, index) of items" :key="index" :class="ui.padding"> <div v-if="popper.arrow" data-popper-arrow :class="['invisible before:visible before:block before:rotate-45 before:z-[-1]', Object.values(ui.arrow)]" />
<HMenuItem v-for="(item, subIndex) of subItems" :key="subIndex" v-slot="{ active, disabled: itemDisabled }" :disabled="item.disabled"> <HMenuItems :class="[ui.base, ui.divide, ui.ring, ui.rounded, ui.shadow, ui.background, ui.height]" static>
<ULink <div v-for="(subItems, index) of items" :key="index" :class="ui.padding">
v-bind="omit(item, ['label', 'slot', 'icon', 'iconClass', 'avatar', 'shortcuts', 'disabled', 'click'])" <HMenuItem v-for="(item, subIndex) of subItems" :key="subIndex" v-slot="{ active, disabled: itemDisabled }" :disabled="item.disabled">
:class="[ui.item.base, ui.item.padding, ui.item.size, ui.item.rounded, active ? ui.item.active : ui.item.inactive, itemDisabled && ui.item.disabled]" <ULink
@click="item.click" v-bind="omit(item, ['label', 'slot', 'icon', 'iconClass', 'avatar', 'shortcuts', 'disabled', 'click'])"
> :class="[ui.item.base, ui.item.padding, ui.item.size, ui.item.rounded, active ? ui.item.active : ui.item.inactive, itemDisabled && ui.item.disabled]"
<slot :name="item.slot || 'item'" :item="item"> @click="item.click"
<UIcon v-if="item.icon" :name="item.icon" :class="[ui.item.icon.base, active ? ui.item.icon.active : ui.item.icon.inactive, item.iconClass]" /> >
<UAvatar v-else-if="item.avatar" v-bind="{ size: ui.item.avatar.size, ...item.avatar }" :class="ui.item.avatar.base" /> <slot :name="item.slot || 'item'" :item="item">
<UIcon v-if="item.icon" :name="item.icon" :class="[ui.item.icon.base, active ? ui.item.icon.active : ui.item.icon.inactive, item.iconClass]" />
<UAvatar v-else-if="item.avatar" v-bind="{ size: ui.item.avatar.size, ...item.avatar }" :class="ui.item.avatar.base" />
<span class="truncate">{{ item.label }}</span> <span class="truncate">{{ item.label }}</span>
<span v-if="item.shortcuts?.length" :class="ui.item.shortcuts"> <span v-if="item.shortcuts?.length" :class="ui.item.shortcuts">
<UKbd v-for="shortcut of item.shortcuts" :key="shortcut">{{ shortcut }}</UKbd> <UKbd v-for="shortcut of item.shortcuts" :key="shortcut">{{ shortcut }}</UKbd>
</span> </span>
</slot> </slot>
</ULink> </ULink>
</HMenuItem> </HMenuItem>
</div> </div>
</HMenuItems> </HMenuItems>
</div>
</Transition> </Transition>
</div> </div>
</HMenu> </HMenu>
@@ -185,6 +188,8 @@ export default defineComponent({
// eslint-disable-next-line vue/no-dupe-keys // eslint-disable-next-line vue/no-dupe-keys
ui, ui,
attrs, attrs,
// eslint-disable-next-line vue/no-dupe-keys
popper,
trigger, trigger,
container, container,
containerStyle, containerStyle,

View File

@@ -52,64 +52,67 @@
<div v-if="open" ref="container" :class="[uiMenu.container, uiMenu.width]"> <div v-if="open" ref="container" :class="[uiMenu.container, uiMenu.width]">
<Transition appear v-bind="uiMenu.transition"> <Transition appear v-bind="uiMenu.transition">
<component :is="searchable ? 'HComboboxOptions' : 'HListboxOptions'" static :class="[uiMenu.base, uiMenu.divide, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]"> <div>
<HComboboxInput <div v-if="popper.arrow" data-popper-arrow :class="['invisible before:visible before:block before:rotate-45 before:z-[-1]', Object.values(uiMenu.arrow)]" />
v-if="searchable" <component :is="searchable ? 'HComboboxOptions' : 'HListboxOptions'" static :class="[uiMenu.base, uiMenu.divide, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]">
ref="searchInput" <HComboboxInput
:display-value="() => query" v-if="searchable"
name="q" ref="searchInput"
:placeholder="searchablePlaceholder" :display-value="() => query"
autofocus name="q"
autocomplete="off" :placeholder="searchablePlaceholder"
:class="uiMenu.input" autofocus
@change="query = $event.target.value" autocomplete="off"
/> :class="uiMenu.input"
<component @change="query = $event.target.value"
:is="searchable ? 'HComboboxOption' : 'HListboxOption'" />
v-for="(option, index) in filteredOptions" <component
v-slot="{ active, selected, disabled: optionDisabled }" :is="searchable ? 'HComboboxOption' : 'HListboxOption'"
:key="index" v-for="(option, index) in filteredOptions"
as="template" v-slot="{ active, selected, disabled: optionDisabled }"
:value="valueAttribute ? option[valueAttribute] : option" :key="index"
:disabled="option.disabled" as="template"
> :value="valueAttribute ? option[valueAttribute] : option"
<li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive, selected && uiMenu.option.selected, optionDisabled && uiMenu.option.disabled]"> :disabled="option.disabled"
<div :class="uiMenu.option.container"> >
<slot name="option" :option="option" :active="active" :selected="selected"> <li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive, selected && uiMenu.option.selected, optionDisabled && uiMenu.option.disabled]">
<UIcon v-if="option.icon" :name="option.icon" :class="[uiMenu.option.icon.base, active ? uiMenu.option.icon.active : uiMenu.option.icon.inactive, option.iconClass]" aria-hidden="true" /> <div :class="uiMenu.option.container">
<UAvatar <slot name="option" :option="option" :active="active" :selected="selected">
v-else-if="option.avatar" <UIcon v-if="option.icon" :name="option.icon" :class="[uiMenu.option.icon.base, active ? uiMenu.option.icon.active : uiMenu.option.icon.inactive, option.iconClass]" aria-hidden="true" />
v-bind="{ size: uiMenu.option.avatar.size, ...option.avatar }" <UAvatar
:class="uiMenu.option.avatar.base" v-else-if="option.avatar"
aria-hidden="true" v-bind="{ size: uiMenu.option.avatar.size, ...option.avatar }"
/> :class="uiMenu.option.avatar.base"
<span v-else-if="option.chip" :class="uiMenu.option.chip.base" :style="{ background: `#${option.chip}` }" /> aria-hidden="true"
/>
<span v-else-if="option.chip" :class="uiMenu.option.chip.base" :style="{ background: `#${option.chip}` }" />
<span class="truncate">{{ ['string', 'number'].includes(typeof option) ? option : option[optionAttribute] }}</span> <span class="truncate">{{ ['string', 'number'].includes(typeof option) ? option : option[optionAttribute] }}</span>
</slot> </slot>
</div> </div>
<span v-if="selected" :class="[uiMenu.option.selectedIcon.wrapper, uiMenu.option.selectedIcon.padding]"> <span v-if="selected" :class="[uiMenu.option.selectedIcon.wrapper, uiMenu.option.selectedIcon.padding]">
<UIcon :name="selectedIcon" :class="uiMenu.option.selectedIcon.base" aria-hidden="true" /> <UIcon :name="selectedIcon" :class="uiMenu.option.selectedIcon.base" aria-hidden="true" />
</span> </span>
</li> </li>
</component>
<component :is="searchable ? 'HComboboxOption' : 'HListboxOption'" v-if="creatable && queryOption && !filteredOptions.length" v-slot="{ active, selected }" :value="queryOption" as="template">
<li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive]">
<div :class="uiMenu.option.container">
<slot name="option-create" :option="queryOption" :active="active" :selected="selected">
<span class="block truncate">Create "{{ queryOption[optionAttribute] }}"</span>
</slot>
</div>
</li>
</component>
<p v-else-if="searchable && query && !filteredOptions.length" :class="uiMenu.option.empty">
<slot name="option-empty" :query="query">
No results for "{{ query }}".
</slot>
</p>
</component> </component>
</div>
<component :is="searchable ? 'HComboboxOption' : 'HListboxOption'" v-if="creatable && queryOption && !filteredOptions.length" v-slot="{ active, selected }" :value="queryOption" as="template">
<li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive]">
<div :class="uiMenu.option.container">
<slot name="option-create" :option="queryOption" :active="active" :selected="selected">
<span class="block truncate">Create "{{ queryOption[optionAttribute] }}"</span>
</slot>
</div>
</li>
</component>
<p v-else-if="searchable && query && !filteredOptions.length" :class="uiMenu.option.empty">
<slot name="option-empty" :query="query">
No results for "{{ query }}".
</slot>
</p>
</component>
</Transition> </Transition>
</div> </div>
</component> </component>
@@ -449,6 +452,8 @@ export default defineComponent({
// eslint-disable-next-line vue/no-dupe-keys // eslint-disable-next-line vue/no-dupe-keys
name, name,
inputId, inputId,
// eslint-disable-next-line vue/no-dupe-keys
popper,
trigger, trigger,
container, container,
isLeading, isLeading,

View File

@@ -1,8 +1,11 @@
<template> <template>
<div v-if="isOpen" ref="container" :class="wrapperClass" v-bind="attrs"> <div v-if="isOpen" ref="container" :class="wrapperClass" v-bind="attrs">
<Transition appear v-bind="ui.transition"> <Transition appear v-bind="ui.transition">
<div :class="[ui.base, ui.ring, ui.rounded, ui.shadow, ui.background]"> <div>
<slot /> <div v-if="popper.arrow" data-popper-arrow :class="['invisible before:visible before:block before:rotate-45 before:z-[-1]', Object.values(ui.arrow)]" />
<div :class="[ui.base, ui.ring, ui.rounded, ui.shadow, ui.background]">
<slot />
</div>
</div> </div>
</Transition> </Transition>
</div> </div>
@@ -85,6 +88,8 @@ export default defineComponent({
attrs, attrs,
isOpen, isOpen,
wrapperClass, wrapperClass,
// eslint-disable-next-line vue/no-dupe-keys
popper,
container container
} }
} }

View File

@@ -17,9 +17,12 @@
<div v-if="(open !== undefined) ? open : headlessOpen" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver"> <div v-if="(open !== undefined) ? open : headlessOpen" ref="container" :class="[ui.container, ui.width]" :style="containerStyle" @mouseover="onMouseOver">
<Transition appear v-bind="ui.transition"> <Transition appear v-bind="ui.transition">
<HPopoverPanel :class="[ui.base, ui.background, ui.ring, ui.rounded, ui.shadow]" static> <div>
<slot name="panel" :open="(open !== undefined) ? open : headlessOpen" :close="close" /> <div v-if="popper.arrow" data-popper-arrow :class="['invisible before:visible before:block before:rotate-45 before:z-[-1]', Object.values(ui.arrow)]" />
</HPopoverPanel> <HPopoverPanel :class="[ui.base, ui.background, ui.ring, ui.rounded, ui.shadow]" static>
<slot name="panel" :open="(open !== undefined) ? open : headlessOpen" :close="close" />
</HPopoverPanel>
</div>
</Transition> </Transition>
</div> </div>
</HPopover> </HPopover>
@@ -162,6 +165,8 @@ export default defineComponent({
ui, ui,
attrs, attrs,
popover, popover,
// eslint-disable-next-line vue/no-dupe-keys
popper,
trigger, trigger,
container, container,
containerStyle, containerStyle,

View File

@@ -1,5 +1,14 @@
// Data // Data
const _popperArrowPresets = {
base: 'before:w-2 before:h-2',
ring: 'before:ring-1 before:ring-gray-200 dark:before:ring-gray-800',
rounded: 'before:rounded-sm',
background: 'before:bg-gray-200 dark:before:bg-gray-800',
shadow: 'before:shadow',
placement: 'group-data-[popper-placement*="right"]:-left-1 group-data-[popper-placement*="left"]:-right-1 group-data-[popper-placement*="top"]:-bottom-1 group-data-[popper-placement*="bottom"]:-top-1'
}
export const table = { export const table = {
wrapper: 'relative overflow-x-auto', wrapper: 'relative overflow-x-auto',
base: 'min-w-full table-fixed', base: 'min-w-full table-fixed',
@@ -250,7 +259,7 @@ export const buttonGroup = {
export const dropdown = { export const dropdown = {
wrapper: 'relative inline-flex text-left rtl:text-right', wrapper: 'relative inline-flex text-left rtl:text-right',
container: 'z-20', container: 'z-20 group',
width: 'w-48', width: 'w-48',
height: '', height: '',
background: 'bg-white dark:bg-gray-800', background: 'bg-white dark:bg-gray-800',
@@ -291,6 +300,11 @@ export const dropdown = {
popper: { popper: {
placement: 'bottom-end', placement: 'bottom-end',
strategy: 'fixed' strategy: 'fixed'
},
arrow: {
..._popperArrowPresets,
ring: 'before:ring-1 before:ring-gray-200 dark:before:ring-gray-700',
background: 'before:bg-white dark:before:bg-gray-700'
} }
} }
@@ -525,7 +539,7 @@ export const select = {
} }
export const selectMenu = { export const selectMenu = {
container: 'z-20', container: 'z-20 group',
width: 'w-full', width: 'w-full',
height: 'max-h-60', height: 'max-h-60',
base: 'relative focus:outline-none overflow-y-auto scroll-py-1', base: 'relative focus:outline-none overflow-y-auto scroll-py-1',
@@ -576,6 +590,11 @@ export const selectMenu = {
}, },
default: { default: {
selectedIcon: 'i-heroicons-check-20-solid' selectedIcon: 'i-heroicons-check-20-solid'
},
arrow: {
..._popperArrowPresets,
ring: 'before:ring-1 before:ring-gray-200 dark:before:ring-gray-700',
background: 'before:bg-white dark:before:bg-gray-700'
} }
} }
@@ -1009,25 +1028,18 @@ export const tooltip = {
popper: { popper: {
strategy: 'fixed' strategy: 'fixed'
}, },
arrow: { arrow: _popperArrowPresets
base: 'before:w-2 before:h-2',
ring: 'before:ring-1 before:ring-gray-200 dark:before:ring-gray-800',
rounded: 'before:rounded-sm',
background: 'before:bg-white dark:before:bg-gray-900',
shadow: 'before:shadow',
placement: 'group-data-[popper-placement=right]:-left-1 group-data-[popper-placement=left]:-right-1 group-data-[popper-placement=top]:-bottom-1 group-data-[popper-placement=bottom]:-top-1'
}
} }
export const popover = { export const popover = {
wrapper: 'relative', wrapper: 'relative',
container: 'z-20', container: 'z-20 group',
width: '', width: '',
background: 'bg-white dark:bg-gray-900', background: 'bg-white dark:bg-gray-900',
shadow: 'shadow-lg', shadow: 'shadow-lg',
rounded: 'rounded-md', rounded: 'rounded-md',
ring: 'ring-1 ring-gray-200 dark:ring-gray-800', ring: 'ring-1 ring-gray-200 dark:ring-gray-800',
base: 'overflow-hidden focus:outline-none', base: 'overflow-hidden focus:outline-none relative',
// Syntax for `<Transition>` component https://vuejs.org/guide/built-ins/transition.html#css-based-transitions // Syntax for `<Transition>` component https://vuejs.org/guide/built-ins/transition.html#css-based-transitions
transition: { transition: {
enterActiveClass: 'transition ease-out duration-200', enterActiveClass: 'transition ease-out duration-200',
@@ -1039,18 +1051,19 @@ export const popover = {
}, },
popper: { popper: {
strategy: 'fixed' strategy: 'fixed'
} },
arrow: _popperArrowPresets
} }
export const contextMenu = { export const contextMenu = {
wrapper: 'relative', wrapper: 'relative',
container: 'z-20', container: 'z-20 group',
width: '', width: '',
background: 'bg-white dark:bg-gray-900', background: 'bg-white dark:bg-gray-900',
shadow: 'shadow-lg', shadow: 'shadow-lg',
rounded: 'rounded-md', rounded: 'rounded-md',
ring: 'ring-1 ring-gray-200 dark:ring-gray-800', ring: 'ring-1 ring-gray-200 dark:ring-gray-800',
base: 'overflow-hidden focus:outline-none', base: 'overflow-hidden focus:outline-none relative',
// Syntax for `<Transition>` component https://vuejs.org/guide/built-ins/transition.html#css-based-transitions // Syntax for `<Transition>` component https://vuejs.org/guide/built-ins/transition.html#css-based-transitions
transition: { transition: {
enterActiveClass: 'transition ease-out duration-200', enterActiveClass: 'transition ease-out duration-200',
@@ -1063,7 +1076,8 @@ export const contextMenu = {
popper: { popper: {
placement: 'bottom-start', placement: 'bottom-start',
scroll: false scroll: false
} },
arrow: _popperArrowPresets
} }
export const notification = { export const notification = {