From 433118a54be7762941c1eb09fec1a8e8e39dc556 Mon Sep 17 00:00:00 2001 From: Guillaume Chau Date: Tue, 1 Feb 2022 12:12:15 +0100 Subject: [PATCH] feat: positioningDisabled + mobile example --- .../components/DropdownMobileDemo.vue | 95 +++++++++++++ packages/docs/src/api/README.md | 4 + packages/docs/src/guide/component.md | 126 +++++++++++++++--- packages/docs/src/guide/css.md | 2 + .../floating-vue/src/components/Popper.ts | 43 ++++-- .../src/components/PopperContent.vue | 20 +-- 6 files changed, 251 insertions(+), 39 deletions(-) create mode 100644 packages/docs/src/.vuepress/components/DropdownMobileDemo.vue diff --git a/packages/docs/src/.vuepress/components/DropdownMobileDemo.vue b/packages/docs/src/.vuepress/components/DropdownMobileDemo.vue new file mode 100644 index 00000000..49392616 --- /dev/null +++ b/packages/docs/src/.vuepress/components/DropdownMobileDemo.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/packages/docs/src/api/README.md b/packages/docs/src/api/README.md index d42cac64..90e7bcda 100755 --- a/packages/docs/src/api/README.md +++ b/packages/docs/src/api/README.md @@ -329,6 +329,10 @@ Hide the popper if clicked outside. Boolean that disables the popper. If it was already open, it will be closed. +### `positioningDisabled` + +Boolean that disables the automatic positioning of the popper. You can then style it manually. Useful for mobile version of the popper. + ### `handleResize` Boolean: Automatically update the popper position if its size changes. diff --git a/packages/docs/src/guide/component.md b/packages/docs/src/guide/component.md index 97f6f0f6..6d52462f 100644 --- a/packages/docs/src/guide/component.md +++ b/packages/docs/src/guide/component.md @@ -209,22 +209,6 @@ To fix this, specify the `padding` option of the `arrow` modifier. In the follow -## Disable popper - -Disabling a popper will prevent it from being shown. - -```vue - -``` - -```js -data () { - return { - isDisabled: true, - } -} -``` - ## Hide from slot Use the `hide` slot prop to close the popper: @@ -281,3 +265,113 @@ Close all the poppers in the page with the `all` modifier: ```vue Close All ``` + +## Disable popper + +Disabling a popper will prevent it from being shown. + +```vue + +``` + +```js +data () { + return { + isDisabled: true, + } +} +``` + +## Mobile + +You can also just disable the positioning of the popper with `positioningDisabled`: + +```vue + +``` + +It can for example be useful on the mobile version of your app if you want to apply a fixed position to the popper with CSS. + + + +```vue + + + + + +``` diff --git a/packages/docs/src/guide/css.md b/packages/docs/src/guide/css.md index 45459e5e..d5d7a221 100644 --- a/packages/docs/src/guide/css.md +++ b/packages/docs/src/guide/css.md @@ -116,6 +116,7 @@ HTML result: 'v-popper__popper--hidden', 'v-popper__popper--skip-transition', 'v-popper__popper--arrow-overflow', + 'v-popper__popper--no-positioning', 'v-popper__popper--show-from', 'v-popper__popper--show-to', 'v-popper__popper--hide-from', @@ -149,6 +150,7 @@ The `popper` element has several dynamic classes: - `v-popper__popper--hidden`: the popper is hidden. - `v-popper__popper--skip-transition`: the transition should be skipped. - `v-popper__popper--arrow-overflow`: the arrow is overflowing past the reference, and should probably be hidden. +- `v-popper__popper--no-positioning`: positioning is disabled with `positioningDisabled` prop. Full example style: diff --git a/packages/floating-vue/src/components/Popper.ts b/packages/floating-vue/src/components/Popper.ts index e5d37f40..bae959e3 100644 --- a/packages/floating-vue/src/components/Popper.ts +++ b/packages/floating-vue/src/components/Popper.ts @@ -76,6 +76,11 @@ export default () => ({ default: defaultPropFactory('disabled'), }, + positioningDisabled: { + type: Boolean, + default: defaultPropFactory('positioningDisabled'), + }, + placement: { type: String, default: defaultPropFactory('placement'), @@ -269,7 +274,7 @@ export default () => ({ ...this.classes, popperClass: this.popperClass, }, - result: this.result, + result: this.positioningDisabled ? null : this.result, } }, }, @@ -292,12 +297,13 @@ export default () => ({ } }, - triggers () { - if (!this.$_isDisposed) { - this.$_removeEventListeners() - this.$_addEventListeners() - } - }, + ...[ + 'triggers', + 'positioningDisabled', + ].reduce((acc, prop) => { + acc[prop] = '$_refreshListeners' + return acc + }, {}), ...[ 'placement', @@ -411,7 +417,7 @@ export default () => ({ }, async $_computePosition () { - if (this.$_isDisposed) return + if (this.$_isDisposed || this.positioningDisabled) return const options: ComputePositionConfig = { strategy: this.strategy, @@ -764,12 +770,14 @@ export default () => ({ addEvents([this.$_popperNode], HIDE_EVENT_MAP, this.popperTriggers, this.popperHideTriggers, handleHide) // Scroll - addListeners([ - ...getScrollParents(this.$_referenceNode), - ...getScrollParents(this.$_popperNode), - ], 'scroll', () => { - this.$_computePosition() - }) + if (!this.positioningDisabled) { + addListeners([ + ...getScrollParents(this.$_referenceNode), + ...getScrollParents(this.$_popperNode), + ], 'scroll', () => { + this.$_computePosition() + }) + } }, $_removeEventListeners () { @@ -779,6 +787,13 @@ export default () => ({ this.$_events = [] }, + $_refreshListeners () { + if (!this.$_isDisposed) { + this.$_removeEventListeners() + this.$_addEventListeners() + } + }, + $_handleGlobalClose (event, touch = false) { if (this.$_showFrameLocked) return diff --git a/packages/floating-vue/src/components/PopperContent.vue b/packages/floating-vue/src/components/PopperContent.vue index e4d27288..ea962b4d 100644 --- a/packages/floating-vue/src/components/PopperContent.vue +++ b/packages/floating-vue/src/components/PopperContent.vue @@ -14,23 +14,24 @@ 'v-popper__popper--hide-from': classes.hideFrom, 'v-popper__popper--hide-to': classes.hideTo, 'v-popper__popper--skip-transition': skipTransition, - 'v-popper__popper--arrow-overflow': result.arrow.overflow, + 'v-popper__popper--arrow-overflow': result && result.arrow.overflow, + 'v-popper__popper--no-positioning': !result, }, ]" - :style="{ + :style="result ? { position: result.strategy, transform: `translate3d(${Math.round(result.x)}px,${Math.round(result.y)}px,0)`, - }" + } : undefined" :aria-hidden="shown ? 'false' : 'true'" :tabindex="autoHide ? 0 : undefined" - :data-popper-placement="result.placement" + :data-popper-placement="result ? result.placement : undefined" @keyup.esc="autoHide && $emit('hide')" >
@@ -142,7 +143,8 @@ export default { height: 10px; } -.v-popper__popper--arrow-overflow .v-popper__arrow-container { +.v-popper__popper--arrow-overflow .v-popper__arrow-container, +.v-popper__popper--no-positioning .v-popper__arrow-container { display: none; }