diff --git a/packages/vant/src/checkbox/Checkbox.tsx b/packages/vant/src/checkbox/Checkbox.tsx index 197c1ca1a..65f41fa14 100644 --- a/packages/vant/src/checkbox/Checkbox.tsx +++ b/packages/vant/src/checkbox/Checkbox.tsx @@ -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('round'), bindGroup: truthProp, }); diff --git a/packages/vant/src/checkbox/Checker.tsx b/packages/vant/src/checkbox/Checker.tsx index 9d96f68f2..97b03b440 100644 --- a/packages/vant/src/checkbox/Checker.tsx +++ b/packages/vant/src/checkbox/Checker.tsx @@ -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('round'), disabled: Boolean, iconSize: numericProp, modelValue: unknownProp, @@ -40,6 +41,7 @@ export default defineComponent({ props: extend({}, checkerProps, { bem: makeRequiredProp(Function), role: String, + shape: makeStringProp('round'), parent: Object as PropType, checked: Boolean, bindGroup: truthProp, @@ -107,12 +109,25 @@ export default defineComponent({
{slots.icon ? ( slots.icon({ checked, disabled: disabled.value }) - ) : ( + ) : shape !== 'dot' ? ( + ) : ( +
)}
); diff --git a/packages/vant/src/radio/README.md b/packages/vant/src/radio/README.md index 315063b50..0ba6d374a 100644 --- a/packages/vant/src/radio/README.md +++ b/packages/vant/src/radio/README.md @@ -66,6 +66,11 @@ export default { Radio 1 Radio 2 + + + Radio 1 + Radio 2 + ``` ### 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)_ | - | diff --git a/packages/vant/src/radio/README.zh-CN.md b/packages/vant/src/radio/README.zh-CN.md index 6098d97cb..9fefc5f9d 100644 --- a/packages/vant/src/radio/README.zh-CN.md +++ b/packages/vant/src/radio/README.zh-CN.md @@ -65,13 +65,18 @@ export default { ### 自定义形状 -将 `shape` 属性设置为 `square`,单选框的形状会变成方形。 +`shape` 属性可选值为 `square` 和 `dot`,单选框形状分别对应方形和圆形。 ```html 单选框 1 单选框 2 + + + Radio 1 + Radio 2 + ``` ### 自定义颜色 @@ -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)_ | - | diff --git a/packages/vant/src/radio/Radio.tsx b/packages/vant/src/radio/Radio.tsx index 393399fea..df1306977 100644 --- a/packages/vant/src/radio/Radio.tsx +++ b/packages/vant/src/radio/Radio.tsx @@ -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('round'), +}); -export type RadioShape = CheckerShape; export type RadioLabelPosition = CheckerLabelPosition; export type RadioProps = ExtractPropTypes; @@ -25,7 +28,7 @@ const [name, bem] = createNamespace('radio'); export default defineComponent({ name, - props: checkerProps, + props: radioProps, emits: ['update:modelValue'], diff --git a/packages/vant/src/radio/demo/index.vue b/packages/vant/src/radio/demo/index.vue index ea031a375..90ad123a6 100644 --- a/packages/vant/src/radio/demo/index.vue +++ b/packages/vant/src/radio/demo/index.vue @@ -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'); - + {{ t('radio') }} 1 {{ t('radio') }} 2 + + {{ t('radio') }} 1 + {{ t('radio') }} 2 + diff --git a/packages/vant/src/radio/index.less b/packages/vant/src/radio/index.less index eb8f55fab..51e4ac747 100644 --- a/packages/vant/src/radio/index.less +++ b/packages/vant/src/radio/index.less @@ -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 { diff --git a/packages/vant/src/radio/test/__snapshots__/demo-ssr.spec.ts.snap b/packages/vant/src/radio/test/__snapshots__/demo-ssr.spec.ts.snap index 9f2d7c9b9..9572dba8b 100644 --- a/packages/vant/src/radio/test/__snapshots__/demo-ssr.spec.ts.snap +++ b/packages/vant/src/radio/test/__snapshots__/demo-ssr.spec.ts.snap @@ -191,6 +191,50 @@ exports[`should render demo and match snapshot 1`] = ` +
+ + + +
diff --git a/packages/vant/src/radio/test/__snapshots__/demo.spec.ts.snap b/packages/vant/src/radio/test/__snapshots__/demo.spec.ts.snap index 235631b50..1248ee613 100644 --- a/packages/vant/src/radio/test/__snapshots__/demo.spec.ts.snap +++ b/packages/vant/src/radio/test/__snapshots__/demo.spec.ts.snap @@ -126,6 +126,37 @@ exports[`should render demo and match snapshot 1`] = `
+
+ + +