Skip to content

Commit

Permalink
Merge pull request #246 from LUI-UI/fix-menu-resize-bug
Browse files Browse the repository at this point in the history
fix(menu): fix menu position bug when page resized or target element …
  • Loading branch information
rhmkstk committed Jan 18, 2024
2 parents 0a72cf2 + 7205eb4 commit 2824970
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 285 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"vue": "^3.2.26"
},
"dependencies": {
"@floating-ui/vue": "^1.0.2",
"@vueuse/integrations": "^10.3.0",
"focus-trap": "^7.5.2"
},
Expand Down
30 changes: 30 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 21 additions & 25 deletions src/components/MenuDropdown/LuiMenuDropdown.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const descriptions = {
'LuiMenuDropdown, when used with LuiMenuItem, provides a vertical list of selectable options, typically displayed in a dropdown fashion when triggered, allowing users to choose from available menu items.',
},
argTypes: {
menuPosition: 'Used to control the position of the menu items',
placement: 'Used to control the position of the menu items',
trigger: 'Used to insert a template in the component',
default: 'Used as default to add a text in the component',
// triggerAppend: 'Used to place an icon in the component'
Expand All @@ -38,20 +38,20 @@ const meta: Meta<typeof LuiMenuDropdown> = {
filter,
text,
// triggerAppend: { description: descriptions.argTypes.triggerAppend },
menuPosition: {
placement: {
control: 'select',
default: 'bottomLeft',
default: 'bottom-start',
options: [
'bottomLeft',
'bottomRight',
'topLeft',
'topRight',
'leftTop',
'leftBottom',
'rightTop',
'rightBottom',
'top-start',
'top-end',
'right-start',
'right-end',
'bottom-start',
'bottom-end',
'left-start',
'left-end',
],
description: descriptions.argTypes.menuPosition,
description: descriptions.argTypes.placement,
},
trigger: {
description: descriptions.argTypes.trigger,
Expand Down Expand Up @@ -491,7 +491,7 @@ export const PrependSlot: Story = {
}

const menuPositionTemplate = `
<lui-menu-dropdown v-for="position in positions" :key="position" :menu-position="position" :text="position">
<lui-menu-dropdown v-for="position in positions" :key="position" :placement="position" :text="position">
<lui-menu-item>Some long items for center</lui-menu-item>
<lui-menu-item>Some long items for center</lui-menu-item>
<lui-menu-item>Some long items for center</lui-menu-item>
Expand All @@ -502,18 +502,14 @@ export const MenuPosition: Story = {
render: () => ({
setup() {
const positions = [
'bottomLeft',
'bottomRight',
'bottom',
'topLeft',
'topRight',
'top',
'leftTop',
'leftBottom',
'left',
'rightTop',
'rightBottom',
'right',
'top-start',
'top-end',
'right-start',
'right-end',
'bottom-start',
'bottom-end',
'left-start',
'left-end',
]
return { positions }
},
Expand Down
34 changes: 24 additions & 10 deletions src/components/MenuDropdown/LuiMenuDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ export default {

<script setup lang="ts">
import { Teleport as TeleportComp, computed, h, nextTick, reactive, ref, toRefs, useSlots, watch } from 'vue'
import {
autoUpdate, flip,
offset,
shift,
useFloating,
} from '@floating-ui/vue'
import type { PropType } from 'vue'
import type { Placement } from '@floating-ui/vue'
import LuiButton from '../Button/LuiButton.vue'
import { useMenuStyles, useOutsideClick, useTeleportWrapper } from '../../composables'
// import { useMenuPositionStyles } from '../../composables/useMenuPositionStyles'
import { useId } from '../../utils/useId'
import type { Block, Color, Filter, Position, Rounded, Size, Variant } from '@/globals/types'
import type { Block, Color, Filter, MenuClasses, Rounded, Size, Variant } from '@/globals/types'
import type { TwClassInterface } from '@/globals/interfaces'
interface IMenuItems {
Expand All @@ -37,9 +44,9 @@ const props = defineProps({
type: String as PropType<string>,
default: '',
},
menuPosition: {
type: String as PropType<Position>,
default: 'bottomLeft',
placement: {
type: String as PropType<Placement>,
default: 'bottom-end',
},
variant: {
type: String as PropType<Variant>,
Expand All @@ -66,7 +73,7 @@ const props = defineProps({
default: false,
},
menuClasses: {
type: [String, Array] as PropType<string | string[]>,
type: [String, Array] as PropType<MenuClasses>,
default: '',
},
teleport: {
Expand All @@ -84,7 +91,7 @@ const slots = useSlots()
// VARIABLES
const luiDropdownWrapper = ref<HTMLElement>()
const luiDropdownTrigger = ref<HTMLDivElement>()
const luiDropdownMenu = ref<HTMLElement | null>(null)
const luiDropdownMenu = ref<HTMLElement>()
const menuActive = ref(false)
const buttonId = `lui-dropdown-button-${useId()}`
const menuId = `lui-dropdown-menu-${useId()}`
Expand All @@ -96,7 +103,12 @@ const menuState = reactive<IMenuState>({
})
const teleportId = useTeleportWrapper('dropdown')
const { classes: menuClasses, styles: menuStyles } = useMenuStyles({ ...toRefs(props), triggerEl: luiDropdownWrapper, menuEl: luiDropdownMenu })
const { classes: menuClasses } = useMenuStyles({ ...toRefs(props) })
const { floatingStyles, middlewareData } = useFloating(luiDropdownTrigger, luiDropdownMenu, {
placement: props.placement,
middleware: [offset(6), flip(), shift()],
whileElementsMounted: autoUpdate,
})
watch(
() => props.open,
Expand Down Expand Up @@ -277,6 +289,8 @@ function ArrowDownIcon() {
],
)
}
const isMenuActive = computed(() => menuActive.value && !middlewareData.value.hide?.referenceHidden)
</script>

<template>
Expand Down Expand Up @@ -340,11 +354,11 @@ function ArrowDownIcon() {
leave-to-class="transform scale-95 opacity-0 "
>
<div
v-show="menuActive"
v-show="isMenuActive"
:id="menuId"
ref="luiDropdownMenu"
:class="menuClasses"
:style="menuStyles"
:style="floatingStyles"
>
<ul
role="menu"
Expand Down
29 changes: 22 additions & 7 deletions src/components/MultiSelect/LuiMultiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import type { PropType } from 'vue'
import {
Fragment, Teleport as TeleportComp, computed, h, nextTick, provide, reactive, ref, toRef, toRefs, useAttrs, useSlots, watch,
} from 'vue'
import type { Block, Color, Description, Filter, NarrowedVariant, Position, Rounded, Size, State, StateIcon } from '../../globals/types'
import {
autoUpdate, flip,
offset,
shift,
useFloating,
} from '@floating-ui/vue'
import type { Placement } from '@floating-ui/vue'
import type { Block, Color, Description, Filter, NarrowedVariant, Rounded, Size, State, StateIcon } from '../../globals/types'
import type {
ListboxStateType,
ModelValue,
Expand Down Expand Up @@ -90,9 +97,9 @@ const props = defineProps({
type: Boolean as PropType<boolean>,
default: false,
},
menuPosition: {
type: String as PropType<Position>,
default: 'bottomLeft',
placement: {
type: String as PropType<Placement>,
default: 'bottom-end',
},
teleport: {
type: Boolean as PropType<boolean>,
Expand Down Expand Up @@ -134,6 +141,7 @@ const listboxState: ListboxStateType = reactive({
currentIndex: 0,
currentId: '',
})
const { classes: menuClasses } = useMenuStyles({ ...toRefs(props) })
const teleportId = useTeleportWrapper('multi-select')
nextTick(() => {
if (isOptionsValid()) {
Expand All @@ -153,7 +161,12 @@ provide(ContextKey, {
})
const { appendClasses, prependClasses } = useInputClasses(toRefs(props), attrs)
const { classes: menuClasses, styles: menuStyles } = useMenuStyles({ ...toRefs(props), triggerEl: wrapperRef, menuEl: optionsWrapperRef })
const { floatingStyles, middlewareData } = useFloating(wrapperRef, optionsWrapperRef, {
placement: props.placement,
middleware: [offset(6), flip(), shift()],
whileElementsMounted: autoUpdate,
})
useOutsideClick(wrapperRef, () => {
searchQuery.value = ''
Expand Down Expand Up @@ -625,6 +638,8 @@ function ArrowIcon() {
],
)
}
const isOptionsActive = computed(() => optionsActive.value && !middlewareData.value.hide?.referenceHidden)
</script>

<template>
Expand Down Expand Up @@ -686,11 +701,11 @@ function ArrowIcon() {
leave-to-class="transform scale-95 opacity-0"
>
<div
v-show="optionsActive"
v-show="isOptionsActive"
:id="optionsId"
ref="optionsWrapperRef"
:class="menuClasses"
:style="menuStyles"
:style="floatingStyles"
>
<ul
ref="optionsRef"
Expand Down
18 changes: 9 additions & 9 deletions src/components/Popover/LuiPopover.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ const meta: Meta<typeof LuiPopover> = {
title: 'LUI/Popover',
component: LuiPopover,
argTypes: {
dialogPosition: {
placement: {
control: 'select',
options: ['bottomLeft',
'bottomRight',
'topLeft',
'topRight',
'leftTop',
'leftBottom',
'rightTop',
'rightBottom'],
options: ['top-start',
'top-end',
'right-start',
'right-end',
'bottom-start',
'bottom-end',
'left-start',
'left-end'],
},
text: {
control: 'text',
Expand Down

0 comments on commit 2824970

Please sign in to comment.