diff --git a/packages/vant/src/floating-panel/FloatingPanel.tsx b/packages/vant/src/floating-panel/FloatingPanel.tsx index 61f8b19b51a..2513ee81d02 100644 --- a/packages/vant/src/floating-panel/FloatingPanel.tsx +++ b/packages/vant/src/floating-panel/FloatingPanel.tsx @@ -29,6 +29,7 @@ export const floatingPanelProps = { anchors: makeArrayProp(), duration: makeNumericProp(0.3), magnetic: truthProp, + draggable: truthProp, contentDraggable: truthProp, lockScroll: Boolean, safeAreaInsetBottom: truthProp, @@ -97,6 +98,8 @@ export default defineComponent({ const touch = useTouch(); const onTouchstart = (e: TouchEvent) => { + if (!props.draggable) return; + touch.start(e); dragging.value = true; startY = -height.value; @@ -104,6 +107,8 @@ export default defineComponent({ }; const onTouchmove = (e: TouchEvent) => { + if (!props.draggable) return; + touch.move(e); const target = e.target as Element; @@ -130,8 +135,17 @@ export default defineComponent({ const onTouchend = () => { maxScroll = -1; + + if (!dragging.value) { + return; + } + dragging.value = false; + if (!props.draggable) { + return; + } + if (props.magnetic) { height.value = closest(anchors.value, height.value); } else { @@ -162,6 +176,10 @@ export default defineComponent({ return slots.header(); } + if (!props.draggable) { + return null; + } + return (
diff --git a/packages/vant/src/floating-panel/README.md b/packages/vant/src/floating-panel/README.md index a73cdef1e4c..54a939383e2 100644 --- a/packages/vant/src/floating-panel/README.md +++ b/packages/vant/src/floating-panel/README.md @@ -93,6 +93,18 @@ When `magnetic` is set to `false`, the panel will not automatically snap to anch ``` +### Disable Dragging + +You can disable the dragging functionality of the panel through the `draggable` attribute. When set to `false`, the panel will not be draggable, and the header drag bar will be hidden. + +```html + +
+

This panel cannot be dragged

+
+
+``` + ## API ### Props @@ -104,6 +116,7 @@ When `magnetic` is set to `false`, the panel will not automatically snap to anch | duration | Transition duration, unit second | _number \| string_ | `0.3` | | magnetic | Whether to enable magnetic adsorption to anchors. When disabled, panel can stop at any position within the anchor boundaries | _boolean_ | `true` | | content-draggable | Allow dragging content | _boolean_ | `true` | +| draggable | Whether to allow dragging the panel. When disabled, the header drag bar will be hidden | _boolean_ | `true` | | lock-scroll `v4.6.4` | When not dragging, Whether to lock background scroll | _boolean_ | `false` | | safe-area-inset-bottom | Whether to enable bottom safe area adaptation | _boolean_ | `true` | diff --git a/packages/vant/src/floating-panel/README.zh-CN.md b/packages/vant/src/floating-panel/README.zh-CN.md index 5dcc252b543..c8e1d177036 100644 --- a/packages/vant/src/floating-panel/README.zh-CN.md +++ b/packages/vant/src/floating-panel/README.zh-CN.md @@ -93,6 +93,18 @@ export default { ``` +### 禁用拖拽 + +你可以通过 `draggable` 属性来禁用面板的拖拽功能。当设置为 `false` 时,面板将不可拖拽,同时头部拖拽栏也会被隐藏。 + +```html + +
+

该面板不可拖拽

+
+
+``` + ## API ### Props @@ -104,6 +116,7 @@ export default { | duration | 动画时长,单位秒,设置为 0 可以禁用动画 | _number \| string_ | `0.3` | | magnetic | 是否启用磁力吸附到锚点。禁用后面板可在锚点边界范围内任意位置停留 | _boolean_ | `true` | | content-draggable | 允许拖拽内容容器 | _boolean_ | `true` | +| draggable | 是否允许拖拽面板。禁用后头部拖拽栏会被隐藏 | _boolean_ | `true` | | lock-scroll `v4.6.4` | 当不拖拽时,是否锁定背景滚动 | _boolean_ | `false` | | safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/advanced-usage#di-bu-an-quan-qu-gua-pei) | _boolean_ | `true` | diff --git a/packages/vant/src/floating-panel/demo/index.vue b/packages/vant/src/floating-panel/demo/index.vue index 953ab1089b6..06452b75f36 100644 --- a/packages/vant/src/floating-panel/demo/index.vue +++ b/packages/vant/src/floating-panel/demo/index.vue @@ -15,6 +15,8 @@ const t = useTranslate({ customAnchors: '自定义锚点', headDragOnly: '仅头部拖拽', disableMagnetic: '禁用吸附', + disableDragging: '禁用拖拽', + panelUnDrag: '该面板不可拖拽', panelShowHeight: '面板显示高度', contentUnDrag: '内容不可拖拽', magneticDisabled: '已禁用磁力吸附,可在边界内任意停留', @@ -23,6 +25,8 @@ const t = useTranslate({ customAnchors: 'Custom Anchors', headDragOnly: 'Head Drag Only', disableMagnetic: 'Disable Magnetic', + disableDragging: 'Disable Dragging', + panelUnDrag: 'This panel cannot be dragged', panelShowHeight: 'Panel Show Height', contentUnDrag: 'Content cannot be dragged', magneticDisabled: 'Magnetic disabled, free positioning within boundaries', @@ -76,5 +80,13 @@ const height = ref(anchors[0]);
+ + + +
+

{{ t('panelUnDrag') }}

+
+
+
diff --git a/packages/vant/src/floating-panel/test/__snapshots__/demo-ssr.spec.ts.snap b/packages/vant/src/floating-panel/test/__snapshots__/demo-ssr.spec.ts.snap index 9dc5832c13c..fd87f8389f1 100644 --- a/packages/vant/src/floating-panel/test/__snapshots__/demo-ssr.spec.ts.snap +++ b/packages/vant/src/floating-panel/test/__snapshots__/demo-ssr.spec.ts.snap @@ -56,6 +56,16 @@ exports[`should render demo and match snapshot 1`] = ` style="display:none;" >
+ `; diff --git a/packages/vant/src/floating-panel/test/__snapshots__/demo.spec.ts.snap b/packages/vant/src/floating-panel/test/__snapshots__/demo.spec.ts.snap index 75c024eee44..94a5c69fa8d 100644 --- a/packages/vant/src/floating-panel/test/__snapshots__/demo.spec.ts.snap +++ b/packages/vant/src/floating-panel/test/__snapshots__/demo.spec.ts.snap @@ -60,6 +60,19 @@ exports[`should render demo and match snapshot 1`] = ` Disable Magnetic +
+ `; diff --git a/packages/vant/src/floating-panel/test/index.spec.tsx b/packages/vant/src/floating-panel/test/index.spec.tsx index b7577abc603..4357d562054 100644 --- a/packages/vant/src/floating-panel/test/index.spec.tsx +++ b/packages/vant/src/floating-panel/test/index.spec.tsx @@ -189,3 +189,38 @@ test('should add padding bottom to content when panel is not fully expanded', as await wrapper.setProps({ height: 400 }); expect(content.style.paddingBottom).toBe('0px'); }); + +test('should not allow dragging when draggable is false', async () => { + const wrapper = mount({ + render() { + return ( + this.$emit('change', h)} + > + Content + + ); + }, + }); + + expect(wrapper.find('.van-floating-panel__header').exists()).toBe(false); + + await triggerDrag(wrapper.find('.van-floating-panel__content'), 0, -199); + await later(); + expect(wrapper.emitted('change')).toBeFalsy(); +}); + +test('should render header slot even when draggable is false', () => { + const wrapper = mount(FloatingPanel, { + props: { + draggable: false, + }, + slots: { + header: () => 'Custom Header', + }, + }); + + expect(wrapper.html()).toContain('Custom Header'); +});