Skip to content

Commit

Permalink
feat(components): [checkbox] 新增选中部分属性
Browse files Browse the repository at this point in the history
  • Loading branch information
Ce1ling committed Oct 3, 2023
1 parent 78e4abe commit 992e5d0
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 115 deletions.
100 changes: 63 additions & 37 deletions packages/components/Checkbox/Checkbox.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script setup lang="ts">
import { computed, watch } from 'vue'
import { computed, watch } from 'vue'
import type { CheckboxProps, CheckboxEmits, CheckboxSlots } from './checkbox'
const props = withDefaults(defineProps<CheckboxProps>(), {
label: '',
disabled: false,
border: false,
isBtn: false
isBtn: false,
isCheckedPart: false,
})
const emit = defineEmits<CheckboxEmits>()
Expand All @@ -17,28 +17,32 @@ defineSlots<CheckboxSlots>()
const isChecked = computed(() => {
return typeof props.modelValue !== 'boolean'
? props.modelValue.find(v => v === props.label) === props.label
? props.modelValue.find(e => e === props.label) === props.label
: props.modelValue
})
const checkboxClass = computed(() => ({
'is-checked': isChecked.value,
'is-checked': !props.isCheckedPart && isChecked.value,
'is-disabled': props.disabled,
'has-border': props.border && !props.isBtn,
'is-button': props.isBtn
'is-button': props.isBtn,
'is-checked-part': props.isCheckedPart,
}))
const updateModelValue = () => {
if (typeof props.modelValue === 'boolean') {
emit('update:modelValue', !props.modelValue)
return
return
}
const arr = [...props.modelValue]
const i = arr.indexOf(props.label)
if (i === -1) { arr.push(props.label) }
else { arr.splice(i, 1) }
if (i === -1) {
arr.push(props.label)
} else {
arr.splice(i, 1)
}
emit('update:modelValue', arr)
}
Expand All @@ -50,19 +54,19 @@ watch(isChecked, (value, oldValue) => {

<template>
<label class="vi-checkbox" :class="checkboxClass">
<input
type="checkbox"
<input
type="checkbox"
class="vi-checkbox__input"
:name="label"
:value="label"
:name="label"
:value="label"
:checked="isChecked"
@input="updateModelValue"
@input="updateModelValue"
:disabled="disabled"
/>
<span class="vi-checkbox__square"></span>
<span class="vi-checkbox__square" />
<span class="vi-checkbox__label">
<slot v-if="$slots.default" />
<template v-else>{{ label }}</template>
<template v-else>{{ label }}</template>
</span>
</label>
</template>
Expand All @@ -75,7 +79,7 @@ watch(isChecked, (value, oldValue) => {
cursor: pointer;
user-select: none;
position: relative;
&:hover {
.vi-checkbox__square {
border-color: var(--vi-color-primary);
Expand All @@ -96,24 +100,22 @@ watch(isChecked, (value, oldValue) => {
border-radius: 2px;
transition: all var(--vi-animation-duration);
}
&.is-checked {
.vi-checkbox__square {
background-color: var(--vi-color-primary);
border-color: var(--vi-color-primary);
&::before {
content: '';
width: 4px;
height: 8px;
background-color: transparent;
position: absolute;
border: 1px solid var(--vi-checkbox-square-inner-color);
border-top: none;
border-left: none;
top: 1px;
left: 4px;
transform: rotate(45deg);
animation: vi-checkbox-zoom var(--vi-animation-duration);
}
&.is-checked .vi-checkbox__square {
background-color: var(--vi-color-primary);
border-color: var(--vi-color-primary);
&::before {
content: '';
width: 4px;
height: 8px;
background-color: transparent;
position: absolute;
border: 1px solid var(--vi-checkbox-square-inner-color);
border-top: none;
border-left: none;
top: 1px;
left: 4px;
transform: rotate(45deg);
animation: vi-checkbox-rotate-zoom var(--vi-animation-duration);
}
}
&.is-disabled {
Expand Down Expand Up @@ -165,14 +167,38 @@ watch(isChecked, (value, oldValue) => {
position: absolute;
}
}
&.is-checked-part .vi-checkbox__square {
background-color: var(--vi-color-primary);
border-color: var(--vi-color-primary);
&::before {
content: '';
width: 60%;
height: 1px;
background-color: var(--vi-checkbox-square-inner-color);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: vi-checkbox-zoom var(--vi-animation-duration);
}
}
}
@keyframes vi-checkbox-zoom {
@keyframes vi-checkbox-rotate-zoom {
from {
transform: rotate(45deg) scale(0);
}
to {
transform: rotate(45deg) scale(1);
}
}
</style>
@keyframes vi-checkbox-zoom {
from {
transform: translate(-50%, -50%) scale(0);
}
to {
transform: translate(-50%, -50%) scale(1);
}
}
</style>
4 changes: 3 additions & 1 deletion packages/components/Checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export interface CheckboxProps {
disabled?: boolean
border?: boolean
isBtn?: boolean
/** 是否为选中部分 */
isCheckedPart?: boolean
}

export interface CheckboxEmits {
Expand All @@ -15,4 +17,4 @@ export interface CheckboxEmits {

export interface CheckboxSlots {
default?: (props: {}) => any
}
}
68 changes: 24 additions & 44 deletions packages/components/Transfer/Transfer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,32 @@ import { computed, provide } from 'vue'
import { useTransfer } from './useTransfer'
import TransferContainer from './TransferContainer.vue'
import type {
TransferActionType,
TransferItem,
TransferProps,
TransferPropsDefaults,
TransferEmits
import type {
TransferActionType,
TransferItem,
TransferProps,
TransferPropsDefaults,
TransferEmits,
} from './transfer'
import type { UseTransfer } from './useTransfer'
const props = withDefaults<
TransferProps<T>,
TransferPropsDefaults<T>
>(defineProps<TransferProps<T>>(), {
showTotal: false,
titles: () => ['List 1', 'List 2'],
draggable: false
})
const props = withDefaults<TransferProps<T>, TransferPropsDefaults<T>>(
defineProps<TransferProps<T>>(),
{
showTotal: false,
titles: () => ['List 1', 'List 2'],
draggable: false,
}
)
const emit = defineEmits<TransferEmits>()
const {
leftList,
rightList,
setList,
checkItem,
checkAll
} = useTransfer(props.list)
const useTransferMethods = useTransfer(props.list)
const { leftList, rightList, setList } = useTransferMethods
provide<TransferProps<T>>('transferProps', props)
provide<TransferEmits>('transferEmits', emit)
provide<ReturnType<UseTransfer>>('useTransfer', {
leftList,
rightList,
setList,
checkItem,
checkAll
})
provide<ReturnType<UseTransfer>>('useTransfer', useTransferMethods)
const listCheckedLen = (list: TransferItem[]) => {
return computed(() => list.filter(item => item.checked).length)
Expand All @@ -55,30 +43,22 @@ const setListData = (to: TransferActionType, list: TransferItem[]) => {

<template>
<div class="vi-transfer">
<TransferContainer
type="left"
:title="titles[0]"
:list="leftList"
/>
<TransferContainer type="left" :title="titles[0]" :list="leftList" />
<div class="vi-transfer__buttons">
<vi-button
@click="setListData('left', rightList)"
<vi-button
@click="setListData('left', rightList)"
:disabled="!listCheckedLen(rightList).value"
>
<vi-icon name="Left" size="22px" cursor="inheirt" />
</vi-button>
<vi-button
@click="setListData('right', leftList)"
<vi-button
@click="setListData('right', leftList)"
:disabled="!listCheckedLen(leftList).value"
>
<vi-icon name="Right" size="22px" cursor="inheirt" />
</vi-button>
</div>
<TransferContainer
type="right"
:title="titles[1]"
:list="rightList"
/>
<TransferContainer type="right" :title="titles[1]" :list="rightList" />
</div>
</template>

Expand All @@ -94,4 +74,4 @@ const setListData = (to: TransferActionType, list: TransferItem[]) => {
gap: 8px;
}
}
</style>
</style>
17 changes: 7 additions & 10 deletions packages/components/Transfer/TransferContainer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup generic="T extends TransferItem[]">
import { computed, inject, ref, watch } from 'vue'
import { computed, inject, ref } from 'vue'
import type {
TransferItem,
Expand All @@ -14,7 +14,7 @@ const props = defineProps<TransferContainerProps<T>>()
const transferProps = inject<TransferProps<T>>('transferProps')!
const transferEmits = inject<TransferEmits>('transferEmits')!
const { setList, checkItem, checkAll } =
const { setList, checkItem, checkAll, isCheckedPart } =
inject<ReturnType<UseTransfer>>('useTransfer')!
const isDragging = ref(false)
Expand All @@ -41,24 +41,20 @@ const handleItemClick = (item: TransferItem) => {
handleCheckChange([item])
}
const dragStart = (e: DragEvent, item: TransferItem) => {
const handleDragStart = (e: DragEvent, item: TransferItem) => {
e.dataTransfer?.setData('item_id', item.id)
e.dataTransfer?.setData('origin', props.type)
isDragging.value = true
}
const handleDrop = (e: DragEvent) => {
if (!transferProps.draggable) {
return
}
if (!transferProps.draggable) return
const id = e.dataTransfer?.getData('item_id')
const dropTarget = e.dataTransfer?.getData('origin')
const targetItem = transferProps.list.find(item => item.id === id)
if (dropTarget === props.type || !targetItem) {
return
}
if (dropTarget === props.type || !targetItem) return
setList(props.type, [targetItem])
transferEmits('change', props.type, [targetItem])
Expand All @@ -71,6 +67,7 @@ const handleDrop = (e: DragEvent) => {
<vi-checkbox
v-model="checkAll(type).value"
@change="handleCheckChange(list as TransferItem[])"
:is-checked-part="isCheckedPart(type)"
/>
<span class="vi-transfer__title-inner">{{ title }}</span>
<span class="vi-transfer-total" v-if="transferProps.showTotal">
Expand All @@ -85,7 +82,7 @@ const handleDrop = (e: DragEvent) => {
:key="item.id"
:draggable="transferProps.draggable && !item.disabled"
@click="handleItemClick(item)"
@dragstart="dragStart($event, item)"
@dragstart="handleDragStart($event, item)"
@dragend="isDragging = false"
>
<vi-checkbox
Expand Down
Loading

0 comments on commit 992e5d0

Please sign in to comment.