Skip to content

Commit

Permalink
feat: 新增rate组件
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Dec 3, 2024
1 parent bc04f39 commit 5542d86
Show file tree
Hide file tree
Showing 15 changed files with 406 additions and 4 deletions.
3 changes: 2 additions & 1 deletion example/app.mpx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
"./pages/checkbox-group/index",
"./pages/checkbox-modal/index",
"./pages/textarea/index",
"./pages/float-ball/index"
"./pages/float-ball/index",
"./pages/rate/index"
]
}
</script>
Expand Down
29 changes: 29 additions & 0 deletions example/pages/rate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Cube-Segment-Picker

<card>

### 介绍

段选择器,用于实现多段的选择,比如选择时间段:2010年9月1日 - 2014年6月30日。

</card>

## 示例

<card>

### 城市选择器

可以配置多段城市选择。

<!-- @example: segment-city-picker -->

</card>

<card>

### 日期选择器

<!-- @example: segment-date-picker -->

</card>
130 changes: 130 additions & 0 deletions example/pages/rate/index.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<template>
<view class="rate-page">
<base-container>
<view class="content">
<view class="rate-wrapper">
<rate wx:model="{{value}}" wx:model-prop="value" disabled="{{disabled}}" max="{{_max}}" justify="{{justify}}" allowHalf="{{allowHalf}}">
<rate-item wx:for="{{_max}}" wx:key="item" index="{{item}}" value="{{value}}">
<view class="rate-item" wx:if="{{customStar}}"></view>
</rate-item>
</rate>
</view>
<view class="options">
<view class="title">Options</view>
<view class="option-list">
<view class="option-list">
<view class="group">
<view class="group-item">
<view class="item">Disabled</view>
<switch
color="{{ switchColor }}"
checked="{{ disabled }}"
bindchange="updateDisabled"
/>
</view>
<view class="group-item">
<view class="item sub">Star Numbers</view>
<input
class="input-maxlength"
type="number"
value="{{ max }}"
bind:input="updateMaxLength"
/>
</view>
<view class="group-item">
<view class="item">Justify</view>
<switch
color="{{ switchColor }}"
checked="{{ justify }}"
bindchange="updateJustify"
/>
</view>
<view class="group-item">
<view class="item">CustomStar</view>
<switch
color="{{ switchColor }}"
checked="{{ customStar }}"
bindchange="updateCustomStar"
/>
</view>
<view class="group-item">
<view class="item">AllowHalf</view>
<switch
color="{{ switchColor }}"
checked="{{ allowHalf }}"
bindchange="updateAllowHalf"
/>
</view>
</view>
</view>
</view>
</view>
</view>
</base-container>
</view>
</template>

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

createPage({
data: {
value: 4,
max: '5',
customStar: false,
justify: false,
allowHalf: true,
disabled: false,
switchColor: '#fc9153'
},
computed: {
_max() {
return Number(this.max)
}
},
methods: {
updateDisabled (e) {
const { value } = e.detail
this.disabled = value
},
updateMaxLength (e) {
const { value } = e.detail
this.max = value
},
updateJustify (e) {
const { value } = e.detail
this.justify = value
},
updateCustomStar (e) {
const { value } = e.detail
this.customStar = value
},
updateAllowHalf (e) {
const { value } = e.detail
this.allowHalf = value
},
}
})
</script>

<style lang="stylus">
.rate-page
margin-top: 10px
height 100%
background-color rgba(239, 239, 244, .7)
.options
margin-top: 20px

.desc
margin-top 15px
</style>

<script type="application/json">
{
"usingComponents": {
"base-container": "../../components/base-container/index.mpx",
"rate": "@mpxjs/mpx-cube-ui/src/components/rate/index.mpx",
"rate-item": "@mpxjs/mpx-cube-ui/src/components/rate/rate-item.mpx"
}
}
</script>
8 changes: 6 additions & 2 deletions packages/mpx-cube-ui/src/common/stylus/mixin.styl
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,14 @@ hide-scrollbar()
width 0
height 0

// bg-image($url, $ext = ".png")
// background-image url($url + "@2x" + $ext)
// @media (min-resolution: 3dppx)
// background-image url($url + "@3x" + $ext)
bg-image($url, $ext = ".png")
background-image url($url + "@2x" + $ext)
add-property('background-image', s('url(%s)', $url + '@2x' + $ext))
@media (min-resolution: 3dppx)
background-image url($url + "@3x" + $ext)
add-property('background-image', s('url(%s)', $url + '@3x' + $ext))

functions = constant env
safe-area-fn(fn, position)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions packages/mpx-cube-ui/src/components/rate/index.mpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<view ref="rateContainer"
class="cube-rate"
wx:class="{{rateClass}}"
bindtouchstart.stop="handleStart"
bindtouchmove.stop.prevent="handleMove"
bindtouchend.stop="handleEnd"
bindmousedown.stop="handleStart"
bindmousemove.stop="handleMove"
bindmouseup.stop="handleEnd">
<slot>
<rate-item wx:for="{{max}}" wx:key="index" index="{{index}}" value="{{value}}"></rate-item>
</slot>
</view>
</template>

<script src="./index.ts" lang="ts"></script>

<style lang="stylus">
@require "@mpxjs/mpx-cube-ui/src/common/stylus/variable.styl"
@require "@mpxjs/mpx-cube-ui/src/common/stylus/mixin.styl"
.cube-rate
list-style: none
display: inline-flex
vertical-align: top
flex-wrap: nowrap
max-width: 100%
.cube-rate-justify
width: 100%
justify-content: space-between
</style>

<script type="application/json">
{
"styleIsolation": "shared",
"component": true,
"usingComponents": {
"rate-item": "./rate-item.mpx"
}
}
</script>
131 changes: 131 additions & 0 deletions packages/mpx-cube-ui/src/components/rate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { createComponent } from '@mpxjs/core'

const EVENT_INPUT = 'input'
const EVENT_TYPE_MOUSE = 'mouse'

function isMouseEvent(e) {
return e.type.indexOf(EVENT_TYPE_MOUSE) > -1
}
createComponent({
options: {
multipleSlots: true,
styleIsolation: 'shared'
},
properties: {
/**
* @description 拓展 class 属性,`cube-${type}`,可用于样式覆盖和定制
*/
value: {
type: Number,
value: 0
},
/**
* @description 是否显示遮罩
*/
max: {
type: Number,
value: 0
},
/**
* @description 是否显示遮罩
*/
disabled: {
type: Boolean,
value: false
},
/**
* @description 文本内容,**微信&web** 支持 `html string` 的文本格式,**支付宝**目前不支持,所以需要自己转,具体见:支付宝 [rich-text文档](https://opendocs.alipay.com/mini/component/rich-text#%E5%B1%9E%E6%80%A7%E8%AF%B4%E6%98%8E)
*/
justify: {
type: Boolean,
value: false
},
/**
* @description 是否居中显示
*/
allowHalf: {
type: Boolean,
value: false
}
},
data: {
tempValue: 0
},
computed: {
rateClass() {
return this.justify && 'cube-rate-justify'
}
},
watch: {
value: {
immediate: true,
handler(val) {
if (val !== this.tempValue) {
this.tempValue = this.handleNum(val)
}
}
}
},
lifetimes: {
created() {
this.mousePressed = false
}
},
methods: {
handleStart(e) {
if (!this.disabled) {
if (isMouseEvent(e)) {
this.mousePressed = true
document.addEventListener('mouseup', this.handleEnd)
document.addEventListener('mousemove', this.handleMove)
}
const rect = this.$refs.rateContainer.$el.getBoundingClientRect()
this.left = rect.left
this.containerWidth = rect.width
}
},
handleMove(e) {
console.log('handleMove')
if (this.disabled) return

if (!isMouseEvent(e)) {
this.computeTempValue(e.touches[0])
} else if (this.mousePressed) {
this.computeTempValue(e)
}
},
handleEnd(e) {
console.log('handleEnd')
if (this.disabled) return
if ((!isMouseEvent(e) || this.mousePressed)) {
if (isMouseEvent(e)) {
this.mousePressed = false
document.removeEventListener('mouseup', this.handleEnd)
document.removeEventListener('mousemove', this.handleMove)
}
this.computeTempValue(isMouseEvent(e) ? e : e.changedTouches[0])
this.triggerEvent(EVENT_INPUT, { value: this.tempValue })
}
},
handleNum(num) {
if (this.allowHalf) {
const baseNum = Math.ceil(num) - 0.5
num = num <= baseNum ? baseNum : baseNum + 0.5
} else {
num = Math.ceil(num)
}
return num
},
computeTempValue(touch) {
let num = (touch.clientX - this.left) / this.containerWidth * this.max
num = this.handleNum(num)
if (num > 0 && num <= this.max) {
this.tempValue = num
} else if (num <= 0) {
this.tempValue = 0
} else {
this.tempValue = this.max
}
}
}
})
21 changes: 21 additions & 0 deletions packages/mpx-cube-ui/src/components/rate/rate-item-index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createComponent } from '@mpxjs/core'
createComponent({
properties: {
index: {
type: Number,
value: 0
},
value: {
type: Number,
value: 0
}
},
computed: {
rateItemClass() {
return {
'cube-rate-item_active': this.index <= this.value,
'cube-rate-item_half_active': this.index === this.value + 0.5
}
}
}
})
Loading

0 comments on commit 5542d86

Please sign in to comment.