Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/config/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ module.exports = [
{
title: 'ActionSheet 操作列表',
path: '/components/base/action-sheet'
},
{
title: 'FloatingPanel 悬浮面板',
path: '/components/base/floating-panel'
}
]
},
Expand Down
1 change: 1 addition & 0 deletions example/app.mpx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"./pages/loading/index",
"./pages/input/index",
"./pages/action-sheet/index",
"./pages/floating-panel/index"
"./pages/tab-bar/index"
]
}
Expand Down
3 changes: 2 additions & 1 deletion example/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export default {
'dialog',
'modal',
'tip',
'action-sheet'
'action-sheet',
'floating-panel'
]
},
{
Expand Down
41 changes: 41 additions & 0 deletions example/pages/floating-panel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Cube-FloatingPanel

<card>

### 介绍

浮层组件,浮动在页面底部的面板,可以上下拖动来浏览内容,常用于提供额外的功能或信息。支持使用`wx:model`对数据双向绑定。

</card>

## 示例

<card>

### 基础用法

FloatingPanel 的默认高度为 `100px`,用户可以拖动来展开面板,使高度达到 `60%` 的屏幕高度。
<!-- @example: floating-panel-default -->

</card>

<card>

### 自定义锚点

你可以通过 `anchors` 属性来设置 FloatingPanel 的锚点位置,并通过 `wx:model` 来控制当前面板的显示高度。

比如,使面板的高度在 `100px`、`40%` 屏幕高度和 `70%` 屏幕高度三个位置停靠:
<!-- @example: floating-panel-anchors -->

</card>

<card>

### 仅头部拖拽

默认情况下,FloatingPanel 的头部区域和内容区域都可以被拖拽,你可以通过 `contentDraggable` 属性来禁用内容区域的拖拽。

<!-- @example: floating-panel-contentDraggable -->

</card>
34 changes: 34 additions & 0 deletions example/pages/floating-panel/floating-panel-anchors.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<cube-floating-panel
wx:model="{{ height }}"
wx:model-prop="height"
anchors="{{ anchors }}"
>
<view>
<view>height: {{ height }} px</view>
</view>
</cube-floating-panel>
</template>

<script>
import { createPage } from '@mpxjs/core'

createPage({
data: {
height: 100,
anchors: [
100,
Math.round(0.4 * window.innerHeight),
Math.round(0.7 * window.innerHeight),
]
}
})
</script>

<script type="application/json">
{
"usingComponents": {
"cube-input": "@mpxjs/mpx-cube-ui/src/components/input/index"
}
}
</script>
37 changes: 37 additions & 0 deletions example/pages/floating-panel/floating-panel-contentDraggable.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<base-container>
<cube-floating-panel
wx:model="{{ height }}"
wx:model-prop="height"
contentDraggable="{{ contentDraggable }}"
>
<view>
内容不可拖拽
</view>
</cube-floating-panel>
</base-container>
</template>

<script>
import { createPage } from '@mpxjs/core'

createPage({
data: {
height: 100,
contentDraggable: false,
}
})
</script>

<style lang="stylus">

</style>

<script type="application/json">
{
"usingComponents": {
"base-container": "../../components/base-container/index",
"cube-floating-panel": "@mpxjs/mpx-cube-ui/src/components/floating-panel/index"
}
}
</script>
31 changes: 31 additions & 0 deletions example/pages/floating-panel/floating-panel-default.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<cube-floating-panel
wx:model="{{ height }}"
wx:model-prop="height"
>
<view>
<view wx:for="{{letters}}" wx:key="item">{{item}}</view>
</view>
</cube-floating-panel>
</template>

<script>
import { createPage } from '@mpxjs/core'

createPage({
data: {
letters: [
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
]
}
})
</script>

<script type="application/json">
{
"usingComponents": {
"cube-input": "@mpxjs/mpx-cube-ui/src/components/input/index"
}
}
</script>
47 changes: 47 additions & 0 deletions example/pages/floating-panel/index.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<base-container>
<view class="background">我是背景</view>
<cube-floating-panel
wx:model="{{ height }}"
wx:model-prop="height"
contentDraggable="{{ contentDraggable }}"
magnetic="{{ magnetic }}"
>
<view class="content">
<view>height: {{ height }} px</view>
</view>
</cube-floating-panel>
</base-container>
</template>

<script>
import { createPage } from '@mpxjs/core'

createPage({
data: {
height: 100,
contentDraggable: true,
magnetic: true,
letters: [
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
]
}
})
</script>

<style lang="stylus">
.background
height: 100vh
.content
padding: 20px
</style>

<script type="application/json">
{
"usingComponents": {
"base-container": "../../components/base-container/index",
"cube-floating-panel": "@mpxjs/mpx-cube-ui/src/components/floating-panel/index"
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`component floating-panel unit test props check default matchSnapshot 1`] = `"<wx-view class=\\"main--cube-floating-panel main--cube-floating-panel-safe-area-bottom\\" style=\\"height:500px;transform:translateY(calc(100% + -100px));transition:transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);\\"><wx-view class=\\"main--cube-floating-panel-extender\\"></wx-view><wx-view class=\\"main--cube-floating-panel-header\\"><wx-view class=\\"main--cube-floating-panel-header-bar\\"></wx-view></wx-view><wx-scroll-view class=\\"main--cube-floating-panel-content\\"></wx-scroll-view></wx-view>"`;

exports[`component floating-panel unit test slot render check matchSnapshot 1`] = `"<main><wx-view class=\\"main--cube-floating-panel main--cube-floating-panel-safe-area-bottom\\" style=\\"height:500px;transform:translateY(calc(100% + -100px));transition:transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);\\"><wx-view class=\\"main--cube-floating-panel-extender\\"></wx-view><wx-view class=\\"main--cube-floating-panel-header\\"><wx-view class=\\"main--cube-floating-panel-header-bar\\"></wx-view></wx-view><wx-scroll-view class=\\"main--cube-floating-panel-content\\"></wx-scroll-view></wx-view></main>"`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
const simulate = require('@mpxjs/miniprogram-simulate')

describe('component floating-panel unit test', () => {
const componentId = simulate.loadMpx('src/components/floating-panel/index.mpx')

function newComponent(props) {
const component = simulate.render(componentId, props)
component.attach(document.createElement('parent'))
return component
}

async function _snapTest(component) {
expect(component.dom.innerHTML).toMatchSnapshot()
}

const baseProps = {
height: 100,
anchors: [100, 500],
duration: 0.3
}

describe('props check default', () => {
const component = newComponent(baseProps)

it('matchSnapshot', () => {
_snapTest(component)
})

it('should render correct initial style', () => {
const root = component.querySelector('.cube-floating-panel')
// height: anchors[max] -> 500px
expect(root.dom.style.height).toBe('500px')
// transform: translateY(calc(100% + -100px)) because initial height is 100
expect(root.dom.style.transform).toBe('translateY(calc(100% + -100px))')
})
})

describe('slot render check', () => {
const component = simulate.render(simulate.load({
usingComponents: {
'cube-floating-panel': componentId
},
template: `
<cube-floating-panel height="{{100}}" anchors="{{[100, 500]}}">
<view class="slot-node" slot="default">test</view>
</cube-floating-panel>`
}))
const parent = document.createElement('parent')
component.attach(parent)
it('matchSnapshot', () => {
_snapTest(component)
})

it('should render correct slot content', () => {
const content = component.querySelector('.slot-node').dom.innerHTML
expect(content).toBe('test')
})
})

describe('props check safeAreaInsetBottom', () => {
const props = Object.assign({}, baseProps, {
safeAreaInsetBottom: false
})
const component = newComponent(props)
it('should not have safe-area class', () => {
const root = component.querySelector('.cube-floating-panel')
expect(root.dom.classList.contains('cube-floating-panel-safe-area-bottom')).toBe(false)
})
})

describe('props check contentDraggable', () => {
it('should drag when contentDraggable is true (default)', async () => {
// This is covered by default props, but we can test on content element
const component = newComponent(baseProps)
const content = component.querySelector('.cube-floating-panel-content')
const start = { touches: [{ pageY: 500 }] }
const move = { touches: [{ pageY: 450 }] }
const inputHandler = jest.fn()
component.addEventListener('input', inputHandler)

content.dispatchEvent('touchstart', start)
content.dispatchEvent('touchmove', move)
await simulate.sleep(10)

expect(inputHandler).toHaveBeenCalled()
})

it('should not drag when contentDraggable is false', async () => {
const props = Object.assign({}, baseProps, {
contentDraggable: false
})
const component = newComponent(props)
const content = component.querySelector('.cube-floating-panel-content')
const start = { touches: [{ pageY: 500 }] }
const move = { touches: [{ pageY: 450 }] }
const inputHandler = jest.fn()
component.addEventListener('input', inputHandler)

content.dispatchEvent('touchstart', start)
content.dispatchEvent('touchmove', move)
await simulate.sleep(10)

expect(inputHandler).not.toHaveBeenCalled()
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @type floating-panel
$floating-panel-z-index := 999 // 浮层z-index
$floating-panel-top-left-radius := 16px // 浮层左上角圆角
$floating-panel-top-right-radius := 16px // 浮层右上角圆角
$floating-panel-bottom-right-radius := 0 // 浮层右下角圆角
$floating-panel-bottom-left-radius := 0 // 浮层左下角圆角
$floating-panel-radius := $floating-panel-top-left-radius $floating-panel-top-right-radius $floating-panel-bottom-right-radius $floating-panel-bottom-left-radius // 边框圆角
$floating-panel-bgc := $var(color-white) // 浮层背景颜色
$floating-panel-header-height := 30px // 浮层标题高度
$floating-panel-bar-width := 20px // 浮层拖动条宽度
$floating-panel-bar-height := 3px // 浮层拖动条高度
$floating-panel-bar-color := #c8c9cc // 浮层拖动条颜色
$floating-panel-border-color := #c8c9cc // 浮层边框颜色


// @type floating-panel-bottom
$floating-panel-padding-top := 0 // 浮层区域顶部内边距
$floating-panel-padding-right := 0 // 浮层内容区域右侧内边距
$floating-panel-padding-bottom := 20px // 浮层内容区域底部内边距
$floating-panel-padding-left := 0 // 浮层内容区域左侧内边距
$floating-panel-padding := $floating-panel-padding-top $floating-panel-padding-right $floating-panel-padding-bottom $floating-panel-padding-left // 浮层内容区域内边距
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@require "../../common/stylus/variable.styl"
@require "../../common/stylus/mixin.styl"
Loading