xt-element-ui 1.0.8 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/index.common.js +715 -396
  2. package/lib/index.css +1 -1
  3. package/lib/index.umd.js +715 -396
  4. package/lib/index.umd.min.js +1 -1
  5. package/package.json +2 -2
  6. package/src/components/button/index.vue +54 -15
  7. package/src/components/button/style/index copy.scss +221 -0
  8. package/src/components/button/style/index.scss +136 -0
  9. package/src/components/card/index.vue +20 -41
  10. package/src/components/card/style/index.scss +49 -0
  11. package/src/components/card-item/index.vue +71 -90
  12. package/src/components/card-item/style/index.scss +72 -0
  13. package/src/components/config-provider/index.js +2 -0
  14. package/src/components/config-provider/index.vue +193 -0
  15. package/src/components/config-provider/style/index.scss +12 -0
  16. package/src/components/flex-box/index.vue +20 -90
  17. package/src/components/flex-box/style/index.scss +91 -0
  18. package/src/components/index.scss +22 -0
  19. package/src/components/input/index.vue +28 -11
  20. package/src/components/input/style/index.scss +27 -0
  21. package/src/components/text/index.js +2 -0
  22. package/src/components/text/index.vue +42 -0
  23. package/src/components/text/style/index.scss +45 -0
  24. package/src/index.js +69 -123
  25. package/src/styles/{theme.scss → css-variables.scss} +72 -31
  26. package/src/styles/{theme-element.scss → element-theme.scss} +0 -10
  27. package/src/styles/theme/background.scss +6 -0
  28. package/src/styles/theme/border-radius.scss +4 -0
  29. package/src/styles/theme/borders.scss +4 -0
  30. package/src/styles/theme/colors.scss +11 -0
  31. package/src/styles/theme/component-variables.scss +70 -0
  32. package/src/styles/theme/dark-variables.scss +29 -0
  33. package/src/styles/theme/font.scss +10 -0
  34. package/src/styles/theme/index.scss +11 -0
  35. package/src/styles/theme/shadows.scss +3 -0
  36. package/src/styles/theme/spacing.scss +5 -0
  37. package/src/styles/theme/transitions.scss +3 -0
  38. package/src/styles/theme/typography.scss +5 -0
  39. package/src/styles/{export.scss → variables-export.scss} +1 -1
  40. package/src/styles/variables.scss +1 -126
  41. package/src/utils/index.js +193 -124
@@ -1,112 +1,93 @@
1
1
  <template>
2
- <FlexBox v-if="iconType=='border'" class="xt-card-item is-border" :class="[iconType=='border'?`is-${type}`:'']" content="between">
3
- <span class="item_label" v-if="title">
4
- <slot name="label">{{label }}</slot>
5
- </span>
6
- <span class="item-value">
7
- <slot name="value">{{value }}</slot>
8
- </span>
9
- <span class="item_unit">
10
- <slot name="unit">{{ unit }}</slot>
11
- </span>
12
- </FlexBox>
13
- <FlexBox v-else class="xt-card-item" :direction="direction" :content="contentAlign">
14
- <slot name="icon">
15
- <el-button :type="type" :circle="circle" :round="round" plain :icon="icon"></el-button>
16
- </slot>
17
- <div class="item-value">
18
- <span class="value">
19
- <slot name="value">{{ label }}</slot>
2
+ <FlexBox
3
+ v-if="iconType=='border'"
4
+ class="xt-card-item is-border"
5
+ :class="[iconType=='border'?`is-${type}`:'']"
6
+ :style="cardItemStyle"
7
+ content="between"
8
+ >
9
+ <span class="item__label" v-if="title">
10
+ <slot name="label">{{ label }}</slot>
20
11
  </span>
21
- <div class="unit">{{ value }}</div>
22
- </div>
23
-
24
- </FlexBox>
12
+ <span class="item__value">
13
+ <slot name="value">{{ value }}</slot>
14
+ </span>
15
+ <span class="item__unit">
16
+ <slot name="unit">{{ unit }}</slot>
17
+ </span>
18
+ </FlexBox>
19
+ <FlexBox
20
+ v-else
21
+ class="xt-card-item"
22
+ :direction="direction"
23
+ :content="contentAlign"
24
+ >
25
+ <slot name="icon">
26
+ <el-button :type="type" :circle="circle" :round="round" plain :icon="icon"></el-button>
27
+ </slot>
28
+ <div class="item__value">
29
+ <span class="value" :style="valueStyle">
30
+ <slot name="value">{{ label }}</slot>
31
+ </span>
32
+ <div class="unit">{{ value }}</div>
33
+ </div>
34
+ </FlexBox>
25
35
  </template>
26
36
  <script>
27
37
  import FlexBox from '../flex-box/index.vue'
28
38
  export default {
29
- name:"XtCardItem",
30
- components:{
39
+ name: "XtCardItem",
40
+ components: {
31
41
  FlexBox
32
42
  },
33
- props:{
34
- iconType:{default:"border"},
35
- type:{default:"primary"},
36
- label:{},
37
- value:{},
38
- unit:{},
39
- icon:{},
40
- iconAt:{default:"right"}
43
+ props: {
44
+ iconType: { default: "border" },
45
+ type: { default: "primary" },
46
+ label: {},
47
+ value: {},
48
+ unit: {},
49
+ icon: {},
50
+ iconAt: { default: "right" },
51
+ color: {
52
+ type: String,
53
+ default: ''
54
+ }
41
55
  },
42
- data(){
43
- return{
56
+ data() {
57
+ return {
44
58
  circle: false,
45
59
  round: false
46
60
  }
47
61
  },
48
- computed:{
49
- contentAlign(){
50
- return this.iconAt=='center'?'center':'start'
62
+ computed: {
63
+ contentAlign() {
64
+ return this.iconAt == 'center' ? 'center' : 'start'
51
65
  },
52
- direction(){
66
+ direction() {
53
67
  const iconAtMap = {
54
- left:'row',
55
- right:'row-reverse',
56
- top:'column',
57
- bottom:'column-reverse'
68
+ left: 'row',
69
+ right: 'row-reverse',
70
+ top: 'column',
71
+ bottom: 'column-reverse'
58
72
  }
59
73
  return iconAtMap[this.iconAt]
60
- }
61
- }
62
- }
63
- </script>
64
- <style lang="scss" scoped>
65
- .xt-card-item{
66
- min-height: 40px;
67
- + .xt-card-item{
68
- margin-top: 10px;
69
- }
70
- &.is-border{
71
- border-right: 3px solid transparent;
72
- background-color: #f5f7fa;
73
- &.is-primary{
74
- border-right-color: $xt-color-primary;
75
- .item-value .value{
76
- color: $xt-color-primary;
77
- }
78
- }
79
- &.is-success{
80
- border-right-color: #67c23a;
81
- .item-value .value{
82
- color: #67c23a;
83
- }
84
- }
85
- &.is-warning{
86
- border-right-color: #e6a23c;
87
- .item-value .value{
88
- color: #e6a23c;
74
+ },
75
+ cardItemStyle() {
76
+ if (this.iconType === 'border' && this.type === 'primary' && this.color) {
77
+ return {
78
+ '--xt-card-item-color': this.color
79
+ }
89
80
  }
90
- }
91
- &.is-danger{
92
- border-right-color: #f56c6c;
93
- .item-value .value{
94
- color: #f56c6c;
81
+ return {}
82
+ },
83
+ valueStyle() {
84
+ if (this.iconType !== 'border' && this.type === 'primary' && this.color) {
85
+ return {
86
+ color: this.color
87
+ }
95
88
  }
89
+ return {}
96
90
  }
97
91
  }
98
- .item-value{
99
- padding-right: 10px;
100
- .value{
101
- font-weight: 600;
102
- font-size: $xt-font-size-base;
103
- }
104
- }
105
- .item_label{
106
- padding-left: 10px;
107
- }
108
- .item_unit{
109
- padding-left: 5px;
110
- }
111
92
  }
112
- </style>
93
+ </script>
@@ -0,0 +1,72 @@
1
+ @import '../../../styles/variables.scss';
2
+
3
+ .xt-card-item {
4
+ --xt-card-item-color: var(--xt-color-primary, #1890ff);
5
+
6
+ min-height: var(--xt-card-item-min-height, 40px);
7
+ }
8
+
9
+ .xt-card-item + .xt-card-item {
10
+ margin-top: var(--xt-card-item-gap, 10px);
11
+ }
12
+
13
+ .xt-card-item.is-border {
14
+ border-right: var(--xt-card-item-border-width, 3px) solid transparent;
15
+ background-color: var(--xt-color-bg-secondary, #f5f7fa);
16
+ }
17
+
18
+ .xt-card-item.is-border.is-primary {
19
+ border-right-color: var(--xt-card-item-color);
20
+ }
21
+
22
+ .xt-card-item.is-border.is-primary .item__value .value {
23
+ color: var(--xt-card-item-color);
24
+ }
25
+
26
+ .xt-card-item.is-border.is-success {
27
+ border-right-color: var(--xt-color-success, #67C23A);
28
+ }
29
+
30
+ .xt-card-item.is-border.is-success .item__value .value {
31
+ color: var(--xt-color-success, #67C23A);
32
+ }
33
+
34
+ .xt-card-item.is-border.is-warning {
35
+ border-right-color: var(--xt-color-warning, #E6A23C);
36
+ }
37
+
38
+ .xt-card-item.is-border.is-warning .item__value .value {
39
+ color: var(--xt-color-warning, #E6A23C);
40
+ }
41
+
42
+ .xt-card-item.is-border.is-danger {
43
+ border-right-color: var(--xt-color-danger, #F56C6C);
44
+ }
45
+
46
+ .xt-card-item.is-border.is-danger .item__value .value {
47
+ color: var(--xt-color-danger, #F56C6C);
48
+ }
49
+
50
+ .xt-card-item .item__value {
51
+ padding-right: 10px;
52
+ }
53
+
54
+ .xt-card-item .item__value .value {
55
+ font-weight: 600;
56
+ font-size: var(--xt-font-size-base, 14px);
57
+ }
58
+
59
+ .xt-card-item .item__value .unit {
60
+ font-size: var(--xt-font-size-small, 13px);
61
+ color: var(--xt-color-text-secondary, #909399);
62
+ }
63
+
64
+ .xt-card-item .item__label {
65
+ padding-left: 10px;
66
+ color: var(--xt-color-text-secondary, #909399);
67
+ }
68
+
69
+ .xt-card-item .item__unit {
70
+ padding-left: 5px;
71
+ color: var(--xt-color-text-secondary, #909399);
72
+ }
@@ -0,0 +1,2 @@
1
+ import ConfigProvider from './index.vue'
2
+ export default ConfigProvider
@@ -0,0 +1,193 @@
1
+ <template>
2
+ <!-- 根据 tag 属性选择渲染的标签 -->
3
+ <component
4
+ :is="tag"
5
+ :style="mergedStyle"
6
+ :class="computedClass"
7
+ v-bind="customAttrs"
8
+ >
9
+ <slot></slot>
10
+ </component>
11
+ </template>
12
+
13
+ <script>
14
+ export default {
15
+ name: 'XtConfigProvider',
16
+ inheritAttrs: false,
17
+ props: {
18
+ theme: {
19
+ type: String,
20
+ default: 'white'
21
+ },
22
+ size: {
23
+ type: String,
24
+ default: 'medium'
25
+ },
26
+ primaryColor: {
27
+ type: String,
28
+ default: '#409EFF'
29
+ },
30
+ vars: {
31
+ type: Object,
32
+ default: () => ({})
33
+ },
34
+ tag: {
35
+ type: String,
36
+ default: 'div',
37
+ validator: (value) => {
38
+ return ['div', 'span', 'section', 'main', 'template', 'article', 'aside'].includes(value)
39
+ }
40
+ },
41
+ injectBackground: {
42
+ type: Boolean,
43
+ default: false
44
+ },
45
+ injectColor: {
46
+ type: Boolean,
47
+ default: false
48
+ }
49
+ },
50
+ computed: {
51
+ mergedStyle() {
52
+ const result = { ...this.vars }
53
+
54
+ if (this.primaryColor) {
55
+ const color = this.normalizeColor(this.primaryColor)
56
+ result['--xt-color-primary'] = color
57
+ result['--xt-color-primary-light-3'] = this.lightenColor(color, 30)
58
+ result['--xt-color-primary-light-5'] = this.lightenColor(color, 50)
59
+ result['--xt-color-primary-light-7'] = this.lightenColor(color, 70)
60
+ result['--xt-color-primary-light-8'] = this.lightenColor(color, 80)
61
+ result['--xt-color-primary-light-9'] = this.lightenColor(color, 90)
62
+ }
63
+
64
+ const sizeMap = {
65
+ small: '12px',
66
+ medium: '14px',
67
+ large: '16px'
68
+ }
69
+ if (sizeMap[this.size]) {
70
+ result['--xt-font-size-base'] = sizeMap[this.size]
71
+ }
72
+
73
+ if (this.theme === 'dark') {
74
+ result['--xt-color-text-primary'] = 'rgba(255, 255, 255, 0.95)'
75
+ result['--xt-color-text-regular'] = 'rgba(255, 255, 255, 0.8)'
76
+ result['--xt-color-text-secondary'] = 'rgba(255, 255, 255, 0.6)'
77
+ result['--xt-color-bg-primary'] = '#1f1f1f'
78
+ result['--xt-color-bg-secondary'] = '#2d2d2d'
79
+ result['--xt-color-bg-container'] = '#1f1f1f'
80
+ result['--xt-color-border'] = '#434343'
81
+ result['--xt-color-border-light'] = '#3d3d3d'
82
+
83
+ if (this.injectBackground) {
84
+ result.backgroundColor = result['--xt-color-bg-primary']
85
+ }
86
+ if (this.injectColor) {
87
+ result.color = result['--xt-color-text-primary']
88
+ }
89
+ } else {
90
+ // 恢复默认主题颜色(white 主题)
91
+ result['--xt-color-text-primary'] = '#303133'
92
+ result['--xt-color-text-regular'] = '#606266'
93
+ result['--xt-color-text-secondary'] = '#909399'
94
+ result['--xt-color-bg-primary'] = '#ffffff'
95
+ result['--xt-color-bg-secondary'] = '#f5f7fa'
96
+ result['--xt-color-bg-container'] = '#f5f7fa'
97
+ result['--xt-color-border'] = '#DCDFE6'
98
+ result['--xt-color-border-light'] = '#E4E7ED'
99
+
100
+ if (this.injectBackground) {
101
+ result.backgroundColor = result['--xt-color-bg-primary']
102
+ }
103
+ if (this.injectColor) {
104
+ result.color = result['--xt-color-text-primary']
105
+ }
106
+ }
107
+
108
+ return result
109
+ },
110
+ computedClass() {
111
+ const classes = []
112
+
113
+ if (this.tag !== 'template') {
114
+ classes.push('xt-config-provider')
115
+
116
+ if (this.theme === 'dark') {
117
+ classes.push('xt-config-provider--dark')
118
+ }
119
+ }
120
+
121
+ return classes
122
+ },
123
+ customAttrs() {
124
+ const props = ['theme', 'size', 'primaryColor', 'vars', 'tag', 'injectBackground', 'injectColor']
125
+ const attrs = {}
126
+
127
+ for (const key in this.$attrs) {
128
+ if (!props.includes(key)) {
129
+ attrs[key] = this.$attrs[key]
130
+ }
131
+ }
132
+
133
+ return attrs
134
+ }
135
+ },
136
+ methods: {
137
+ normalizeColor(color) {
138
+ if (!color) return '#409EFF'
139
+
140
+ if (/^#[0-9A-Fa-f]{6}$/.test(color)) {
141
+ return color
142
+ }
143
+
144
+ if (/^#[0-9A-Fa-f]{3}$/.test(color)) {
145
+ return '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]
146
+ }
147
+
148
+ if (/^#[0-9A-Fa-f]{8}$/.test(color)) {
149
+ return color.substring(0, 7)
150
+ }
151
+
152
+ const rgbaMatch = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)/i)
153
+ if (rgbaMatch) {
154
+ const r = parseInt(rgbaMatch[1])
155
+ const g = parseInt(rgbaMatch[2])
156
+ const b = parseInt(rgbaMatch[3])
157
+ return this.rgbToHex(r, g, b)
158
+ }
159
+
160
+ console.warn('[XtConfigProvider] 无法识别的颜色格式:', color)
161
+ return '#409EFF'
162
+ },
163
+
164
+ hexToRgb(hex) {
165
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
166
+ return result ? {
167
+ r: parseInt(result[1], 16),
168
+ g: parseInt(result[2], 16),
169
+ b: parseInt(result[3], 16)
170
+ } : null
171
+ },
172
+
173
+ rgbToHex(r, g, b) {
174
+ return '#' + [r, g, b].map(x => {
175
+ const hex = x.toString(16)
176
+ return hex.length === 1 ? '0' + hex : hex
177
+ }).join('')
178
+ },
179
+
180
+ lightenColor(hex, percent) {
181
+ const rgb = this.hexToRgb(hex)
182
+ if (!rgb) return hex
183
+
184
+ const amount = Math.round(2.55 * percent)
185
+ const r = Math.min(255, rgb.r + amount)
186
+ const g = Math.min(255, rgb.g + amount)
187
+ const b = Math.min(255, rgb.b + amount)
188
+
189
+ return this.rgbToHex(r, g, b)
190
+ }
191
+ }
192
+ }
193
+ </script>
@@ -0,0 +1,12 @@
1
+ @import '../../../styles/variables.scss';
2
+
3
+ .xt-config-provider {
4
+ }
5
+
6
+ .xt-config-provider--dark {
7
+ }
8
+
9
+ .xt-config-provider--dark.xt-config-provider--with-bg {
10
+ background-color: var(--xt-color-bg-primary, #1f1f1f);
11
+ color: var(--xt-color-text-primary, rgba(255, 255, 255, 0.95));
12
+ }
@@ -1,104 +1,34 @@
1
- <<template>
2
- <div class="xt-flex-box" :class="classAttrs" style="gap: gap">
1
+ <template>
2
+ <div class="xt-flex-box" :class="classAttrs" :style="flexStyle">
3
3
  <slot></slot>
4
4
  </div>
5
5
  </template>
6
6
 
7
7
  <script>
8
8
  export default {
9
- name: "XtFlex",
9
+ name: "XtFlexBox",
10
10
  props: {
11
- type: "flex",
12
- align: "center",
13
- content: "start",
14
- direction: "row",
15
- wrap: "unset",
16
- gap: {}
11
+ type: { type: String, default: "flex" },
12
+ align: { type: String, default: "center" },
13
+ content: { type: String, default: "start" },
14
+ direction: { type: String, default: "row" },
15
+ wrap: { type: String, default: "unset" },
16
+ gap: { type: String, default: "" }
17
17
  },
18
18
  computed: {
19
19
  classAttrs(){
20
- const {inline, align, wrap, direction,content} = this;
21
- return [`${inline?'is-inline':'flex'}`, `align-${align} content-${content} direction-${direction} wrap-${wrap}`]
22
- }
23
- }
24
- }
25
- </script>
26
-
27
- <style scoped lang="scss">
28
- .xt-flex-box{
29
- &.flex{
30
- display: flex;
31
- &.direction{
32
- &-row,&-row-reverse{
33
- >.flex{
34
- width: 100%;
35
- }
20
+ const { type, align, wrap, direction, content } = this;
21
+ return [`${type}`, `align-${align}`, `content-${content}`, `direction-${direction}`, `wrap-${wrap}`]
22
+ },
23
+ flexStyle() {
24
+ const result = {}
25
+ if (this.gap) {
26
+ result.gap = this.gap
27
+ } else {
28
+ result.gap = 'var(--xt-flex-box-gap, 8px)'
36
29
  }
37
- &-column,&-column-reverse{
38
- >.flex{
39
- height: 100%;
40
- }
41
- }
42
- }
43
- }
44
- &.is-inline{
45
- display: inline-flex;
46
- }
47
-
48
- }
49
- .direction{
50
- &-row{
51
- flex-direction: row;
52
- &-reverse{
53
- flex-direction: row-reverse;
54
- }
55
- }
56
- &-column{
57
- flex-direction: column;
58
- &-reverse{
59
- flex-direction: column-reverse;
30
+ return result
60
31
  }
61
32
  }
62
33
  }
63
- .align{
64
- &-center{
65
- align-items: center;
66
- }
67
- &-start{
68
- align-items: flex-start;
69
- }
70
- &-end{
71
- align-items: flex-end;
72
- }
73
-
74
- }
75
-
76
- .content{
77
- &-center{
78
- justify-content: center;
79
- }
80
- &-around{
81
- justify-content: space-around;
82
- }
83
- &-between{
84
- justify-content: space-between;
85
- }
86
- &-start{
87
- justify-content: flex-start;
88
- }
89
- &-end{
90
- justify-content: flex-end;
91
- }
92
- }
93
- .wrap{
94
- &-wrap{
95
- flex-wrap: wrap;
96
- }
97
- &-nowrap{
98
- flex-wrap: nowrap;
99
- }
100
- &-unset{
101
- flex-wrap: wrap;
102
- }
103
- }
104
- </style>
34
+ </script>
@@ -0,0 +1,91 @@
1
+ @import '../../../styles/variables.scss';
2
+
3
+ .xt-flex-box.flex {
4
+ display: flex;
5
+ }
6
+
7
+ .xt-flex-box.flex.direction-row > .flex,
8
+ .xt-flex-box.flex.direction-row-reverse > .flex {
9
+ width: 100%;
10
+ }
11
+
12
+ .xt-flex-box.flex.direction-column > .flex,
13
+ .xt-flex-box.flex.direction-column-reverse > .flex {
14
+ height: 100%;
15
+ }
16
+
17
+ .xt-flex-box.is-inline {
18
+ display: inline-flex;
19
+ }
20
+
21
+ .direction-row {
22
+ flex-direction: row;
23
+ }
24
+
25
+ .direction-row-reverse {
26
+ flex-direction: row-reverse;
27
+ }
28
+
29
+ .direction-column {
30
+ flex-direction: column;
31
+ }
32
+
33
+ .direction-column-reverse {
34
+ flex-direction: column-reverse;
35
+ }
36
+
37
+ .align-center {
38
+ align-items: center;
39
+ }
40
+
41
+ .align-start {
42
+ align-items: flex-start;
43
+ }
44
+
45
+ .align-end {
46
+ align-items: flex-end;
47
+ }
48
+
49
+ .align-baseline {
50
+ align-items: baseline;
51
+ }
52
+
53
+ .align-stretch {
54
+ align-items: stretch;
55
+ }
56
+
57
+ .content-center {
58
+ justify-content: center;
59
+ }
60
+
61
+ .content-around {
62
+ justify-content: space-around;
63
+ }
64
+
65
+ .content-between {
66
+ justify-content: space-between;
67
+ }
68
+
69
+ .content-start {
70
+ justify-content: flex-start;
71
+ }
72
+
73
+ .content-end {
74
+ justify-content: flex-end;
75
+ }
76
+
77
+ .content-evenly {
78
+ justify-content: space-evenly;
79
+ }
80
+
81
+ .wrap-wrap {
82
+ flex-wrap: wrap;
83
+ }
84
+
85
+ .wrap-nowrap {
86
+ flex-wrap: nowrap;
87
+ }
88
+
89
+ .wrap-unset {
90
+ flex-wrap: wrap;
91
+ }
@@ -0,0 +1,22 @@
1
+ // 组件样式统一入口文件
2
+
3
+ // Button 组件样式
4
+ @import './button/style/index.scss';
5
+
6
+ // Card 组件样式
7
+ @import './card/style/index.scss';
8
+
9
+ // CardItem 组件样式
10
+ @import './card-item/style/index.scss';
11
+
12
+ // Input 组件样式
13
+ @import './input/style/index.scss';
14
+
15
+ // FlexBox 组件样式
16
+ @import './flex-box/style/index.scss';
17
+
18
+ // ConfigProvider 组件样式
19
+ @import './config-provider/style/index.scss';
20
+
21
+ // Text 组件样式
22
+ @import './text/style/index.scss';