Popover menu

Updated at:

Displays a bubble-style menu triggered exclusively by a navigation bar icon. Use this component for infrequently accessed features.

Properties

Popover

Property

Type

Required

Default

Description

visible

boolean

No

false

Whether the popover is visible.

mode

'dark' | 'light'

No

'dark'

Display theme.

placement

'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'left-top' | 'left-bottom' | 'right' | 'right-top' | 'right-bottom'

No

'bottom-right'

Position relative to the trigger element.

className

string

No

-

Custom CSS class name.

mask

boolean

No

false

Whether to show a mask layer.

maskClosable

boolean

No

true

Whether tapping the mask closes the popover.

fixMaskFull

boolean

No

false

Fixes incomplete mask display caused by the CSS transform property.

PopoverItem

Property

Type

Required

Default

Description

icon

string

No

-

Icon type.

className

string

No

-

Custom CSS class name.

Events

Popover

Event name

Description

Type

onVisibleChange

Fires when the popover visibility changes.

( visible: boolean, mode: 'component' | 'mask' ) => void

PopoverItem

Event name

Description

Type

onTap

Fires when the item is tapped.

() => void

Slots

Popover

Name

Description

items

Popover content slot. Use PopoverItem to render a menu list.

PopoverItem

Name

Description

icon

Icon slot.

Style classes

Popover

Class name

Description

amd-popover

Overall style.

amd-popover-container

Main content container.

amd-popover-content

Content area.

amd-popover-arrow

Arrow indicator.

amd-popover-inner

Inner content area.

amd-popover-inner-pseudo

Overall style for the popover content.

Class name

Description

amd-popover-item

Overall style.

amd-popover-item-icon

Icon container.

amd-popover-item-icon-item

Icon element.

amd-popover-item-text

Text label.

Code examples

Basic usage

`index.axml`:

<view>
  <demo-block title="Basic Usage">
    <view class="wrap dark">
      <popover 
        placement="bottom"
        visible="{{showDark}}"
        onVisibleChange="handleDarkVisibleChange">
        <button inlineSize="large" inline>Tap Me</button>
        <view slot="items" class="tooltip">Hello World</view>
      </popover>
    </view>
  </demo-block>
  <demo-block title="Light Popover">
    <view class="wrap">
      <popover 
        placement="right"
        mode="light"
        visible="{{showLight}}"
        onVisibleChange="handleLightVisibleChange">
        <button inlineSize="large" inline>Tap Me</button>
        <view slot="items" class="tooltip">Hello World</view>
      </popover>
    </view>
  </demo-block>
  <demo-block title="Popover Position" className="multi-demo">
    <view class="multi-wrap">
      <popover 
        placement="{{placement}}"
        visible="{{show}}"
        mask="{{showMask}}"
        onVisibleChange="handleVisibleChange">
        <view class="multi">
          <view>Tap to {{show ? 'Hide' : 'Show'}}</view>
          <view>
            {{placement}}
          </view>
        </view>
        <view slot="items" class="tooltip">
          <view>Popover</view> 
          <view>
            Content
          </view>
        </view>
      </popover>
    </view>
    <view class="demo-btn-container">
      <button 
        class="demo-btn"
        onTap="handleNextPosition">
        Next Position
      </button>
      <button 
        class="demo-btn"
        onTap="handleToggleMask">
        {{showMask?'Hide':'Show'}} Mask
      </button>
    </view>
  </demo-block>
</view>

`index.js`:

const placement = [
  'top',
  'top-right',
  'top-left',
  'bottom',
  'bottom-left',
  'bottom-right',
  'left',
  'left-top',
  'left-bottom',
  'right',
  'right-top',
  'right-bottom',
];
Page({
  data: {
    placement: placement[0],
    show: true,
    showMask: false,
    showLight: true,
    showDark: true,
  },
  handleLightVisibleChange(e) {
    this.setData({
      showLight: e,
    });
  },
  handleDarkVisibleChange(e) {
    this.setData({
      showDark: e,
    });
  },
  handleNextPosition() {
    let index = placement.indexOf(this.data.placement);
    index = index >= placement.length - 1 ? 0 : index + 1;
    this.setData({
      show: true,
      placement: placement[index],
    });
  },
  handleVisibleChange(visible, mode) {
    this.setData({
      show: visible,
    });
    if (mode === 'mask') {
      my.showToast({ content: 'Popover closed by tapping the mask', duration: 2000 });
    }
  },
  handleToggleMask() {
    this.setData({
      showMask: !this.data.showMask,
    });
  },
});

`index.acss`:

.wrap {
  display: flex;
}
.wrap.dark {
  padding-bottom: 100rpx;
}
.wrap.dark .tooltip {
  color: #fff;
}
.wrap .tooltip {
  white-space: nowrap;
  font-size: 24rpx;
  padding: 16rpx;
}
.multi-demo .demo-block-content {
  background: transparent;
}

.multi-wrap {
  height: 600rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}
.multi-wrap .multi {
  background: #aaa;
  border-radius: 12rpx;
  height: 200rpx;
  width: 200rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.multi-wrap .tooltip {
  color: #fff;
  font-size: 24rpx;
  padding: 16rpx;
}
.demo-btn-container {
  display: flex;
  justify-content: space-around;
}

.demo-btn {
  width: 45%;
}

`index.json`:

{
  "defaultTitle": "PopoverBase",
  "usingComponents": {
    "popover": "antd-mini/es/Popover/index",
    "demo-block": "../../components/DemoBlock/index",
    "button": "antd-mini/es/Button/index"
  }
}

PopoverItem usage

`index.axml`:

<view>
  <demo-block title="Dark Popover Menu">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showDark}}"
        mask
        onVisibleChange="handleDarkVisibleChange">
        <button inline inlineSize="large">Tap Me</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            icon="ScanningOutline"
            data-type="showDark"
            data-name="Scan">
            Scan
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="ReceivePaymentOutline"
            data-type="showDark"
            data-name="Pay/Receive">
            Pay/Receive
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="TransportQRcodeOutline"
            data-type="showDark"
            data-name="Transport Code">
            Transport Code
          </popover-item>
          <popover-item 
            onTap="handleTapItem"
            data-type="showDark"
            data-name="icon slot">
            <image
              slot="icon"
              mode="scaleToFill"
              src="{{url}}"
              style="width: 100%;height: 100%;"/>
            icon slot
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  <demo-block title="Light Popover Menu">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showLight}}"
        mode="light"
        mask
        onVisibleChange="handleLightVisibleChange">
        <button inline inlineSize="large">Tap Me</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            icon="ScanningOutline"
            data-type="showLight"
            data-name="Scan">
            Scan
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            icon="ReceivePaymentOutline"
            data-type="showLight"
            data-name="Pay/Receive">
            Pay/Receive
          </popover-item>

            <popover-item 
              onTap="handleTapItem"
              icon="TransportQRcodeOutline"
              data-type="showLight"
              data-name="Transport Code">
              Transport Code
          </popover-item>
          <popover-item 
            onTap="handleTapItem"
            data-type="showLight"
            data-name="icon slot">
            <image
              slot="icon"
              mode="scaleToFill"
              src="{{url}}"
              style="width: 100%;height: 100%;"/>
            icon slot
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  <demo-block title="Popover Menu Without Icons">
    <view class="wrap">
      <popover 
        placement="bottom-left"
        visible="{{showNoIcon}}"
        mask
        onVisibleChange="handleNoIconVisibleChange">
        <button inline inlineSize="large">Tap Me</button>
        <block slot="items">
          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="Scan">
            Scan
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="Pay/Receive">
            Pay/Receive
          </popover-item>

          <popover-item 
            onTap="handleTapItem"
            data-type="showNoIcon"
            data-name="Transport Code">
            Transport Code
          </popover-item>
        </block>
      </popover>
    </view>
  </demo-block>
  
</view>

`index.js`:

Page({
  data: {
    showLight: false,
    showDark: false,
    showNoIcon: false,
    url: 'https://gw.alipayobjects.com/mdn/rms_ce4c6f/afts/img/A*XMCgSYx3f50AAAAAAAAAAABkARQnAQ',
  },
  handleLightVisibleChange(e, mode) {
    this.setData({
      showLight: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: 'Popover closed by tapping the mask', duration: 2000 });
    }
  },
  handleDarkVisibleChange(e, mode) {
    this.setData({
      showDark: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: 'Popover closed by tapping the mask', duration: 2000 });
    }
  },
  handleNoIconVisibleChange(e, mode) {
    this.setData({
      showNoIcon: e,
    });
    if (mode === 'mask') {
      my.showToast({ content: 'Popover closed by tapping the mask', duration: 2000 });
    }
  },
  handleTapItem(e) {
    this.setData({
      [e.target.dataset.type]: false,
    });
    my.showToast({ content: `Tapped ${e.target.dataset.name}` });
  },
});

`index.acss`:

.wrap {
  display: flex;
}

`index.json`:

{
  "defaultTitle": "Popover: Use with PopoverItem Component",
  "usingComponents": {
    "popover": "antd-mini/es/Popover/index",
    "popover-item": "antd-mini/es/Popover/PopoverItem/index",
    "demo-block": "../../components/DemoBlock/index",
    "button": "antd-mini/es/Button/index"
  }
}