Skip to content

Commit 59eb0cb

Browse files
committed
feat(button): 补充button loading 状态和按钮组button-group(changelog-needed)
affects: @ued-plus/components ISSUES CLOSED: none
1 parent 9a93167 commit 59eb0cb

File tree

19 files changed

+517
-25
lines changed

19 files changed

+517
-25
lines changed

.stylelintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ module.exports = {
2121
'alpha-value-notation': null,
2222
'color-hex-length': null,
2323
'value-keyword-case': null,
24+
'selector-not-notation': null,
2425
},
2526
}

packages/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { App } from 'vue'
22
import * as components from './src/index'
3+
// 引入全局样式变量
4+
import '../theme/common/var.scss'
35
// 引入初始化css文件
46
import '../theme/initialize/init.scss'
57
export * from './src/index'
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<div class="ued-button-group">
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script lang="ts" setup>
8+
import { provide } from 'vue'
9+
import './styles/button-group.scss'
10+
11+
defineOptions({ name: 'UedButtonGroup' })
12+
13+
type ButtonGroupProps = {
14+
type?: string
15+
size?: string
16+
}
17+
18+
const buttonGroupProps = defineProps<ButtonGroupProps>()
19+
20+
buttonGroupProps.type && provide('type', buttonGroupProps.type)
21+
buttonGroupProps.size && provide('size', buttonGroupProps.size)
22+
</script>

packages/components/src/button/button.vue

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,30 @@
22
<template>
33
<component
44
:is="buttonTag"
5+
ref="buttonRef"
56
:class="buttonStyle"
67
:disabled="disabled"
78
class="ued-button"
89
>
9-
<ued-icon v-if="icon">
10-
<component :is="icon" />
10+
<ued-icon v-if="icon || $slots.icon" :class="loadingStyle">
11+
<component :is="icon" v-if="icon" />
12+
<slot v-else name="icon" />
1113
</ued-icon>
12-
<slot />
14+
<span v-if="$slots.default">
15+
<slot />
16+
</span>
1317
</component>
1418
</template>
1519

1620
<script lang="ts" setup>
1721
import { UedIcon } from '../icon'
18-
import { computed, ComponentCustomProps } from 'vue'
22+
import { Loading } from '../icon/icon'
23+
import { computed, ComponentCustomProps, useSlots, ref, inject } from 'vue'
1924
import './styles/index.scss'
2025
26+
const buttonType = inject('type', undefined)
27+
const buttonSize = inject('size', undefined)
28+
2129
defineOptions({ name: 'UedButton' })
2230
2331
type ButtonProps = {
@@ -32,25 +40,59 @@ type ButtonProps = {
3240
size?: string
3341
tag?: string
3442
icon?: ComponentCustomProps
43+
loading?: boolean
44+
loadingIcon?: ComponentCustomProps
3545
}
3646
3747
const buttonProps = defineProps<ButtonProps>()
3848
49+
const $slots = useSlots()
50+
51+
const buttonRef = ref()
52+
3953
const buttonStyle = computed(() => {
4054
return {
41-
[`ued-button--${buttonProps.type}`]: buttonProps.type,
42-
[`ued-button--${buttonProps.size}`]: buttonProps.size,
55+
[`ued-button--${buttonType ?? buttonProps.type}`]:
56+
buttonType ?? buttonProps.type,
57+
[`ued-button--${buttonSize ?? buttonProps.size}`]:
58+
buttonSize ?? buttonProps.size,
4359
'is-plain': buttonProps.plain,
4460
'is-round': buttonProps.round,
4561
'is-circle': buttonProps.circle,
46-
'is-disabled': buttonProps.disabled,
62+
'is-disabled': buttonProps.disabled || buttonProps.loading,
4763
'is-link': buttonProps.link,
4864
'is-text': buttonProps.text,
4965
'is-has-bg': buttonProps.bg,
66+
'is-loading': buttonProps.loading,
67+
}
68+
})
69+
70+
const loadingStyle = computed(() => {
71+
return {
72+
'is-loading': buttonProps.loading,
5073
}
5174
})
5275
5376
const buttonTag = computed(() => {
5477
return buttonProps.tag ?? 'button'
5578
})
79+
80+
const icon = computed(() => {
81+
return buttonProps.loading
82+
? $slots.icon
83+
? undefined
84+
: buttonProps.loadingIcon ?? Loading
85+
: buttonProps.icon
86+
})
87+
88+
defineExpose({
89+
/** @description button html element */
90+
ref: buttonRef,
91+
/** @description button type */
92+
type: buttonProps.type,
93+
/** @description button disabled */
94+
disabled: buttonProps.disabled,
95+
/** @description button size */
96+
size: buttonProps.size,
97+
})
5698
</script>
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import _Button from './button.vue'
2+
import _ButtonGroup from './button-group.vue'
23
import withInstall from '../../script/utils/install'
34
export const UedButton = withInstall(_Button)
4-
export default UedButton
5+
export const UedButtonGroup = withInstall(_ButtonGroup)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
.ued-button-group {
2+
--el-button-divide-border-color: rgba(255, 255, 255, 0.5);
3+
4+
display: inline-flex;
5+
vertical-align: middle;
6+
7+
& + & {
8+
margin-left: 12px;
9+
}
10+
11+
& > .ued-button {
12+
margin: 0;
13+
}
14+
15+
& > .ued-button:first-child:last-child.is-round {
16+
border-radius: var(--ued-border-radius-round);
17+
}
18+
19+
& > .ued-button:first-child:last-child.is-circle {
20+
border-radius: 50%;
21+
}
22+
23+
& > .ued-button:first-child {
24+
border-top-right-radius: 0;
25+
border-bottom-right-radius: 0;
26+
}
27+
28+
& > .ued-button:last-child {
29+
border-top-left-radius: 0;
30+
border-bottom-left-radius: 0;
31+
}
32+
33+
& > .ued-button:not(:last-child) {
34+
margin-right: -1px;
35+
}
36+
37+
& > .ued-button:hover,
38+
& > .ued-button:focus,
39+
& > .ued-button:active {
40+
z-index: 1;
41+
}
42+
43+
& > .ued-button:not(:first-child):not(:last-child) {
44+
border-radius: 0;
45+
}
46+
47+
& > .ued-button.is-active {
48+
z-index: 1;
49+
}
50+
51+
& .ued-button--primary:first-child {
52+
border-right-color: var(--ued-button-divide-border-color);
53+
}
54+
55+
& .ued-button--primary:last-child {
56+
border-left-color: var(--ued-button-divide-border-color);
57+
}
58+
59+
& .ued-button--primary:not(:first-child):not(:last-child) {
60+
border-right-color: var(--ued-button-divide-border-color);
61+
border-left-color: var(--ued-button-divide-border-color);
62+
}
63+
64+
& .ued-button--success:first-child {
65+
border-right-color: var(--ued-button-divide-border-color);
66+
}
67+
68+
& .ued-button--success:last-child {
69+
border-left-color: var(--ued-button-divide-border-color);
70+
}
71+
72+
& .ued-button--success:not(:first-child):not(:last-child) {
73+
border-right-color: var(--ued-button-divide-border-color);
74+
border-left-color: var(--ued-button-divide-border-color);
75+
}
76+
77+
& .ued-button--warning:first-child {
78+
border-right-color: var(--ued-button-divide-border-color);
79+
}
80+
81+
& .ued-button--warning:last-child {
82+
border-left-color: var(--ued-button-divide-border-color);
83+
}
84+
85+
& .ued-button--warning:not(:first-child):not(:last-child) {
86+
border-right-color: var(--ued-button-divide-border-color);
87+
border-left-color: var(--ued-button-divide-border-color);
88+
}
89+
90+
& .ued-button--danger:first-child {
91+
border-right-color: var(--ued-button-divide-border-color);
92+
}
93+
94+
& .ued-button--danger:last-child {
95+
border-left-color: var(--ued-button-divide-border-color);
96+
}
97+
98+
& .ued-button--danger:not(:first-child):not(:last-child) {
99+
border-right-color: var(--ued-button-divide-border-color);
100+
border-left-color: var(--ued-button-divide-border-color);
101+
}
102+
103+
& .ued-button--info:first-child {
104+
border-right-color: var(--ued-button-divide-border-color);
105+
}
106+
107+
& .ued-button--info:last-child {
108+
border-left-color: var(--ued-button-divide-border-color);
109+
}
110+
111+
& .ued-button--info:not(:first-child):not(:last-child) {
112+
border-right-color: var(--ued-button-divide-border-color);
113+
border-left-color: var(--ued-button-divide-border-color);
114+
}
115+
}

packages/components/src/button/styles/index.scss

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
@import url('../../../../theme/common/var.scss');
2-
31
.ued-button {
42
box-sizing: border-box;
53
display: inline-flex;
64
height: 32px;
75
padding: 8px 15px;
8-
margin: 0 0 0 12px;
96
font-size: var(--ued-font-size-base);
107
font-weight: var(--ued-font-weight-primary);
118
line-height: 1;
@@ -19,6 +16,14 @@
1916
outline: none;
2017
transition: 0.1s;
2118

19+
& + & {
20+
margin-left: 12px;
21+
}
22+
23+
& > span {
24+
display: inline-flex;
25+
}
26+
2227
&:first-child {
2328
margin: 0;
2429
}
@@ -348,4 +353,14 @@
348353
padding: 5px 11px;
349354
font-size: var(--ued-font-size-extra-small);
350355
}
356+
// icon
357+
& > [class*='ued-icon'] + span {
358+
margin-left: 6px;
359+
}
360+
361+
// loading
362+
&.is-loading {
363+
position: relative;
364+
pointer-events: none;
365+
}
351366
}

packages/components/src/components.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import * as components from './index'
22
declare module '@vue/runtime-core' {
33
// 组件全局提示效果
44
export interface GlobalComponents {
5-
UedButton: typeof components.Button
5+
UedButton: typeof components.UedButton
6+
UedButtonGroup: typeof components.UedButtonGroup
7+
UedIcon: typeof components.UedIcon
68
}
79
}
810
export {}

0 commit comments

Comments
 (0)