Skip to content

Commit

Permalink
feat(comp:button): the ButtonGroup extends Space (#1279)
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm committed Nov 16, 2022
1 parent 4d5e770 commit 46e65b1
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// Vitest Snapshot v1

exports[`ButtonGroup > render work 1`] = `"<div class=\\"ix-button-group\\"><button class=\\"ix-button ix-button-default ix-button-md\\" type=\\"button\\"><span>default</span></button><button class=\\"ix-button ix-button-primary ix-button-md\\" type=\\"button\\"><span>primary</span></button><button class=\\"ix-button ix-button-default ix-button-lg\\" type=\\"button\\"><span>large</span></button><button class=\\"ix-button ix-button-default ix-button-circle ix-button-md\\" type=\\"button\\"><span>circle</span></button></div>"`;
exports[`ButtonGroup > render work 1`] = `
"<div class=\\"ix-space ix-button-group\\" style=\\"margin-bottom: -0px;\\">
<div class=\\"ix-space-item\\" style=\\"margin-right: 0px; padding-bottom: 0px;\\"><button class=\\"ix-button ix-button-default ix-button-md\\" type=\\"button\\"><span>default</span></button></div>
<div class=\\"ix-space-item\\" style=\\"margin-right: 0px; padding-bottom: 0px;\\"><button class=\\"ix-button ix-button-primary ix-button-md\\" type=\\"button\\"><span>primary</span></button></div>
<div class=\\"ix-space-item\\" style=\\"margin-right: 0px; padding-bottom: 0px;\\"><button class=\\"ix-button ix-button-default ix-button-lg\\" type=\\"button\\"><span>large</span></button></div>
<div class=\\"ix-space-item\\" style=\\"padding-bottom: 0px;\\"><button class=\\"ix-button ix-button-default ix-button-circle ix-button-md\\" type=\\"button\\"><span>circle</span></button></div>
</div>"
`;
60 changes: 39 additions & 21 deletions packages/components/button/__tests__/buttonGroup.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
import { mount } from '@vue/test-utils'
import { MountingOptions, mount } from '@vue/test-utils'
import { h } from 'vue'

import { renderWork } from '@tests'

import Button from '../src/Button'
import ButtonGroup from '../src/ButtonGroup'
import { ButtonGroupProps } from '../src/types'

const TestComponent = {
components: { ButtonGroup, Button },
template: `
<ButtonGroup :mode="mode" :size="size" :shape="shape">
<Button>default</Button>
<Button mode="primary">primary</Button>
<Button size="lg">large</Button>
<Button shape="circle">circle</Button>
</ButtonGroup>
`,
props: {
mode: String,
size: String,
shape: String,
},
}
const defaultSlot = () => [
h(Button, null, () => 'default'),
h(Button, { mode: 'primary' }, () => 'primary'),
h(Button, { size: 'lg' }, () => 'large'),
h(Button, { shape: 'circle' }, () => 'circle'),
]

describe('ButtonGroup', () => {
renderWork(TestComponent)
const ButtonGroupMount = (options?: MountingOptions<Partial<ButtonGroupProps>>) => {
const { slots, ...rest } = options || {}
return mount(ButtonGroup, {
...rest,
slots: { default: defaultSlot, ...slots },
})
}

renderWork(ButtonGroup, { slots: { default: defaultSlot } })

test('gap work', async () => {
const wrapper = ButtonGroupMount({ props: { gap: 12 } })

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

await wrapper.setProps({ gap: 0 })

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

await wrapper.setProps({ gap: '0' })

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

await wrapper.setProps({ gap: '' })

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

test('mode work', async () => {
const wrapper = mount(TestComponent)
const wrapper = ButtonGroupMount()

expect(wrapper.findAll('.ix-button-primary').length).toBe(1)
expect(wrapper.findAll('.ix-button-dashed').length).toBe(0)
Expand All @@ -38,7 +56,7 @@ describe('ButtonGroup', () => {
})

test('size work', async () => {
const wrapper = mount(TestComponent)
const wrapper = ButtonGroupMount()

expect(wrapper.findAll('.ix-button-lg').length).toBe(1)
expect(wrapper.findAll('.ix-button-md').length).toBe(3)
Expand All @@ -50,7 +68,7 @@ describe('ButtonGroup', () => {
})

test('shape work', async () => {
const wrapper = mount(TestComponent)
const wrapper = ButtonGroupMount()

expect(wrapper.findAll('.ix-button-circle').length).toBe(1)
expect(wrapper.findAll('.ix-button-round').length).toBe(0)
Expand Down
4 changes: 3 additions & 1 deletion packages/components/button/docs/Api.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@

#### ButtonGroupProps

> 除以下表格之外还支持原生 `Space` 组件的[所有属性](/components/space/zh?tab=api#SpaceProps)
| 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 |
| --- | --- | --- | --- | --- | --- |
| `gap` | 设置按钮组的 gap 配置 | `number \| string` | - | - | 兼容性问题参见: [Can I use](https://caniuse.com/flexbox-gap) |
| `gap` | 设置按钮组的 gap 配置 | `number \| string` | `0` | - | 也就是 `Space``size` |
| `mode` | 设置组内按钮种类 | `'primary' \| 'default' \| 'dashed' \| 'text' \| 'link'` | - | - |- |
| `shape` | 设置组内按钮形状 | `'circle' \| 'round'` | - | - |- |
| `size` | 设置组内按钮大小 | `'lg' \| 'md' \| 'sm'` | - | - |- |
13 changes: 4 additions & 9 deletions packages/components/button/src/ButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import { computed, defineComponent, normalizeClass, provide } from 'vue'

import { convertCssPixel } from '@idux/cdk/utils'
import { useGlobalConfig } from '@idux/components/config'
import { IxSpace } from '@idux/components/space'

import { buttonToken } from './token'
import { buttonGroupProps } from './types'
Expand All @@ -25,21 +25,16 @@ export default defineComponent({
const prefixCls = mergedPrefixCls.value
return normalizeClass({
[prefixCls]: true,
[`${prefixCls}-with-gap`]: !!gap,
[`${prefixCls}-with-gap`]: !!gap && gap !== '0',
})
})

const style = computed(() => {
const { gap } = props
return gap ? `gap: ${convertCssPixel(gap)};` : undefined
})

provide(buttonToken, props)

return () => (
<div class={classes.value} style={style.value}>
<IxSpace class={classes.value} size={props.gap}>
{slots.default && slots.default()}
</div>
</IxSpace>
)
},
})
5 changes: 3 additions & 2 deletions packages/components/button/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import type { ExtractInnerPropTypes, ExtractPublicPropTypes } from '@idux/cdk/utils'
import type { SpaceProps } from '@idux/components/space'
import type { AnchorHTMLAttributes, ButtonHTMLAttributes, DefineComponent, HTMLAttributes, PropType } from 'vue'

export type ButtonMode = 'primary' | 'default' | 'dashed' | 'text' | 'link'
Expand Down Expand Up @@ -36,14 +37,14 @@ export type ButtonComponent = DefineComponent<
export type ButtonInstance = InstanceType<DefineComponent<ButtonProps>>

export const buttonGroupProps = {
gap: { type: [Number, String] as PropType<number | string>, default: undefined },
gap: { type: [Number, String] as PropType<number | string>, default: 0 },
mode: String as PropType<ButtonMode>,
size: String as PropType<ButtonSize>,
shape: String as PropType<ButtonShape>,
} as const

export type ButtonGroupProps = ExtractInnerPropTypes<typeof buttonGroupProps>
export type ButtonGroupPublicProps = ExtractPublicPropTypes<typeof buttonGroupProps>
export type ButtonGroupPublicProps = ExtractPublicPropTypes<typeof buttonGroupProps> & SpaceProps
export type ButtonGroupComponent = DefineComponent<
Omit<HTMLAttributes, keyof ButtonGroupPublicProps> & ButtonGroupPublicProps
>
Expand Down
4 changes: 3 additions & 1 deletion packages/components/button/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,10 @@
&:not(&-with-gap) {
.@{button-prefix} {
border-radius: 0;
}

&:not(:first-child) {
.@{space-prefix}-item:not(:first-child) {
.@{button-prefix} {
margin-left: -1px;
}
}
Expand Down
3 changes: 1 addition & 2 deletions packages/site/plugins/themePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ export const themePlugin = (options?: Options): Plugin => {

const changeRuntimeTheme = async (theme: string): Promise<void> => {
const lessFilePath = path.join(srcPath, 'styles/themes', 'index.less')
const themeContent = (await readFile(lessFilePath)).toString()
return writeFile(lessFilePath, themeContent.replace(/\/.*?.less/, `/${theme}.less`))
return writeFile(lessFilePath, `@import './${theme}.less';`)
}

return {
Expand Down
2 changes: 0 additions & 2 deletions packages/site/src/styles/themes/index.less

This file was deleted.

0 comments on commit 46e65b1

Please sign in to comment.