@ecolovo/uniapp-components 1.0.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 (97) hide show
  1. package/components/aspect/aspect.vue +43 -0
  2. package/components/badge/badge.vue +88 -0
  3. package/components/button/button.vue +409 -0
  4. package/components/checkbox/checkbox.vue +183 -0
  5. package/components/checkbox-group/checkbox-group.vue +101 -0
  6. package/components/checkbox-group2/checkbox-group2.vue +138 -0
  7. package/components/checkbox-group2/checkbox.vue +103 -0
  8. package/components/data-list/data-list.vue +130 -0
  9. package/components/date-picker/date-picker-view.vue +181 -0
  10. package/components/date-picker/date-picker.vue +237 -0
  11. package/components/datetime-picker/datetime-picker-view.vue +209 -0
  12. package/components/datetime-picker/datetime-picker.vue +235 -0
  13. package/components/dialog/dialog-content.vue +162 -0
  14. package/components/dialog/dialog.vue +166 -0
  15. package/components/dropdown/dropdown.vue +145 -0
  16. package/components/empty/empty.vue +102 -0
  17. package/components/flex/flex.vue +76 -0
  18. package/components/form/form.vue +43 -0
  19. package/components/form/mixin.js +13 -0
  20. package/components/form-item/form-item.vue +141 -0
  21. package/components/icon/icon.vue +114 -0
  22. package/components/image/image.vue +61 -0
  23. package/components/input/input.vue +154 -0
  24. package/components/input/password-input.vue +95 -0
  25. package/components/list-page/list-page.js +10 -0
  26. package/components/list-page/list-page.vue +150 -0
  27. package/components/load-more/load-more.vue +97 -0
  28. package/components/loading/animations/loading-animation1.vue +92 -0
  29. package/components/loading/animations/loading-animation2.vue +28 -0
  30. package/components/loading/animations/loading-animation3.vue +81 -0
  31. package/components/loading/animations/loading-animation4.vue +74 -0
  32. package/components/loading/loading.vue +91 -0
  33. package/components/message-box/message-box.vue +60 -0
  34. package/components/number-dialog/number-dialog.vue +360 -0
  35. package/components/number-input/number-input.vue +352 -0
  36. package/components/numpad/numpad.vue +224 -0
  37. package/components/page/page-body.vue +227 -0
  38. package/components/page/page-footer.vue +75 -0
  39. package/components/page/page-header.vue +222 -0
  40. package/components/page/page.vue +128 -0
  41. package/components/picker/picker-popup.vue +295 -0
  42. package/components/picker/picker.vue +151 -0
  43. package/components/popover/popover-content.vue +255 -0
  44. package/components/popover/popover-mask.vue +113 -0
  45. package/components/popover/popover.vue +84 -0
  46. package/components/popup/popup-content.vue +162 -0
  47. package/components/popup/popup.vue +168 -0
  48. package/components/price/price.vue +104 -0
  49. package/components/search/search.vue +220 -0
  50. package/components/searching/searching.vue +86 -0
  51. package/components/selector/selector.vue +86 -0
  52. package/components/switch/switch.vue +180 -0
  53. package/components/tab/tab.vue +235 -0
  54. package/components/table/table.vue +112 -0
  55. package/components/textarea/textarea.vue +192 -0
  56. package/components/time-picker/time-picker-view.vue +127 -0
  57. package/components/time-picker/time-picker.vue +140 -0
  58. package/components/uploader/download.js +81 -0
  59. package/components/uploader/file-uploader.vue +52 -0
  60. package/components/uploader/files.js +225 -0
  61. package/components/uploader/media-uploader.vue +133 -0
  62. package/components/uploader/mixin.js +106 -0
  63. package/components/uploader/uni.js +38 -0
  64. package/components/uploader/upload-button.vue +29 -0
  65. package/components/uploader/uploader copy.vue +547 -0
  66. package/components/uploader/uploader.vue +117 -0
  67. package/configs/index.js +41 -0
  68. package/easyCom.js +25 -0
  69. package/init.js +17 -0
  70. package/mixins/componentName.js +32 -0
  71. package/mixins/listPage.js +1 -0
  72. package/mixins/windowInfo.js +1 -0
  73. package/package.json +12 -0
  74. package/resources/iconfont/uniapp_ui_icon/demo.css +539 -0
  75. package/resources/iconfont/uniapp_ui_icon/demo_index.html +555 -0
  76. package/resources/iconfont/uniapp_ui_icon/iconfont.css +78 -0
  77. package/resources/iconfont/uniapp_ui_icon/iconfont.js +1 -0
  78. package/resources/iconfont/uniapp_ui_icon/iconfont.json +121 -0
  79. package/resources/iconfont/uniapp_ui_icon/iconfont.woff2 +0 -0
  80. package/resources/image/empty.svg +13 -0
  81. package/styles/global.scss +24 -0
  82. package/styles/index.scss +2 -0
  83. package/styles/utils/css-var.scss +87 -0
  84. package/styles/utils/ellipsis.scss +26 -0
  85. package/styles/utils/global-var.scss +11 -0
  86. package/styles/utils/index.scss +5 -0
  87. package/styles/utils/selector.scss +5 -0
  88. package/styles/utils/z-index.scss +10 -0
  89. package/styles/var/component.scss +242 -0
  90. package/styles/var/index.scss +2 -0
  91. package/styles/var/theme.scss +40 -0
  92. package/utils/date.js +151 -0
  93. package/utils/floor.js +20 -0
  94. package/utils/freezeDeep.js +19 -0
  95. package/utils/price.js +32 -0
  96. package/utils/round.js +22 -0
  97. package/utils/windowInfo.js +77 -0
@@ -0,0 +1,192 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <template v-if="!isReadonly">
4
+ <textarea
5
+ :value="value"
6
+ :maxlength="maxlength"
7
+ :auto-height="autoHeight"
8
+ :class="$style['Textarea--input']"
9
+ @input="$emit('input', $event.detail.value)"
10
+ @blur="$_trim"
11
+ >
12
+ </textarea>
13
+ <view v-if="!value" :class="$style['Textarea--placeholder']">
14
+ <slot name="placeholder">
15
+ <icon-cpn icon="textarea-edit" :class="$style['Textarea--icon']" />
16
+ <text> {{ placeholder }} </text>
17
+ </slot>
18
+ </view>
19
+ <view :class="$style['Textarea--counter']"> 已输入 {{ count }}/{{ maxlength }} </view>
20
+ </template>
21
+ <!-- 只读文本展示 -->
22
+ <view v-else-if="value" :class="$style['Textarea--readonly']">
23
+ <view :class="{ [$style['Textarea--fold']]: fold && isFolded }"> {{ value }} </view>
24
+ <view v-if="fold && hasFoldButton" :class="$style['Textarea--fold-button']" @click="isFolded = !isFolded">
25
+ <text v-if="isFolded"> <icon-cpn icon="arrow-down" /> 展开 </text>
26
+ <text v-else> <icon-cpn icon="arrow-up" /> 收起 </text>
27
+ </view>
28
+ <!-- 隐藏文字,用于计算是否显示收起展开按钮 -->
29
+ <view v-if="fold" :class="[$style['Textarea--hidden-text'], $style['Textarea--fold']]"> {{ value }} </view>
30
+ <view v-if="fold" :class="$style['Textarea--hidden-text']"> {{ value }} </view>
31
+ </view>
32
+ <!-- 空文本展示 -->
33
+ <view v-else :class="[$style['Textarea--readonly'], $style['Textarea--empty']]"> 未填写 </view>
34
+ </view>
35
+ </template>
36
+
37
+ <script>
38
+ import componentName from '../../mixins/componentName';
39
+ import { isFormReadonly } from '../form/mixin';
40
+ import IconCpn from '../icon/icon.vue';
41
+
42
+ export default {
43
+ name: 'AppTextarea',
44
+ options: {
45
+ virtualHost: true,
46
+ styleIsolation: 'shared',
47
+ },
48
+ components: { IconCpn },
49
+ mixins: [componentName, isFormReadonly],
50
+ props: {
51
+ /** 绑定值 */
52
+ value: {
53
+ type: String,
54
+ default: '',
55
+ },
56
+ /** 最大输入文本长度 */
57
+ maxlength: {
58
+ type: Number,
59
+ default: 300,
60
+ },
61
+ /** 占位文本 */
62
+ placeholder: {
63
+ type: String,
64
+ default: '请输入',
65
+ },
66
+ /** 是否自动调整高度 */
67
+ autoHeight: {
68
+ type: Boolean,
69
+ default: true,
70
+ },
71
+ /** 是否只读 */
72
+ readonly: {
73
+ type: Boolean,
74
+ default: false,
75
+ },
76
+ /** 当只读时,如果文字过多,是否折叠 */
77
+ fold: {
78
+ type: Boolean,
79
+ default: true,
80
+ },
81
+ },
82
+ data() {
83
+ return {
84
+ /** 是否有收起展开按钮 */
85
+ hasFoldButton: false,
86
+ /** 当前是否处于收起状态 */
87
+ isFolded: true,
88
+ };
89
+ },
90
+ computed: {
91
+ /** 是否只读 */
92
+ isReadonly() {
93
+ return this.readonly || this.isFormReadonly;
94
+ },
95
+ /** 已输入字符长度 */
96
+ count() {
97
+ return this.value.length;
98
+ },
99
+ },
100
+ watch: {
101
+ isReadonly: {
102
+ handler(newVal) {
103
+ if (newVal && this.fold) {
104
+ this.$nextTick(() => {
105
+ this.shouldShowFold();
106
+ });
107
+ }
108
+ },
109
+ immediate: true,
110
+ },
111
+ },
112
+ methods: {
113
+ /** 去除头尾空白字符 */
114
+ $_trim(event) {
115
+ this.$emit('input', event.detail.value.trim());
116
+ },
117
+ /** 计算是否需要显示收起展开按钮 */
118
+ shouldShowFold() {
119
+ uni.createSelectorQuery()
120
+ .in(this)
121
+ .selectAll('.' + this.$style['Textarea--hidden-text'])
122
+ .boundingClientRect((rects) => {
123
+ this.hasFoldButton = rects.length === 2 && rects[1].height > rects[0].height;
124
+ })
125
+ .exec();
126
+ },
127
+ },
128
+ };
129
+ </script>
130
+
131
+ <style lang="scss" module>
132
+ @use '../../styles/index' as *;
133
+
134
+ :host {
135
+ display: block;
136
+ }
137
+ :host(.display-inline) {
138
+ display: inline;
139
+ }
140
+
141
+ .Textarea {
142
+ flex: 1;
143
+ position: relative;
144
+ padding: 20rpx;
145
+ background: UTILS__GLOBAL_VAR(color, background);
146
+ border-radius: 20rpx;
147
+ line-height: 1.5;
148
+ }
149
+ .Textarea--input {
150
+ width: 100%;
151
+ height: 150rpx;
152
+ min-height: 150rpx;
153
+ max-height: 300rpx;
154
+ padding: 0;
155
+ }
156
+ .Textarea--placeholder {
157
+ position: absolute;
158
+ top: 20rpx;
159
+ left: 20rpx;
160
+ padding: 0;
161
+ color: UTILS__GLOBAL_VAR(color, placeholder);
162
+ }
163
+ .Textarea--icon {
164
+ margin-right: 6rpx;
165
+ }
166
+ .Textarea--counter {
167
+ text-align: right;
168
+ color: UTILS__GLOBAL_VAR(color, placeholder);
169
+ }
170
+ .Textarea--readonly {
171
+ position: relative;
172
+ white-space: pre-wrap;
173
+ overflow: hidden;
174
+ }
175
+ .Textarea--fold {
176
+ @include UTILS__ELLIPSIS(5);
177
+ }
178
+ .Textarea--fold-button {
179
+ text-align: right;
180
+ color: #999;
181
+ }
182
+ .Textarea--hidden-text {
183
+ visibility: hidden;
184
+ position: absolute;
185
+ top: 0;
186
+ left: 0;
187
+ width: 100%;
188
+ }
189
+ .Textarea--empty {
190
+ color: #ccc;
191
+ }
192
+ </style>
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <picker-view
3
+ immediate-change
4
+ :value="pickerValue"
5
+ :class="componentClassNames"
6
+ @change="handlePickerChange"
7
+ @pickend="onPickEnd"
8
+ >
9
+ <picker-view-column>
10
+ <view v-for="item in hourOptions" :key="item" :class="$style['TimePickerView--option']">
11
+ {{ item }} 时
12
+ </view>
13
+ </picker-view-column>
14
+ <picker-view-column>
15
+ <view v-for="item in minuteOptions" :key="item" :class="$style['TimePickerView--option']">
16
+ {{ item }} 分
17
+ </view>
18
+ </picker-view-column>
19
+ </picker-view>
20
+ </template>
21
+
22
+ <script>
23
+ import range from 'lodash-es/range';
24
+ import componentName from '../../mixins/componentName';
25
+ import { formatDate } from '../../utils/date';
26
+
27
+ const hourOptions = range(0, 24).map((item) => ('' + item).padStart(2, '0'));
28
+
29
+ export default {
30
+ name: 'AppTimePickerView',
31
+ options: {
32
+ virtualHost: true,
33
+ styleIsolation: 'shared',
34
+ },
35
+ mixins: [componentName],
36
+ props: {
37
+ /** 绑定值 */
38
+ value: {
39
+ type: [String, null],
40
+ default: null,
41
+ },
42
+ /** 分钟步长 */
43
+ step: {
44
+ type: Number,
45
+ default: 5,
46
+ },
47
+ },
48
+ data() {
49
+ return {
50
+ innerValue: '',
51
+ /** 小时选项列表 */
52
+ hourOptions,
53
+ /** 分钟选项列表 */
54
+ minuteOptions: [],
55
+ /** picker-view 绑定值 */
56
+ pickerValue: [0, 0],
57
+ };
58
+ },
59
+ computed: {
60
+ currentValue: {
61
+ get: function () {
62
+ return this.value === null ? this.innerValue : this.value;
63
+ },
64
+ set: function (value) {
65
+ this.$emit('input', value);
66
+ this.innerValue = value;
67
+ this.$emit('change', value);
68
+ },
69
+ },
70
+ },
71
+ created() {
72
+ this.minuteOptions = range(0, 60, this.step);
73
+ },
74
+ mounted() {
75
+ this.$nextTick(() => {
76
+ this.syncPickerValue(this.currentValue || new Date());
77
+ });
78
+ },
79
+ methods: {
80
+ /** 同步 picker-view 选中索引 */
81
+ syncPickerValue(time) {
82
+ const [h, m] = time.split(':');
83
+ const i1 = this.hourOptions.indexOf(h);
84
+ const i2 = Math.max(this.minuteOptions.indexOf(Math.round(Number(m) / this.step) * this.step), 0);
85
+ this.$nextTick(() => {
86
+ this.pickerValue =
87
+ typeof this.pickerValue[0] === 'number' ? [i1, i2].map((item) => item.toString()) : [i1, i2];
88
+ });
89
+ },
90
+ /** picker-view 选项值变化处理 */
91
+ handlePickerChange(e) {
92
+ const newPickerValue = e.detail.value;
93
+ const hour = this.hourOptions[newPickerValue[0]];
94
+ const minute = this.step >= 0 ? this.minuteOptions[newPickerValue[1]] : '00';
95
+ this.pickerValue = newPickerValue;
96
+ const dateValue = new Date(0, 0, 1, hour, minute, 0, 0);
97
+ let dateStr = formatDate(dateValue, formatDate.TIME_MINUTE);
98
+ this.currentValue = dateStr;
99
+ },
100
+ /** 滑动结束处理,保持选择器显示值与输入框值一致 */
101
+ onPickEnd() {
102
+ this.$nextTick(() => {
103
+ this.syncPickerValue(this.currentValue);
104
+ });
105
+ },
106
+ },
107
+ };
108
+ </script>
109
+
110
+ <style lang="scss" module>
111
+ @use '../../styles/index' as *;
112
+
113
+ :host {
114
+ display: flex;
115
+ }
116
+
117
+ .TimePickerView {
118
+ margin-top: 24rpx;
119
+ height: 300rpx;
120
+ }
121
+ .TimePickerView--option {
122
+ display: flex;
123
+ align-items: center;
124
+ justify-content: center;
125
+ white-space: nowrap;
126
+ }
127
+ </style>
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <selector-cpn
4
+ :value="showText"
5
+ :readonly="isReadonly"
6
+ :disabled="disabled"
7
+ :placeholder="placeholder"
8
+ @click="showPicker"
9
+ />
10
+
11
+ <!-- 选择器弹框 -->
12
+ <popup-cpn
13
+ v-if="isShowPopup"
14
+ ref="popup"
15
+ v-model="isShowPopup"
16
+ :cancel="false"
17
+ title="选择时间"
18
+ @click.native.stop.prevent="doNothing"
19
+ @confirm="onConfirm"
20
+ >
21
+ <view class="TimePicker--picker-area">
22
+ <time-picker-view-cpn v-model="startStr" :step="step" />
23
+ <template v-if="range">
24
+ <view>至</view>
25
+ <time-picker-view-cpn v-model="endStr" :step="step" />
26
+ </template>
27
+ </view>
28
+ </popup-cpn>
29
+ </view>
30
+ </template>
31
+
32
+ <script>
33
+ import componentName from '../../mixins/componentName';
34
+ import { isFormReadonly } from '../form/mixin';
35
+ import PopupCpn from '../popup/popup.vue';
36
+ import SelectorCpn from '../selector/selector.vue';
37
+ import TimePickerViewCpn from './time-picker-view.vue';
38
+
39
+ export default {
40
+ name: 'AppTimePicker',
41
+ options: {
42
+ virtualHost: true,
43
+ styleIsolation: 'shared',
44
+ },
45
+ components: { PopupCpn, SelectorCpn, TimePickerViewCpn },
46
+ mixins: [componentName, isFormReadonly],
47
+ props: {
48
+ /** 绑定值 */
49
+ value: {
50
+ type: [String, null, Array],
51
+ default: null,
52
+ },
53
+ /** 是否禁用 */
54
+ disabled: {
55
+ type: Boolean,
56
+ default: false,
57
+ },
58
+ /** 是否只读 */
59
+ readonly: {
60
+ type: Boolean,
61
+ default: false,
62
+ },
63
+ /** 占位文本 */
64
+ placeholder: {
65
+ type: String,
66
+ default: '请选择',
67
+ },
68
+ /** 是否时间范围选择器 */
69
+ range: {
70
+ type: Boolean,
71
+ default: false,
72
+ },
73
+ /** 分钟步长 */
74
+ step: {
75
+ type: Number,
76
+ default: 5,
77
+ },
78
+ },
79
+ data() {
80
+ return {
81
+ /** 选择框是否可见 */
82
+ isShowPopup: false,
83
+ /** 开始日期 */
84
+ startStr: '',
85
+ /** 结束日期 */
86
+ endStr: '',
87
+ };
88
+ },
89
+ computed: {
90
+ isReadonly() {
91
+ return this.readonly || this.isFormReadonly;
92
+ },
93
+ startTime() {
94
+ return this.range && Array.isArray(this.value) ? this.value[0] : this.value;
95
+ },
96
+ endTime() {
97
+ return this.range && Array.isArray(this.value) ? this.value[1] : '';
98
+ },
99
+ showText() {
100
+ return this.range && this.startTime && this.endTime
101
+ ? `${this.startTime} 至 ${this.endTime}`
102
+ : this.startTime;
103
+ },
104
+ },
105
+ methods: {
106
+ doNothing() {},
107
+ /** 显示选择器弹出框 */
108
+ showPicker() {
109
+ if (this.disabled || this.isReadonly) {
110
+ return;
111
+ }
112
+
113
+ this.startStr = this.startTime;
114
+ this.endStr = this.endTime;
115
+
116
+ this.isShowPopup = true;
117
+ this.$emit('show');
118
+ },
119
+ onConfirm() {
120
+ this.$refs.popup.close();
121
+ this.$emit('input', this.range ? [this.startStr, this.endStr] : this.startStr);
122
+ this.$emit('change', this.range ? [this.startStr, this.endStr] : this.startStr);
123
+ },
124
+ },
125
+ };
126
+ </script>
127
+
128
+ <style lang="scss" module>
129
+ @use '../../styles/index' as *;
130
+
131
+ .TimePicker {
132
+ width: 100%;
133
+ height: 100%;
134
+ }
135
+
136
+ .TimePicker--picker-area {
137
+ display: flex;
138
+ align-items: center;
139
+ }
140
+ </style>
@@ -0,0 +1,81 @@
1
+ const STORAGE_KEY = 'cached_files';
2
+
3
+ function hasFile(url) {
4
+ const files = uni.getStorageSync(STORAGE_KEY);
5
+ if (!files || !files[url]) {
6
+ return false;
7
+ }
8
+ try {
9
+ uni.getFileSystemManager().accessSync(files[url]);
10
+ return files[url];
11
+ } catch {
12
+ return false;
13
+ }
14
+ }
15
+
16
+ /**
17
+ * 缓存文件
18
+ * @param {string} url 文件下载路径
19
+ * @param {string} name 带后缀的文件名
20
+ * @returns 缓存后的路口
21
+ */
22
+ function cacheFile(url, name) {
23
+ const filePath = hasFile(url);
24
+ if (filePath) {
25
+ return Promise.resolve(filePath);
26
+ }
27
+ return download(url).then((res) => {
28
+ let filePath = uni.getFileSystemManager().saveFileSync(
29
+ res.filePath,
30
+ /* #ifdef MP-WEIXIN */
31
+ `${wx.env.USER_DATA_PATH}/${name}`,
32
+ /* #endif */
33
+ /* #ifdef MP-ALIPAY */
34
+ `${my.env.USER_DATA_PATH}/${name}`
35
+ /* #endif */
36
+ );
37
+ const files = uni.getStorageSync(STORAGE_KEY) || {};
38
+ /* #ifdef MP-ALIPAY */
39
+ filePath = filePath.savedFilePath;
40
+ /* #endif */
41
+ files[url] = filePath;
42
+ uni.setStorageSync(STORAGE_KEY, files);
43
+
44
+ return filePath;
45
+ });
46
+ }
47
+
48
+ /**
49
+ * 下载文件
50
+ * @param {string} url 文件下载路径
51
+ * @param {string} name 文件下载后名称
52
+ * @returns 下载后的临时路径
53
+ */
54
+ function download(url, name) {
55
+ return new Promise((resolve, reject) => {
56
+ uni.downloadFile({
57
+ url,
58
+ filePath: name ? `${wx.env.USER_DATA_PATH}/${name}` : undefined,
59
+ success: function (res) {
60
+ const filePath = res.filePath || res.tempFilePath;
61
+ let fileName = name || '';
62
+ // 从响应头获取文件名
63
+ if (!fileName && res.header) {
64
+ const match = /(filename=(.*))|(filename\*=[^']*'[^']*'(.*))/.exec(
65
+ res.header['Content-Disposition']
66
+ );
67
+ if (match) {
68
+ fileName = decodeURI(match[2] || match[4]);
69
+ fileName = fileName.replace(/^["']*|["']*$/g, '');
70
+ }
71
+ }
72
+ resolve({ res, filePath, fileName });
73
+ },
74
+ fail: function (error) {
75
+ reject(error);
76
+ },
77
+ });
78
+ });
79
+ }
80
+
81
+ export { download, cacheFile };
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <view :class="componentClassNames">
3
+ <view>
4
+ <button-cpn>上传</button-cpn>
5
+ </view>
6
+ <view>
7
+ <view v-for="(file, idx) in currentValue" :key="idx" :class="$style['Uploader--file-item']">
8
+ {{ file.name || file.path }}
9
+ </view>
10
+ </view>
11
+ </view>
12
+ </template>
13
+
14
+ <script>
15
+ import componentName from '../../mixins/componentName';
16
+ import ButtonCpn from '../button/button.vue';
17
+ import UploadMixin from './mixin';
18
+
19
+ export default {
20
+ name: 'AppUploader',
21
+ options: {
22
+ virtualHost: true,
23
+ styleIsolation: 'shared',
24
+ },
25
+ components: { ButtonCpn },
26
+ mixins: [componentName, UploadMixin],
27
+ props: {
28
+ /** 文件列表 */
29
+ value: {
30
+ type: Array,
31
+ default: () => [],
32
+ },
33
+ },
34
+ methods: {},
35
+ };
36
+ </script>
37
+
38
+ <style lang="scss" module>
39
+ .Uploader {
40
+ width: 100%;
41
+ }
42
+ .Uploader--file-item {
43
+ &:first-child {
44
+ margin-top: 20rpx;
45
+ }
46
+ padding: 15rpx 0;
47
+ font-size: 28rpx;
48
+ white-space: nowrap;
49
+ overflow: hidden;
50
+ text-overflow: ellipsis;
51
+ }
52
+ </style>