vdesign-ui 0.1.22 → 0.1.23

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.
@@ -5,15 +5,14 @@
5
5
  <input type="radio" :class="inputClasses" :disabled="disabled" :checked="currentValue" @change="change">
6
6
  </span>
7
7
  <div class="vd-radio__label" v-if="$slots.default">
8
- <p class="vd-radio__text">
8
+ <div class="vd-radio__text">
9
9
  <slot></slot>
10
- </p>
11
- <p class="vd-radio__description" v-if="extra">{{ extra }}</p>
10
+ </div>
11
+ <!-- <p class="vd-radio__description" v-if="extra">{{ extra }}</p> -->
12
12
  </div>
13
13
  </label>
14
14
 
15
15
 
16
- <!-- 传入文字小icon 不传文字大icon -->
17
16
  <label class="vd-radio vd-radio-button" :class="radioButtonClasses" v-else>
18
17
  <input type="radio" :class="inputClasses" :disabled="disabled" :checked="currentValue" @change="change">
19
18
  <span class="vd-radio-button-text">
@@ -36,9 +35,9 @@ export default {
36
35
  type: Boolean,
37
36
  default: false
38
37
  },
39
- extra: {
40
- type: [String, Number, Boolean],
41
- },
38
+ // extra: {
39
+ // type: [String, Number, Boolean],
40
+ // },
42
41
  value: {
43
42
  type: [String, Number, Boolean],
44
43
  default: false
@@ -0,0 +1,213 @@
1
+ .vd-radio {
2
+ position: relative;
3
+ cursor: pointer;
4
+ display: flex;
5
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
6
+ }
7
+ .vd-radio__input {
8
+ position: relative;
9
+ margin-inline-end: calc(var(--spacing-check_radio-icon-margin_right) * 1px);
10
+ width: calc(var(--icon-check_radio-sizing) * 1px);
11
+ height: calc(var(--icon-check_radio-sizing) * 1px);
12
+ }
13
+ .vd-radio__label {
14
+ flex: 1;
15
+ }
16
+ .vd-radio__text {
17
+ color: var(--color-check_radio-text-default);
18
+ font-size: calc(var(--en-single-f-d-r-fontSize) * 1px);
19
+ font-weight: var(--en-single-f-d-r-fontWeight);
20
+ }
21
+ .vd-radio__description {
22
+ line-height: 1;
23
+ margin-top: calc(var(--spacing-check_radio-text-margin_top) * 1px);
24
+ color: var(--color-check_radio-text_describe-default);
25
+ font-size: calc(var(--en-single-f-b-r-fontSize) * 1px);
26
+ font-weight: var(--en-single-f-b-r-fontWeight);
27
+ }
28
+ .vd-radio .vd-radio__icon {
29
+ display: block;
30
+ width: calc(var(--icon-check_radio-sizing) * 1px);
31
+ height: calc(var(--icon-check_radio-sizing) * 1px);
32
+ position: relative;
33
+ }
34
+ .vd-radio .vd-radio__icon::before {
35
+ position: absolute;
36
+ box-sizing: border-box;
37
+ content: ' ';
38
+ pointer-events: none;
39
+ top: -50%;
40
+ right: -50%;
41
+ bottom: -50%;
42
+ left: -50%;
43
+ border: 0 solid var(--color-check_radio-default);
44
+ -webkit-transform: scale(0.5);
45
+ transform: scale(0.5);
46
+ border-width: 3px;
47
+ border-radius: 50%;
48
+ }
49
+ .vd-radio__original {
50
+ width: 100%;
51
+ height: 100%;
52
+ position: absolute;
53
+ top: 0;
54
+ bottom: 0;
55
+ left: 0;
56
+ right: 0;
57
+ z-index: 1;
58
+ cursor: pointer;
59
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
60
+ opacity: 0;
61
+ }
62
+ .vd-radio--checked .vd-radio__text {
63
+ font-size: calc(var(--en-single-f-d-s-fontSize) * 1px);
64
+ font-weight: var(--en-single-f-d-s-fontWeight);
65
+ }
66
+ .vd-radio--checked .vd-radio__icon::before {
67
+ border: 0 solid var(--color-check_radio-active);
68
+ border-width: 3px;
69
+ }
70
+ .vd-radio--checked .vd-radio__icon::after {
71
+ position: absolute;
72
+ width: 8px;
73
+ height: 8px;
74
+ left: 50%;
75
+ top: 50%;
76
+ transform: translate(-50%, -50%);
77
+ border-radius: 50%;
78
+ display: table;
79
+ border-top: 0;
80
+ border-left: 0;
81
+ content: " ";
82
+ background-color: var(--color-check_radio-active);
83
+ }
84
+ .vd-radio--disabled {
85
+ cursor: not-allowed;
86
+ }
87
+ .vd-radio--disabled .vd-radio__text {
88
+ color: var(--color-check_radio-text-disable);
89
+ }
90
+ .vd-radio--disabled .vd-radio__description {
91
+ color: var(--color-check_radio-text_describe-disable);
92
+ }
93
+ .vd-radio--disabled .vd-radio__icon::before {
94
+ border-color: var(--color-check_radio-disable);
95
+ }
96
+ .vd-radio--checked.vd-radio--disabled .vd-radio__icon::before {
97
+ border-color: var(--color-check_radio-active-disable);
98
+ }
99
+ .vd-radio--checked.vd-radio--disabled .vd-radio__icon::after {
100
+ background-color: var(--color-check_radio-active-disable);
101
+ }
102
+ .vd-radio-group {
103
+ display: flex;
104
+ flex-direction: column;
105
+ gap: calc(var(--spacing-check_radio-group-margin_x)*1px);
106
+ }
107
+ .vd-radio-group-card {
108
+ display: flex;
109
+ flex-wrap: wrap;
110
+ flex-direction: row;
111
+ gap: 12px;
112
+ }
113
+ .vd-radio-group-card .vd-radio-button-cell {
114
+ flex: 1;
115
+ }
116
+ .vd-radio-button {
117
+ position: relative;
118
+ display: inline-flex;
119
+ align-items: center;
120
+ flex-direction: column;
121
+ justify-content: center;
122
+ line-height: 1;
123
+ width: 100%;
124
+ }
125
+ .vd-radio-button::after {
126
+ position: absolute;
127
+ box-sizing: border-box;
128
+ content: ' ';
129
+ pointer-events: none;
130
+ top: -50%;
131
+ right: -50%;
132
+ bottom: -50%;
133
+ left: -50%;
134
+ border: 0 solid var(--color-check_radio-radio_border-default);
135
+ -webkit-transform: scale(0.5);
136
+ transform: scale(0.5);
137
+ border-width: 1px;
138
+ }
139
+ .vd-radio-button--large {
140
+ height: calc(var(--height-check_radio-radio_button_l) * 1px);
141
+ }
142
+ .vd-radio-button--large .vd-radio-button-text {
143
+ color: var(--color-check_radio-radio_button_text-default);
144
+ font-size: calc(var(--en-single-f-d-r-fontSize) * 1px);
145
+ font-weight: var(--en-single-f-d-r-fontWeight);
146
+ }
147
+ .vd-radio-button--large::after {
148
+ border-radius: calc(var(--radius-check_radio-radio_l) * 2px);
149
+ }
150
+ .vd-radio-button--medium {
151
+ height: calc(var(--height-check_radio-radio_button_m) * 1px);
152
+ }
153
+ .vd-radio-button--medium .vd-radio-button-text {
154
+ color: var(--color-check_radio-radio_button_text-default);
155
+ font-size: calc(var(--en-single-f-c-r-fontSize) * 1px);
156
+ font-weight: var(--en-single-f-c-r-fontWeight);
157
+ }
158
+ .vd-radio-button--medium::after {
159
+ border-radius: calc(var(--radius-check_radio-m) * 2px);
160
+ }
161
+ .vd-radio-button--small {
162
+ height: calc(var(--height-check_radio-radio_button_s) * 1px);
163
+ }
164
+ .vd-radio-button--small .vd-radio-button-text {
165
+ color: var(--color-check_radio-radio_button_text-default);
166
+ font-size: calc(var(--en-single-f-c-r-fontSize) * 1px);
167
+ font-weight: var(--en-single-f-c-r-fontWeight);
168
+ }
169
+ .vd-radio-button--small::after {
170
+ border-radius: calc(var(--radius-check_radio-s) * 2px);
171
+ }
172
+ .vd-radio-button--checked {
173
+ background-color: var(--color-check_radio-radio_button_bg-active);
174
+ }
175
+ .vd-radio-button--checked::after {
176
+ border-color: var(--color-check_radio-radio_border-active);
177
+ border-width: 2px;
178
+ }
179
+ .vd-radio-button--checked .vd-radio-button-text {
180
+ color: var(--color-check_radio-radio_button_text-active);
181
+ }
182
+ .vd-radio-button--checked.vd-radio-button--large .vd-radio-button-text {
183
+ font-size: calc(var(--en-single-f-d-s-fontSize) * 1px);
184
+ font-weight: var(--en-single-f-d-s-fontWeight);
185
+ }
186
+ .vd-radio-button--checked.vd-radio-button--medium .vd-radio-button-text {
187
+ font-size: calc(var(--en-single-f-c-s-fontSize) * 1px);
188
+ font-weight: var(--en-single-f-c-s-fontWeight);
189
+ }
190
+ .vd-radio-button--checked.vd-radio-button--small .vd-radio-button-text {
191
+ font-size: calc(var(--en-single-f-c-s-fontSize) * 1px);
192
+ font-weight: var(--en-single-f-c-s-fontWeight);
193
+ }
194
+ .vd-radio-button--disabled {
195
+ cursor: not-allowed;
196
+ }
197
+ .vd-radio-button--disabled .vd-radio-button-text {
198
+ color: var(--color-check_radio-radio_button_text-disable);
199
+ }
200
+ .vd-radio-group {
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: calc(var(--spacing-check_radio-group-margin_x)*1px);
204
+ }
205
+ .vd-radio-group__card {
206
+ display: flex;
207
+ flex-direction: row;
208
+ flex-wrap: wrap;
209
+ gap: 12px;
210
+ }
211
+ .vd-radio-group .vd-radio-button {
212
+ flex: 1;
213
+ }
@@ -19,6 +19,11 @@
19
19
  width: calc(var(--icon-check_radio-sizing) * 1px);
20
20
  height: calc(var(--icon-check_radio-sizing) * 1px);
21
21
  }
22
+
23
+ &__label{
24
+ flex: 1;
25
+ }
26
+
22
27
  &__text {
23
28
  color: var(--color-check_radio-text-default);
24
29
  font-size: calc(var(--en-single-f-d-r-fontSize) * 1px);
@@ -1,220 +1,99 @@
1
1
  <template>
2
- <div class="vd-upload" :class="{ 'vd-upload--block': (block && listData.length === 0) }">
2
+ <div class="vd-upload" :class="{ 'vd-upload--block': block }">
3
3
  <div class="vd-upload__wrapper">
4
4
  <div class="vd-upload__uploader" :class="{ 'vd-upload__uploader--text': text }">
5
- <vd-icon name="icon_btn_photo" class="vd-upload__icon"></vd-icon>
5
+ <vd-icon :name="photo" class="vd-upload__icon"></vd-icon>
6
6
  <p class="vd-upload__text" v-if="text">{{ text }}</p>
7
- <input type="file" class="vd-upload__input" accept="image/*,.pdf" :multiple="multiple" @change="onChange"
7
+ <input type="file" ref="input" class="vd-upload__input" :accept="accept" @change="onChange"
8
8
  :disabled="disabled">
9
9
  </div>
10
- <div class="vd-upload__preview" v-for="item in listData" :key="item.id" :class="fileCls(item.type)">
11
- <div class="vd-upload__preview-img" v-if="item.type.startsWith('image')" @click="onPreview(item)">
12
- <img :src="item.url" />
13
- </div>
14
- <div class="vd-upload__preview-word" v-if="item.type === 'application/pdf'">PDF</div>
15
- <div class="vd-upload__preview-delete" @click="onDelete($event, item)" v-if="deletable">
16
- <vd-icon name="icon_btn_close" class="vd-upload__preview-delete-icon"></vd-icon>
17
- </div>
18
- </div>
19
- </div>
20
- <div class="vd-image-preview" v-if="isPreview" @click="closePreview">
21
- <div class="vd-image-preview__item" v-for="item in listData" :key="item.id" v-show="curNum === item.id"><img
22
- :src="item.url" /></div>
23
10
  </div>
24
11
  </div>
25
12
  </template>
26
13
 
27
14
  <script>
28
- const prefixCls = 'vd-upload';
29
15
  export default {
30
16
  name: 'vd-upload',
31
- model: {
32
- prop: 'fileList'
33
- },
17
+ inheritAttrs: false,
18
+
34
19
  props: {
35
- uploaded: {
36
- type: Boolean,
37
- default: false
38
- },
39
- preview: {
40
- type: Boolean,
41
- default: true
42
- },
43
- block: {
44
- type: Boolean,
45
- default: false
46
- },
47
- text: {
20
+ photo: {
48
21
  type: String,
49
- default: ''
50
- },
51
- fileList: {
52
- type: Array,
53
- default: () => []
54
- },
55
- deletable: {
56
- type: Boolean,
57
- default: true
58
- },
59
- disabled: {
60
- type: Boolean,
61
- default: false
62
- },
63
- /**
64
- * 文件读取前钩子函数
65
- */
66
- beforeRead: {
67
- type: Function,
68
- default: () => () => true
69
- },
70
- /**
71
- * 文件读取完钩子函数
72
- */
73
- afterRead: {
74
- type: Function,
75
- default: () => () => true
76
- },
77
- /**
78
- * 文件删除前钩子函数
79
- */
80
- beforeDelete: {
81
- type: Function,
82
- default: () => () => true
83
- },
84
- maxCount: {
85
- type: Number,
86
- default: 1000
22
+ default: 'icon_btn_photo'
23
+ },
24
+ text: String,
25
+ block: Boolean,
26
+ disabled: Boolean,
27
+ beforeRead: Function,
28
+ afterRead: Function,
29
+ accept: {
30
+ type: String,
31
+ default: 'image/*'
87
32
  },
88
33
  maxSize: {
89
34
  type: Number,
90
- default: 6 * 1024 * 1024
91
- },
92
- multiple: {
93
- type: Boolean,
94
- default: false
95
- },
96
- },
97
- data() {
98
- return {
99
- listData: this.fileList,
100
- curNum: 1,
101
- isPreview: false
102
- }
103
- },
104
- watch: {
105
- /**
106
- * 监听列表数据
107
- */
108
- fileList: {
109
- handler(value) {
110
- this.listData = value
111
- },
112
- deep: true
35
+ default: Number.MAX_VALUE
113
36
  }
114
37
  },
38
+
115
39
  methods: {
116
- fileCls(file) {
117
- if (file === 'application/pdf') {
118
- return [`${prefixCls}__preview--pdf`];
119
- } else {
120
- return [];
40
+ onChange(event) {
41
+ let { files } = event.target;
42
+ if (this.disabled || !files.length) {
43
+ return;
121
44
  }
122
- },
123
- onDelete(e, item) {
124
- e.stopPropagation()
125
- const { disabled, beforeDelete, listData } = this
126
- /**
127
- * 判断是否允许删除文件
128
- */
129
- if (!disabled && beforeDelete(item) !== false) {
130
- /**
131
- * 索引
132
- */
133
- let i = 0
134
- /**
135
- * 循环遍历数组定位下标位置
136
- */
137
- for (; i < listData.length; i++) {
138
- /**
139
- * 判断 id 是否相等
140
- */
141
- if (listData[i].id === item.id) break
142
- }
143
- /**
144
- * 删除
145
- */
146
- listData.splice(i, 1)
147
- this.$emit('input', listData)
148
- this.$emit('on-change', listData)
45
+
46
+ files = files.length === 1 ? files[0] : [].slice.call(files, 0);
47
+ if (!files || (this.beforeRead && !this.beforeRead(files))) {
48
+ return;
149
49
  }
150
- },
151
- onChange(e) {
152
- const { beforeRead, afterRead, maxSize, maxCount, listData } = this
153
- /**
154
- * 获取不超过 maxCount 文件
155
- */
156
- const files = Object.values(e.target.files).slice(0, maxCount)
157
50
 
158
- /**
159
- * 判断是否允许读取文件
160
- */
161
- if (beforeRead(files) !== false) {
162
- /**
163
- * 循环遍历添加数据
164
- */
165
- const arr = []
166
- files.forEach(elem => {
167
- /**
168
- * 判断大小是否小于或等于 maxSize
169
- */
170
- if (elem.size <= maxSize) {
171
- /**
172
- * 数组长度
173
- */
174
- const len = listData.length
175
- /**
176
- * 获取 id
177
- */
178
- const id = len === 0 ? 1 : listData[len - 1].id + 1
179
- /**
180
- * 创建 blob 预览图片地址
181
- */
182
- const url = window.URL.createObjectURL(elem)
51
+ if (Array.isArray(files)) {
52
+ Promise.all(files.map(this.readFile)).then(contents => {
53
+ let oversize = false;
54
+ const payload = files.map((file, index) => {
55
+ if (file.size > this.maxSize) {
56
+ oversize = true;
57
+ }
183
58
 
184
- const type = e.target.files[0].type;
185
- /**
186
- * 添加进数组
187
- */
188
- listData.push({ id, url, type })
189
- arr.push(elem)
190
- }
191
- })
192
- /**
193
- * 符合规则的图片数组
194
- */
195
- if (arr.length > 0) {
196
- afterRead(arr)
197
- this.$emit('change', listData)
198
- this.$emit('num-changed', this.curNum);
199
- }
200
- }
201
- },
202
- onPreview({ id }) {
203
- const { disabled, preview } = this
204
- /**
205
- * 判断是否允许预览
206
- */
207
- if (!disabled && preview) {
208
- this.curNum = id
209
- /**
210
- * 打开图片预览
211
- */
212
- this.isPreview = true
59
+ return {
60
+ file: files[index],
61
+ content: contents[index]
62
+ };
63
+ });
64
+
65
+ this.onAfterRead(payload, oversize);
66
+ });
67
+ } else {
68
+ this.readFile(files).then(content => {
69
+ this.onAfterRead(
70
+ { file: files, content },
71
+ files.size > this.maxSize
72
+ );
73
+ });
213
74
  }
214
75
  },
215
- closePreview() {
216
- this.isPreview = false
76
+
77
+ readFile(file) {
78
+ return new Promise(resolve => {
79
+ const reader = new FileReader();
80
+
81
+ reader.onload = event => {
82
+ resolve(event.target.result);
83
+ };
84
+ reader.readAsDataURL(file);
85
+
86
+ });
217
87
  },
88
+
89
+ onAfterRead(files, oversize) {
90
+ if (oversize) {
91
+ this.$emit('oversize', files);
92
+ } else {
93
+ this.afterRead && this.afterRead(files);
94
+ this.$refs.input && (this.$refs.input.value = '');
95
+ }
96
+ }
218
97
  }
219
98
  }
220
99
  </script>