mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-21 15:36:22 +08:00
Fix flyouts in main navigation [SCI-10208]
This commit is contained in:
parent
596582d4fe
commit
bcad0145a3
|
@ -3,19 +3,20 @@
|
||||||
<div ref="field" class="cursor-pointer" @click.stop="isOpen = (!isOpen || fieldOnlyOpen)">
|
<div ref="field" class="cursor-pointer" @click.stop="isOpen = (!isOpen || fieldOnlyOpen)">
|
||||||
<slot name="field"></slot>
|
<slot name="field"></slot>
|
||||||
</div>
|
</div>
|
||||||
<teleport to="body">
|
<template v-if="isOpen">
|
||||||
<div ref="flyout"
|
<teleport to="body">
|
||||||
class="sn-dropdown fixed z-[3000] bg-sn-white inline-block
|
<div ref="flyout"
|
||||||
rounded p-2.5 sn-shadow-menu-sm"
|
class="sn-dropdown fixed z-[3000] bg-sn-white inline-block
|
||||||
:class="{
|
rounded p-2.5 sn-shadow-menu-sm"
|
||||||
'right-0': position === 'right',
|
:class="{
|
||||||
'left-0': position === 'left',
|
'right-0': position === 'right',
|
||||||
}"
|
'left-0': position === 'left',
|
||||||
v-if="isOpen"
|
}"
|
||||||
>
|
>
|
||||||
<slot name="flyout"></slot>
|
<slot name="flyout"></slot>
|
||||||
</div>
|
</div>
|
||||||
</teleport>
|
</teleport>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -6,57 +6,58 @@
|
||||||
<i v-if="caret && isOpen" class="sn-icon sn-icon-up"></i>
|
<i v-if="caret && isOpen" class="sn-icon sn-icon-up"></i>
|
||||||
<i v-else-if="caret" class="sn-icon sn-icon-down"></i>
|
<i v-else-if="caret" class="sn-icon sn-icon-down"></i>
|
||||||
</button>
|
</button>
|
||||||
<teleport to="body">
|
<template v-if="isOpen">
|
||||||
<div ref="flyout"
|
<teleport to="body">
|
||||||
v-if="isOpen"
|
<div ref="flyout"
|
||||||
class="fixed z-[3000] sn-menu-dropdown bg-sn-white inline-block rounded p-2.5 sn-shadow-menu-sm flex flex-col gap-[1px]"
|
class="fixed z-[3000] sn-menu-dropdown bg-sn-white inline-block rounded p-2.5 sn-shadow-menu-sm flex flex-col gap-[1px]"
|
||||||
:class="{
|
:class="{
|
||||||
'right-0': position === 'right',
|
'right-0': position === 'right',
|
||||||
'left-0': position === 'left',
|
'left-0': position === 'left',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<span v-for="(item, i) in listItems" :key="i" class="contents">
|
<span v-for="(item, i) in listItems" :key="i" class="contents">
|
||||||
<div v-if="item.dividerBefore" class="border-0 border-t border-solid border-sn-light-grey"></div>
|
<div v-if="item.dividerBefore" class="border-0 border-t border-solid border-sn-light-grey"></div>
|
||||||
<a :href="item.url" v-if="!item.submenu"
|
<a :href="item.url" v-if="!item.submenu"
|
||||||
:target="item.url_target || '_self'"
|
:target="item.url_target || '_self'"
|
||||||
:class="{ 'bg-sn-super-light-blue': item.active }"
|
|
||||||
:data-toggle="item.modalTarget && 'modal'"
|
|
||||||
:data-target="item.modalTarget"
|
|
||||||
class="block whitespace-nowrap rounded px-3 py-2.5 hover:!text-sn-blue hover:no-underline cursor-pointer hover:bg-sn-super-light-grey leading-5"
|
|
||||||
@click="handleClick($event, item)"
|
|
||||||
>
|
|
||||||
{{ item.text }}
|
|
||||||
</a>
|
|
||||||
<div v-else class="-mx-2.5 px-2.5 group relative">
|
|
||||||
<span
|
|
||||||
:class="{ 'bg-sn-super-light-blue': item.active }"
|
:class="{ 'bg-sn-super-light-blue': item.active }"
|
||||||
class="flex group items-center rounded relative text-sn-blue whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer
|
:data-toggle="item.modalTarget && 'modal'"
|
||||||
group-hover:bg-sn-super-light-blue hover:!bg-sn-super-light-grey"
|
:data-target="item.modalTarget"
|
||||||
|
class="block whitespace-nowrap rounded px-3 py-2.5 hover:!text-sn-blue hover:no-underline cursor-pointer hover:bg-sn-super-light-grey leading-5"
|
||||||
|
@click="handleClick($event, item)"
|
||||||
>
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
<i class="sn-icon sn-icon-right ml-auto"></i>
|
</a>
|
||||||
</span>
|
<div v-else class="-mx-2.5 px-2.5 group relative">
|
||||||
<div
|
<span
|
||||||
class="absolute bg-sn-white top-0 rounded p-2.5 sn-shadow-menu-sm flex flex-col gap-[1px] tw-hidden group-hover:block"
|
|
||||||
:class="{
|
|
||||||
'left-0 ml-[100%]': item.position === 'right',
|
|
||||||
'right-0 mr-[100%]': item.position === 'left'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<a v-for="(sub_item, si) in item.submenu" :key="si"
|
|
||||||
:href="sub_item.url"
|
|
||||||
:traget="sub_item.url_target || '_self'"
|
|
||||||
:class="{ 'bg-sn-super-light-blue': item.active }"
|
:class="{ 'bg-sn-super-light-blue': item.active }"
|
||||||
class="block whitespace-nowrap rounded px-3 py-2.5 hover:!text-sn-blue hover:no-underline cursor-pointer hover:bg-sn-super-light-grey leading-5"
|
class="flex group items-center rounded relative text-sn-blue whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer
|
||||||
@click="handleClick($event, sub_item)"
|
group-hover:bg-sn-super-light-blue hover:!bg-sn-super-light-grey"
|
||||||
>
|
>
|
||||||
{{ sub_item.text }}
|
{{ item.text }}
|
||||||
</a>
|
<i class="sn-icon sn-icon-right ml-auto"></i>
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
class="absolute bg-sn-white top-0 rounded p-2.5 sn-shadow-menu-sm flex flex-col gap-[1px] tw-hidden group-hover:block"
|
||||||
|
:class="{
|
||||||
|
'left-0 ml-[100%]': item.position === 'right',
|
||||||
|
'right-0 mr-[100%]': item.position === 'left'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<a v-for="(sub_item, si) in item.submenu" :key="si"
|
||||||
|
:href="sub_item.url"
|
||||||
|
:traget="sub_item.url_target || '_self'"
|
||||||
|
:class="{ 'bg-sn-super-light-blue': item.active }"
|
||||||
|
class="block whitespace-nowrap rounded px-3 py-2.5 hover:!text-sn-blue hover:no-underline cursor-pointer hover:bg-sn-super-light-grey leading-5"
|
||||||
|
@click="handleClick($event, sub_item)"
|
||||||
|
>
|
||||||
|
{{ sub_item.text }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</teleport>
|
||||||
</teleport>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -46,44 +46,46 @@
|
||||||
<i v-else class="sn-icon ml-auto"
|
<i v-else class="sn-icon ml-auto"
|
||||||
:class="{ 'sn-icon-down': !isOpen, 'sn-icon-up': isOpen, 'text-sn-grey': disabled}"></i>
|
:class="{ 'sn-icon-down': !isOpen, 'sn-icon-up': isOpen, 'text-sn-grey': disabled}"></i>
|
||||||
</div>
|
</div>
|
||||||
<teleport to="body">
|
<template v-if="isOpen">
|
||||||
<div v-if="isOpen" ref="flyout"
|
<teleport to="body">
|
||||||
class="sn-select-dropdown bg-white inline-block sn-shadow-menu-sm rounded w-full
|
<div ref="flyout"
|
||||||
fixed z-[3000]">
|
class="sn-select-dropdown bg-white inline-block sn-shadow-menu-sm rounded w-full
|
||||||
<div v-if="multiple && withCheckboxes" class="p-2.5 pb-0">
|
fixed z-[3000]">
|
||||||
<div @click="selectAll" :class="sizeClass"
|
<div v-if="multiple && withCheckboxes" class="p-2.5 pb-0">
|
||||||
class="border-x-0 border-transparent border-solid border-b-sn-light-grey
|
<div @click="selectAll" :class="sizeClass"
|
||||||
py-1.5 px-3 cursor-pointer flex items-center gap-2 shrink-0">
|
class="border-x-0 border-transparent border-solid border-b-sn-light-grey
|
||||||
<div class="sn-checkbox-icon"
|
py-1.5 px-3 cursor-pointer flex items-center gap-2 shrink-0">
|
||||||
:class="selectAllState"
|
<div class="sn-checkbox-icon"
|
||||||
></div>
|
:class="selectAllState"
|
||||||
{{ i18n.t('general.select_all') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<perfect-scrollbar class="p-2.5 flex flex-col max-h-80 relative" :class="{ 'pt-0': withCheckboxes }">
|
|
||||||
<template v-for="option in filteredOptions" :key="option[0]">
|
|
||||||
<div
|
|
||||||
@click.stop="setValue(option[0])"
|
|
||||||
class="py-1.5 px-3 rounded cursor-pointer flex items-center gap-2 shrink-0"
|
|
||||||
:class="[sizeClass, {'!bg-sn-super-light-blue': valueSelected(option[0])}]"
|
|
||||||
>
|
|
||||||
<div v-if="withCheckboxes"
|
|
||||||
class="sn-checkbox-icon"
|
|
||||||
:class="{
|
|
||||||
'checked': valueSelected(option[0]),
|
|
||||||
'unchecked': !valueSelected(option[0]),
|
|
||||||
}"
|
|
||||||
></div>
|
></div>
|
||||||
<div v-if="optionRenderer" v-html="optionRenderer(option)"></div>
|
{{ i18n.t('general.select_all') }}
|
||||||
<div v-else >{{ option[1] }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
<div v-if="filteredOptions.length === 0" class="text-sn-grey text-center py-2.5">
|
|
||||||
{{ noOptionsPlaceholder || this.i18n.t('general.select_dropdown.no_options_placeholder') }}
|
|
||||||
</div>
|
</div>
|
||||||
</perfect-scrollbar>
|
<perfect-scrollbar class="p-2.5 flex flex-col max-h-80 relative" :class="{ 'pt-0': withCheckboxes }">
|
||||||
</div>
|
<template v-for="option in filteredOptions" :key="option[0]">
|
||||||
</teleport>
|
<div
|
||||||
|
@click.stop="setValue(option[0])"
|
||||||
|
class="py-1.5 px-3 rounded cursor-pointer flex items-center gap-2 shrink-0"
|
||||||
|
:class="[sizeClass, {'!bg-sn-super-light-blue': valueSelected(option[0])}]"
|
||||||
|
>
|
||||||
|
<div v-if="withCheckboxes"
|
||||||
|
class="sn-checkbox-icon"
|
||||||
|
:class="{
|
||||||
|
'checked': valueSelected(option[0]),
|
||||||
|
'unchecked': !valueSelected(option[0]),
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
<div v-if="optionRenderer" v-html="optionRenderer(option)"></div>
|
||||||
|
<div v-else >{{ option[1] }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-if="filteredOptions.length === 0" class="text-sn-grey text-center py-2.5">
|
||||||
|
{{ noOptionsPlaceholder || this.i18n.t('general.select_dropdown.no_options_placeholder') }}
|
||||||
|
</div>
|
||||||
|
</perfect-scrollbar>
|
||||||
|
</div>
|
||||||
|
</teleport>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in a new issue