first commit
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classPrefix + ' ' + tClass"
|
||||
:style="tools._style([customStyle])"
|
||||
>
|
||||
<slot />
|
||||
<t-checkbox
|
||||
v-for="(item, index) in checkboxOptions"
|
||||
:key="index"
|
||||
:ref="prefix + '-checkbox-option'"
|
||||
:class="prefix + '-checkbox-option'"
|
||||
:data-item="item"
|
||||
:label="item.label || item.text || ''"
|
||||
:value="item.value == null ? '' : item.value"
|
||||
:block="item.block || true"
|
||||
:check-all="item.checkAll || false"
|
||||
:checked="item.checked || false"
|
||||
:content="item.content || ''"
|
||||
:content-disabled="item.contentDisabled || false"
|
||||
:icon="item.icon || 'circle'"
|
||||
:indeterminate="item.indeterminate || false"
|
||||
:disabled="item.disabled == null ? disabled : item.disabled"
|
||||
:max-content-row="item.maxContentRow || 5"
|
||||
:max-label-row="item.maxLabelRow || 3"
|
||||
:name="item.name || ''"
|
||||
:borderless="borderless"
|
||||
:readonly="item.readonly || false"
|
||||
:placement="item.placement || 'left'"
|
||||
:relation-key="relationKey"
|
||||
@change="({checked}) => handleInnerChildChange($event, { item, checked })"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TCheckbox from '../checkbox/checkbox';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import { coalesce } from '../common/utils';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
|
||||
const name = `${prefix}-checkbox-group`;
|
||||
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
controlledProps: [
|
||||
{
|
||||
key: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
],
|
||||
externalClasses: [
|
||||
`${prefix}-class`,
|
||||
],
|
||||
|
||||
inject: {
|
||||
[RELATION_MAP.FormKey]: {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
mixins: [ParentMixin(RELATION_MAP.Checkbox)],
|
||||
components: {
|
||||
TCheckbox,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
checkboxOptions: [],
|
||||
tools,
|
||||
|
||||
dataValue: coalesce(this.value, this.defaultValue),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(v) {
|
||||
this.dataValue = v;
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
dataValue: {
|
||||
handler() {
|
||||
this.updateChildren();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
options: {
|
||||
handler() {
|
||||
this.initWithOptions();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
},
|
||||
disabled: {
|
||||
handler(v) {
|
||||
if (this.options?.length) {
|
||||
this.initWithOptions();
|
||||
return;
|
||||
}
|
||||
this.getChildren()?.forEach((item) => {
|
||||
item.setDisabled(v);
|
||||
});
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$checkAll = null;
|
||||
},
|
||||
mounted() {
|
||||
this.setCheckall();
|
||||
|
||||
this.getChildren()?.forEach((item) => {
|
||||
item.setDisabled(this.disabled);
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.updateChildren();
|
||||
}, 33);
|
||||
},
|
||||
methods: {
|
||||
getChildren() {
|
||||
let items = this.children;
|
||||
if (!items?.length) {
|
||||
items = this.$refs[`${prefix}-checkbox-option`];
|
||||
}
|
||||
return items || [];
|
||||
},
|
||||
|
||||
updateChildren() {
|
||||
const items = this.getChildren();
|
||||
const { dataValue } = this;
|
||||
|
||||
|
||||
if (items.length > 0) {
|
||||
items.forEach((item) => {
|
||||
if (!item.checkAll) {
|
||||
item.dataChecked = dataValue?.includes(item.value);
|
||||
}
|
||||
});
|
||||
// 关联可全选项
|
||||
if (items.some(item => item.checkAll)) {
|
||||
this.setCheckall();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateValue({ validChildren, trigger, value, checked, checkAll, item, indeterminate }) {
|
||||
let { dataValue: newValue } = this;
|
||||
const { max } = this;
|
||||
|
||||
if (validChildren !== false) {
|
||||
const keySet = new Set(this.getChildren().map(item => item.value));
|
||||
newValue = newValue.filter(value => keySet.has(value));
|
||||
}
|
||||
|
||||
if (max && checked && newValue.length === max) return;
|
||||
|
||||
if (checkAll) {
|
||||
const items = this.getChildren();
|
||||
newValue = !checked && indeterminate
|
||||
? items
|
||||
.filter(data => !(data.disabled && !newValue.includes(data.value)))
|
||||
.map(item => item.value)
|
||||
: items
|
||||
.filter((data) => {
|
||||
if (data.disabled) {
|
||||
return newValue.includes(data.value);
|
||||
}
|
||||
return checked && !data.checkAll;
|
||||
})
|
||||
.map(data => data.value);
|
||||
} else if (checked) {
|
||||
newValue = newValue.concat(value);
|
||||
} else {
|
||||
const index = newValue.findIndex(v => v === value);
|
||||
newValue.splice(index, 1);
|
||||
}
|
||||
|
||||
if (trigger !== 'init') {
|
||||
this._trigger('change', { value: newValue, context: item });
|
||||
|
||||
this.onChange(newValue);
|
||||
}
|
||||
},
|
||||
|
||||
onChange(value) {
|
||||
if (this[RELATION_MAP.FormKey]
|
||||
&& this[RELATION_MAP.FormKey].onValueChange) {
|
||||
this[RELATION_MAP.FormKey].onValueChange(value);
|
||||
}
|
||||
},
|
||||
|
||||
initWithOptions() {
|
||||
const { options, dataValue: value, keys } = this;
|
||||
|
||||
if (!options?.length || !Array.isArray(options)) return;
|
||||
|
||||
const checkboxOptions = options.map((item) => {
|
||||
const isLabel = ['number', 'string'].includes(typeof item);
|
||||
return isLabel
|
||||
? {
|
||||
label: `${item}`,
|
||||
value: item,
|
||||
checked: value?.includes(item),
|
||||
}
|
||||
: {
|
||||
...item,
|
||||
label: item[coalesce(keys?.label, 'label')],
|
||||
value: item[coalesce(keys?.value, 'value')],
|
||||
checked: value?.includes(item[coalesce(keys?.value, 'value')]),
|
||||
};
|
||||
});
|
||||
|
||||
this.checkboxOptions = checkboxOptions;
|
||||
},
|
||||
|
||||
handleInnerChildChange(tools, { item, checked }) {
|
||||
const rect = {};
|
||||
|
||||
if (item.checkAll) {
|
||||
rect.indeterminate = this.$checkAll?.indeterminate;
|
||||
}
|
||||
|
||||
this.updateValue({ ...item, checked, item, ...rect });
|
||||
},
|
||||
|
||||
setCheckall() {
|
||||
const items = this.getChildren();
|
||||
|
||||
if (!this.$checkAll) {
|
||||
this.$checkAll = items.find(item => item.checkAll);
|
||||
}
|
||||
|
||||
if (!this.$checkAll) return;
|
||||
|
||||
const { dataValue } = this;
|
||||
const valueSet = new Set(dataValue?.filter(val => val !== this.$checkAll.value));
|
||||
const isCheckall = items.every(item => (item.checkAll ? true : valueSet.has(item.value)));
|
||||
|
||||
this.$checkAll.dataChecked = valueSet.size > 0;
|
||||
this.$checkAll.dataIndeterminate = !isCheckall;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { TdCheckboxGroupProps } from './type';
|
||||
export default {
|
||||
/** 是否开启无边框模式。优先级低于 Checkbox.borderless */
|
||||
borderless: Boolean,
|
||||
/** 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled */
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** 用来定义 value / label / disabled 在 `options` 中对应的字段别名 */
|
||||
keys: {
|
||||
type: Object,
|
||||
},
|
||||
/** 支持最多选中的数量 */
|
||||
max: {
|
||||
type: Number,
|
||||
default: undefined,
|
||||
},
|
||||
/** 统一设置内部复选框 HTML 属性 */
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」 */
|
||||
options: {
|
||||
type: Array,
|
||||
default: (): TdCheckboxGroupProps['options'] => [],
|
||||
},
|
||||
/** 只读状态 */
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: undefined,
|
||||
},
|
||||
/** -1 时代表独立,不再寻找 parent,用于头条小程序 */
|
||||
relationKey: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
/** 选中值 */
|
||||
value: {
|
||||
type: Array,
|
||||
},
|
||||
/** 选中值,非受控属性 */
|
||||
defaultValue: {
|
||||
type: Array,
|
||||
},
|
||||
/** 值变化时触发。`context` 表示当前点击项内容 */
|
||||
onChange: {
|
||||
type: Function,
|
||||
default: () => ({}),
|
||||
},
|
||||
};
|
||||
72
uni_modules/tdesign-uniapp/components/checkbox-group/type.ts
Normal file
72
uni_modules/tdesign-uniapp/components/checkbox-group/type.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
|
||||
* */
|
||||
|
||||
import type { KeysType } from '../common/common';
|
||||
|
||||
export interface TdCheckboxGroupProps<T = CheckboxGroupValue> {
|
||||
/**
|
||||
* 是否开启无边框模式。优先级低于 Checkbox.borderless
|
||||
* @default false
|
||||
*/
|
||||
borderless?: boolean;
|
||||
/**
|
||||
* 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled
|
||||
*/
|
||||
disabled?: boolean;
|
||||
/**
|
||||
* 用来定义 value / label / disabled 在 `options` 中对应的字段别名
|
||||
*/
|
||||
keys?: KeysType;
|
||||
/**
|
||||
* 支持最多选中的数量
|
||||
*/
|
||||
max?: number;
|
||||
/**
|
||||
* 统一设置内部复选框 HTML 属性
|
||||
* @default ''
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」
|
||||
* @default []
|
||||
*/
|
||||
options?: Array<CheckboxOption>;
|
||||
/**
|
||||
* 只读状态
|
||||
*/
|
||||
readonly?: boolean;
|
||||
/**
|
||||
* -1 时代表独立,不再寻找 parent,用于头条小程序
|
||||
* @default ''
|
||||
*/
|
||||
relationKey?: string;
|
||||
/**
|
||||
* 选中值
|
||||
*/
|
||||
value?: T;
|
||||
/**
|
||||
* 选中值,非受控属性
|
||||
*/
|
||||
defaultValue?: T;
|
||||
/**
|
||||
* 值变化时触发。`context` 表示当前点击项内容
|
||||
*/
|
||||
onChange?: (context: {
|
||||
value: CheckboxGroupValue;
|
||||
context: { value: boolean | number | string; label: boolean | number | string };
|
||||
}) => void;
|
||||
}
|
||||
|
||||
export type CheckboxOption = string | number | CheckboxOptionObj;
|
||||
|
||||
export interface CheckboxOptionObj {
|
||||
label?: string;
|
||||
value?: string | number;
|
||||
disabled?: boolean;
|
||||
checkAll?: true;
|
||||
}
|
||||
|
||||
export type CheckboxGroupValue = Array<string | number | boolean>;
|
||||
Reference in New Issue
Block a user