mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-21 13:59:15 +08:00
feat(Radio): support dot shape (#12057)
* feat(Radio): support dot shape * chore: update test * chore: format code
This commit is contained in:
parent
3319d1e5cd
commit
39a54a8d9a
@ -1,7 +1,13 @@
|
||||
import { watch, computed, defineComponent, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { createNamespace, extend, pick, truthProp } from '../utils';
|
||||
import {
|
||||
pick,
|
||||
extend,
|
||||
truthProp,
|
||||
makeStringProp,
|
||||
createNamespace,
|
||||
} from '../utils';
|
||||
import { CHECKBOX_GROUP_KEY } from '../checkbox-group/CheckboxGroup';
|
||||
|
||||
// Composables
|
||||
@ -9,7 +15,7 @@ import { useParent, useCustomFieldValue } from '@vant/use';
|
||||
import { useExpose } from '../composables/use-expose';
|
||||
|
||||
// Components
|
||||
import Checker, { checkerProps } from './Checker';
|
||||
import Checker, { checkerProps, type CheckerShape } from './Checker';
|
||||
|
||||
// Types
|
||||
import type { CheckboxExpose } from './types';
|
||||
@ -17,6 +23,7 @@ import type { CheckboxExpose } from './types';
|
||||
const [name, bem] = createNamespace('checkbox');
|
||||
|
||||
export const checkboxProps = extend({}, checkerProps, {
|
||||
shape: makeStringProp<CheckerShape>('round'),
|
||||
bindGroup: truthProp,
|
||||
});
|
||||
|
||||
|
@ -11,6 +11,8 @@ import {
|
||||
} from '../utils';
|
||||
import { Icon } from '../icon';
|
||||
|
||||
import type { RadioShape } from '../radio';
|
||||
|
||||
export type CheckerShape = 'square' | 'round';
|
||||
export type CheckerDirection = 'horizontal' | 'vertical';
|
||||
export type CheckerLabelPosition = 'left' | 'right';
|
||||
@ -27,7 +29,6 @@ export type CheckerParent = {
|
||||
|
||||
export const checkerProps = {
|
||||
name: unknownProp,
|
||||
shape: makeStringProp<CheckerShape>('round'),
|
||||
disabled: Boolean,
|
||||
iconSize: numericProp,
|
||||
modelValue: unknownProp,
|
||||
@ -40,6 +41,7 @@ export default defineComponent({
|
||||
props: extend({}, checkerProps, {
|
||||
bem: makeRequiredProp(Function),
|
||||
role: String,
|
||||
shape: makeStringProp<CheckerShape | RadioShape>('round'),
|
||||
parent: Object as PropType<CheckerParent | null>,
|
||||
checked: Boolean,
|
||||
bindGroup: truthProp,
|
||||
@ -107,12 +109,25 @@ export default defineComponent({
|
||||
<div
|
||||
ref={iconRef}
|
||||
class={bem('icon', [shape, { disabled: disabled.value, checked }])}
|
||||
style={{ fontSize: addUnit(iconSize) }}
|
||||
style={
|
||||
shape !== 'dot'
|
||||
? { fontSize: addUnit(iconSize) }
|
||||
: {
|
||||
width: addUnit(iconSize),
|
||||
height: addUnit(iconSize),
|
||||
borderColor: iconStyle.value?.borderColor,
|
||||
}
|
||||
}
|
||||
>
|
||||
{slots.icon ? (
|
||||
slots.icon({ checked, disabled: disabled.value })
|
||||
) : (
|
||||
) : shape !== 'dot' ? (
|
||||
<Icon name="success" style={iconStyle.value} />
|
||||
) : (
|
||||
<div
|
||||
class={bem('icon--dot__icon')}
|
||||
style={{ backgroundColor: iconStyle.value?.backgroundColor }}
|
||||
></div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
@ -66,6 +66,11 @@ export default {
|
||||
<van-radio name="1" shape="square">Radio 1</van-radio>
|
||||
<van-radio name="2" shape="square">Radio 2</van-radio>
|
||||
</van-radio-group>
|
||||
|
||||
<van-radio-group v-model="checked">
|
||||
<van-radio name="1" shape="dot">Radio 1</van-radio>
|
||||
<van-radio name="2" shape="dot">Radio 2</van-radio>
|
||||
</van-radio-group>
|
||||
```
|
||||
|
||||
### Custom Color
|
||||
@ -190,7 +195,7 @@ import type {
|
||||
| Attribute | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| name | Radio name, usually a unique string or number | _any_ | - |
|
||||
| shape | Can be set to `square` | _string_ | `round` |
|
||||
| shape | Can be set to `square` `dot` | _string_ | `round` |
|
||||
| disabled | Whether to disable radio | _boolean_ | `false` |
|
||||
| label-disabled | Whether to disable label click | _boolean_ | `false` |
|
||||
| label-position | Can be set to `left` | _string_ | `right` |
|
||||
@ -235,6 +240,7 @@ The component provides the following CSS variables, which can be used to customi
|
||||
| Name | Default Value | Description |
|
||||
| -------------------------------- | -------------------------- | ----------- |
|
||||
| --van-radio-size | _20px_ | - |
|
||||
| --van-radio-dot-size | _8px_ | - |
|
||||
| --van-radio-border-color | _var(--van-gray-5)_ | - |
|
||||
| --van-radio-duration | _var(--van-duration-fast)_ | - |
|
||||
| --van-radio-label-margin | _var(--van-padding-xs)_ | - |
|
||||
|
@ -65,13 +65,18 @@ export default {
|
||||
|
||||
### 自定义形状
|
||||
|
||||
将 `shape` 属性设置为 `square`,单选框的形状会变成方形。
|
||||
`shape` 属性可选值为 `square` 和 `dot`,单选框形状分别对应方形和圆形。
|
||||
|
||||
```html
|
||||
<van-radio-group v-model="checked">
|
||||
<van-radio name="1" shape="square">单选框 1</van-radio>
|
||||
<van-radio name="2" shape="square">单选框 2</van-radio>
|
||||
</van-radio-group>
|
||||
|
||||
<van-radio-group v-model="checked">
|
||||
<van-radio name="1" shape="dot">Radio 1</van-radio>
|
||||
<van-radio name="2" shape="dot">Radio 2</van-radio>
|
||||
</van-radio-group>
|
||||
```
|
||||
|
||||
### 自定义颜色
|
||||
@ -190,7 +195,7 @@ export default {
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| name | 标识符,通常为一个唯一的字符串或数字 | _any_ | - |
|
||||
| shape | 形状,可选值为 `square` | _string_ | `round` |
|
||||
| shape | 形状,可选值为 `square` `dot` | _string_ | `round` |
|
||||
| disabled | 是否为禁用状态 | _boolean_ | `false` |
|
||||
| label-disabled | 是否禁用文本内容点击 | _boolean_ | `false` |
|
||||
| label-position | 文本位置,可选值为 `left` | _string_ | `right` |
|
||||
@ -249,6 +254,7 @@ import type {
|
||||
| 名称 | 默认值 | 描述 |
|
||||
| -------------------------------- | -------------------------- | ---- |
|
||||
| --van-radio-size | _20px_ | - |
|
||||
| --van-radio-dot-size | _8px_ | - |
|
||||
| --van-radio-border-color | _var(--van-gray-5)_ | - |
|
||||
| --van-radio-duration | _var(--van-duration-fast)_ | - |
|
||||
| --van-radio-label-margin | _var(--van-padding-xs)_ | - |
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { defineComponent, type ExtractPropTypes } from 'vue';
|
||||
|
||||
// Utils
|
||||
import { pick, createNamespace } from '../utils';
|
||||
import { pick, extend, createNamespace, makeStringProp } from '../utils';
|
||||
import { RADIO_KEY } from '../radio-group/RadioGroup';
|
||||
|
||||
// Composables
|
||||
@ -10,13 +10,16 @@ import { useParent } from '@vant/use';
|
||||
// Components
|
||||
import Checker, {
|
||||
checkerProps,
|
||||
CheckerShape,
|
||||
CheckerLabelPosition,
|
||||
type CheckerShape,
|
||||
type CheckerLabelPosition,
|
||||
} from '../checkbox/Checker';
|
||||
|
||||
export const radioProps = checkerProps;
|
||||
export type RadioShape = CheckerShape | 'dot';
|
||||
|
||||
export const radioProps = extend({}, checkerProps, {
|
||||
shape: makeStringProp<RadioShape>('round'),
|
||||
});
|
||||
|
||||
export type RadioShape = CheckerShape;
|
||||
export type RadioLabelPosition = CheckerLabelPosition;
|
||||
export type RadioProps = ExtractPropTypes<typeof radioProps>;
|
||||
|
||||
@ -25,7 +28,7 @@ const [name, bem] = createNamespace('radio');
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
||||
props: checkerProps,
|
||||
props: radioProps,
|
||||
|
||||
emits: ['update:modelValue'],
|
||||
|
||||
|
@ -41,7 +41,8 @@ const radio3 = ref('1');
|
||||
const radio4 = ref('1');
|
||||
const radio5 = ref('1');
|
||||
const radioLabel = ref('1');
|
||||
const radioShape = ref('1');
|
||||
const radioSquare = ref('1');
|
||||
const radioDot = ref('1');
|
||||
const radioIconSize = ref('1');
|
||||
const radioHorizontal = ref('1');
|
||||
const radioLeftLabel = ref('1');
|
||||
@ -76,10 +77,18 @@ const inactiveIcon = cdnURL('user-inactive.png');
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('customShape')">
|
||||
<van-radio-group v-model="radioShape" class="demo-radio-group">
|
||||
<van-radio-group v-model="radioSquare" class="demo-radio-group">
|
||||
<van-radio name="1" shape="square">{{ t('radio') }} 1</van-radio>
|
||||
<van-radio name="2" shape="square">{{ t('radio') }} 2</van-radio>
|
||||
</van-radio-group>
|
||||
<van-radio-group
|
||||
v-model="radioDot"
|
||||
class="demo-radio-group"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<van-radio name="1" shape="dot">{{ t('radio') }} 1</van-radio>
|
||||
<van-radio name="2" shape="dot">{{ t('radio') }} 2</van-radio>
|
||||
</van-radio-group>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('customColor')">
|
||||
|
@ -1,5 +1,6 @@
|
||||
:root {
|
||||
--van-radio-size: 20px;
|
||||
--van-radio-dot-size: 8px;
|
||||
--van-radio-border-color: var(--van-gray-5);
|
||||
--van-radio-duration: var(--van-duration-fast);
|
||||
--van-radio-label-margin: var(--van-padding-xs);
|
||||
@ -56,12 +57,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
&--dot {
|
||||
position: relative;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
width: var(--van-radio-size);
|
||||
height: var(--van-radio-size);
|
||||
border: 1px solid var(--van-radio-border-color);
|
||||
transition-duration: var(--van-radio-duration);
|
||||
transition-property: border-color;
|
||||
|
||||
&__icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 100%;
|
||||
height: calc(100% - var(--van-radio-dot-size));
|
||||
width: calc(100% - var(--van-radio-dot-size));
|
||||
transition-duration: var(--van-radio-duration);
|
||||
transition-property: border-color, background-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--checked {
|
||||
.van-icon {
|
||||
color: var(--van-white);
|
||||
background-color: var(--van-radio-checked-icon-color);
|
||||
border-color: var(--van-radio-checked-icon-color);
|
||||
}
|
||||
|
||||
&.van-radio__icon--dot {
|
||||
border-color: var(--van-radio-checked-icon-color);
|
||||
.van-radio__icon--dot__icon {
|
||||
background: var(--van-radio-checked-icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
|
@ -191,6 +191,50 @@ exports[`should render demo and match snapshot 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-radio-group demo-radio-group"
|
||||
role="radiogroup"
|
||||
style="margin-top:20px;"
|
||||
>
|
||||
<!--[-->
|
||||
<div role="radio"
|
||||
class="van-radio"
|
||||
tabindex="0"
|
||||
aria-checked="true"
|
||||
>
|
||||
<!--[-->
|
||||
<div class="van-radio__icon van-radio__icon--dot van-radio__icon--checked"
|
||||
style
|
||||
>
|
||||
<div class="van-radio__icon--dot__icon"
|
||||
style
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<span class="van-radio__label">
|
||||
<!--[-->
|
||||
Radio 1
|
||||
</span>
|
||||
</div>
|
||||
<div role="radio"
|
||||
class="van-radio"
|
||||
tabindex="0"
|
||||
aria-checked="false"
|
||||
>
|
||||
<!--[-->
|
||||
<div class="van-radio__icon van-radio__icon--dot"
|
||||
style
|
||||
>
|
||||
<div class="van-radio__icon--dot__icon"
|
||||
style
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<span class="van-radio__label">
|
||||
<!--[-->
|
||||
Radio 2
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!--[-->
|
||||
|
@ -126,6 +126,37 @@ exports[`should render demo and match snapshot 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-radio-group demo-radio-group"
|
||||
role="radiogroup"
|
||||
style="margin-top: 20px;"
|
||||
>
|
||||
<div role="radio"
|
||||
class="van-radio"
|
||||
tabindex="0"
|
||||
aria-checked="true"
|
||||
>
|
||||
<div class="van-radio__icon van-radio__icon--dot van-radio__icon--checked">
|
||||
<div class="van-radio__icon--dot__icon">
|
||||
</div>
|
||||
</div>
|
||||
<span class="van-radio__label">
|
||||
Radio 1
|
||||
</span>
|
||||
</div>
|
||||
<div role="radio"
|
||||
class="van-radio"
|
||||
tabindex="0"
|
||||
aria-checked="false"
|
||||
>
|
||||
<div class="van-radio__icon van-radio__icon--dot">
|
||||
<div class="van-radio__icon--dot__icon">
|
||||
</div>
|
||||
</div>
|
||||
<span class="van-radio__label">
|
||||
Radio 2
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-radio-group demo-radio-group"
|
||||
|
@ -1,5 +1,6 @@
|
||||
export type RadioThemeVars = {
|
||||
radioSize?: string;
|
||||
radioDotSize?: string;
|
||||
radioBorderColor?: string;
|
||||
radioDuration?: string;
|
||||
radioLabelMargin?: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user