添加 cl-slide-verify 滑动验证组件,支持转正图片
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cool-unix",
|
"name": "cool-unix",
|
||||||
"version": "8.0.18",
|
"version": "8.0.19",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-ui": "node ./uni_modules/cool-ui/scripts/generate-types.js",
|
"build-ui": "node ./uni_modules/cool-ui/scripts/generate-types.js",
|
||||||
|
|||||||
@@ -429,6 +429,12 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "SVG 图标"
|
"navigationBarTitleText": "SVG 图标"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "other/slide-verify",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "SlideVerify 滑动验证"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
47
pages/demo/other/slide-verify.uvue
Normal file
47
pages/demo/other/slide-verify.uvue
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<cl-page>
|
||||||
|
<view class="p-3">
|
||||||
|
<demo-item :label="t('基础用法')">
|
||||||
|
<cl-slide-verify
|
||||||
|
v-model="status"
|
||||||
|
@success="onSuccess"
|
||||||
|
@fail="onFail"
|
||||||
|
></cl-slide-verify>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('没有错误提示')">
|
||||||
|
<cl-slide-verify :show-fail="false"></cl-slide-verify>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('转动图片')">
|
||||||
|
<cl-slide-verify
|
||||||
|
mode="image"
|
||||||
|
image-url="https://unix.cool-js.com/images/demo/avatar.jpg"
|
||||||
|
></cl-slide-verify>
|
||||||
|
</demo-item>
|
||||||
|
</view>
|
||||||
|
</cl-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import DemoItem from "../components/item.uvue";
|
||||||
|
import { t } from "@/locale";
|
||||||
|
import { useUi } from "@/uni_modules/cool-ui";
|
||||||
|
|
||||||
|
const ui = useUi();
|
||||||
|
|
||||||
|
const status = ref(false);
|
||||||
|
|
||||||
|
function onSuccess() {
|
||||||
|
ui.showToast({
|
||||||
|
message: t("验证通过")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFail() {
|
||||||
|
ui.showToast({
|
||||||
|
message: t("验证失败")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -438,6 +438,11 @@ const data = computed<Item[]>(() => {
|
|||||||
label: "SVG",
|
label: "SVG",
|
||||||
icon: "bubble-chart-line",
|
icon: "bubble-chart-line",
|
||||||
path: "/pages/demo/other/svg"
|
path: "/pages/demo/other/svg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "SlideVerify",
|
||||||
|
icon: "contract-right-fill",
|
||||||
|
path: "/pages/demo/other/slide-verify"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,501 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="cl-slide-verify"
|
||||||
|
:class="[
|
||||||
|
{
|
||||||
|
'cl-slide-verify--disabled': disabled,
|
||||||
|
'cl-slide-verify--success': isSuccess,
|
||||||
|
'cl-slide-verify--fail': isFail
|
||||||
|
},
|
||||||
|
pt.className
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<!-- 背景图片(图片验证模式) -->
|
||||||
|
<image
|
||||||
|
v-if="mode == 'image' && imageUrl != ''"
|
||||||
|
class="cl-slide-verify__image"
|
||||||
|
:class="[pt.image?.className]"
|
||||||
|
:src="imageUrl"
|
||||||
|
:style="{
|
||||||
|
transform: `rotate(${currentAngle}deg)`,
|
||||||
|
height: parseRpx(imageSize!),
|
||||||
|
width: parseRpx(imageSize!)
|
||||||
|
}"
|
||||||
|
mode="aspectFill"
|
||||||
|
></image>
|
||||||
|
|
||||||
|
<!-- 滑动轨道 -->
|
||||||
|
<view
|
||||||
|
class="cl-slide-verify__track"
|
||||||
|
:class="[
|
||||||
|
{
|
||||||
|
'cl-slide-verify__track--success': isSuccess,
|
||||||
|
'cl-slide-verify__track--fail': isFail,
|
||||||
|
'cl-slide-verify__track--dark': isDark
|
||||||
|
},
|
||||||
|
pt.track?.className
|
||||||
|
]"
|
||||||
|
:style="{
|
||||||
|
height: size + 'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!-- 滑动进度条 -->
|
||||||
|
<view
|
||||||
|
class="cl-slide-verify__progress"
|
||||||
|
:class="[
|
||||||
|
{
|
||||||
|
'cl-slide-verify__progress--success': isSuccess,
|
||||||
|
'cl-slide-verify__progress--fail': isFail
|
||||||
|
},
|
||||||
|
pt.progress?.className
|
||||||
|
]"
|
||||||
|
:style="progressStyle"
|
||||||
|
></view>
|
||||||
|
|
||||||
|
<!-- 滑动按钮 -->
|
||||||
|
<view
|
||||||
|
class="cl-slide-verify__slider"
|
||||||
|
:class="[
|
||||||
|
{
|
||||||
|
'cl-slide-verify__slider--active': isDragging,
|
||||||
|
'cl-slide-verify__slider--success': isSuccess,
|
||||||
|
'cl-slide-verify__slider--fail': isFail,
|
||||||
|
'cl-slide-verify__slider--dark': isDark
|
||||||
|
},
|
||||||
|
pt.slider?.className
|
||||||
|
]"
|
||||||
|
:style="sliderStyle"
|
||||||
|
@touchstart="onTouchStart"
|
||||||
|
@touchmove.stop.prevent="onTouchMove"
|
||||||
|
@touchend="onTouchEnd"
|
||||||
|
@touchcancel="onTouchEnd"
|
||||||
|
>
|
||||||
|
<cl-icon
|
||||||
|
:name="sliderIcon"
|
||||||
|
:size="44"
|
||||||
|
:color="sliderColor"
|
||||||
|
:pt="{
|
||||||
|
className: parseClass([pt.icon?.className])
|
||||||
|
}"
|
||||||
|
></cl-icon>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 文字提示 -->
|
||||||
|
<view class="cl-slide-verify__text" :class="[pt.text?.className]">
|
||||||
|
<cl-text
|
||||||
|
:color="textColor"
|
||||||
|
:pt="{
|
||||||
|
className: parseClass([pt.label?.className])
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ currentText }}
|
||||||
|
</cl-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch, nextTick, getCurrentInstance, type PropType } from "vue";
|
||||||
|
import { isDark, parseClass, parsePt, parseRpx, random } from "@/cool";
|
||||||
|
import type { PassThroughProps } from "../../types";
|
||||||
|
import { vibrate } from "@/uni_modules/cool-vibrate";
|
||||||
|
import { t } from "@/locale";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "cl-slide-verify"
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件属性定义
|
||||||
|
const props = defineProps({
|
||||||
|
// 样式穿透
|
||||||
|
pt: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
// 是否验证成功
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 验证模式:slide-直接滑动验证, image-图片旋转验证
|
||||||
|
mode: {
|
||||||
|
type: String as PropType<"slide" | "image">,
|
||||||
|
default: "slide"
|
||||||
|
},
|
||||||
|
// 滑块大小
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: 40
|
||||||
|
},
|
||||||
|
// 是否禁用
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 图片URL(图片模式使用)
|
||||||
|
imageUrl: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
// 图片大小(图片模式使用)
|
||||||
|
imageSize: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
// 角度容错范围
|
||||||
|
angleThreshold: {
|
||||||
|
type: Number,
|
||||||
|
default: 10
|
||||||
|
},
|
||||||
|
// 提示文字
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
// 成功文字
|
||||||
|
successText: {
|
||||||
|
type: String,
|
||||||
|
default: () => t("验证成功")
|
||||||
|
},
|
||||||
|
// 是否错误提示
|
||||||
|
showFail: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 错误提示文字
|
||||||
|
failText: {
|
||||||
|
type: String,
|
||||||
|
default: () => t("验证失败")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 事件定义
|
||||||
|
const emit = defineEmits(["update:modelValue", "success", "fail", "change"]);
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance()!;
|
||||||
|
|
||||||
|
// 样式穿透类型
|
||||||
|
type PassThrough = {
|
||||||
|
className?: string;
|
||||||
|
track?: PassThroughProps;
|
||||||
|
image?: PassThroughProps;
|
||||||
|
progress?: PassThroughProps;
|
||||||
|
slider?: PassThroughProps;
|
||||||
|
icon?: PassThroughProps;
|
||||||
|
text?: PassThroughProps;
|
||||||
|
label?: PassThroughProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 样式穿透计算
|
||||||
|
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||||
|
|
||||||
|
// 滑动状态相关变量
|
||||||
|
const isDragging = ref(false); // 是否正在拖动
|
||||||
|
const isSuccess = ref(false); // 是否验证成功
|
||||||
|
const isFail = ref(false); // 是否验证失败
|
||||||
|
const sliderLeft = ref(0); // 滑块左侧距离
|
||||||
|
const progressWidth = ref(0); // 进度条宽度
|
||||||
|
const startX = ref(0); // 触摸起始点X坐标
|
||||||
|
const currentAngle = ref(0); // 当前图片角度
|
||||||
|
const initialAngle = ref(0); // 初始图片角度
|
||||||
|
|
||||||
|
// 轨道宽度
|
||||||
|
const trackWidth = ref(0); // 滑动轨道宽度
|
||||||
|
|
||||||
|
// 当前显示的提示文字
|
||||||
|
const currentText = computed(() => {
|
||||||
|
if (isSuccess.value) {
|
||||||
|
// 成功时显示成功文字
|
||||||
|
return props.successText;
|
||||||
|
}
|
||||||
|
if (isFail.value) {
|
||||||
|
// 失败时显示失败文字
|
||||||
|
return props.failText;
|
||||||
|
}
|
||||||
|
if (props.text != "") {
|
||||||
|
// 有自定义文字时显示自定义文字
|
||||||
|
return props.text;
|
||||||
|
}
|
||||||
|
if (props.mode == "image") {
|
||||||
|
// 图片模式下默认提示
|
||||||
|
return t("向右滑动转动图片");
|
||||||
|
}
|
||||||
|
return t("向右滑动验证"); // 默认提示
|
||||||
|
});
|
||||||
|
|
||||||
|
// 滑块图标
|
||||||
|
const sliderIcon = computed(() => {
|
||||||
|
if (isSuccess.value) {
|
||||||
|
// 成功时显示对勾
|
||||||
|
return "check-line";
|
||||||
|
}
|
||||||
|
return "arrow-right-double-line"; // 其他情况显示双箭头
|
||||||
|
});
|
||||||
|
|
||||||
|
// 滑块颜色
|
||||||
|
const sliderColor = computed(() => {
|
||||||
|
if (isSuccess.value || isFail.value) {
|
||||||
|
// 成功或失败时为白色
|
||||||
|
return "white";
|
||||||
|
}
|
||||||
|
return "primary"; // 其他情况为主题色
|
||||||
|
});
|
||||||
|
|
||||||
|
// 文字颜色
|
||||||
|
const textColor = computed(() => {
|
||||||
|
if (isSuccess.value) {
|
||||||
|
// 成功时为绿色
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
if (isFail.value) {
|
||||||
|
// 失败时为红色
|
||||||
|
return "error";
|
||||||
|
}
|
||||||
|
if (isDragging.value) {
|
||||||
|
// 拖动时为主题色
|
||||||
|
return "primary";
|
||||||
|
}
|
||||||
|
return "info"; // 默认为信息色
|
||||||
|
});
|
||||||
|
|
||||||
|
// 进度条样式
|
||||||
|
const progressStyle = computed(() => {
|
||||||
|
const style = {}; // 样式对象
|
||||||
|
let width = progressWidth.value; // 当前进度条宽度
|
||||||
|
if (width > props.size) {
|
||||||
|
// 超过滑块宽度时,增加宽度
|
||||||
|
width += props.size / 2;
|
||||||
|
}
|
||||||
|
style["width"] = width + "px"; // 设置宽度
|
||||||
|
if (!isDragging.value) {
|
||||||
|
// 非拖动时添加过渡动画
|
||||||
|
style["transition-duration"] = "300ms";
|
||||||
|
}
|
||||||
|
return style; // 返回样式对象
|
||||||
|
});
|
||||||
|
|
||||||
|
// 滑块样式
|
||||||
|
const sliderStyle = computed(() => {
|
||||||
|
const style = {
|
||||||
|
left: sliderLeft.value + "px", // 滑块左侧距离
|
||||||
|
height: props.size + "px", // 滑块高度
|
||||||
|
width: props.size + "px" // 滑块宽度
|
||||||
|
};
|
||||||
|
if (!isDragging.value) {
|
||||||
|
// 非拖动时添加过渡动画
|
||||||
|
style["transition-duration"] = "300ms";
|
||||||
|
}
|
||||||
|
return style; // 返回样式对象
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查验证是否成功
|
||||||
|
function checkVerification(): boolean {
|
||||||
|
if (props.mode == "slide") {
|
||||||
|
// 滑动模式下,滑块到达最右侧即为成功
|
||||||
|
return sliderLeft.value / (trackWidth.value - props.size) == 1;
|
||||||
|
} else if (props.mode == "image") {
|
||||||
|
// 图片模式下,角度在容错范围内即为成功
|
||||||
|
const angle = currentAngle.value % 360;
|
||||||
|
return angle <= props.angleThreshold || angle >= 360 - props.angleThreshold;
|
||||||
|
}
|
||||||
|
return false; // 其他情况返回失败
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置组件状态
|
||||||
|
function reset() {
|
||||||
|
sliderLeft.value = 0; // 滑块归零
|
||||||
|
progressWidth.value = 0; // 进度条归零
|
||||||
|
isSuccess.value = false; // 清除成功状态
|
||||||
|
isFail.value = false; // 清除失败状态
|
||||||
|
isDragging.value = false; // 清除拖动状态
|
||||||
|
// 图片模式下重新设置随机初始角度
|
||||||
|
if (props.mode == "image") {
|
||||||
|
initialAngle.value = random(100, 180); // 随机初始角度
|
||||||
|
currentAngle.value = initialAngle.value; // 当前角度等于初始角度
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化组件
|
||||||
|
function init() {
|
||||||
|
nextTick(() => {
|
||||||
|
// 等待DOM更新后执行
|
||||||
|
reset(); // 重置组件状态
|
||||||
|
// 获取轨道宽度
|
||||||
|
uni.createSelectorQuery()
|
||||||
|
.in(proxy)
|
||||||
|
.select(".cl-slide-verify")
|
||||||
|
.boundingClientRect()
|
||||||
|
.exec((res) => {
|
||||||
|
trackWidth.value = (res[0] as NodeInfo).width ?? 0; // 设置轨道宽度
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触摸开始事件
|
||||||
|
function onTouchStart(e: TouchEvent) {
|
||||||
|
if (props.disabled || isSuccess.value || isFail.value) return; // 禁用或已完成时不处理
|
||||||
|
isDragging.value = true; // 标记为拖动中
|
||||||
|
startX.value = e.touches[0].clientX; // 记录起始X坐标
|
||||||
|
vibrate(1); // 震动反馈
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触摸移动事件
|
||||||
|
function onTouchMove(e: TouchEvent) {
|
||||||
|
if (!isDragging.value || props.disabled || isSuccess.value || isFail.value) return; // 非拖动或禁用/完成时不处理
|
||||||
|
const currentX = e.touches[0].clientX; // 当前X坐标
|
||||||
|
const deltaX = currentX - startX.value; // 计算滑动距离
|
||||||
|
// 限制滑动范围
|
||||||
|
const newLeft = Math.max(0, Math.min(trackWidth.value - props.size, deltaX));
|
||||||
|
sliderLeft.value = newLeft; // 设置滑块位置
|
||||||
|
progressWidth.value = newLeft; // 设置进度条宽度
|
||||||
|
// 图片模式下,根据滑动距离旋转图片
|
||||||
|
if (props.mode == "image") {
|
||||||
|
const progress = newLeft / (trackWidth.value - props.size); // 计算滑动进度
|
||||||
|
// 从初始错误角度线性旋转到正确角度
|
||||||
|
currentAngle.value = initialAngle.value + initialAngle.value * progress * 3;
|
||||||
|
}
|
||||||
|
emit("change", {
|
||||||
|
progress: newLeft / trackWidth.value, // 当前进度
|
||||||
|
angle: currentAngle.value // 当前角度
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触摸结束事件
|
||||||
|
function onTouchEnd() {
|
||||||
|
if (!isDragging.value || props.disabled || isSuccess.value || isFail.value) return; // 非拖动或禁用/完成时不处理
|
||||||
|
isDragging.value = false; // 结束拖动
|
||||||
|
// 检查验证是否成功
|
||||||
|
const isComplete = checkVerification();
|
||||||
|
if (isComplete) {
|
||||||
|
// 验证成功
|
||||||
|
isSuccess.value = true;
|
||||||
|
emit("update:modelValue", true); // 通知父组件
|
||||||
|
emit("success", {
|
||||||
|
mode: props.mode,
|
||||||
|
progress: sliderLeft.value / trackWidth.value,
|
||||||
|
angle: currentAngle.value
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (props.showFail) {
|
||||||
|
isFail.value = true; // 显示失败状态
|
||||||
|
} else {
|
||||||
|
// 验证失败,重置位置
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
emit("update:modelValue", false); // 通知父组件
|
||||||
|
emit("fail", {
|
||||||
|
mode: props.mode,
|
||||||
|
progress: sliderLeft.value / trackWidth.value,
|
||||||
|
angle: currentAngle.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
vibrate(2); // 震动反馈
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听模式变化,重新初始化
|
||||||
|
watch(
|
||||||
|
computed(() => props.mode),
|
||||||
|
() => {
|
||||||
|
reset();
|
||||||
|
init();
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听图片URL变化
|
||||||
|
watch(
|
||||||
|
computed(() => props.imageUrl),
|
||||||
|
() => {
|
||||||
|
if (props.mode == "image") {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
reset
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.cl-slide-verify {
|
||||||
|
@apply relative rounded-lg w-full flex flex-col items-center justify-center;
|
||||||
|
|
||||||
|
&__track {
|
||||||
|
@apply relative w-full h-full;
|
||||||
|
@apply bg-surface-100 rounded-lg;
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
@apply bg-green-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--fail {
|
||||||
|
@apply bg-red-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--dark {
|
||||||
|
@apply bg-surface-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
@apply rounded-full mb-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__progress {
|
||||||
|
@apply absolute left-0 top-0 h-full;
|
||||||
|
@apply bg-primary-100;
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
@apply bg-green-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--fail {
|
||||||
|
@apply bg-red-200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__slider {
|
||||||
|
@apply absolute top-1/2 left-0 z-20;
|
||||||
|
@apply bg-white rounded-lg;
|
||||||
|
@apply flex items-center justify-center;
|
||||||
|
@apply border border-surface-200;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
@apply shadow-lg border-primary-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
@apply bg-green-500 border-green-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--fail {
|
||||||
|
@apply bg-red-500 border-red-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--dark {
|
||||||
|
@apply bg-surface-900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
@apply absolute flex items-center justify-center h-full w-full;
|
||||||
|
@apply pointer-events-none z-10;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
@apply opacity-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
@apply border-green-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--fail {
|
||||||
|
@apply border-red-300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
28
uni_modules/cool-ui/components/cl-slide-verify/props.ts
Normal file
28
uni_modules/cool-ui/components/cl-slide-verify/props.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import type { PassThroughProps } from "../../types";
|
||||||
|
|
||||||
|
export type ClSlideVerifyPassThrough = {
|
||||||
|
className?: string;
|
||||||
|
track?: PassThroughProps;
|
||||||
|
image?: PassThroughProps;
|
||||||
|
progress?: PassThroughProps;
|
||||||
|
slider?: PassThroughProps;
|
||||||
|
icon?: PassThroughProps;
|
||||||
|
text?: PassThroughProps;
|
||||||
|
label?: PassThroughProps;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ClSlideVerifyProps = {
|
||||||
|
className?: string;
|
||||||
|
pt?: ClSlideVerifyPassThrough;
|
||||||
|
modelValue?: boolean;
|
||||||
|
mode?: "slide" | "image";
|
||||||
|
size?: number;
|
||||||
|
disabled?: boolean;
|
||||||
|
imageUrl?: string;
|
||||||
|
imageSize?: any;
|
||||||
|
angleThreshold?: number;
|
||||||
|
text?: string;
|
||||||
|
successText?: string;
|
||||||
|
showFail?: boolean;
|
||||||
|
failText?: string;
|
||||||
|
};
|
||||||
2
uni_modules/cool-ui/index.d.ts
vendored
2
uni_modules/cool-ui/index.d.ts
vendored
@@ -55,6 +55,7 @@ import type { ClSelectTimeProps, ClSelectTimePassThrough } from "./components/cl
|
|||||||
import type { ClSelectTriggerProps, ClSelectTriggerPassThrough } from "./components/cl-select-trigger/props";
|
import type { ClSelectTriggerProps, ClSelectTriggerPassThrough } from "./components/cl-select-trigger/props";
|
||||||
import type { ClSignProps, ClSignPassThrough } from "./components/cl-sign/props";
|
import type { ClSignProps, ClSignPassThrough } from "./components/cl-sign/props";
|
||||||
import type { ClSkeletonProps, ClSkeletonPassThrough } from "./components/cl-skeleton/props";
|
import type { ClSkeletonProps, ClSkeletonPassThrough } from "./components/cl-skeleton/props";
|
||||||
|
import type { ClSlideVerifyProps, ClSlideVerifyPassThrough } from "./components/cl-slide-verify/props";
|
||||||
import type { ClSliderProps, ClSliderPassThrough } from "./components/cl-slider/props";
|
import type { ClSliderProps, ClSliderPassThrough } from "./components/cl-slider/props";
|
||||||
import type { ClStickyProps } from "./components/cl-sticky/props";
|
import type { ClStickyProps } from "./components/cl-sticky/props";
|
||||||
import type { ClSwitchProps, ClSwitchPassThrough } from "./components/cl-switch/props";
|
import type { ClSwitchProps, ClSwitchPassThrough } from "./components/cl-switch/props";
|
||||||
@@ -127,6 +128,7 @@ declare module "vue" {
|
|||||||
"cl-select-trigger": (typeof import('./components/cl-select-trigger/cl-select-trigger.uvue')['default']) & import('vue').DefineComponent<ClSelectTriggerProps>;
|
"cl-select-trigger": (typeof import('./components/cl-select-trigger/cl-select-trigger.uvue')['default']) & import('vue').DefineComponent<ClSelectTriggerProps>;
|
||||||
"cl-sign": (typeof import('./components/cl-sign/cl-sign.uvue')['default']) & import('vue').DefineComponent<ClSignProps>;
|
"cl-sign": (typeof import('./components/cl-sign/cl-sign.uvue')['default']) & import('vue').DefineComponent<ClSignProps>;
|
||||||
"cl-skeleton": (typeof import('./components/cl-skeleton/cl-skeleton.uvue')['default']) & import('vue').DefineComponent<ClSkeletonProps>;
|
"cl-skeleton": (typeof import('./components/cl-skeleton/cl-skeleton.uvue')['default']) & import('vue').DefineComponent<ClSkeletonProps>;
|
||||||
|
"cl-slide-verify": (typeof import('./components/cl-slide-verify/cl-slide-verify.uvue')['default']) & import('vue').DefineComponent<ClSlideVerifyProps>;
|
||||||
"cl-slider": (typeof import('./components/cl-slider/cl-slider.uvue')['default']) & import('vue').DefineComponent<ClSliderProps>;
|
"cl-slider": (typeof import('./components/cl-slider/cl-slider.uvue')['default']) & import('vue').DefineComponent<ClSliderProps>;
|
||||||
"cl-sticky": (typeof import('./components/cl-sticky/cl-sticky.uvue')['default']) & import('vue').DefineComponent<ClStickyProps>;
|
"cl-sticky": (typeof import('./components/cl-sticky/cl-sticky.uvue')['default']) & import('vue').DefineComponent<ClStickyProps>;
|
||||||
"cl-switch": (typeof import('./components/cl-switch/cl-switch.uvue')['default']) & import('vue').DefineComponent<ClSwitchProps>;
|
"cl-switch": (typeof import('./components/cl-switch/cl-switch.uvue')['default']) & import('vue').DefineComponent<ClSwitchProps>;
|
||||||
|
|||||||
Reference in New Issue
Block a user