Skip to content

Commit

Permalink
fix(comp:radio): style update and css variable support (#1293)
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm committed Nov 21, 2022
1 parent b378ef2 commit e438cb3
Show file tree
Hide file tree
Showing 23 changed files with 180 additions and 359 deletions.
6 changes: 4 additions & 2 deletions packages/components/checkbox/__tests__/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,13 @@ describe('Checkbox', () => {
props: { size: 'sm' },
})

expect(wrapper.classes()).not.toContain('ix-button-sm')
expect(wrapper.classes()).not.toContain('ix-checkbox-sm')
expect(wrapper.classes()).not.toContain('ix-button-xs')

await wrapper.setProps({ buttoned: true })

expect(wrapper.classes()).toContain('ix-button-sm')
expect(wrapper.classes()).toContain('ix-checkbox-sm')
expect(wrapper.classes()).toContain('ix-button-xs')
})

test('disabled work', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ describe('CheckboxGroup', () => {
props: { buttoned: true, size: 'sm' },
})

expect(wrapper.findAll('.ix-button-sm').length).toBe(3)
expect(wrapper.findAll('.ix-checkbox-sm').length).toBe(3)
})
})
16 changes: 6 additions & 10 deletions packages/components/checkbox/demo/Disabled.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<template>
<IxCheckbox :disabled="disabled">A</IxCheckbox>
<IxCheckbox :checked="true" :disabled="disabled">B</IxCheckbox>
<IxButton @click="toggle">Toggle</IxButton>
<IxSpace align="center">
<IxCheckbox disabled>A</IxCheckbox>
<IxCheckbox :checked="true" disabled>B</IxCheckbox>
<IxCheckbox buttoned disabled>C</IxCheckbox>
<IxCheckbox :checked="true" buttoned disabled>D</IxCheckbox>
</IxSpace>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const disabled = ref(true)
const toggle = () => (disabled.value = !disabled.value)
</script>
15 changes: 7 additions & 8 deletions packages/components/checkbox/src/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ export default defineComponent({
return checkboxGroup ? key : undefined
})
const isButtoned = computed(() => props.buttoned ?? checkboxGroup?.props.buttoned ?? false)
const mergedSize = computed(() => {
const size = props.size ?? checkboxGroup?.props.size ?? formContext?.size.value ?? config.size
return buttonSizeMap[size]
})
const size = computed(() => props.size ?? checkboxGroup?.props.size ?? formContext?.size.value ?? config.size)
const { isChecked, isDisabled, isFocused, handleChange, handleBlur, handleFocus } = useCheckbox(
props,
checkboxGroup,
Expand All @@ -64,16 +61,18 @@ export default defineComponent({
const { indeterminate } = props
const buttoned = isButtoned.value
const prefixCls = mergedPrefixCls.value
const commonPrefixCls = common.prefixCls
const classes = {
[prefixCls]: true,
[`${prefixCls}-checked`]: !indeterminate && isChecked.value,
[`${prefixCls}-disabled`]: isDisabled.value,
[`${prefixCls}-focused`]: isFocused.value,
[`${prefixCls}-indeterminate`]: indeterminate,
[`${common.prefixCls}-button`]: buttoned,
[`${common.prefixCls}-button-default`]: buttoned,
[`${common.prefixCls}-button-disabled`]: buttoned && isDisabled.value,
[`${common.prefixCls}-button-${mergedSize.value}`]: buttoned,
[`${prefixCls}-${size.value}`]: buttoned,
[`${commonPrefixCls}-button`]: buttoned,
[`${commonPrefixCls}-button-default`]: buttoned,
[`${commonPrefixCls}-button-disabled`]: buttoned && isDisabled.value,
[`${commonPrefixCls}-button-${buttonSizeMap[size.value]}`]: buttoned,
}
return normalizeClass([classes, attrs.class])
})
Expand Down
28 changes: 14 additions & 14 deletions packages/components/checkbox/style/index.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@import '../../style/mixins/reset.less';
@import './mixin.less';

.@{checkbox-prefix} {
&:not(.@{button-prefix}) {
Expand Down Expand Up @@ -27,7 +26,6 @@
&-input {
position: relative;
line-height: 1;
outline: none;
cursor: pointer;

&-inner {
Expand All @@ -46,6 +44,7 @@
display: block;
width: 16px;
height: 16px;
background-color: @checkbox-background-color;
border: 1px solid @checkbox-border-color;
border-radius: @checkbox-border-radius;
transition: all var(--ix-transition-duration-fast) var(--ix-ease-in-out);
Expand Down Expand Up @@ -76,6 +75,14 @@
}
}

&:hover &-input-box {
border-color: @checkbox-border-color-hover;
}

&-focused &-input-box {
border-color: @checkbox-border-color-focus;
}

&-checked {
.@{checkbox-prefix}-input {
&-box {
Expand All @@ -95,6 +102,7 @@

&.@{button-prefix} {
z-index: 2;
color: @checkbox-color-active;
border-color: @checkbox-color-active;
}
}
Expand All @@ -115,14 +123,6 @@
}
}

&:hover &-input-box {
border-color: @checkbox-border-color-hover;
}

&-focused &-input-box {
border-color: @checkbox-border-color-focus;
}

&&-disabled {
cursor: not-allowed;
color: @checkbox-color-disabled;
Expand All @@ -136,10 +136,10 @@
border-color: @checkbox-color-disabled;
}
}
}

&-tick {
border-top-color: @checkbox-color-disabled;
}
&.@{checkbox-prefix}-checked .@{checkbox-prefix}-input-tick {
border-top-color: @checkbox-color-disabled;
}

&.@{checkbox-prefix}-indeterminate .@{checkbox-prefix}-input-box {
Expand All @@ -150,7 +150,7 @@

&.@{button-prefix} {
z-index: 0;
border-color: @button-border-color;
border-color: @checkbox-border-color;
}
}

Expand Down
7 changes: 0 additions & 7 deletions packages/components/checkbox/style/mixin.less

This file was deleted.

1 change: 0 additions & 1 deletion packages/components/checkbox/style/themes/default.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@import '../../../style/themes/default.less';
@import '../../../button/style/themes/default.variable.less';
@import '../../../form/style/themes/default.variable.less';
@import './default.variable.less';

Expand Down
1 change: 0 additions & 1 deletion packages/components/checkbox/style/themes/seer.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@import '../../../style/themes/seer.less';
@import '../../../button/style/themes/seer.variable.less';
@import '../../../form/style/themes/seer.variable.less';
@import './seer.variable.less';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// Vitest Snapshot v1

exports[`RadioGroup > render work 1`] = `"<div class=\\"ix-radio-group\\"><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"a\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Beijing</span></label><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"b\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Shanghai</span></label><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"c\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Guangzhou</span></label><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"d\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Shenzhen</span></label></div>"`;
exports[`RadioGroup > render work 1`] = `
"<div class=\\"ix-space ix-radio-group\\" style=\\"margin-bottom: -8px;\\">
<div class=\\"ix-space-item\\" style=\\"margin-right: 8px; padding-bottom: 8px;\\"><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"a\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Beijing</span></label></div>
<div class=\\"ix-space-item\\" style=\\"margin-right: 8px; padding-bottom: 8px;\\"><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"b\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Shanghai</span></label></div>
<div class=\\"ix-space-item\\" style=\\"margin-right: 8px; padding-bottom: 8px;\\"><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"c\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Guangzhou</span></label></div>
<div class=\\"ix-space-item\\" style=\\"padding-bottom: 8px;\\"><label class=\\"ix-radio\\" role=\\"radio\\" aria-checked=\\"false\\" aria-disabled=\\"false\\"><span class=\\"ix-radio-input\\"><input type=\\"radio\\" class=\\"ix-radio-input-inner\\" aria-hidden=\\"true\\" value=\\"d\\"><span class=\\"ix-radio-input-box\\"></span></span><span class=\\"ix-radio-label\\">Shenzhen</span></label></div>
</div>"
`;
18 changes: 11 additions & 7 deletions packages/components/radio/__tests__/radio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ describe('Radio', () => {
test('buttoned work', async () => {
const wrapper = RadioMount({ props: { buttoned: true } })

expect(wrapper.classes()).toContain('ix-radio-button')
expect(wrapper.classes()).toContain('ix-button')

await wrapper.setProps({ buttoned: false })

expect(wrapper.classes()).not.toContain('ix-radio-button')
expect(wrapper.classes()).not.toContain('ix-button')
})

test('disabled work', async () => {
Expand Down Expand Up @@ -81,17 +81,21 @@ describe('Radio', () => {
})

test('mode work', async () => {
const wrapper = RadioMount({ props: { buttoned: true, mode: 'primary' } })
const wrapper = RadioMount({ props: { checked: true, buttoned: true, mode: 'primary' } })

expect(wrapper.classes()).toContain('ix-radio-primary')
expect(wrapper.classes()).toContain('ix-button-primary')

await wrapper.setProps({ mode: 'default' })

expect(wrapper.classes()).toContain('ix-radio-default')
expect(wrapper.classes()).toContain('ix-button-default')

await wrapper.setProps({ buttoned: false, mode: 'primary' })
await wrapper.setProps({ checked: false, mode: 'primary' })

expect(wrapper.classes()).not.toContain('ix-radio-primary')
expect(wrapper.classes()).not.toContain('ix-button-primary')

await wrapper.setProps({ buttoned: false })

expect(wrapper.classes()).not.toContain('ix-button-default')
})

test('size work', async () => {
Expand Down
22 changes: 6 additions & 16 deletions packages/components/radio/__tests__/radioGroup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ describe('RadioGroup', () => {
test('buttoned work', async () => {
const wrapper = RadioGroupMount({ props: { buttoned: true } })

expect(wrapper.findAll('.ix-radio-button').length).toBe(4)
expect(wrapper.findAll('.ix-button').length).toBe(4)

await wrapper.setProps({ buttoned: false })

expect(wrapper.findAll('.ix-radio-button').length).toBe(0)
expect(wrapper.findAll('.ix-button').length).toBe(0)
})

test('disabled work', async () => {
Expand All @@ -65,17 +65,6 @@ describe('RadioGroup', () => {
expect(wrapper.findAll('.ix-radio-disabled').length).toBe(0)
})

test('gap work', async () => {
const wrapper = RadioGroupMount()

expect(wrapper.classes()).not.toContain('ix-radio-group-with-gap')

await wrapper.setProps({ gap: 8 })

expect(wrapper.classes()).toContain('ix-radio-group-with-gap')
expect((wrapper.element as HTMLElement).style.gap).toEqual('8px')
})

test('name work', async () => {
const wrapper = RadioGroupMount({ props: { name: 'city' } })

Expand All @@ -87,13 +76,14 @@ describe('RadioGroup', () => {
})

test('mode work', async () => {
const wrapper = RadioGroupMount({ props: { mode: 'primary', buttoned: true } })
const wrapper = RadioGroupMount({ props: { value: 'a', mode: 'primary', buttoned: true } })

expect(wrapper.findAll('.ix-radio-primary').length).toBe(4)
expect(wrapper.findAll('.ix-button-primary').length).toBe(1)
expect(wrapper.findAll('.ix-button-default').length).toBe(3)

await wrapper.setProps({ mode: 'default' })

expect(wrapper.findAll('.ix-radio-default').length).toBe(4)
expect(wrapper.findAll('.ix-button-default').length).toBe(4)
})

test('dataSource work', async () => {
Expand Down
16 changes: 6 additions & 10 deletions packages/components/radio/demo/Disabled.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<template>
<IxRadio :disabled="disabled">A</IxRadio>
<IxRadio checked :disabled="disabled">B</IxRadio>
<IxButton @click="toggle">Toggle</IxButton>
<IxSpace align="center">
<IxRadio disabled>A</IxRadio>
<IxRadio :checked="true" disabled>B</IxRadio>
<IxRadio buttoned disabled>C</IxRadio>
<IxRadio :checked="true" buttoned disabled>D</IxRadio>
</IxSpace>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const disabled = ref(true)
const toggle = () => (disabled.value = !disabled.value)
</script>
5 changes: 3 additions & 2 deletions packages/components/radio/docs/Api.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@

#### RadioGroupProps

除以下表格之外还支持 `Space` 组件的[所有属性](/components/space/zh?tab=api#SpaceProps)

| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `control` | 控件控制器 | `string \| number \| AbstractControl` | - | - | 配合 `@idux/cdk/forms` 使用, 参考 [Form](/components/form/zh) |
| `v-model:value` | 当前选中的值 | `any` | - | - | 使用 `control` 时,此配置无效 |
| `buttoned` | 设置单选框组内 `IxRadio``buttoned` | `boolean` | - | - | - |
| `dataSource` | 以配置形式设置子元素 | `RadioData[]`| - | 优先级高于 `default` 插槽 | |
| `disabled` | 设置单选框组内 `IxRadio``disabled` | `boolean` | - | - | 使用 `control` 时,此配置无效 |
| `gap` | 设置单选框组内的 `IxRadio` 的间隔 | `number \| string` | - | - | - |
| `gap` | 设置单选框组内的 `IxRadio` 的间隔 | `number \| string` | - | - | 也就是 `Space``size`, 默认为 `8`, 为按钮组时默认为 `0` |
| `name` | 设置单选框组内的 `IxRadio` 的原生 `name` 属性 | `string` | - | - | - |
| `mode` | 设置单选框组内 `IxRadio``mode` | `'default' \| 'primary'`| - | - | - |
| `size` | 设置单选框组内 `IxRadio``size` | `'sm' \| 'md' \| 'lg'`| `'md'` | - | - |
| `vertical` | 设置组内排列方向 | `boolean` | - | - | 默认为水平排列方向,可设`true`为垂直排列 |
| `onChange` | 选中值发生变化后的回调 | `(value: any, oldValue: any) => void`| - | - | - |

```ts
Expand Down
1 change: 1 addition & 0 deletions packages/components/radio/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ category: components
type: 数据录入
title: Radio
subtitle: 单选框
theme: true
---

27 changes: 19 additions & 8 deletions packages/components/radio/src/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ import { useAccessorAndControl } from '@idux/cdk/forms'
import { callEmit } from '@idux/cdk/utils'
import { useGlobalConfig } from '@idux/components/config'
import { FORM_TOKEN, useFormElement, useFormItemRegister } from '@idux/components/form'
import { useKey } from '@idux/components/utils'
import { convertStringVNode, useKey } from '@idux/components/utils'

import { type RadioGroupContext, radioGroupToken } from './token'
import { type RadioProps, radioProps } from './types'

const buttonSizeMap = {
sm: 'xs',
md: 'sm',
lg: 'md',
}

export default defineComponent({
name: 'IxRadio',
inheritAttrs: false,
Expand Down Expand Up @@ -55,25 +61,30 @@ export default defineComponent({
)
const classes = computed(() => {
const buttoned = isButtoned.value
const checked = isChecked.value
const isPrimary = buttoned && checked && mode.value === 'primary'
const prefixCls = mergedPrefixCls.value
const commonPrefixCls = common.prefixCls
const classes = {
[prefixCls]: true,
[`${prefixCls}-button`]: buttoned,
[`${prefixCls}-checked`]: isChecked.value,
[`${prefixCls}-disabled`]: isDisabled.value,
[`${prefixCls}-focused`]: isFocused.value,
[`${prefixCls}-${mode.value}`]: buttoned,
[`${prefixCls}-${size.value}`]: buttoned,
[`${commonPrefixCls}-button`]: buttoned,
[`${commonPrefixCls}-button-default`]: buttoned && !isPrimary,
[`${commonPrefixCls}-button-primary`]: isPrimary,
[`${commonPrefixCls}-button-disabled`]: buttoned && isDisabled.value,
[`${commonPrefixCls}-button-${buttonSizeMap[size.value]}`]: buttoned,
}
return normalizeClass([classes, attrs.class])
})

return () => {
const prefixCls = mergedPrefixCls.value
const { autofocus, label } = props
const labelNode = slots.default?.() ?? label
const labelWrapper = labelNode && <span class={`${prefixCls}-label`}>{labelNode}</span>
const { class: className, style, type, tabindex, ...restAttrs } = attrs
const prefixCls = mergedPrefixCls.value
const labelNode = convertStringVNode(slots.default, label)
return (
<label
class={classes.value}
Expand All @@ -98,9 +109,9 @@ export default defineComponent({
onFocus={handleFocus}
{...restAttrs}
/>
{isButtoned.value ? null : <span class={`${prefixCls}-input-box`} tabindex={tabindex as number}></span>}
{!isButtoned.value && <span class={`${prefixCls}-input-box`} tabindex={tabindex as number} />}
</span>
{labelWrapper}
{labelNode && <span class={`${prefixCls}-label`}>{labelNode}</span>}
</label>
)
}
Expand Down

0 comments on commit e438cb3

Please sign in to comment.