feat: migrate to Tailwind CSS v4 (#7614)
* chore: update deps * feat: use jsonc/x language * chore: update eslint 10.0 * fix: no-useless-assignment * feat: add CLAUDE.md * chore: ignore * feat: claude * fix: lint * chore: suppot eslint v10 * fix: lint * fix: lint * fix: type check * fix: unit test * fix: Suggested fix * fix: unit test * chore: update stylelint v17 * chore: update all major deps * fix: echarts console warn * chore: update vitest v4 * feat: add skills ignores * chore: update deps * chore: update deps * fix: cspell * chore: update deps * chore: update tailwindcss v4 * chore: remove postcss config * fix: no use catalog * chore: tailwind v4 config * fix: tailwindcss v4 sort * feat: use eslint-plugin-better-tailwindcss * fix: Interference between enforce-consistent-line-wrapping, jsx-curly-brace-presence and Prettier * fix: Interference between enforce-consistent-line-wrapping, jsx-curly-brace-presence and Prettier * fix(lint): resolve prettier and better-tailwindcss formatting conflicts * fix(tailwind): update theme references and lint sources * style(format): normalize apps docs and playground vue files * style(format): normalize core ui-kit components * style(format): normalize effects ui and layout components
This commit is contained in:
@@ -135,7 +135,7 @@ setupVbenVxeTable({
|
||||
vxeUI.renderer.add('CellOperation', {
|
||||
renderTableDefault({ attrs, options, props }, { column, row }) {
|
||||
const defaultProps = { size: 'small', type: 'link', ...props };
|
||||
let align = 'end';
|
||||
let align: string;
|
||||
switch (column.align) {
|
||||
case 'center': {
|
||||
align = 'center';
|
||||
|
||||
@@ -107,8 +107,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}
|
||||
|
||||
async function fetchUserInfo() {
|
||||
let userInfo: null | UserInfo = null;
|
||||
userInfo = await getUserInfoApi();
|
||||
const userInfo = await getUserInfoApi();
|
||||
userStore.setUserInfo(userInfo);
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ const chartTabs: TabOption[] = [
|
||||
</AnalysisChartsTabs>
|
||||
|
||||
<div class="mt-5 w-full md:flex">
|
||||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="访问数量">
|
||||
<AnalysisChartCard class="mt-5 md:mt-0 md:mr-4 md:w-1/3" title="访问数量">
|
||||
<AnalyticsVisitsData />
|
||||
</AnalysisChartCard>
|
||||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="访问来源">
|
||||
<AnalysisChartCard class="mt-5 md:mt-0 md:mr-4 md:w-1/3" title="访问来源">
|
||||
<AnalyticsVisitsSource />
|
||||
</AnalysisChartCard>
|
||||
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源">
|
||||
|
||||
@@ -37,7 +37,7 @@ const { isFullscreen: isDomFullscreen, toggle: toggleDom } =
|
||||
|
||||
<div
|
||||
ref="domRef"
|
||||
class="mx-auto mt-10 flex h-64 w-1/2 items-center justify-center rounded-md bg-yellow-400"
|
||||
class="mx-auto mt-10 flex-center h-64 w-1/2 rounded-md bg-yellow-400"
|
||||
>
|
||||
<Button class="mr-2" type="primary" @click="toggleDom">
|
||||
{{ isDomFullscreen ? 'Exit Dom Full Screen' : 'Enter Dom Full Screen' }}
|
||||
|
||||
@@ -33,7 +33,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
<template>
|
||||
<Page description="用于前端简单的拖动校验场景" title="滑块校验">
|
||||
<Card class="mb-5" title="基础示例">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha ref="el1" @success="handleSuccess" />
|
||||
<Button class="ml-2" type="primary" @click="handleBtnClick(el1)">
|
||||
还原
|
||||
@@ -41,7 +41,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
</div>
|
||||
</Card>
|
||||
<Card class="mb-5" title="自定义圆角">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha
|
||||
ref="el2"
|
||||
class="rounded-full"
|
||||
@@ -53,7 +53,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
</div>
|
||||
</Card>
|
||||
<Card class="mb-5" title="自定义背景色">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha
|
||||
ref="el3"
|
||||
:bar-style="{
|
||||
@@ -69,7 +69,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
</div>
|
||||
</Card>
|
||||
<Card class="mb-5" title="自定义拖拽图标">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha ref="el4" @success="handleSuccess">
|
||||
<template #actionIcon="{ isPassing }">
|
||||
<Bell v-if="isPassing" />
|
||||
@@ -82,7 +82,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
</div>
|
||||
</Card>
|
||||
<Card class="mb-5" title="自定义文本">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha
|
||||
ref="el5"
|
||||
success-text="成功"
|
||||
@@ -95,7 +95,7 @@ const el6 = ref<SliderCaptchaActionType>();
|
||||
</div>
|
||||
</Card>
|
||||
<Card class="mb-5" title="自定义内容(slot)">
|
||||
<div class="flex items-center justify-center p-4 px-[30%]">
|
||||
<div class="flex-center p-4 px-[30%]">
|
||||
<SliderCaptcha ref="el6" @success="handleSuccess">
|
||||
<template #text="{ isPassing }">
|
||||
<template v-if="isPassing">
|
||||
|
||||
@@ -20,7 +20,7 @@ const avatar = computed(() => {
|
||||
<template>
|
||||
<Page description="用于前端简单的拖动校验场景" title="滑块旋转校验">
|
||||
<Card class="mb-5" title="基本示例">
|
||||
<div class="flex items-center justify-center p-4">
|
||||
<div class="flex-center p-4">
|
||||
<SliderRotateCaptcha :src="avatar" @success="handleSuccess" />
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@@ -14,7 +14,7 @@ function handleSuccess() {
|
||||
title="拼图滑块校验"
|
||||
>
|
||||
<Card class="mb-5" title="基本示例">
|
||||
<div class="flex items-center justify-center p-4">
|
||||
<div class="flex-center p-4">
|
||||
<SliderTranslateCaptcha
|
||||
src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/pro-avatar.webp"
|
||||
:canvas-width="420"
|
||||
|
||||
@@ -85,7 +85,7 @@ function onFinished() {
|
||||
</Button>
|
||||
</template>
|
||||
<Card title="基本用法">
|
||||
<div class="flex w-full items-center justify-center pb-4">
|
||||
<div class="flex-center w-full pb-4">
|
||||
<CountTo v-bind="props" @started="onStarted" @finished="onFinished" />
|
||||
</div>
|
||||
<Form :model="props">
|
||||
@@ -105,7 +105,7 @@ function onFinished() {
|
||||
<template #addonAfter>
|
||||
<IconifyIcon
|
||||
v-tippy="`设置一个随机值`"
|
||||
class="size-5 cursor-pointer outline-none"
|
||||
class="size-5 cursor-pointer outline-hidden"
|
||||
icon="ix:random-filled"
|
||||
@click="changeNumber"
|
||||
/>
|
||||
|
||||
@@ -138,7 +138,7 @@ async function fillPartialData() {
|
||||
</template>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="rounded bg-blue-50 p-4">
|
||||
<div class="rounded-sm bg-blue-50 p-4">
|
||||
<h3 class="mb-2 font-medium">测试说明:</h3>
|
||||
<ul class="list-inside list-disc space-y-1 text-sm">
|
||||
<li>所有验证方法在验证失败时都会自动滚动到第一个错误字段</li>
|
||||
@@ -146,7 +146,7 @@ async function fillPartialData() {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="rounded border p-4">
|
||||
<div class="rounded-sm border p-4">
|
||||
<h4 class="mb-3 font-medium">验证方法测试:</h4>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<Button type="primary" @click="testValidateAndSubmit">
|
||||
@@ -162,7 +162,7 @@ async function fillPartialData() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded border p-4">
|
||||
<div class="rounded-sm border p-4">
|
||||
<h4 class="mb-3 font-medium">数据填充测试:</h4>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<Button @click="fillPartialData"> 填充部分数据 </Button>
|
||||
|
||||
@@ -28,7 +28,7 @@ export const json1 = {
|
||||
|
||||
export const json2 = JSON.parse(`
|
||||
{
|
||||
"id": "chatcmpl-123",
|
||||
"id": "chatgpt-123",
|
||||
"object": "chat.completion",
|
||||
"created": 1677652288,
|
||||
"model": "gpt-3.5-turbo-0613",
|
||||
|
||||
@@ -42,11 +42,7 @@ const leftMaxWidth = ref(props.leftMaxWidth || 100);
|
||||
<template #left="{ isCollapsed, expand }">
|
||||
<div v-if="isCollapsed" @click="expand">
|
||||
<Tooltip title="点击展开左侧">
|
||||
<Button
|
||||
shape="circle"
|
||||
type="primary"
|
||||
class="flex items-center justify-center"
|
||||
>
|
||||
<Button shape="circle" type="primary" class="flex-center">
|
||||
<template #icon>
|
||||
<IconifyIcon class="text-2xl" icon="bi:arrow-right" />
|
||||
</template>
|
||||
@@ -56,7 +52,7 @@ const leftMaxWidth = ref(props.leftMaxWidth || 100);
|
||||
<div
|
||||
v-else
|
||||
:style="{ minWidth: '200px' }"
|
||||
class="mr-2 rounded-[var(--radius)] border border-border bg-card p-2"
|
||||
class="mr-2 rounded-(--radius) border border-border bg-card p-2"
|
||||
>
|
||||
<p>这里是左侧内容</p>
|
||||
<p>这里是左侧内容</p>
|
||||
|
||||
@@ -37,16 +37,13 @@ const loadingV = refAutoReset(false, 3000);
|
||||
<Loading
|
||||
:spinning="loading"
|
||||
text="正在加载..."
|
||||
class="flex h-full w-full items-center justify-center"
|
||||
class="flex-center size-full"
|
||||
>
|
||||
<Button type="primary" @click="loading = true">默认动画</Button>
|
||||
</Loading>
|
||||
</div>
|
||||
<div class="size-40">
|
||||
<Loading
|
||||
:spinning="loading"
|
||||
class="flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<Loading :spinning="loading" class="flex-center size-full">
|
||||
<Button type="primary" @click="loading = true">自定义动画1</Button>
|
||||
<template #icon>
|
||||
<IconifyIcon
|
||||
@@ -57,10 +54,7 @@ const loadingV = refAutoReset(false, 3000);
|
||||
</Loading>
|
||||
</div>
|
||||
<div class="size-40">
|
||||
<Loading
|
||||
:spinning="loading"
|
||||
class="flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<Loading :spinning="loading" class="flex-center size-full">
|
||||
<Button type="primary" @click="loading = true">自定义动画2</Button>
|
||||
<template #icon>
|
||||
<IconifyIcon
|
||||
@@ -90,10 +84,7 @@ const loadingV = refAutoReset(false, 3000);
|
||||
<template #actions>
|
||||
Spinner组件是Loading组件的一个特例,只有一个固定的统一样式。
|
||||
</template>
|
||||
<Spinner
|
||||
:spinning="spinning"
|
||||
class="flex size-40 items-center justify-center"
|
||||
>
|
||||
<Spinner :spinning="spinning" class="flex-center size-40">
|
||||
<Button type="primary" @click="spinning = true">显示Spinner</Button>
|
||||
</Spinner>
|
||||
</Card>
|
||||
|
||||
@@ -84,9 +84,7 @@ function openDocPage() {
|
||||
title="使用组件(将内部作为一个整体添加动画)"
|
||||
:body-style="{ padding: 0 }"
|
||||
>
|
||||
<div
|
||||
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
|
||||
>
|
||||
<div class="relative flex-center min-h-32 gap-2 overflow-hidden">
|
||||
<Motion
|
||||
v-bind="motionProps"
|
||||
v-if="showCard2"
|
||||
@@ -96,9 +94,7 @@ function openDocPage() {
|
||||
<span>附属组件,会作为整体处理动画</span>
|
||||
</Motion>
|
||||
</div>
|
||||
<div
|
||||
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
|
||||
>
|
||||
<div class="relative flex-center min-h-32 gap-2 overflow-hidden">
|
||||
<div v-if="showCard2" class="flex items-center gap-2">
|
||||
<span>顺序延迟</span>
|
||||
<Motion
|
||||
@@ -158,9 +154,7 @@ function openDocPage() {
|
||||
title="分组动画(每个子元素都会应用相同的独立动画)"
|
||||
:body-style="{ padding: 0 }"
|
||||
>
|
||||
<div
|
||||
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
|
||||
>
|
||||
<div class="relative flex-center min-h-32 gap-2 overflow-hidden">
|
||||
<MotionGroup v-bind="motionGroupProps" v-if="showCard3">
|
||||
<Button size="large">按钮1</Button>
|
||||
<Button size="large">按钮2</Button>
|
||||
|
||||
@@ -50,7 +50,7 @@ const resize = (size?: TSize, rect?: TSize) => {
|
||||
>
|
||||
<div
|
||||
:style="{ backgroundColor: colorMap[idx] }"
|
||||
class="h-full w-full"
|
||||
class="size-full"
|
||||
></div>
|
||||
</VResize>
|
||||
</template>
|
||||
|
||||
@@ -122,7 +122,7 @@ function onDelete(row: SystemMenuApi.SystemMenu) {
|
||||
</template>
|
||||
<template #title="{ row }">
|
||||
<div class="flex w-full items-center gap-1">
|
||||
<div class="size-5 flex-shrink-0">
|
||||
<div class="size-5 shrink-0">
|
||||
<IconifyIcon
|
||||
v-if="row.type === 'button'"
|
||||
icon="carbon:security"
|
||||
|
||||
Reference in New Issue
Block a user