@zfqh/uview-x 0.0.0-stage → 0.0.1
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/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/README.md +127 -3
- package/components/uv-badge/props.ts +83 -0
- package/components/uv-badge/uv-badge.vue +186 -0
- package/components/uv-button/props.ts +148 -0
- package/components/uv-button/uv-button.vue +565 -0
- package/components/uv-checkbox/props.ts +83 -0
- package/components/uv-checkbox/uv-checkbox.vue +403 -0
- package/components/uv-checkbox-group/props.ts +97 -0
- package/components/uv-checkbox-group/uv-checkbox-group.vue +163 -0
- package/components/uv-code/props.ts +48 -0
- package/components/uv-code/uv-code.vue +156 -0
- package/components/uv-dialog/props.ts +56 -0
- package/components/uv-dialog/uv-dialog.vue +492 -0
- package/components/uv-form/props.ts +59 -0
- package/components/uv-form/uv-form.vue +256 -0
- package/components/uv-form/valid.ts +1344 -0
- package/components/uv-form-item/props.ts +62 -0
- package/components/uv-form-item/uv-form-item.vue +335 -0
- package/components/uv-icon/icons.ts +161 -0
- package/components/uv-icon/props.ts +91 -0
- package/components/uv-icon/uv-icon.vue +204 -0
- package/components/uv-icon/uvicons.ttf +0 -0
- package/components/uv-input/props.ts +185 -0
- package/components/uv-input/uv-input.vue +431 -0
- package/components/uv-line/props.ts +42 -0
- package/components/uv-line/uv-line.vue +75 -0
- package/components/uv-line-progress/props.ts +43 -0
- package/components/uv-line-progress/uv-line-progress.vue +166 -0
- package/components/uv-loading-icon/props.ts +78 -0
- package/components/uv-loading-icon/uv-loading-icon.vue +226 -0
- package/components/uv-overlay/props.ts +38 -0
- package/components/uv-overlay/uv-overlay.vue +120 -0
- package/components/uv-popup/props.ts +101 -0
- package/components/uv-popup/uv-popup.vue +371 -0
- package/components/uv-safe-bottom/props.ts +18 -0
- package/components/uv-safe-bottom/uv-safe-bottom.vue +120 -0
- package/components/uv-status-bar/props.ts +22 -0
- package/components/uv-status-bar/uv-status-bar.vue +121 -0
- package/components/uv-tabs/props.ts +84 -0
- package/components/uv-tabs/uv-tabs.vue +432 -0
- package/components/uv-transition/props.ts +38 -0
- package/components/uv-transition/uv-transition.vue +170 -0
- package/hooks/index.ts +5 -0
- package/hooks/useDebounce.ts +35 -0
- package/hooks/useI18n.ts +95 -0
- package/hooks/useThrottle.ts +38 -0
- package/index.ts +23 -0
- package/libs/dayjs/index.ts +217 -0
- package/libs/index.ts +4 -0
- package/libs/luch-request/adapters/index.ts +133 -0
- package/libs/luch-request/core/InterceptorManager.ts +52 -0
- package/libs/luch-request/core/Request.ts +202 -0
- package/libs/luch-request/core/buildFullPath.ts +21 -0
- package/libs/luch-request/core/defaults.ts +34 -0
- package/libs/luch-request/core/dispatchRequest.ts +7 -0
- package/libs/luch-request/core/mergeConfig.ts +127 -0
- package/libs/luch-request/core/settle.ts +17 -0
- package/libs/luch-request/helpers/buildURL.ts +65 -0
- package/libs/luch-request/helpers/combineURLs.ts +15 -0
- package/libs/luch-request/helpers/isAbsoluteURL.ts +15 -0
- package/libs/luch-request/index.d.ts +197 -0
- package/libs/luch-request/index.ts +3 -0
- package/libs/luch-request/utils/clone.ts +265 -0
- package/libs/luch-request/utils.ts +136 -0
- package/locales/en.ts +78 -0
- package/locales/index.ts +169 -0
- package/locales/zh-Hans.ts +78 -0
- package/package.json +42 -4
- package/styles/color.scss +33 -0
- package/styles/common.scss +134 -0
- package/styles/components.scss +19 -0
- package/styles/index.scss +7 -0
- package/styles/theme.scss +44 -0
- package/styles/var.module.scss +32 -0
- package/styles/vue.scss +39 -0
- package/theme.scss +2 -0
- package/types/index.d.ts +66 -0
- package/utils/colorGradient.ts +139 -0
- package/utils/compat.ts +165 -0
- package/utils/compress.ts +34 -0
- package/utils/config.ts +95 -0
- package/utils/debounce.ts +7 -0
- package/utils/digit.ts +157 -0
- package/utils/function.ts +771 -0
- package/utils/http.ts +5 -0
- package/utils/index.ts +57 -0
- package/utils/locale.ts +296 -0
- package/utils/platform.ts +71 -0
- package/utils/route.ts +142 -0
- package/utils/test.ts +256 -0
- package/utils/throttle.ts +7 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="uv-checkbox"
|
|
4
|
+
:class="rootClasses"
|
|
5
|
+
:style="[checkboxStyle]"
|
|
6
|
+
@tap.stop="wrapperClickHandler"
|
|
7
|
+
>
|
|
8
|
+
<view
|
|
9
|
+
class="uv-checkbox__icon-wrap"
|
|
10
|
+
:class="iconClasses"
|
|
11
|
+
:style="[iconWrapStyle]"
|
|
12
|
+
@tap.stop="iconClickHandler"
|
|
13
|
+
>
|
|
14
|
+
<slot name="icon">
|
|
15
|
+
<uv-icon
|
|
16
|
+
class="uv-checkbox__icon-wrap__icon"
|
|
17
|
+
name="checkbox-mark"
|
|
18
|
+
:size="elIconSize"
|
|
19
|
+
:color="elIconColor"
|
|
20
|
+
/>
|
|
21
|
+
</slot>
|
|
22
|
+
</view>
|
|
23
|
+
<view
|
|
24
|
+
v-if="p.label !== false"
|
|
25
|
+
class="uv-checkbox__label-wrap"
|
|
26
|
+
@tap.stop="labelClickHandler"
|
|
27
|
+
>
|
|
28
|
+
<slot>
|
|
29
|
+
<text
|
|
30
|
+
:style="{
|
|
31
|
+
color: elDisabled ? elInactiveColor : elLabelColor,
|
|
32
|
+
fontSize: elLabelSize,
|
|
33
|
+
lineHeight: elLabelSize
|
|
34
|
+
}"
|
|
35
|
+
>{{ p.label }}</text>
|
|
36
|
+
</slot>
|
|
37
|
+
</view>
|
|
38
|
+
</view>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup lang="ts">
|
|
42
|
+
import { computed, inject, nextTick, onUnmounted, ref, watch } from 'vue'
|
|
43
|
+
import { $uv } from '../../utils'
|
|
44
|
+
import props from './props'
|
|
45
|
+
import { preventEvent } from '../../utils/compat'
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
defineOptions({
|
|
49
|
+
name: 'uv-checkbox',
|
|
50
|
+
// #ifdef UNI-APP-X
|
|
51
|
+
styleIsolation: 'app-and-page',
|
|
52
|
+
// #endif
|
|
53
|
+
virtualHost: true,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* checkbox 复选框
|
|
58
|
+
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
|
59
|
+
* @tutorial https://www.uvui.cn/components/checkbox.html
|
|
60
|
+
* @property {String | Number | Boolean} name checkbox组件的标示符
|
|
61
|
+
* @property {String} shape 形状,square为方形,circle为圆型
|
|
62
|
+
* @property {String | Number} size 整体的大小
|
|
63
|
+
* @property {Boolean} checked 是否默认选中
|
|
64
|
+
* @property {String | Boolean} disabled 是否禁用
|
|
65
|
+
* @property {String} activeColor 选中状态下的颜色
|
|
66
|
+
* @property {String} inactiveColor 未选中的颜色
|
|
67
|
+
* @property {String | Number} iconSize 图标的大小,单位px
|
|
68
|
+
* @property {String} iconColor 图标颜色
|
|
69
|
+
* @property {String | Number} label label提示文字
|
|
70
|
+
* @property {String} labelColor label的颜色
|
|
71
|
+
* @property {String | Number} labelSize label的字体大小,px单位
|
|
72
|
+
* @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框
|
|
73
|
+
* @property {Object} customStyle 定义需要用到的外部样式
|
|
74
|
+
* @event {Function} change 某个checkbox状态发生变化时触发(选中状态)
|
|
75
|
+
* @example <uv-checkbox v-model="checked" :disabled="false">天涯</uv-checkbox>
|
|
76
|
+
*/
|
|
77
|
+
const p = defineProps(props)
|
|
78
|
+
|
|
79
|
+
const emit = defineEmits(['change'])
|
|
80
|
+
|
|
81
|
+
// 是否被选中
|
|
82
|
+
const isChecked = ref(false)
|
|
83
|
+
|
|
84
|
+
// 注入 uv-checkbox-group 提供的组上下文
|
|
85
|
+
const checkboxGroupContext: any = inject('uv-checkbox-group-context', null)
|
|
86
|
+
// 注入 uv-form-item 提供的表单域上下文(用于触发表单校验)
|
|
87
|
+
const formItemContext: any = inject('uv-form-item-context', null)
|
|
88
|
+
|
|
89
|
+
// 注册到 checkbox-group 的句柄
|
|
90
|
+
const handle: any = {
|
|
91
|
+
getName: () => p.name,
|
|
92
|
+
getChecked: () => isChecked.value,
|
|
93
|
+
setChecked: (checked: boolean) => {
|
|
94
|
+
isChecked.value = checked
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!checkboxGroupContext) {
|
|
99
|
+
$uv.error('uv-checkbox必须搭配uv-checkbox-group组件使用')
|
|
100
|
+
} else {
|
|
101
|
+
checkboxGroupContext.register(handle)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
onUnmounted(() => {
|
|
105
|
+
if (checkboxGroupContext) checkboxGroupContext.unregister(handle)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
// 初始化选中状态
|
|
109
|
+
const init = () => {
|
|
110
|
+
if (p.checked) {
|
|
111
|
+
isChecked.value = true
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
const parentValue = checkboxGroupContext ? checkboxGroupContext.value : []
|
|
115
|
+
// 父组件uv-checkbox-group的value可能是array,所以额外判断
|
|
116
|
+
if ($uv.test.array(parentValue)) {
|
|
117
|
+
// 查找数组是是否存在此name元素值
|
|
118
|
+
isChecked.value = parentValue.some((item: any) => item === p.name)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
init()
|
|
122
|
+
|
|
123
|
+
// 监听父组件值的变化,同步选中状态
|
|
124
|
+
watch(
|
|
125
|
+
() => (checkboxGroupContext ? checkboxGroupContext.value : null),
|
|
126
|
+
(value: any) => {
|
|
127
|
+
if ($uv.test.array(value)) {
|
|
128
|
+
isChecked.value = value.some((item: any) => item === p.name)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
watch(
|
|
134
|
+
() => p.checked,
|
|
135
|
+
(checked: boolean) => {
|
|
136
|
+
isChecked.value = checked
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
// 是否禁用,如果父组件uv-checkbox-group禁用的话,将会忽略子组件的配置
|
|
141
|
+
const elDisabled = computed(() => {
|
|
142
|
+
if (p.disabled !== '') return !!p.disabled
|
|
143
|
+
if (checkboxGroupContext) return checkboxGroupContext.disabled !== null && checkboxGroupContext.disabled !== undefined
|
|
144
|
+
? !!checkboxGroupContext.disabled
|
|
145
|
+
: false
|
|
146
|
+
return false
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// 是否禁用label点击
|
|
150
|
+
const elLabelDisabled = computed(() => {
|
|
151
|
+
if (p.labelDisabled !== '') return !!p.labelDisabled
|
|
152
|
+
if (checkboxGroupContext) return checkboxGroupContext.labelDisabled !== null && checkboxGroupContext.labelDisabled !== undefined
|
|
153
|
+
? !!checkboxGroupContext.labelDisabled
|
|
154
|
+
: false
|
|
155
|
+
return false
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// 组件尺寸,对应size的值,默认值为21px
|
|
159
|
+
const elSize = computed(() => {
|
|
160
|
+
return p.size ? p.size : checkboxGroupContext && checkboxGroupContext.size ? checkboxGroupContext.size : 21
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// 组件的勾选图标的尺寸,默认12px
|
|
164
|
+
const elIconSize = computed(() => {
|
|
165
|
+
return p.iconSize
|
|
166
|
+
? p.iconSize
|
|
167
|
+
: checkboxGroupContext && checkboxGroupContext.iconSize
|
|
168
|
+
? checkboxGroupContext.iconSize
|
|
169
|
+
: 12
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// 组件选中激活时的颜色
|
|
173
|
+
const elActiveColor = computed(() => {
|
|
174
|
+
return p.activeColor
|
|
175
|
+
? p.activeColor
|
|
176
|
+
: checkboxGroupContext && checkboxGroupContext.activeColor
|
|
177
|
+
? checkboxGroupContext.activeColor
|
|
178
|
+
: '#2979ff'
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
// 组件未选中时的颜色
|
|
182
|
+
const elInactiveColor = computed(() => {
|
|
183
|
+
return p.inactiveColor
|
|
184
|
+
? p.inactiveColor
|
|
185
|
+
: checkboxGroupContext && checkboxGroupContext.inactiveColor
|
|
186
|
+
? checkboxGroupContext.inactiveColor
|
|
187
|
+
: '#c8c9cc'
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// label的颜色
|
|
191
|
+
const elLabelColor = computed(() => {
|
|
192
|
+
return p.labelColor
|
|
193
|
+
? p.labelColor
|
|
194
|
+
: checkboxGroupContext && checkboxGroupContext.labelColor
|
|
195
|
+
? checkboxGroupContext.labelColor
|
|
196
|
+
: '#606266'
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
// 组件的形状
|
|
200
|
+
const elShape = computed(() => {
|
|
201
|
+
return p.shape ? p.shape : checkboxGroupContext && checkboxGroupContext.shape ? checkboxGroupContext.shape : 'circle'
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
// label大小
|
|
205
|
+
const elLabelSize = computed(() => {
|
|
206
|
+
return $uv.addUnit(
|
|
207
|
+
p.labelSize
|
|
208
|
+
? p.labelSize
|
|
209
|
+
: checkboxGroupContext && checkboxGroupContext.labelSize
|
|
210
|
+
? checkboxGroupContext.labelSize
|
|
211
|
+
: '15'
|
|
212
|
+
)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
const elIconPlacement = computed(() => {
|
|
216
|
+
return checkboxGroupContext ? checkboxGroupContext.iconPlacement || 'left' : 'left'
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
const elIconColor = computed(() => {
|
|
220
|
+
const iconColor = p.iconColor
|
|
221
|
+
? p.iconColor
|
|
222
|
+
: checkboxGroupContext && checkboxGroupContext.iconColor
|
|
223
|
+
? checkboxGroupContext.iconColor
|
|
224
|
+
: '#ffffff'
|
|
225
|
+
// 图标的颜色
|
|
226
|
+
if (elDisabled.value) {
|
|
227
|
+
// disabled状态下,已勾选的checkbox图标改为elInactiveColor
|
|
228
|
+
return isChecked.value ? elInactiveColor.value : 'rgba(0, 0, 0, 0)'
|
|
229
|
+
}
|
|
230
|
+
return isChecked.value ? iconColor : 'rgba(0, 0, 0, 0)'
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
const iconClasses = computed(() => {
|
|
234
|
+
const classes: string[] = []
|
|
235
|
+
// 组件的形状
|
|
236
|
+
classes.push(`uv-checkbox__icon-wrap--${elShape.value}`)
|
|
237
|
+
if (elDisabled.value) {
|
|
238
|
+
classes.push('uv-checkbox__icon-wrap--disabled')
|
|
239
|
+
}
|
|
240
|
+
if (isChecked.value && elDisabled.value) {
|
|
241
|
+
classes.push('uv-checkbox__icon-wrap--disabled--checked')
|
|
242
|
+
}
|
|
243
|
+
return classes
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
const iconWrapStyle = computed(() => {
|
|
247
|
+
// checkbox的整体样式
|
|
248
|
+
const style: any = {}
|
|
249
|
+
style.backgroundColor = isChecked.value && !elDisabled.value ? elActiveColor.value : '#ffffff'
|
|
250
|
+
style.borderColor = isChecked.value && !elDisabled.value ? elActiveColor.value : elInactiveColor.value
|
|
251
|
+
style.width = $uv.addUnit(elSize.value)
|
|
252
|
+
style.height = $uv.addUnit(elSize.value)
|
|
253
|
+
if (elDisabled.value) {
|
|
254
|
+
// 与 uv-ui 一致:禁用时背景固定为 #ebedf0(原实现通过 CSS !important 覆盖),边框取未选中颜色
|
|
255
|
+
style.backgroundColor = '#ebedf0'
|
|
256
|
+
style.borderColor = elInactiveColor.value
|
|
257
|
+
}
|
|
258
|
+
// 如果是图标在右边的话,移除它的右边距
|
|
259
|
+
if (elIconPlacement.value === 'right') {
|
|
260
|
+
style.marginRight = 0
|
|
261
|
+
}
|
|
262
|
+
return style
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
const rootClasses = computed(() => {
|
|
266
|
+
const classes: string[] = [`uv-checkbox-label--${elIconPlacement.value}`]
|
|
267
|
+
if (p.customClass) classes.push(p.customClass)
|
|
268
|
+
if (checkboxGroupContext && checkboxGroupContext.borderBottom && checkboxGroupContext.placement === 'column') {
|
|
269
|
+
classes.push('uv-border-bottom')
|
|
270
|
+
}
|
|
271
|
+
return classes
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
const checkboxStyle = computed(() => {
|
|
275
|
+
const style: any = {}
|
|
276
|
+
if (checkboxGroupContext && checkboxGroupContext.borderBottom && checkboxGroupContext.placement === 'row') {
|
|
277
|
+
$uv.error('检测到您将borderBottom设置为true,需要同时将uv-checkbox-group的placement设置为column才有效')
|
|
278
|
+
}
|
|
279
|
+
// 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
|
|
280
|
+
if (checkboxGroupContext && checkboxGroupContext.borderBottom && checkboxGroupContext.placement === 'column') {
|
|
281
|
+
style.paddingBottom = '8px'
|
|
282
|
+
}
|
|
283
|
+
return $uv.deepMerge(style, $uv.addStyle(p.customStyle))
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
// 横向两端排列时,点击组件即可触发选中事件
|
|
287
|
+
const wrapperClickHandler = (e: any) => {
|
|
288
|
+
if (elIconPlacement.value === 'right') iconClickHandler(e)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 点击图标
|
|
292
|
+
const iconClickHandler = (e: any) => {
|
|
293
|
+
preventEvent(e)
|
|
294
|
+
// 如果整体被禁用,不允许被点击
|
|
295
|
+
if (!elDisabled.value) {
|
|
296
|
+
setCheckedStatus()
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 点击label
|
|
301
|
+
const labelClickHandler = (e: any) => {
|
|
302
|
+
preventEvent(e)
|
|
303
|
+
// 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
|
|
304
|
+
if (!elLabelDisabled.value && !elDisabled.value) {
|
|
305
|
+
setCheckedStatus()
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const emitEvent = () => {
|
|
310
|
+
emit('change', isChecked.value)
|
|
311
|
+
// 尝试调用uv-form的验证方法
|
|
312
|
+
nextTick(() => {
|
|
313
|
+
if (formItemContext) formItemContext.validate('change')
|
|
314
|
+
})
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// 改变组件选中状态
|
|
318
|
+
const setCheckedStatus = () => {
|
|
319
|
+
// 将本组件标记为与原来相反的状态
|
|
320
|
+
isChecked.value = !isChecked.value
|
|
321
|
+
emitEvent()
|
|
322
|
+
// 通知父组件 uv-checkbox-group 重新收集选中的值
|
|
323
|
+
if (checkboxGroupContext) checkboxGroupContext.refresh()
|
|
324
|
+
}
|
|
325
|
+
</script>
|
|
326
|
+
|
|
327
|
+
<style lang="scss">
|
|
328
|
+
@import '../../styles/components.scss';
|
|
329
|
+
@import '../../styles/color.scss';
|
|
330
|
+
|
|
331
|
+
$uv-checkbox-label-wrap-padding-right: 6px !default;
|
|
332
|
+
$uv-checkbox-icon-wrap-font-size: 6px !default;
|
|
333
|
+
$uv-checkbox-icon-wrap-border-width: 1px !default;
|
|
334
|
+
$uv-checkbox-icon-wrap-border-color: #c8c9cc !default;
|
|
335
|
+
$uv-checkbox-icon-wrap-circle-border-radius: 100% !default;
|
|
336
|
+
$uv-checkbox-icon-wrap-square-border-radius: 3px !default;
|
|
337
|
+
$uv-checkbox-icon-wrap-checked-color: #fff !default;
|
|
338
|
+
$uv-checkbox-icon-wrap-checked-background-color: red !default;
|
|
339
|
+
$uv-checkbox-icon-wrap-checked-border-color: #2979ff !default;
|
|
340
|
+
$uv-checkbox-icon-wrap-disabled-background-color: #ebedf0 !default;
|
|
341
|
+
$uv-checkbox-icon-wrap-disabled-checked-color: #c8c9cc !default;
|
|
342
|
+
|
|
343
|
+
.uv-checkbox {
|
|
344
|
+
display: flex;
|
|
345
|
+
flex-direction: row;
|
|
346
|
+
overflow: hidden;
|
|
347
|
+
align-items: center;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.uv-checkbox-label--left {
|
|
351
|
+
flex-direction: row;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.uv-checkbox-label--right {
|
|
355
|
+
flex-direction: row-reverse;
|
|
356
|
+
justify-content: space-between;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.uv-checkbox__icon-wrap {
|
|
360
|
+
/* #ifndef APP-NVUE */
|
|
361
|
+
display: flex;
|
|
362
|
+
box-sizing: border-box;
|
|
363
|
+
transition-property: background-color;
|
|
364
|
+
transition-duration: 0.2s;
|
|
365
|
+
/* #endif */
|
|
366
|
+
flex-direction: row;
|
|
367
|
+
color: rgba(0, 0, 0, 0);
|
|
368
|
+
align-items: center;
|
|
369
|
+
justify-content: center;
|
|
370
|
+
text-align: center;
|
|
371
|
+
font-size: $uv-checkbox-icon-wrap-font-size;
|
|
372
|
+
border-width: $uv-checkbox-icon-wrap-border-width;
|
|
373
|
+
border-color: $uv-checkbox-icon-wrap-border-color;
|
|
374
|
+
border-style: solid;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.uv-checkbox__icon-wrap--circle {
|
|
378
|
+
border-radius: 100px;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.uv-checkbox__icon-wrap--square {
|
|
382
|
+
border-radius: $uv-checkbox-icon-wrap-square-border-radius;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.uv-checkbox__icon-wrap--checked {
|
|
386
|
+
color: $uv-checkbox-icon-wrap-checked-color;
|
|
387
|
+
background-color: $uv-checkbox-icon-wrap-checked-background-color;
|
|
388
|
+
border-color: $uv-checkbox-icon-wrap-checked-border-color;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.uv-checkbox__icon-wrap--disabled {
|
|
392
|
+
background-color: $uv-checkbox-icon-wrap-disabled-background-color;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.uv-checkbox__icon-wrap--disabled--checked {
|
|
396
|
+
color: $uv-checkbox-icon-wrap-disabled-checked-color;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.uv-checkbox__label-wrap {
|
|
400
|
+
flex: 1;
|
|
401
|
+
padding-left: $uv-checkbox-label-wrap-padding-right;
|
|
402
|
+
}
|
|
403
|
+
</style>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
|
|
3
|
+
import config from '../../utils/config';
|
|
4
|
+
|
|
5
|
+
const props = {
|
|
6
|
+
// 绑定的值
|
|
7
|
+
value: {
|
|
8
|
+
type: Array,
|
|
9
|
+
default: () => [],
|
|
10
|
+
},
|
|
11
|
+
modelValue: {
|
|
12
|
+
type: Array,
|
|
13
|
+
default: () => [],
|
|
14
|
+
},
|
|
15
|
+
// 标识符
|
|
16
|
+
name: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: '',
|
|
19
|
+
},
|
|
20
|
+
// 形状,circle-圆形,square-方形
|
|
21
|
+
shape: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: 'square',
|
|
24
|
+
},
|
|
25
|
+
// 是否禁用全部checkbox
|
|
26
|
+
disabled: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false,
|
|
29
|
+
},
|
|
30
|
+
// 选中状态下的颜色
|
|
31
|
+
activeColor: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: '#2979ff',
|
|
34
|
+
},
|
|
35
|
+
// 未选中的颜色
|
|
36
|
+
inactiveColor: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: '#c8c9cc',
|
|
39
|
+
},
|
|
40
|
+
// 整个组件的尺寸,默认px
|
|
41
|
+
size: {
|
|
42
|
+
type: [String, Number],
|
|
43
|
+
default: 18,
|
|
44
|
+
},
|
|
45
|
+
// 布局方式,row-横向,column-纵向
|
|
46
|
+
placement: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: 'row',
|
|
49
|
+
},
|
|
50
|
+
// label的字体大小,px单位
|
|
51
|
+
labelSize: {
|
|
52
|
+
type: [String, Number],
|
|
53
|
+
default: 14,
|
|
54
|
+
},
|
|
55
|
+
// label的字体颜色
|
|
56
|
+
labelColor: {
|
|
57
|
+
type: [String],
|
|
58
|
+
default: '#303133',
|
|
59
|
+
},
|
|
60
|
+
// 是否禁止点击文本操作
|
|
61
|
+
labelDisabled: {
|
|
62
|
+
type: Boolean,
|
|
63
|
+
default: false,
|
|
64
|
+
},
|
|
65
|
+
// 图标颜色
|
|
66
|
+
iconColor: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: '#fff',
|
|
69
|
+
},
|
|
70
|
+
// 图标的大小,单位px
|
|
71
|
+
iconSize: {
|
|
72
|
+
type: [String, Number],
|
|
73
|
+
default: 12,
|
|
74
|
+
},
|
|
75
|
+
// 勾选图标的对齐方式,left-左边,right-右边
|
|
76
|
+
iconPlacement: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: 'left',
|
|
79
|
+
},
|
|
80
|
+
// 竖向配列时,是否显示下划线
|
|
81
|
+
borderBottom: {
|
|
82
|
+
type: Boolean,
|
|
83
|
+
default: false,
|
|
84
|
+
},
|
|
85
|
+
customStyle: {
|
|
86
|
+
type: [Object, String],
|
|
87
|
+
default: () => ({}),
|
|
88
|
+
},
|
|
89
|
+
customClass: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: '',
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
...config.props.checkboxGroup,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export default props;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="uv-checkbox-group"
|
|
4
|
+
:class="[bemClass, p.customClass]"
|
|
5
|
+
:style="[$uv.addStyle(p.customStyle)]"
|
|
6
|
+
>
|
|
7
|
+
<slot></slot>
|
|
8
|
+
</view>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { computed, provide, reactive, watch } from 'vue'
|
|
13
|
+
import { $uv } from '../../utils'
|
|
14
|
+
import props from './props'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
defineOptions({
|
|
18
|
+
name: 'uv-checkbox-group',
|
|
19
|
+
// #ifdef UNI-APP-X
|
|
20
|
+
styleIsolation: 'app-and-page',
|
|
21
|
+
// #endif
|
|
22
|
+
virtualHost: true,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* checkboxGroup 复选框组
|
|
27
|
+
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
|
28
|
+
* @tutorial https://www.uvui.cn/components/checkbox.html
|
|
29
|
+
* @property {String} name 标识符
|
|
30
|
+
* @property {Array} value 绑定的值
|
|
31
|
+
* @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )
|
|
32
|
+
* @property {Boolean} disabled 是否禁用全部checkbox (默认 false )
|
|
33
|
+
* @property {String} activeColor 选中状态下的颜色 (默认 '#2979ff' )
|
|
34
|
+
* @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )
|
|
35
|
+
* @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )
|
|
36
|
+
* @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )
|
|
37
|
+
* @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )
|
|
38
|
+
* @property {String} labelColor label的字体颜色 (默认 '#303133' )
|
|
39
|
+
* @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )
|
|
40
|
+
* @property {String} iconColor 图标颜色 (默认 '#ffffff' )
|
|
41
|
+
* @property {String | Number} iconSize 图标的大小,单位px (默认 12 )
|
|
42
|
+
* @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )
|
|
43
|
+
* @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )
|
|
44
|
+
* @property {Object} customStyle 定义需要用到的外部样式
|
|
45
|
+
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
|
|
46
|
+
* @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象
|
|
47
|
+
* @event {Function} update:modelValue 修改通过v-model绑定的值时触发,回调为一个对象
|
|
48
|
+
* @example <uv-checkbox-group></uv-checkbox-group>
|
|
49
|
+
*/
|
|
50
|
+
const p = defineProps(props)
|
|
51
|
+
|
|
52
|
+
const emit = defineEmits(['input', 'update:modelValue', 'change'])
|
|
53
|
+
|
|
54
|
+
// 当前选中的值:优先 value,其次 modelValue
|
|
55
|
+
const groupValue = computed(() => {
|
|
56
|
+
const value = p.value
|
|
57
|
+
if (value && value.length) return value
|
|
58
|
+
const modelValue = p.modelValue
|
|
59
|
+
if (modelValue && modelValue.length) return modelValue
|
|
60
|
+
return []
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// 复选框组上下文:provide/inject 替代 $parent/children 链
|
|
64
|
+
// 复选框组上下文 key(与 uv-checkbox 内 inject 的字符串保持一致)
|
|
65
|
+
const checkboxGroupContext: any = reactive({
|
|
66
|
+
value: groupValue.value,
|
|
67
|
+
disabled: p.disabled,
|
|
68
|
+
inactiveColor: p.inactiveColor,
|
|
69
|
+
activeColor: p.activeColor,
|
|
70
|
+
size: p.size,
|
|
71
|
+
labelDisabled: p.labelDisabled,
|
|
72
|
+
shape: p.shape,
|
|
73
|
+
iconSize: p.iconSize,
|
|
74
|
+
borderBottom: p.borderBottom,
|
|
75
|
+
placement: p.placement,
|
|
76
|
+
labelSize: p.labelSize,
|
|
77
|
+
labelColor: p.labelColor,
|
|
78
|
+
iconPlacement: p.iconPlacement,
|
|
79
|
+
iconColor: p.iconColor,
|
|
80
|
+
// 已注册的 uv-checkbox 句柄
|
|
81
|
+
items: []
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
checkboxGroupContext.register = (handle: any) => {
|
|
85
|
+
checkboxGroupContext.items.push(handle)
|
|
86
|
+
}
|
|
87
|
+
checkboxGroupContext.unregister = (handle: any) => {
|
|
88
|
+
const index = checkboxGroupContext.items.indexOf(handle)
|
|
89
|
+
if (index > -1) checkboxGroupContext.items.splice(index, 1)
|
|
90
|
+
}
|
|
91
|
+
// 子项状态变化后,重新收集所有被选中的值并通知父组件
|
|
92
|
+
checkboxGroupContext.refresh = () => {
|
|
93
|
+
const values: any[] = []
|
|
94
|
+
checkboxGroupContext.items.forEach((item: any) => {
|
|
95
|
+
if (item.getChecked()) values.push(item.getName())
|
|
96
|
+
})
|
|
97
|
+
// 修改通过v-model绑定的值
|
|
98
|
+
emit('input', values)
|
|
99
|
+
emit('update:modelValue', values)
|
|
100
|
+
// 发出事件
|
|
101
|
+
emit('change', values)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
provide('uv-checkbox-group-context', checkboxGroupContext)
|
|
105
|
+
|
|
106
|
+
const bemClass = computed(() => `uv-checkbox-group--${p.placement}`)
|
|
107
|
+
|
|
108
|
+
// 父组件参数变化时同步到上下文,子组件响应式读取
|
|
109
|
+
watch(
|
|
110
|
+
() => [
|
|
111
|
+
groupValue.value,
|
|
112
|
+
p.disabled,
|
|
113
|
+
p.inactiveColor,
|
|
114
|
+
p.activeColor,
|
|
115
|
+
p.size,
|
|
116
|
+
p.labelDisabled,
|
|
117
|
+
p.shape,
|
|
118
|
+
p.iconSize,
|
|
119
|
+
p.borderBottom,
|
|
120
|
+
p.placement,
|
|
121
|
+
p.labelSize,
|
|
122
|
+
p.labelColor,
|
|
123
|
+
p.iconPlacement,
|
|
124
|
+
p.iconColor
|
|
125
|
+
],
|
|
126
|
+
() => {
|
|
127
|
+
checkboxGroupContext.value = groupValue.value
|
|
128
|
+
checkboxGroupContext.disabled = p.disabled
|
|
129
|
+
checkboxGroupContext.inactiveColor = p.inactiveColor
|
|
130
|
+
checkboxGroupContext.activeColor = p.activeColor
|
|
131
|
+
checkboxGroupContext.size = p.size
|
|
132
|
+
checkboxGroupContext.labelDisabled = p.labelDisabled
|
|
133
|
+
checkboxGroupContext.shape = p.shape
|
|
134
|
+
checkboxGroupContext.iconSize = p.iconSize
|
|
135
|
+
checkboxGroupContext.borderBottom = p.borderBottom
|
|
136
|
+
checkboxGroupContext.placement = p.placement
|
|
137
|
+
checkboxGroupContext.labelSize = p.labelSize
|
|
138
|
+
checkboxGroupContext.labelColor = p.labelColor
|
|
139
|
+
checkboxGroupContext.iconPlacement = p.iconPlacement
|
|
140
|
+
checkboxGroupContext.iconColor = p.iconColor
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<style lang="scss">
|
|
146
|
+
@import '../../styles/components.scss';
|
|
147
|
+
@import '../../styles/color.scss';
|
|
148
|
+
|
|
149
|
+
.uv-checkbox-group {
|
|
150
|
+
flex: 1;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.uv-checkbox-group--row {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-direction: row;
|
|
156
|
+
flex-wrap: wrap;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.uv-checkbox-group--column {
|
|
160
|
+
display: flex;
|
|
161
|
+
flex-direction: column;
|
|
162
|
+
}
|
|
163
|
+
</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
|
|
3
|
+
import config from '../../utils/config';
|
|
4
|
+
|
|
5
|
+
const props = {
|
|
6
|
+
// 倒计时总秒数
|
|
7
|
+
seconds: {
|
|
8
|
+
type: [String, Number],
|
|
9
|
+
default: 60,
|
|
10
|
+
},
|
|
11
|
+
// 尚未开始时提示(默认 '',使用内置 i18n 的 uv.code.start)
|
|
12
|
+
startText: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: '',
|
|
15
|
+
},
|
|
16
|
+
// 正在倒计时中的提示(默认 '',使用内置 i18n 的 uv.code.change)
|
|
17
|
+
changeText: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: '',
|
|
20
|
+
},
|
|
21
|
+
// 倒计时结束时的提示(默认 '',使用内置 i18n 的 uv.code.end)
|
|
22
|
+
endText: {
|
|
23
|
+
type: String,
|
|
24
|
+
default: '',
|
|
25
|
+
},
|
|
26
|
+
// 是否在H5刷新或各端返回再进入时继续倒计时
|
|
27
|
+
keepRunning: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
// 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
|
|
32
|
+
uniqueKey: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: '',
|
|
35
|
+
},
|
|
36
|
+
customStyle: {
|
|
37
|
+
type: [Object, String],
|
|
38
|
+
default: () => ({}),
|
|
39
|
+
},
|
|
40
|
+
customClass: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: '',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
...config.props.code,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default props;
|