Skip to content

Commit

Permalink
perf: improve the experience of Captcha components
Browse files Browse the repository at this point in the history
  • Loading branch information
anncwb committed Sep 21, 2024
1 parent d6b2bf8 commit 9e8fc76
Show file tree
Hide file tree
Showing 29 changed files with 621 additions and 649 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
<script lang="ts" setup>
import { computed } from 'vue';
const { animationDuration = 2, animationIterationCount = 'infinite' } =
defineProps<{
// 动画持续时间,单位秒
animationDuration?: number;
// 动画是否只执行一次
animationIterationCount?: 'infinite' | number;
}>();
const style = computed(() => {
return {
animation: `shine ${animationDuration}s linear ${animationIterationCount}`,
};
});
</script>
<template>
<div class="vben-spine-text !bg-clip-text text-transparent">
<div :style="style" class="vben-spine-text !bg-clip-text text-transparent">
<slot></slot>
</div>
</template>
Expand All @@ -9,7 +26,8 @@
radial-gradient(circle at center, rgb(255 255 255 / 80%), #f000) -200% 50% /
200% 100% no-repeat,
#000;
animation: shine 3s linear infinite;
/* animation: shine 3s linear infinite; */
}
.dark .vben-spine-text {
Expand Down
1 change: 1 addition & 0 deletions packages/effects/common-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@vben-core/form-ui": "workspace:*",
"@vben-core/popup-ui": "workspace:*",
"@vben-core/shadcn-ui": "workspace:*",
"@vben-core/shared": "workspace:*",
"@vben/constants": "workspace:*",
"@vben/icons": "workspace:*",
"@vben/locales": "workspace:*",
Expand Down
7 changes: 5 additions & 2 deletions packages/effects/common-ui/src/components/captcha/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export { default as PointSelectionCaptcha } from './point-selection-captcha.vue';
export { default as PointSelectionCaptchaCard } from './point-selection-captcha-card.vue';
export { default as PointSelectionCaptcha } from './point-selection-captcha/index.vue';
export { default as PointSelectionCaptchaCard } from './point-selection-captcha/index.vue';

export { default as SliderCaptcha } from './slider-captcha/index.vue';
export { default as SliderRotateCaptcha } from './slider-rotate-captcha/index.vue';
export type * from './types';
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import type { CaptchaPoint, PointSelectionCaptchaProps } from './types';
import type { CaptchaPoint, PointSelectionCaptchaProps } from '../types';
import { RotateCw } from '@vben/icons';
import { $t } from '@vben/locales';
import { VbenButton, VbenIconButton } from '@vben-core/shadcn-ui';
import { useCaptchaPoints } from './hooks/useCaptchaPoints';
import { useCaptchaPoints } from '../hooks/useCaptchaPoints';
import CaptchaCard from './point-selection-captcha-card.vue';
const props = withDefaults(defineProps<PointSelectionCaptchaProps>(), {
Expand Down Expand Up @@ -121,32 +121,32 @@ function handleConfirm() {
@click="handleClick"
>
<template #title>
<slot name="title">{{ $t('captcha.title') }}</slot>
<slot name="title">{{ $t('ui.captcha.title') }}</slot>
</template>

<template #extra>
<VbenIconButton
:aria-label="$t('captcha.refreshAriaLabel')"
:aria-label="$t('ui.captcha.refreshAriaLabel')"
class="ml-1"
@click="handleRefresh"
>
<RotateCw class="size-5" />
</VbenIconButton>
<VbenButton
v-if="showConfirm"
:aria-label="$t('captcha.confirmAriaLabel')"
:aria-label="$t('ui.captcha.confirmAriaLabel')"
class="ml-2"
size="sm"
@click="handleConfirm"
>
{{ $t('captcha.confirm') }}
{{ $t('ui.captcha.confirm') }}
</VbenButton>
</template>

<div
v-for="(point, index) in points"
:key="index"
:aria-label="$t('captcha.pointAriaLabel') + (index + 1)"
:aria-label="$t('ui.captcha.pointAriaLabel') + (index + 1)"
:style="{
top: `${point.y - POINT_OFFSET}px`,
left: `${point.x - POINT_OFFSET}px`,
Expand All @@ -160,15 +160,15 @@ function handleConfirm() {
<template #footer>
<img
v-if="hintImage"
:alt="$t('captcha.alt')"
:alt="$t('ui.captcha.alt')"
:src="hintImage"
class="h-10 w-full rounded border border-solid border-slate-200"
/>
<div
v-else-if="hintText"
class="flex h-10 w-full items-center justify-center rounded border border-solid border-slate-200"
>
{{ `${$t('captcha.clickInOrder')}` + `${hintText}` }}
{{ `${$t('ui.captcha.clickInOrder')}` + `${hintText}` }}
</div>
</template>
</CaptchaCard>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import type { PointSelectionCaptchaCardProps } from './types';
import type { PointSelectionCaptchaCardProps } from '../types';
import { computed } from 'vue';
Expand All @@ -12,8 +12,6 @@ import {
CardTitle,
} from '@vben-core/shadcn-ui';
import { parseValue } from './utils';
const props = withDefaults(defineProps<PointSelectionCaptchaCardProps>(), {
height: '220px',
paddingX: '12px',
Expand All @@ -26,6 +24,14 @@ const emit = defineEmits<{
click: [MouseEvent];
}>();
const parseValue = (value: number | string) => {
if (typeof value === 'number') {
return value;
}
const parsed = Number.parseFloat(value);
return Number.isNaN(parsed) ? 0 : parsed;
};
const rootStyles = computed(() => ({
padding: `${parseValue(props.paddingY)}px ${parseValue(props.paddingX)}px`,
width: `${parseValue(props.width) + parseValue(props.paddingX) * 2}px`,
Expand All @@ -47,7 +53,7 @@ function handleClick(e: MouseEvent) {
<CardHeader class="p-0">
<CardTitle id="captcha-title" class="flex items-center justify-between">
<template v-if="$slots.title">
<slot name="title">{{ $t('captcha.title') }}</slot>
<slot name="title">{{ $t('ui.captcha.title') }}</slot>
</template>
<template v-else>
<span>{{ title }}</span>
Expand All @@ -60,7 +66,7 @@ function handleClick(e: MouseEvent) {
<CardContent class="relative mt-2 flex w-full overflow-hidden rounded p-0">
<img
v-show="captchaImage"
:alt="$t('captcha.alt')"
:alt="$t('ui.captcha.alt')"
:src="captchaImage"
:style="captchaStyles"
class="relative z-10"
Expand Down
Loading

0 comments on commit 9e8fc76

Please sign in to comment.