FloatPanel

更新时间:
复制 MD 格式

A sliding panel that users can drag up or down to browse content.

  • The initial panel height is 18% of the window height. Sliding up expands it to 35%, and sliding up again expands it to a maximum of 95%.

  • Sliding down from the maximum height returns the panel to 35%. Sliding down again returns it to 18%.

  • The content area becomes scrollable when the panel reaches its maximum height.

  • Requires base library version 2.7.7 or later.

Properties

Property

Type

Required

Default

Description

minHeight

number

No

0.18

Minimum panel height, as a percentage of the page height.

middleHeight

number

No

0.35

Intermediate panel height, as a percentage of the page height.

maxHeight

number

No

0.9

Maximum panel height, as a percentage of the page height.

lowerThreshold

number

No

50

Distance from the bottom of the content area that triggers the onContentToBottom callback.

withMask

boolean

No

true

Whether to display a mask layer. The mask is transparent by default.

className

string

No

-

Custom class name for the component root node.

Events

Event name

Description

Type

onContentToBottom

Triggered when the content area scrolls to the bottom. Typically used for loading more data.

() => void

Slots

Name

Description

header

Header content.

content

Scrollable content.

footer

Footer content.

Style classes

Class name

Description

amd-swiper-box

Root node of the component.

amd-swiper-arrow-wrapper

Indicator area.

amd-swiper-header

Header area.

amd-swiper-scroll-view

Scroll view in the content area.

amd-swiper-footer

Footer area.

amd-swiper-background

Mask layer.

Code examples

Basic usage

Sample code for index.axml:

<view class="map">

</view>
<view class="buttonWrapper">
 <switch class="button" onChange="handleToggleMask" inlineSize="small" inline />
 <text>Mask</text>
</view>

<float-panel
className="wrapper"
maxHeight="{{0.9}}"
withMask="{{withMask}}"
>
 <view slot="header" class="title">
  <text>
   Header Title
  </text>
 </view> 
 <view class="content" slot="content">
  <list radius="{{false}}">
   <list-item class="noLine" a:for="{{isvList1}}">{{index}}</list-item>
  </list>
 </view>
 <view slot="footer" class="footer">
  Footer content
 </view>
</float-panel>

Sample code for index.js:

Page({
    data: {
        isvList1: new Array(20).fill(0),
        withMask: false,
        button1Text: 'Disable Mask',
    },
    handleToggleMask () {
        this.setData({
            button1Text: !this.data.withMask ? 'Disable Mask' : 'Enable Mask',
            withMask: !this.data.withMask
        })
    }
})

Sample code for index.acss:

.title {
    background: #FFF;
    border-radius: 16rpx 16rpx 0 0;
    font-family: PingFangSC-Medium;
    font-size: 36rpx;
    color: #333;
    text-align: center;
    border-bottom: 1rpx solid #EEE;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 98rpx;
    box-sizing: border-box;
}

.content {
    background: #FFF;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 24rpx;
}

.item {
    width: 100%;
    height: 160rpx;
    border-bottom: 1px solid grey;
    display: flex;
}
.item .left {
    width: 200rpx;
    display: flex;
    align-items: center;
}

.item .right {
  flex: 1;
  text-align: right;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.footer {
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
    border-radius: 0;
    height: 128rpx;
    background: #FFF;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
}

.wrapper {
}

.wrapper .amd-swiper-section {
  background-color: #fff;
}

.buttonWrapper {
    display: flex;
    position: fixed;
    align-items: center;
    justify-content: center;
    top: 0;
    z-index: 9999;
}

.button {
    margin: 20rpx;
}

.map {
    width: 100vw;
    height: 100vh;
    background-image: url("https://gw.alipayobjects.com/mdn/rms_186a6d/afts/img/A*Z1x_QYGRR1kAAAAAAAAAAAAAARQnAQ");
}

Sample code for index.json:

{
    "usingComponents":{
        "float-panel": "antd-mini/es/FloatPanel/index",
        "list": "antd-mini/es/List/index",
        "list-item": "antd-mini/es/List/ListItem/index",
        "switch": "antd-mini/es/Switch/index"
    },
    "allowsBounceVertical": "NO"
}

Event listeners

Sample code for index.axml:

<view class="map" />

<float-panel
    className="wrapper"
    maxHeight="{{0.9}}"
    onScroll="handleScrolllStatus"
    onContentToBottom="handleContentScrollToLower"
    ref="saveRef"
>
    <view slot="header" class="title">
        <text>
            Header area. The current panel height detected by the onScroll event callback is <text style="color: red">{{pos1}}</text>
        </text>
    </view> 
    <view class="content" slot="content">
        <list radius="{{false}}">
            <list-item class="noLine" a:for="{{isvList2}}">{{index}}</list-item>
        </list>
        <loading text="Loading" color="#1677ff" a:if="{{showLoading}}" />
    </view>
    <view slot="footer" class="footer">
        Footer content
    </view>
</float-panel>

Sample code for index.js:

Page({
    data: {
        isvList2: new Array(10).fill(0),
        pos1: 'Minimum height',
        showLoading: true
    },
    handleContentScrollToLower () {
        setTimeout(() => {
            this.setData({
                isvList2: new Array(20).fill(0),
                showLoading: false
            })
        }, 2000)
    },
    handleScrolllStatus (pos) {
        this.setData({ pos1: pos === 'MAX' ? 'Maximum height' : pos === 'MIDDLE' ? 'Intermediate height' : 'Minimum height' })
    },
    saveRef (ref) {
        this.panel = ref
    },
})

Sample code for index.acss:

.title {
    background: #FFF;
    border-radius: 16rpx 16rpx 0 0;
    font-family: PingFangSC-Medium;
    font-size: 36rpx;
    color: #333;
    text-align: center;
    border-bottom: 1rpx solid #EEE;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 98rpx;
    box-sizing: border-box;
}

.content {
    background: #FFF;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 24rpx;
}

.item {
    width: 100%;
    height: 160rpx;
    border-bottom: 1px solid grey;
    display: flex;
}
.item .left {
    width: 200rpx;
    display: flex;
    align-items: center;
}

.item .right {
  flex: 1;
  text-align: right;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.footer {
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
    border-radius: 0;
    height: 128rpx;
    background: #FFF;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
}

.wrapper {
}

.wrapper .amd-swiper-section {
  background-color: #fff;
}

.buttonWrapper {
    display: flex;
    position: fixed;
    align-items: center;
    justify-content: center;
    top: 0;
    z-index: 9999;
}

.button {
    margin: 20rpx;
}

.map {
    width: 100vw;
    height: 100vh;
    background-image: url("https://gw.alipayobjects.com/mdn/rms_186a6d/afts/img/A*Z1x_QYGRR1kAAAAAAAAAAAAAARQnAQ");
}

Sample code for index.json:

{
    "usingComponents":{
        "float-panel": "antd-mini/es/FloatPanel/index",
        "loading": "antd-mini/es/Loading/index",
        "list": "antd-mini/es/List/index",
        "list-item": "antd-mini/es/List/ListItem/index"
    },
    "allowsBounceVertical": "NO"
}