tang-ui-x 1.1.4 → 1.1.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.
- package/components/TForm/index.uvue +54 -35
- package/components/TSelect/index.uvue +2 -5
- package/package.json +1 -1
- package/style/index.scss +26 -23
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import TSwitch from '../TSwitch/index.uvue'
|
|
6
6
|
import TRate from '../TRate/index.uvue'
|
|
7
7
|
import TSlider from '../TSlider/index.uvue'
|
|
8
|
+
import TSelect from '../TSelect/index.uvue'
|
|
8
9
|
import type { FormOption, FormSchema, TFormProps, ComponentProps } from './type.uts'
|
|
9
10
|
import { useI18n } from '../../composables/useI18n.uts'
|
|
10
11
|
|
|
@@ -52,23 +53,9 @@
|
|
|
52
53
|
return $t('form.inputPlaceholder', { label: item.label })
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const getSelectOptions = (item : FormSchema) => {
|
|
56
57
|
const options = item.componentProps?.options as FormOption[] | undefined
|
|
57
|
-
return options?.map(o => o.label) || []
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const getSelectLabel = (item : FormSchema) => {
|
|
61
|
-
const options = item.componentProps?.options as FormOption[] | undefined
|
|
62
|
-
const opt = options?.find(o => o.value === model.value[item.field])
|
|
63
|
-
return opt?.label || ''
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const onSelectChange = (e : any, item : FormSchema) => {
|
|
67
|
-
const index = e.detail.value as number
|
|
68
|
-
const options = item.componentProps?.options as FormOption[] | undefined
|
|
69
|
-
const value = options?.[index]?.value ?? ''
|
|
70
|
-
model.value[item.field] = value
|
|
71
|
-
validateField(item)
|
|
58
|
+
return options?.map(o => ({ label: o.label, value: o.value })) || []
|
|
72
59
|
}
|
|
73
60
|
|
|
74
61
|
const onTimeChange = (e : any, item : FormSchema) => {
|
|
@@ -79,11 +66,23 @@
|
|
|
79
66
|
const validateField = (item : FormSchema) => {
|
|
80
67
|
if (item.required && !model.value[item.field]) {
|
|
81
68
|
errors[item.field] = $t('form.requiredError', { label: item.label })
|
|
69
|
+
// 触发抖动动画
|
|
70
|
+
triggerShake(item.field)
|
|
82
71
|
} else {
|
|
83
72
|
delete errors[item.field]
|
|
84
73
|
}
|
|
85
74
|
}
|
|
86
75
|
|
|
76
|
+
// 抖动动画状态
|
|
77
|
+
const shakeFields = reactive<Record<string, boolean>>({})
|
|
78
|
+
|
|
79
|
+
const triggerShake = (field : string) => {
|
|
80
|
+
shakeFields[field] = true
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
shakeFields[field] = false
|
|
83
|
+
}, 500)
|
|
84
|
+
}
|
|
85
|
+
|
|
87
86
|
const onRadioChange = (value : string | number) => {
|
|
88
87
|
// 值已通过 v-model 更新,只需验证
|
|
89
88
|
}
|
|
@@ -164,7 +163,9 @@
|
|
|
164
163
|
<template>
|
|
165
164
|
<view class="t-form">
|
|
166
165
|
<form @submit="onFormSubmit" @reset="onFormReset">
|
|
167
|
-
<view v-for="(item, index) in schemas" class="form-item"
|
|
166
|
+
<view v-for="(item, index) in schemas" class="form-item"
|
|
167
|
+
:class="{ 'form-item-error': errors[item.field], 'form-item-shake': shakeFields[item.field] }"
|
|
168
|
+
:key="index">
|
|
168
169
|
<view class="form-item-content" :class="`form-item--${getItemLayout(item)}`">
|
|
169
170
|
<view class="form-label" >
|
|
170
171
|
<text class="text" :style="{ width: getItemLayout(item) === 'horizontal' ? getItemLabelWidth(item) : labelWidth }">{{ item.label }}</text>
|
|
@@ -192,13 +193,12 @@
|
|
|
192
193
|
v-bind="item.componentProps || {}" @input="validateField(item)"></textarea>
|
|
193
194
|
|
|
194
195
|
<!-- 下拉选择 -->
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
</picker>
|
|
196
|
+
<TSelect v-else-if="item.component === 'Select'"
|
|
197
|
+
v-model="model[item.field]"
|
|
198
|
+
:options="getSelectOptions(item)"
|
|
199
|
+
:placeholder="item.componentProps?.placeholder || $t('form.selectPlaceholder')"
|
|
200
|
+
v-bind="item.componentProps || {}"
|
|
201
|
+
@change="validateField(item)" />
|
|
202
202
|
|
|
203
203
|
<!-- 日期选择 -->
|
|
204
204
|
<picker v-else-if="item.component === 'Date'" mode="date" :name="item.field"
|
|
@@ -245,7 +245,7 @@
|
|
|
245
245
|
|
|
246
246
|
<!-- 错误提示 -->
|
|
247
247
|
<view v-if="errors[item.field]" class="error-message">
|
|
248
|
-
<text>{{ errors[item.field] }}</text>
|
|
248
|
+
<text class="error-text">{{ errors[item.field] }}</text>
|
|
249
249
|
</view>
|
|
250
250
|
</view>
|
|
251
251
|
|
|
@@ -264,10 +264,36 @@
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
.form-item {
|
|
267
|
-
|
|
267
|
+
padding: 24rpx;
|
|
268
|
+
border-radius: 12rpx;
|
|
269
|
+
border: 2rpx solid transparent;
|
|
270
|
+
transition: all 0.3s ease;
|
|
271
|
+
overflow:visible;
|
|
272
|
+
|
|
273
|
+
&.form-item-error {
|
|
274
|
+
border-color: #ff4d4f;
|
|
275
|
+
background-color: #fff1f0;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
&.form-item-shake {
|
|
279
|
+
animation: shake 0.5s ease-in-out;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
@keyframes shake {
|
|
284
|
+
0%, 100% {
|
|
285
|
+
transform: translateX(0);
|
|
286
|
+
}
|
|
287
|
+
10%, 30%, 50%, 70%, 90% {
|
|
288
|
+
transform: translateX(-8rpx);
|
|
289
|
+
}
|
|
290
|
+
20%, 40%, 60%, 80% {
|
|
291
|
+
transform: translateX(8rpx);
|
|
292
|
+
}
|
|
268
293
|
}
|
|
269
294
|
|
|
270
295
|
.form-item-content {
|
|
296
|
+
overflow:visible;
|
|
271
297
|
&.form-item--horizontal {
|
|
272
298
|
display: flex;
|
|
273
299
|
flex-direction: row;
|
|
@@ -317,6 +343,7 @@
|
|
|
317
343
|
.form-control {
|
|
318
344
|
flex: 1;
|
|
319
345
|
width: 100%;
|
|
346
|
+
overflow: visible;
|
|
320
347
|
|
|
321
348
|
.form-item-content.form-item--horizontal & {
|
|
322
349
|
width: auto;
|
|
@@ -324,8 +351,7 @@
|
|
|
324
351
|
}
|
|
325
352
|
|
|
326
353
|
.input,
|
|
327
|
-
.textarea
|
|
328
|
-
.picker {
|
|
354
|
+
.textarea {
|
|
329
355
|
width: 100%;
|
|
330
356
|
padding: 20rpx 24rpx;
|
|
331
357
|
font-size: 28rpx;
|
|
@@ -346,13 +372,6 @@
|
|
|
346
372
|
min-height: 120rpx;
|
|
347
373
|
}
|
|
348
374
|
|
|
349
|
-
.picker {
|
|
350
|
-
display: flex;
|
|
351
|
-
align-items: center;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
375
|
.error-message {
|
|
357
376
|
margin-top: 8rpx;
|
|
358
377
|
font-size: 24rpx;
|
package/package.json
CHANGED
package/style/index.scss
CHANGED
|
@@ -137,9 +137,9 @@ $z-index-toast: 1080 !default;
|
|
|
137
137
|
visibility: hidden !important;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
uni-view {
|
|
141
|
-
|
|
142
|
-
}
|
|
140
|
+
// uni-view {
|
|
141
|
+
// overflow: visible;
|
|
142
|
+
// }
|
|
143
143
|
|
|
144
144
|
// Flex 布局
|
|
145
145
|
.flex {
|
|
@@ -232,79 +232,78 @@ uni-view {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// 字体大小
|
|
235
|
-
@each $name, $size in (
|
|
236
|
-
'xs': $font-size-xs,
|
|
235
|
+
@each $name, $size in ('xs': $font-size-xs,
|
|
237
236
|
'sm': $font-size-sm,
|
|
238
237
|
'base': $font-size-base,
|
|
239
238
|
'md': $font-size-md,
|
|
240
239
|
'lg': $font-size-lg,
|
|
241
240
|
'xl': $font-size-xl,
|
|
242
|
-
'xxl': $font-size-xxl
|
|
243
|
-
) {
|
|
241
|
+
'xxl': $font-size-xxl) {
|
|
244
242
|
.text-#{$name} {
|
|
245
243
|
font-size: $size !important;
|
|
246
244
|
}
|
|
247
245
|
}
|
|
248
246
|
|
|
249
247
|
// 字体粗细
|
|
250
|
-
@each $name, $weight in (
|
|
251
|
-
'light': $font-weight-light,
|
|
248
|
+
@each $name, $weight in ('light': $font-weight-light,
|
|
252
249
|
'normal': $font-weight-normal,
|
|
253
250
|
'medium': $font-weight-medium,
|
|
254
251
|
'semibold': $font-weight-semibold,
|
|
255
|
-
'bold': $font-weight-bold
|
|
256
|
-
) {
|
|
252
|
+
'bold': $font-weight-bold) {
|
|
257
253
|
.font-#{$name} {
|
|
258
254
|
font-weight: $weight !important;
|
|
259
255
|
}
|
|
260
256
|
}
|
|
261
257
|
|
|
262
258
|
// 圆角
|
|
263
|
-
@each $name, $radius in (
|
|
264
|
-
'none': $border-radius-none,
|
|
259
|
+
@each $name, $radius in ('none': $border-radius-none,
|
|
265
260
|
'sm': $border-radius-sm,
|
|
266
261
|
'base': $border-radius-base,
|
|
267
262
|
'md': $border-radius-md,
|
|
268
263
|
'lg': $border-radius-lg,
|
|
269
264
|
'xl': $border-radius-xl,
|
|
270
|
-
'full': $border-radius-full
|
|
271
|
-
) {
|
|
265
|
+
'full': $border-radius-full) {
|
|
272
266
|
.rounded-#{$name} {
|
|
273
267
|
border-radius: $radius !important;
|
|
274
268
|
}
|
|
275
269
|
}
|
|
276
270
|
|
|
277
271
|
// 间距(内边距和外边距)
|
|
278
|
-
@each $name, $space in (
|
|
279
|
-
'xs': $spacing-xs,
|
|
272
|
+
@each $name, $space in ('xs': $spacing-xs,
|
|
280
273
|
'sm': $spacing-sm,
|
|
281
274
|
'base': $spacing-base,
|
|
282
275
|
'md': $spacing-md,
|
|
283
276
|
'lg': $spacing-lg,
|
|
284
277
|
'xl': $spacing-xl,
|
|
285
|
-
'xxl': $spacing-xxl
|
|
286
|
-
|
|
278
|
+
'xxl': $spacing-xxl) {
|
|
279
|
+
|
|
287
280
|
// 内边距
|
|
288
281
|
.p-#{$name} {
|
|
289
282
|
padding: $space !important;
|
|
290
283
|
}
|
|
284
|
+
|
|
291
285
|
.px-#{$name} {
|
|
292
286
|
padding-left: $space !important;
|
|
293
287
|
padding-right: $space !important;
|
|
294
288
|
}
|
|
289
|
+
|
|
295
290
|
.py-#{$name} {
|
|
296
291
|
padding-top: $space !important;
|
|
297
292
|
padding-bottom: $space !important;
|
|
298
293
|
}
|
|
294
|
+
|
|
299
295
|
.pt-#{$name} {
|
|
300
296
|
padding-top: $space !important;
|
|
301
297
|
}
|
|
298
|
+
|
|
302
299
|
.pr-#{$name} {
|
|
303
300
|
padding-right: $space !important;
|
|
304
301
|
}
|
|
302
|
+
|
|
305
303
|
.pb-#{$name} {
|
|
306
304
|
padding-bottom: $space !important;
|
|
307
305
|
}
|
|
306
|
+
|
|
308
307
|
.pl-#{$name} {
|
|
309
308
|
padding-left: $space !important;
|
|
310
309
|
}
|
|
@@ -313,23 +312,29 @@ uni-view {
|
|
|
313
312
|
.m-#{$name} {
|
|
314
313
|
margin: $space !important;
|
|
315
314
|
}
|
|
315
|
+
|
|
316
316
|
.mx-#{$name} {
|
|
317
317
|
margin-left: $space !important;
|
|
318
318
|
margin-right: $space !important;
|
|
319
319
|
}
|
|
320
|
+
|
|
320
321
|
.my-#{$name} {
|
|
321
322
|
margin-top: $space !important;
|
|
322
323
|
margin-bottom: $space !important;
|
|
323
324
|
}
|
|
325
|
+
|
|
324
326
|
.mt-#{$name} {
|
|
325
327
|
margin-top: $space !important;
|
|
326
328
|
}
|
|
329
|
+
|
|
327
330
|
.mr-#{$name} {
|
|
328
331
|
margin-right: $space !important;
|
|
329
332
|
}
|
|
333
|
+
|
|
330
334
|
.mb-#{$name} {
|
|
331
335
|
margin-bottom: $space !important;
|
|
332
336
|
}
|
|
337
|
+
|
|
333
338
|
.ml-#{$name} {
|
|
334
339
|
margin-left: $space !important;
|
|
335
340
|
}
|
|
@@ -373,13 +378,11 @@ uni-view {
|
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
// 阴影
|
|
376
|
-
@each $name, $shadow in (
|
|
377
|
-
'sm': $shadow-sm,
|
|
381
|
+
@each $name, $shadow in ('sm': $shadow-sm,
|
|
378
382
|
'base': $shadow-base,
|
|
379
383
|
'md': $shadow-md,
|
|
380
384
|
'lg': $shadow-lg,
|
|
381
|
-
'xl': $shadow-xl
|
|
382
|
-
) {
|
|
385
|
+
'xl': $shadow-xl) {
|
|
383
386
|
.shadow-#{$name} {
|
|
384
387
|
box-shadow: $shadow !important;
|
|
385
388
|
}
|