v-uni-app-ui 1.0.4 → 1.0.6

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 (89) hide show
  1. package/README.md +62 -82
  2. package/dist/v-uni-app-ui.css +1 -0
  3. package/dist/v-uni-app-ui.es.js +6569 -0
  4. package/dist/v-uni-app-ui.umd.js +7 -0
  5. package/package.json +17 -5
  6. package/components/config/css/basic.scss +0 -19
  7. package/components/config/interface/basic-type.js +0 -16
  8. package/components/config/interface/components-interface.ts +0 -0
  9. package/components/config/interface/monitor/components/input-monitor.js +0 -0
  10. package/components/config/interface/monitor/property-monitor.ts +0 -136
  11. package/components/config/interface/props/basic-props.ts +0 -88
  12. package/components/config/interface/props/components/button-props.ts +0 -85
  13. package/components/config/interface/props/components/input-props.ts +0 -69
  14. package/components/config/interface/props/props-tools.ts +0 -64
  15. package/components/config/style/basic.js +0 -346
  16. package/components/config/style/component-registry.js +0 -142
  17. package/components/config/style/components/button-style.js +0 -160
  18. package/components/config/style/components/input-style.js +0 -98
  19. package/components/config/style/components-style.js +0 -622
  20. package/components/config/style/property-mapper.js +0 -377
  21. package/components/config/style/pseudo-processor.js +0 -213
  22. package/components/config.js +0 -123
  23. package/components/icon/iconfont.css +0 -87
  24. package/components/icon/iconfont.js +0 -1
  25. package/components/icon/iconfont.json +0 -135
  26. package/components/icon/iconfont.ttf +0 -0
  27. package/components/icon/iconfont.woff +0 -0
  28. package/components/icon/iconfont.woff2 +0 -0
  29. package/components/layout/v-card/v-card.vue +0 -108
  30. package/components/layout/v-grid/v-grid.vue +0 -162
  31. package/components/layout/v-icon-grid/v-icon-grid.vue +0 -195
  32. package/components/layout/v-infinite-scroll/v-infinite-scroll.vue +0 -172
  33. package/components/layout/v-list/v-list.vue +0 -43
  34. package/components/layout/v-row/v-row.vue +0 -142
  35. package/components/layout/v-waterfall/v-waterfall.vue +0 -79
  36. package/components/model/compound/v-checkbox-group/v-checkbox-group.vue +0 -96
  37. package/components/model/compound/v-console/v-console.js +0 -20
  38. package/components/model/compound/v-console/v-console.vue +0 -299
  39. package/components/model/compound/v-date-time/v-date-time.vue +0 -261
  40. package/components/model/compound/v-dialog/v-dialog.vue +0 -178
  41. package/components/model/compound/v-drum-select-picker/v-drum-select-picker.vue +0 -83
  42. package/components/model/compound/v-form/v-form.vue +0 -226
  43. package/components/model/compound/v-form-item/v-form-item.vue +0 -255
  44. package/components/model/compound/v-image/v-image.vue +0 -357
  45. package/components/model/compound/v-input-desensitize/v-input-desensitize.vue +0 -101
  46. package/components/model/compound/v-page/v-page.vue +0 -11
  47. package/components/model/compound/v-pages/v-pages.vue +0 -141
  48. package/components/model/compound/v-picker-list/v-picker-list.vue +0 -109
  49. package/components/model/compound/v-popup/v-popup.vue +0 -151
  50. package/components/model/compound/v-radio-group/v-radio-group.vue +0 -86
  51. package/components/model/compound/v-select-picker/v-select-picker.vue +0 -202
  52. package/components/model/compound/v-series-picker-list/v-series-picker-list.vue +0 -221
  53. package/components/model/compound/v-series-select-picker/v-series-select-picker.vue +0 -203
  54. package/components/model/compound/v-switch/v-switch.vue +0 -136
  55. package/components/model/compound/v-tabs-page/v-tabs-page.vue +0 -138
  56. package/components/model/native/v-badge/v-badge.vue +0 -143
  57. package/components/model/native/v-button/v-button.vue +0 -81
  58. package/components/model/native/v-carousel/v-carousel.vue +0 -138
  59. package/components/model/native/v-checkbox/v-checkbox.vue +0 -215
  60. package/components/model/native/v-collapse/v-collapse.vue +0 -190
  61. package/components/model/native/v-header-navigation-bar/v-header-navigation-bar.vue +0 -92
  62. package/components/model/native/v-input/v-input.vue +0 -163
  63. package/components/model/native/v-input-code/v-input-code.vue +0 -146
  64. package/components/model/native/v-loading/v-loading.vue +0 -206
  65. package/components/model/native/v-menu/v-menu.vue +0 -222
  66. package/components/model/native/v-menu-slide/v-menu-slide.vue +0 -364
  67. package/components/model/native/v-min-loading/v-min-loading.vue +0 -80
  68. package/components/model/native/v-null/v-null.vue +0 -97
  69. package/components/model/native/v-overlay/v-overlay.vue +0 -96
  70. package/components/model/native/v-pull-up-refresh/v-pull-up-refresh.vue +0 -157
  71. package/components/model/native/v-radio/v-radio.vue +0 -138
  72. package/components/model/native/v-scroll-list/v-scroll-list.vue +0 -169
  73. package/components/model/native/v-steps/v-steps.vue +0 -253
  74. package/components/model/native/v-table/v-table.vue +0 -203
  75. package/components/model/native/v-tabs/v-tabs.vue +0 -235
  76. package/components/model/native/v-tag/v-tag.vue +0 -206
  77. package/components/model/native/v-text/v-text.vue +0 -187
  78. package/components/model/native/v-textarea/v-textarea.vue +0 -178
  79. package/components/model/native/v-title/v-title.vue +0 -91
  80. package/components/model/native/v-toast/info.png +0 -0
  81. package/components/model/native/v-toast/success.png +0 -0
  82. package/components/model/native/v-toast/v-toast.vue +0 -198
  83. package/components/model/native/v-toast/warn.png +0 -0
  84. package/components/model/native/v-upload-file-button/v-upload-file-button.vue +0 -296
  85. package/components/model/native/v-video/v-video.vue +0 -175
  86. package/components/model/native/v-window/v-window.vue +0 -158
  87. package/components/utils/event-modifiers.ts +0 -139
  88. package/components/utils/validator.ts +0 -451
  89. package/index.js +0 -372
@@ -1,296 +0,0 @@
1
- <template>
2
- <button @click="handleFileChange" :class="['upload-button', { uploading: uploading }]" :disabled="disabled">
3
- <template v-if="!uploading && !fileSelected">
4
- <slot>
5
- <view class="upload-icon">
6
- <text class="icon-upload"></text>
7
- </view>
8
- <view class="upload-text">
9
- {{ buttonText }}
10
- </view>
11
- </slot>
12
- </template>
13
- <template v-else>
14
- <view v-if="uploading" class="upload-progress">
15
- <slot name="loading" :progress="progress">
16
- <view class="progress-bar">
17
- <view class="progress-bar-filled" :style="{ width: `${progress}%` }"></view>
18
- </view>
19
- <view class="progress-text">{{ progress }}%</view>
20
- </slot>
21
- </view>
22
- <view v-else-if="fileSelected" class="selected-file">
23
- <slot name="selected-file" :file="selectedFile" :file-type="fileFormat" :file-size="fileSize">
24
- <view class="file-name">{{ selectedFile.name }}</view>
25
- <view class="file-info">{{ fileFormat }} {{ fileSize }}</view>
26
- </slot>
27
- </view>
28
- </template>
29
- </button>
30
- </template>
31
-
32
- <script setup lang="ts">
33
- import { ref, computed, inject, watchEffect } from 'vue';
34
-
35
- const props = defineProps({
36
- buttonText: {
37
- type: String,
38
- default: '上传文件'
39
- },
40
- accept: {
41
- type: String,
42
- default: '*'
43
- },
44
- disabled: {
45
- type: Boolean,
46
- default: false
47
- },
48
- uploadUrl: {
49
- type: String,
50
- required: true
51
- },
52
- toKen: {
53
- type: String,
54
- default: null
55
- },
56
- requestMode: {
57
- type: String,
58
- default: 'POST'
59
- }
60
- });
61
-
62
- const emit = defineEmits(['success', 'error', 'cancel']);
63
-
64
- const config = inject<any>('config');
65
- const selectedFile = ref(null);
66
- const progress = ref<number>(0);
67
- const uploading = ref<boolean>(false);
68
- const fileSelected = ref<boolean>(false);
69
-
70
- const fileFormat = computed(() => {
71
- if (selectedFile.value) {
72
- const name = selectedFile.value.name;
73
- const extension = name.split('.').pop().toLowerCase(); // 获取文件扩展名
74
-
75
- if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(extension)) {
76
- return '图片';
77
- }
78
- if (extension === 'pdf') {
79
- return 'PDF';
80
- }
81
- return '文件';
82
- }
83
- return '';
84
- });
85
-
86
- const fileSize = computed(() => {
87
- if (selectedFile.value) {
88
- const size = selectedFile.value.size;
89
- if (size < 1024) return `${size} B`;
90
- if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
91
- return `${(size / 1024 / 1024).toFixed(2)} MB`;
92
- }
93
- return '';
94
- });
95
-
96
- watchEffect(() => {
97
- if (props.disabled) {
98
- uploading.value = false;
99
- }
100
- });
101
- const handleFileChange = () => {
102
- if (typeof uni !== 'undefined') {
103
- // 使用 uni.chooseImage 选择图片
104
- uni.chooseImage({
105
- count: 1,
106
- sizeType: ['original', 'compressed'],
107
- sourceType: ['album', 'camera'],
108
- success: (res) => {
109
- const tempFilePath = res.tempFilePaths[0];
110
- selectedFile.value = { path: tempFilePath, name: tempFilePath.split('/').pop() };
111
- fileSelected.value = true;
112
- uploadFile(tempFilePath); // 直接传递文件路径
113
- },
114
- fail: (err) => {
115
- console.error('选择图片失败:', err);
116
- }
117
- });
118
- } else {
119
- // 浏览器环境使用 HTML File API
120
- const input = document.createElement('input');
121
- input.type = 'file';
122
- input.accept = props.accept;
123
- input.onchange = (e) => {
124
- const files = e.target.files;
125
- if (files && files.length > 0) {
126
- selectedFile.value = files[0];
127
- fileSelected.value = true;
128
- uploadFile(files[0]);
129
- }
130
- };
131
- input.click();
132
- }
133
- };
134
-
135
- const uploadFile = (file) => {
136
- if (!file) return;
137
- uploading.value = true;
138
- progress.value = 0;
139
-
140
- if (typeof uni !== 'undefined') {
141
- // uni-app 环境
142
- const uploadTask = uni.uploadFile({
143
- url: props.uploadUrl,
144
- filePath: file,
145
- name: 'file',
146
- header: props.toKen
147
- ? {
148
- Authorization: `Bearer ${props.toKen}`
149
- }
150
- : {},
151
- formData: {},
152
- timeout: 60000, // 设置超时时间为60秒
153
- success: (res) => {
154
- emit('success', JSON.parse(res.data));
155
- },
156
- fail: (err) => {
157
- console.error('上传失败:', err);
158
- emit('error', err);
159
- },
160
- complete: () => {
161
- uploading.value = false;
162
- }
163
- });
164
-
165
- // 监听上传进度
166
- uploadTask.onProgressUpdate((res) => {
167
- progress.value = res.progress;
168
- });
169
- } else {
170
- // 浏览器环境
171
- const formData = new FormData();
172
- formData.append('file', file);
173
-
174
- const xhr = new XMLHttpRequest();
175
- xhr.open(props.requestMode, props.uploadUrl, true);
176
- if (props.toKen) {
177
- xhr.setRequestHeader('Authorization', `Bearer ${props.toKen}`);
178
- }
179
-
180
- xhr.upload.onprogress = (event) => {
181
- if (event.lengthComputable) {
182
- progress.value = (event.loaded / event.total) * 100;
183
- }
184
- };
185
-
186
- xhr.onload = () => {
187
- if (xhr.status >= 200 && xhr.status < 300) {
188
- emit('success', JSON.parse(xhr.responseText));
189
- } else {
190
- console.error('上传失败:', xhr.statusText);
191
- emit('error', { errMsg: '上传失败' });
192
- }
193
- uploading.value = false;
194
- };
195
-
196
- xhr.onerror = () => {
197
- console.error('上传出错:', xhr.statusText);
198
- emit('error', { errMsg: '上传出错' });
199
- uploading.value = false;
200
- };
201
-
202
- xhr.send(formData);
203
- }
204
- };
205
- </script>
206
-
207
- <style lang="scss" scoped>
208
- .upload-button {
209
- position: relative;
210
- display: flex;
211
- flex-direction: column;
212
- align-items: center;
213
- justify-content: center;
214
- width: 100%;
215
- min-height: 140rpx;
216
- border: 4rpx dashed;
217
- border-color: v-bind('config.border.color');
218
- border-radius: v-bind('config.borderRadius.semicircle');
219
- background-color: v-bind('config.VUploadFileButton.backgroundColor');
220
- color: v-bind('config.fontColor.mainText');
221
- cursor: pointer;
222
- transition: all 0.3s;
223
-
224
- &:hover {
225
- border-color: v-bind('config.border.default');
226
- background-color: v-bind('config.VUploadFileButton.backgroundColor');
227
- color: v-bind('config.fontColor.default');
228
- }
229
-
230
- &:disabled {
231
- cursor: not-allowed;
232
- opacity: 0.6;
233
- }
234
-
235
- &.uploading {
236
- border-color: v-bind('config.border.default');
237
- background-color: v-bind('config.VUploadFileButton.backgroundColor');
238
- color: v-bind('config.fontColor.default');
239
- }
240
-
241
- .upload-icon {
242
- margin-bottom: 8rpx;
243
- .icon-upload {
244
- font-size: v-bind('config.fontSize.mediumText');
245
- }
246
- }
247
-
248
- .upload-text {
249
- font-size: v-bind('config.fontSize.mediumText');
250
- }
251
-
252
- .upload-progress {
253
- width: 100%;
254
- text-align: center;
255
- }
256
-
257
- .progress-bar {
258
- width: 100%;
259
- height: 16rpx;
260
- background-color: v-bind('config.VUploadFileButton.backgroundColor');
261
- border-radius: 4rpx;
262
- overflow: hidden;
263
- margin-bottom: 8rpx;
264
- }
265
-
266
- .progress-bar-filled {
267
- height: 100%;
268
- background-color: v-bind('config.backgroundColor.default');
269
- width: 0;
270
- transition: width 0.3s;
271
- }
272
-
273
- .progress-text {
274
- font-size: v-bind('config.fontSize.mediumText');
275
- color: v-bind('config.fontColor.default');
276
- }
277
-
278
- .selected-file {
279
- width: 100%;
280
- text-align: center;
281
- }
282
-
283
- .file-name {
284
- font-size: v-bind('config.fontSize.mediumText');
285
- margin-bottom: 6rpx;
286
- white-space: nowrap;
287
- overflow: hidden;
288
- text-overflow: ellipsis;
289
- }
290
-
291
- .file-info {
292
- font-size: v-bind('config.fontSize.mediumText');
293
- color: v-bind('config.fontColor.info');
294
- }
295
- }
296
- </style>
@@ -1,175 +0,0 @@
1
- <template>
2
- <view class="v-video-container">
3
- <video
4
- :id="videoId"
5
- :src="videoContext.src"
6
- :poster="poster"
7
- :autoplay="autoplay"
8
- :controls="controls"
9
- :loop="loop"
10
- :muted="muted"
11
- :object-fit="objectFit"
12
- :class="videoClass"
13
- :style="videoStyle"
14
- @play="handlePlay"
15
- @pause="handlePause"
16
- @ended="handleEnded"
17
- @click="handleVideoClick"
18
- @touchstart="handleTouchStart"
19
- @touchmove="handleTouchMove"
20
- @touchend="handleTouchEnd"
21
- :error="handleError"
22
- style="width: 100%; height: 100%"
23
- ></video>
24
- <!-- 加载插槽 -->
25
- <slot name="loading" v-if="isLoading" />
26
-
27
- <!-- 错误插槽 -->
28
- <slot name="error" v-if="isError" />
29
-
30
- <!-- 新增:暂停插槽(非 loading / 非 error / 已暂停 / 未结束) -->
31
- <slot name="paused" v-if="!isLoading && !isError && isPaused && !hasEnded" />
32
- </view>
33
- </template>
34
-
35
- <script setup lang="ts">
36
- import { ref, onMounted, watch, reactive } from 'vue';
37
-
38
- interface Props {
39
- src: string;
40
- poster?: string;
41
- autoplay?: boolean;
42
- controls?: boolean;
43
- loop?: boolean;
44
- muted?: boolean;
45
- objectFit?: string;
46
- width?: string;
47
- height?: string;
48
- videoClass?: string;
49
- videoStyle?: string;
50
- }
51
-
52
- const props = withDefaults(defineProps<Props>(), {
53
- poster: '',
54
- autoplay: false,
55
- controls: true,
56
- loop: false,
57
- muted: false,
58
- objectFit: 'contain',
59
- width: '100%',
60
- height: '100%',
61
- videoClass: '',
62
- videoStyle: ''
63
- });
64
-
65
- const emit = defineEmits(['play', 'pause', 'ended', 'error']);
66
-
67
- const videoId = ref('video_' + Date.now());
68
- const isLoading = ref(true);
69
- const isError = ref(false);
70
- const videoContext = reactive({
71
- src: props.src
72
- });
73
- const videoElement = ref(null);
74
- const touchStartX = ref(0);
75
- const touchStartTime = ref(0);
76
- const isLongPress = ref(false);
77
- const clickNumber = ref(0);
78
- const isPaused = ref(true);
79
- const hasEnded = ref(false);
80
-
81
- onMounted(() => {
82
- videoElement.value = uni.createVideoContext(videoId.value);
83
- });
84
-
85
- watch(
86
- () => props.src,
87
- (newValue) => {
88
- isLoading.value = true;
89
- if (newValue) {
90
- videoContext.src = newValue;
91
- }
92
- },
93
- { immediate: true }
94
- );
95
- watch(
96
- () => props.src,
97
- (newValue) => {
98
- isLoading.value = true;
99
- if (newValue) {
100
- videoContext.src = newValue;
101
- }
102
- },
103
- { immediate: true }
104
- );
105
-
106
- const handlePlay = () => {
107
- isLoading.value = false;
108
- isError.value = false;
109
- isPaused.value = false;
110
- hasEnded.value = false;
111
- emit('play');
112
- };
113
-
114
- const handlePause = () => {
115
- isPaused.value = true;
116
- emit('pause');
117
- };
118
-
119
- const handleEnded = () => {
120
- hasEnded.value = true;
121
- isPaused.value = true;
122
- emit('ended');
123
- };
124
-
125
- const handleError = (event: Event) => {
126
- isLoading.value = false;
127
- isError.value = true;
128
- emit('error', event);
129
- };
130
-
131
- const handleVideoClick = () => {
132
- if (!props.controls && videoElement.value) {
133
- clickNumber.value++;
134
- if (clickNumber.value % 2 == 0) {
135
- videoElement.value.play();
136
- } else {
137
- videoElement.value.pause();
138
- }
139
- }
140
- };
141
-
142
- const handleTouchStart = (event) => {
143
- touchStartX.value = event.touches[0].clientX;
144
- touchStartTime.value = Date.now();
145
- setTimeout(() => {
146
- if (Date.now() - touchStartTime.value > 500 && !isLongPress.value) {
147
- isLongPress.value = true;
148
- }
149
- }, 500);
150
- };
151
-
152
- const handleTouchMove = (event) => {
153
- if (!props.controls && isLongPress.value && videoElement.value) {
154
- const touchMoveX = event.touches[0].clientX;
155
- const videoWidth = videoElement.value.videoWidth;
156
- const seekTime = videoElement.value.currentTime;
157
- const duration = videoElement.value.duration;
158
- const moveDistance = touchMoveX - touchStartX.value;
159
- const seekPercentage = moveDistance / videoWidth;
160
- const newTime = Math.max(0, Math.min(duration, seekTime + seekPercentage * duration));
161
- videoElement.value.currentTime = newTime;
162
- }
163
- };
164
-
165
- const handleTouchEnd = () => {
166
- isLongPress.value = false;
167
- };
168
- </script>
169
-
170
- <style scoped>
171
- .v-video-container {
172
- width: 100%;
173
- height: 100%;
174
- }
175
- </style>
@@ -1,158 +0,0 @@
1
- <template>
2
- <view v-show="show" :class="['v-window', `v-window--size-${size}`, { 'v-window--fullscreen': fullscreen }]" :style="windowStyle">
3
- <view class="v-window-header" v-if="title">
4
- <view class="v-window-title">{{ title }}</view>
5
- <view class="v-window-actions" v-if="showActions">
6
- <button class="v-window-action" @click="minimize">
7
- <text class="icon-minimize">-</text>
8
- </button>
9
- <button class="v-window-action" @click="maximize">
10
- <text class="icon-maximize">□</text>
11
- </button>
12
- <button class="v-window-action" @click="close">
13
- <text class="icon-close">×</text>
14
- </button>
15
- </view>
16
- </view>
17
- <view class="v-window-content">
18
- <slot></slot>
19
- </view>
20
- </view>
21
- </template>
22
-
23
- <script setup lang="ts">
24
- import { ref, computed,inject,watch } from 'vue';
25
-
26
- const props = defineProps({
27
- title: {
28
- type: String,
29
- default: ''
30
- },
31
- fullscreen: {
32
- type: Boolean,
33
- default: false
34
- },
35
- showActions:{
36
- type:Boolean,
37
- default:true
38
- },
39
- show:{
40
- type:Boolean,
41
- default:true
42
- }
43
- });
44
-
45
- const emit = defineEmits(['update:show','update:showActions','update:fullscreen','close', 'minimize', 'maximize']);
46
- const config = inject<any>('config');
47
- const windowStyle = computed(() => {
48
- return {
49
- width: props.fullscreen ? '100%' : undefined,
50
- height: props.fullscreen ? '100%' : undefined,
51
- '--window-title-color': '#333',
52
- '--window-content-bg': '#fff',
53
- '--window-border-color': '#e0e0e0'
54
- };
55
- });
56
-
57
- const showActions = ref(props.showActions);
58
- const show = ref(props.show);
59
- const fullscreen = ref(props.fullscreen);
60
-
61
- watch(()=>props.show,(newValue)=>{
62
- show.value = newValue;
63
- },{
64
- immediate:true
65
- })
66
- watch(()=>props.showActions,(newValue)=>{
67
- showActions.value = newValue;
68
- },{
69
- immediate:true
70
- })
71
- watch(()=>props.fullscreen,(newValue)=>{
72
- fullscreen.value = newValue;
73
- },{
74
- immediate:true
75
- })
76
-
77
-
78
- const close = () => {
79
- show.value = false;
80
- emit('update:show',false)
81
- emit('close');
82
- };
83
-
84
- const minimize = () => {
85
- fullscreen.value = false;
86
- emit('update:fullscreen',false);
87
- emit('minimize');
88
- };
89
-
90
- const maximize = () => {
91
- fullscreen.value = true;
92
- emit('update:fullscreen',true);
93
- emit('maximize');
94
- };
95
- </script>
96
-
97
- <style lang="scss" scoped>
98
- .v-window {
99
- width: 80%;
100
- height: 100%;
101
- display: flex;
102
- flex-direction: column;
103
- border: 1rpx solid var(--window-border-color);
104
- border-radius: 4rpx;
105
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
106
- background-color: var(--window-content-bg);
107
- overflow: hidden;
108
- margin: auto;
109
-
110
- &--fullscreen {
111
- width: 100%;
112
- height: 100%;
113
- position: fixed;
114
- top: 0;
115
- left: 0;
116
- right: 0;
117
- bottom: 0;
118
- z-index: 1000;
119
- }
120
-
121
- .v-window-header {
122
- display: flex;
123
- justify-content: space-between;
124
- align-items: center;
125
- padding: 8rpx 16rpx;
126
- background-color: var(--window-content-bg);
127
- border-bottom: 1rpx solid var(--window-border-color);
128
-
129
- .v-window-title {
130
- font-size: v-bind("config.fontSize.mediumTitle");
131
- font-weight: bold;
132
- color: var(--window-title-color);
133
- }
134
-
135
- .v-window-actions {
136
- display: flex;
137
- }
138
-
139
- .v-window-action {
140
- background: none;
141
- border: none;
142
- cursor: pointer;
143
- font-size: v-bind("config.fontSize.smallText");
144
- margin-left: 8rpx;
145
-
146
- &:hover {
147
- background-color: #f5f5f5;
148
- }
149
- }
150
- }
151
-
152
- .v-window-content {
153
- flex: 1;
154
- padding: 16rpx;
155
- overflow: auto;
156
- }
157
- }
158
- </style>