mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [button-group]: add direction prop (#18906)
* feat(components): [button-group]:add vertical direction for button group * feat(components): [button-group]: add direction prop (update) * feat(components): [button-group]: fix docs * feat(components): [button-group]: update version * Update docs/en-US/component/button.md Co-authored-by: btea <2356281422@qq.com> * Update docs/en-US/component/button.md * chore: format * docs: improve sentence * docs: improve display example * refactor: enhance prop type - fit with segmented direction prop - enhance type according with https://github.com/element-plus/element-plus/pull/22757 --------- Co-authored-by: btea <2356281422@qq.com> Co-authored-by: Dsaquel <291874700n@gmail.com>
This commit is contained in:
@@ -75,6 +75,8 @@ button/icon
|
||||
|
||||
Displayed as a button group, can be used to group a series of similar operations.
|
||||
|
||||
In ^(2.11.9) you can use the `direction` attribute.
|
||||
|
||||
:::demo Use tag `<el-button-group>` to group your buttons.
|
||||
|
||||
button/group
|
||||
@@ -180,10 +182,11 @@ button/custom
|
||||
|
||||
### ButtonGroup Attributes
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ---- | ------------------------------------------------ | ------------------------------------------------------------------ | ------- |
|
||||
| size | control the size of buttons in this button-group | ^[enum]`'large' \| 'default' \| 'small'` | — |
|
||||
| type | control the type of buttons in this button-group | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — |
|
||||
| Name | Description | Type | Default |
|
||||
| ------------------- | ------------------------------------------------ | ------------------------------------------------------------------ | ---------- |
|
||||
| size | control the size of buttons in this button-group | ^[enum]`'large' \| 'default' \| 'small'` | — |
|
||||
| type | control the type of buttons in this button-group | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — |
|
||||
| direction ^(2.11.9) | display direction | ^[enum]`'horizontal' \| 'vertical'` | horizontal |
|
||||
|
||||
### ButtonGroup Slots
|
||||
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
<template>
|
||||
<el-button-group>
|
||||
<el-button-group class="mb-4">
|
||||
<el-button type="primary" :icon="ArrowLeft">Previous Page</el-button>
|
||||
<el-button type="primary">
|
||||
Next Page<el-icon class="el-icon--right"><ArrowRight /></el-icon>
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<br />
|
||||
<el-radio-group v-model="direction" class="mb-2">
|
||||
<el-radio value="horizontal">Horizontal</el-radio>
|
||||
<el-radio value="vertical">Vertical</el-radio>
|
||||
</el-radio-group>
|
||||
<br />
|
||||
|
||||
<el-button-group class="ml-4">
|
||||
<el-button type="primary" :icon="Edit" />
|
||||
<el-button type="primary" :icon="Share" />
|
||||
<el-button type="primary" :icon="Delete" />
|
||||
<el-button-group :direction="direction">
|
||||
<el-button type="primary" :icon="House" />
|
||||
<el-button type="primary" :icon="Operation" />
|
||||
<el-button type="primary" :icon="Notification" />
|
||||
</el-button-group>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import {
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
Delete,
|
||||
Edit,
|
||||
Share,
|
||||
House,
|
||||
Notification,
|
||||
Operation,
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
const direction = ref<'horizontal' | 'vertical'>('horizontal')
|
||||
</script>
|
||||
|
||||
@@ -3,12 +3,14 @@ import { mount } from '@vue/test-utils'
|
||||
import { describe, expect, it, test } from 'vitest'
|
||||
import { Loading, Search } from '@element-plus/icons-vue'
|
||||
import Form from '@element-plus/components/form'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import Button from '../src/button.vue'
|
||||
import ButtonGroup from '../src/button-group.vue'
|
||||
|
||||
import type { ComponentSize } from '@element-plus/constants'
|
||||
|
||||
const AXIOM = 'Rem is the best girl'
|
||||
const ns = useNamespace('button')
|
||||
|
||||
describe('Button.vue', () => {
|
||||
it('create', () => {
|
||||
@@ -323,4 +325,23 @@ describe('Button Group', () => {
|
||||
await btn.trigger('click')
|
||||
expect(wrapper.emitted('click')).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('direction prop', async () => {
|
||||
const wrapper = mount({
|
||||
setup: () => () => (
|
||||
<ButtonGroup type="warning">
|
||||
<Button type="primary">Prev</Button>
|
||||
<Button>Next</Button>
|
||||
</ButtonGroup>
|
||||
),
|
||||
})
|
||||
|
||||
expect(wrapper.classes()).toContain(ns.bm('group', 'horizontal'))
|
||||
expect(wrapper.classes()).not.toContain(ns.bm('group', 'vertical'))
|
||||
|
||||
await wrapper.setProps({ direction: 'vertical' })
|
||||
|
||||
expect(wrapper.classes()).toContain(ns.bm('group', 'vertical'))
|
||||
expect(wrapper.classes()).not.toContain(ns.bm('group', 'horizontal'))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { definePropType } from '@element-plus/utils'
|
||||
import { buttonProps } from './button'
|
||||
|
||||
import type { ExtractPropTypes, __ExtractPublicPropTypes } from 'vue'
|
||||
@@ -11,6 +12,14 @@ export const buttonGroupProps = {
|
||||
* @description control the type of buttons in this button-group
|
||||
*/
|
||||
type: buttonProps.type,
|
||||
/**
|
||||
* @description display direction
|
||||
*/
|
||||
direction: {
|
||||
type: definePropType<'horizontal' | 'vertical'>(String),
|
||||
values: ['horizontal', 'vertical'],
|
||||
default: 'horizontal',
|
||||
},
|
||||
} as const
|
||||
export type ButtonGroupProps = ExtractPropTypes<typeof buttonGroupProps>
|
||||
export type ButtonGroupPropsPublic = __ExtractPublicPropTypes<
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="ns.b('group')">
|
||||
<div :class="[ns.b('group'), ns.bm('group', props.direction)]">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -5,24 +5,11 @@
|
||||
@use 'mixins/utils' as *;
|
||||
|
||||
@include b(button-group) {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@include utils-clearfix;
|
||||
|
||||
& > .#{$namespace}-button {
|
||||
float: left;
|
||||
position: relative;
|
||||
& + .#{$namespace}-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
&:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&:first-child:last-child {
|
||||
border-top-right-radius: map.get($button-border-radius, 'default');
|
||||
border-bottom-right-radius: map.get($button-border-radius, 'default');
|
||||
@@ -37,12 +24,10 @@
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-radius: 0;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
@@ -55,25 +40,93 @@
|
||||
}
|
||||
}
|
||||
|
||||
& > .#{$namespace}-dropdown {
|
||||
@include m('horizontal') {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@include utils-clearfix;
|
||||
|
||||
& > .#{$namespace}-button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
float: left;
|
||||
position: relative;
|
||||
|
||||
&:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
@each $type in (primary, success, warning, danger, info) {
|
||||
.#{$namespace}-button--#{$type} {
|
||||
&:first-child {
|
||||
border-right-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
&:last-child {
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
border-right-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .#{$namespace}-dropdown {
|
||||
& > .#{$namespace}-button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $type in (primary, success, warning, danger, info) {
|
||||
.#{$namespace}-button--#{$type} {
|
||||
@include m('vertical') {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
||||
& > .#{$namespace}-button {
|
||||
margin-top: -1px;
|
||||
|
||||
&:first-child {
|
||||
border-right-color: getCssVar('button', 'divide-border-color');
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
& > .#{$namespace}-dropdown {
|
||||
margin-top: -1px;
|
||||
|
||||
& > .#{$namespace}-button {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-left-color: getCssVar('button', 'divide-border-color');
|
||||
border-right-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
|
||||
@each $type in (primary, success, warning, danger, info) {
|
||||
.#{$namespace}-button--#{$type} {
|
||||
&:first-child {
|
||||
border-bottom-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
&:last-child {
|
||||
border-top-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
&:not(:first-child):not(:last-child) {
|
||||
border-top-color: getCssVar('button', 'divide-border-color');
|
||||
border-bottom-color: getCssVar('button', 'divide-border-color');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user