UNPKG

wux-weapp

Version:

一套组件化、可复用、易扩展的微信小程序 UI 组件库

179 lines (168 loc) 5.36 kB
import baseComponent from '../helpers/baseComponent' import classNames from '../helpers/libs/classNames' import styleToCssString from '../helpers/libs/styleToCssString' import fieldNamesBehavior from '../helpers/mixins/fieldNamesBehavior' import eventsMixin from '../helpers/mixins/eventsMixin' import * as common from '../helpers/wxs/common' /** * css var prefix */ const cssVarPattern = /^--/ function getCheckedValues(newVal, oldVal = []) { let checkedValues = [...oldVal] checkedValues = checkedValues.indexOf(newVal) !== -1 ? checkedValues.filter((n) => n !== newVal) : [...checkedValues, newVal] return checkedValues } const getOptions = (options, fieldNames) => common.getOptions(options, fieldNames) baseComponent({ useField: true, behaviors: [fieldNamesBehavior, eventsMixin()], relations: { '../field/index': { type: 'ancestor', }, }, properties: { prefixCls: { type: String, value: 'wux-selector-group', }, theme: { type: String, value: 'balanced', }, shape: { type: String, value: 'default', }, columns: { type: Number, value: 3, }, gap: { type: Number, value: 8, }, options: { type: Array, value: [], }, defaultValue: { type: Array, value: [], }, value: { type: Array, value: [], observer(newVal) { if (this.data.controlled) { this.updated(newVal) } }, }, controlled: { type: Boolean, value: false, }, multiple: { type: Boolean, value: false, }, showCheckMark: { type: Boolean, value: true, }, }, data: { extStyle: '', inputValue: [], }, observers: { ['columns, gap'](columns, gap) { this.updateStyle(columns, gap) }, }, computed: { classes: ['prefixCls, theme, shape', function(prefixCls, theme, shape) { const finalShape = ['rounded', 'rectangular'].includes(shape) ? shape : '' const wrap = classNames(prefixCls, { [`${prefixCls}--${theme}`]: theme, }) const grid = `${prefixCls}__grid` const gridItem = classNames(`${prefixCls}__grid-item`, { [`${prefixCls}__grid-item--${shape}`]: finalShape, }) const desc = `${prefixCls}__desc` const checkMark = `${prefixCls}__check-mark` const checkMarkIcon = `${prefixCls}__check-mark-icon` const selectable = `${prefixCls}__selectable` return { wrap, grid, gridItem, desc, checkMark, checkMarkIcon, selectable, } }], }, methods: { updated(inputValue) { if (this.hasFieldDecorator) return if (this.data.inputValue !== inputValue) { this.setData({ inputValue }) } }, updateStyle(columns, gap) { const extStyle = styleToCssString({ '--selector-group-columns': columns, '--selector-group-column-gap': `${gap * 2}rpx`, }, { exclude: cssVarPattern }) if (extStyle !== this.data.extStyle) { this.setData({ extStyle, }) } }, onCheckboxChange(e) { const { value, checked } = e.detail const { inputValue, multiple } = this.data const checkedValues = multiple ? getCheckedValues(value, inputValue) : checked ? [value] : [] if (!this.data.controlled) { this.updated(checkedValues) } this.triggerEvent('change', { ...this.getValue(checkedValues) }) }, getValue(value = this.data.inputValue, _cols = this.data.options) { const fieldNames = this.getFieldNames() const labelName = fieldNames.label const valueName = fieldNames.value const cols = getOptions(_cols, fieldNames) // Keep sort with value const checkedValues = value.reduce((acc, val) => ( [ ...acc, ...cols.filter((option) => option[valueName] === val), ] ), []) const displayValue = checkedValues.map((option) => option[labelName]) const allValues = cols.map((option) => option[valueName]) const selectedIndex = value.map((n) => allValues.indexOf(n)) return { value, displayValue, selectedIndex, selectedValue: value, cols, } }, }, attached() { const { defaultValue, value, controlled } = this.data const inputValue = controlled ? value : defaultValue this.updated(inputValue) }, })