Browse Source

chore: transition-duration and add TransitionGroup component duration prop

nian 2 months ago
parent
commit
36ced09d33

+ 4 - 5
src/assets/base.css

@@ -18,13 +18,12 @@
 
 @config "../../tailwind.config.ts";
 
+@theme {
+  --default-transition-duration: 300ms;
+}
+
 @theme inline {
   --color-primary: var(--primary-color);
   --color-naive-border: var(--border-color);
   --color-naive-card: var(--card-color);
-
-  --ease-naive-bezier: var(--cubic-bezier-ease-in-out);
-  --ease-naive-bezier-in: var(--cubic-bezier-ease-in);
-  --ease-naive-bezier-out: var(--cubic-bezier-ease-out);
-  --ease-naive-bezier-in-out: var(--cubic-bezier-ease-in-out);
 }

+ 2 - 1
src/components/EmptyPlaceholder.vue

@@ -15,7 +15,8 @@ const props = defineProps<EmptyPlaceholderProps>()
 </script>
 <template>
   <Transition
-    enter-active-class="transition-[opacity,scale] duration-300 ease-naive-bezier"
+    type="transition"
+    enter-active-class="transition-[opacity,scale]"
     enter-from-class="scale-50 opacity-0"
   >
     <div

+ 6 - 5
src/layouts/aside/component/UserCard.vue

@@ -41,7 +41,7 @@ const onUserDropdownSelected = (key: string) => {
 </script>
 <template>
   <div
-    class="mb-4 flex cursor-pointer items-center transition-[background-color,border-radius,margin,padding] duration-300 hover:bg-neutral-200/90 dark:hover:bg-neutral-750/65"
+    class="mb-4 flex cursor-pointer items-center transition-[background-color,border-radius,margin,padding] hover:bg-neutral-200/90 dark:hover:bg-neutral-750/65"
     :class="
       preferencesStore.preferences.menu.collapsed
         ? 'mx-2 rounded'
@@ -57,11 +57,11 @@ const onUserDropdownSelected = (key: string) => {
       :disabled="!preferencesStore.preferences.menu.collapsed"
     >
       <div
-        class="grid place-items-center overflow-hidden rounded-full transition-[margin,padding] duration-300 ease-naive-bezier"
+        class="grid place-items-center overflow-hidden rounded-full transition-[margin,padding]"
         :class="preferencesStore.preferences.menu.collapsed ? 'mr-0 px-2 py-1.5' : 'mr-2'"
       >
         <div
-          class="flex items-center justify-center overflow-hidden transition-[height,width] duration-300 ease-naive-bezier"
+          class="flex items-center justify-center overflow-hidden transition-[height,width]"
           :class="preferencesStore.preferences.menu.collapsed ? 'size-8' : 'size-10'"
         >
           <NAvatar
@@ -79,8 +79,9 @@ const onUserDropdownSelected = (key: string) => {
       </div>
     </NDropdown>
     <Transition
-      enter-active-class="transition-[grid-template-columns] duration-150 ease-naive-bezier"
-      leave-active-class="transition-[grid-template-columns] duration-150 ease-naive-bezier"
+      type="transition"
+      enter-active-class="transition-[grid-template-columns] duration-150"
+      leave-active-class="transition-[grid-template-columns] duration-150"
       enter-from-class="grid-cols-[0fr]"
       leave-to-class="grid-cols-[0fr]"
       enter-to-class="grid-cols-[1fr]"

+ 3 - 3
src/layouts/aside/index.vue

@@ -28,7 +28,7 @@ function handleCollapseClick() {
 </script>
 <template>
   <div
-    class="relative flex h-full flex-col justify-between gap-y-4 border-r border-naive-border bg-naive-card transition-[background-color,border-color,width] duration-300 ease-naive-bezier"
+    class="relative flex h-full flex-col justify-between gap-y-4 border-r border-naive-border bg-naive-card transition-[background-color,border-color,width]"
     :style="{
       width: `${menuCollapseWidth}px`,
     }"
@@ -36,11 +36,11 @@ function handleCollapseClick() {
     <Menu />
     <UserCard />
     <div
-      class="absolute top-1/2 right-0 z-50 grid size-6 translate-x-1/2 -translate-y-1/2 cursor-pointer place-items-center rounded-full border border-naive-border bg-white transition-[background-color,border-color] duration-300 ease-naive-bezier hover:bg-neutral-50 dark:bg-neutral-750 dark:hover:bg-neutral-700"
+      class="absolute top-1/2 right-0 z-50 grid size-6 translate-x-1/2 -translate-y-1/2 cursor-pointer place-items-center rounded-full border border-naive-border bg-white transition-[background-color,border-color] hover:bg-neutral-50 dark:bg-neutral-750 dark:hover:bg-neutral-700"
       @click="handleCollapseClick"
     >
       <span
-        class="iconify size-4.5 transition-[color,rotate] duration-300 ease-naive-bezier ph--caret-left dark:text-neutral-400"
+        class="iconify size-4.5 transition-[color,rotate] ph--caret-left dark:text-neutral-400"
         :class="{
           'rotate-180': preferencesStore.preferences.menu.collapsed,
         }"

+ 19 - 18
src/layouts/component/Tabs.vue

@@ -94,7 +94,7 @@ const tabDropdownOptions = computed<DropdownOption[]>(() => {
 
   const { id, componentName } = targetTab
 
-  const { pinned, locked, keepAlived } = getTab(id) ?? {}
+  const { pinned, locked, keepAlive } = getTab(id) ?? {}
 
   return [
     {
@@ -141,11 +141,11 @@ const tabDropdownOptions = computed<DropdownOption[]>(() => {
       icon: () => (
         <span
           class={
-            keepAlived ? 'iconify-[hugeicons--database-02]' : 'iconify-[hugeicons--database-locked]'
+            keepAlive ? 'iconify-[hugeicons--database-02]' : 'iconify-[hugeicons--database-locked]'
           }
         />
       ),
-      label: keepAlived ? '取消缓存' : '缓存标签页',
+      label: keepAlive ? '取消缓存' : '缓存标签页',
       disabled: isEmpty(componentName),
     },
     {
@@ -233,7 +233,7 @@ function getTabContextMenuActions(): ContextMenuActions | null {
 
   const { id } = tabValue
 
-  const { locked, keepAlived, pinned } = getTab(id) ?? {}
+  const { locked, keepAlive: keepAlived, pinned } = getTab(id) ?? {}
 
   return {
     close: () => {
@@ -255,7 +255,7 @@ function getTabContextMenuActions(): ContextMenuActions | null {
       updateTab(id, { pinned: !pinned })
     },
     keepalive: () => {
-      updateTab(id, { keepAlived: !keepAlived })
+      updateTab(id, { keepAlive: !keepAlived })
     },
     lock: () => {
       updateTab(id, { locked: !locked })
@@ -312,6 +312,8 @@ const CompTabs = defineComponent({
         }}
       >
         <TransitionGroup
+          duration={300}
+          type='transition'
           enterFromClass='max-w-0'
           leaveToClass='max-w-0'
           onAfterEnter={() => scrollToActiveTab('smooth')}
@@ -320,7 +322,7 @@ const CompTabs = defineComponent({
             <div
               key={tab.id}
               class={[
-                'relative cursor-pointer overflow-hidden border-r border-r-naive-border transition-[background-color,border-color,max-width] duration-300 ease-naive-bezier hover:bg-primary/6 [&:not(.max-w-0)]:max-w-40',
+                'relative cursor-pointer overflow-hidden border-r border-r-naive-border transition-[background-color,border-color,max-width] hover:bg-primary/6 [&:not(.max-w-0)]:max-w-48',
                 {
                   'tab-active': tab.path === pendingActivePath.value,
                   group: !tab.locked && !preferencesStore.preferences.showTabClose,
@@ -330,11 +332,14 @@ const CompTabs = defineComponent({
               onContextmenu={(e) => handleTabContextMenuClick(e, tab)}
             >
               <Transition
-                enterActiveClass='transition-[opacity,scale,translate] duration-300 ease-naive-bezier will-change-[opacity,transform,scale]'
-                leaveActiveClass='transition-[opacity,scale,translate] duration-300 ease-naive-bezier will-change-[opacity,transform,scale]'
+                type='transition'
+                leaveActiveClass='transition-[opacity,scale,translate] will-change-[opacity,transform,scale]'
+                enterActiveClass='transition-[opacity,scale,translate] will-change-[opacity,transform,scale]'
                 leaveToClass={tabBackgroundTransitionClasses.leaveToClass}
                 enterFromClass={tabBackgroundTransitionClasses.enterFromClass}
-                onAfterEnter={() => scrollToActiveTab('smooth')}
+                onAfterEnter={() => {
+                  scrollToActiveTab('smooth')
+                }}
               >
                 {tab.path === pendingActivePath.value && (
                   <div class='absolute inset-0 z-0 size-full border-t-[1.5px] border-primary bg-primary/6' />
@@ -344,7 +349,7 @@ const CompTabs = defineComponent({
               <div class={['flex items-center py-2.5 pl-4', tab.pinned ? 'pr-4' : 'pr-2.5']}>
                 <div
                   class={[
-                    'relative flex items-center justify-center overflow-hidden transition-[translate] duration-300 ease-naive-bezier',
+                    'flex flex-1 items-center overflow-hidden transition-[translate]',
                     {
                       'translate-x-2.5':
                         !tab.pinned && (tab.locked || !preferencesStore.preferences.showTabClose),
@@ -358,21 +363,17 @@ const CompTabs = defineComponent({
                       class={[
                         tab.icon,
                         {
-                          'text-primary': tab.componentName && getTab(tab.id)?.keepAlived,
+                          'text-primary': tab.componentName && getTab(tab.id)?.keepAlive,
                         },
                       ]}
                     />
                   </div>
-                  <div class='min-w-0 overflow-hidden'>
-                    <NEllipsis tooltip={showTabTooltip.value}>{tab.title}</NEllipsis>
-                  </div>
+                  <NEllipsis tooltip={showTabTooltip.value}>{tab.title}</NEllipsis>
                 </div>
-
                 {!tab.pinned && (
                   <div
                     class={[
-                      'overflow-hidden',
-                      'ml-1 flex transition-[opacity,scale] duration-300 ease-naive-bezier',
+                      'ml-1 flex overflow-hidden transition-[opacity,scale]',
                       {
                         'scale-0 opacity-0':
                           tab.locked || !preferencesStore.preferences.showTabClose,
@@ -444,7 +445,7 @@ onBeforeUnmount(() => {
 </script>
 <template>
   <div
-    class="flex min-h-0 overflow-hidden border-b border-naive-border bg-naive-card transition-[background-color,border-color] duration-300 ease-naive-bezier select-none"
+    class="flex min-h-0 overflow-hidden border-b border-naive-border bg-naive-card transition-[background-color,border-color] select-none"
   >
     <CompTabs v-model="tabPinnedList" />
     <NScrollbar

+ 1 - 1
src/layouts/footer/index.vue

@@ -7,7 +7,7 @@ const APP_NAME = import.meta.env.VITE_APP_NAME
 </script>
 <template>
   <footer
-    class="min-h-0 border-t border-naive-border bg-naive-card transition-[background-color,border-color] duration-300 ease-naive-bezier"
+    class="min-h-0 border-t border-naive-border bg-naive-card transition-[background-color,border-color]"
   >
     <div class="flex items-center justify-center overflow-hidden py-1.5 text-xs">
       <span>{{ APP_NAME }}</span>

+ 4 - 2
src/layouts/header/Breadcrumb.vue

@@ -36,10 +36,12 @@ function isCurrentRoute(name: RouteRecordNameGeneric) {
 <template>
   <nav class="min-w-0">
     <TransitionGroup
+      :duration="300"
       tag="ul"
       class="flex"
-      enter-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
-      leave-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
+      type="transition"
+      enter-active-class="transition-[grid-template-columns]"
+      leave-active-class="transition-[grid-template-columns]"
       enter-from-class="grid-cols-[0fr]"
       leave-to-class="grid-cols-[0fr]"
       enter-to-class="grid-cols-[1fr]"

+ 3 - 3
src/layouts/header/Logo.vue

@@ -15,13 +15,13 @@ const collapseWidth = computed(() => {
 </script>
 <template>
   <div
-    class="shrink-0 border-r border-naive-border transition-[border-color,width] duration-300 ease-naive-bezier"
+    class="shrink-0 border-r border-naive-border transition-[border-color,width]"
     :style="{
       width: `${collapseWidth}px`,
     }"
   >
     <div
-      class="flex h-full items-center justify-center transition-[opacity,padding] duration-300 ease-naive-bezier"
+      class="flex h-full items-center justify-center transition-[opacity,padding]"
       :class="[
         preferencesStore.preferences.menu.collapsed ? 'px-0' : 'px-4',
         {
@@ -33,7 +33,7 @@ const collapseWidth = computed(() => {
         <div class="size-full rounded bg-primary/10"></div>
       </div>
       <div
-        class="flex-1 overflow-hidden transition-[margin-left,max-width] duration-300"
+        class="flex-1 overflow-hidden transition-[margin-left,max-width]"
         :class="preferencesStore.preferences.menu.collapsed ? 'ml-0 max-w-0' : 'ml-4 max-w-44'"
       >
         <h1 class="truncate text-xl">

+ 6 - 4
src/layouts/header/index.vue

@@ -18,8 +18,9 @@ const preferencesStore = usePreferencesStore()
     <div class="flex flex-1 items-center p-4">
       <div class="flex flex-1 items-center">
         <Transition
-          enter-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
-          leave-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
+          type="transition"
+          enter-active-class="transition-[grid-template-columns]"
+          leave-active-class="transition-[grid-template-columns]"
           enter-from-class="grid-cols-[0fr]"
           leave-to-class="grid-cols-[0fr]"
           enter-to-class="grid-cols-[1fr]"
@@ -34,8 +35,9 @@ const preferencesStore = usePreferencesStore()
         </Transition>
 
         <Transition
-          enter-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
-          leave-active-class="transition-[grid-template-columns] duration-300 ease-naive-bezier"
+          type="transition"
+          enter-active-class="transition-[grid-template-columns]"
+          leave-active-class="transition-[grid-template-columns]"
           enter-from-class="grid-cols-[0fr]"
           leave-to-class="grid-cols-[0fr]"
           enter-to-class="grid-cols-[1fr]"

+ 7 - 5
src/layouts/index.vue

@@ -25,7 +25,7 @@ const { scrollbarInMainLayout } = useComponentThemeOverrides()
 <template>
   <div class="flex h-dvh flex-col overflow-hidden">
     <div
-      class="border-b border-naive-border bg-naive-card transition-[background-color,border-color] duration-300 ease-naive-bezier"
+      class="border-b border-naive-border bg-naive-card transition-[background-color,border-color]"
     >
       <HeaderLayout />
     </div>
@@ -33,8 +33,9 @@ const { scrollbarInMainLayout } = useComponentThemeOverrides()
       <AsideLayout />
       <div class="relative flex flex-1 flex-col overflow-x-hidden">
         <Transition
-          enter-active-class="transition-[grid-template-rows] duration-300 ease-naive-bezier"
-          leave-active-class="transition-[grid-template-rows] duration-300 ease-naive-bezier"
+          type="transition"
+          enter-active-class="transition-[grid-template-rows]"
+          leave-active-class="transition-[grid-template-rows]"
           enter-from-class="grid-rows-[0fr]"
           leave-to-class="grid-rows-[0fr]"
           enter-to-class="grid-rows-[1fr]"
@@ -68,8 +69,9 @@ const { scrollbarInMainLayout } = useComponentThemeOverrides()
           </template>
         </EmptyPlaceholder>
         <Transition
-          enter-active-class="transition-[grid-template-rows] duration-300 ease-naive-bezier"
-          leave-active-class="transition-[grid-template-rows] duration-300 ease-naive-bezier"
+          type="transition"
+          enter-active-class="transition-[grid-template-rows]"
+          leave-active-class="transition-[grid-template-rows]"
           enter-from-class="grid-rows-[0fr]"
           leave-to-class="grid-rows-[0fr]"
           enter-to-class="grid-rows-[1fr]"

+ 10 - 10
src/views/dashboard/index.vue

@@ -98,7 +98,7 @@ function generateCardData() {
       percentage: parseFloat((3.2 + Math.random() * 4).toFixed(2)),
       iconClass: 'iconify ph--users-bold text-indigo-50 dark:text-indigo-150',
       iconBgClass:
-        'text-indigo-500/5 bg-indigo-400 ring-4 ring-indigo-200 duration-300 dark:bg-indigo-650 dark:ring-indigo-500/30',
+        'text-indigo-500/5 bg-indigo-400 ring-4 ring-indigo-200 dark:bg-indigo-650 dark:ring-indigo-500/30 transition-all',
       precision: 0,
       description: `${currentMonth}月新增 ${Math.floor(100 + Math.random() * 200)} 人`,
     },
@@ -108,7 +108,7 @@ function generateCardData() {
       percentage: parseFloat((-2 + Math.random() * 20).toFixed(2)),
       iconClass: 'iconify ph--eye-bold text-blue-50 dark:text-blue-150',
       iconBgClass:
-        'text-blue-500/5 bg-blue-400 ring-4 ring-blue-200 duration-300 dark:bg-blue-650 dark:ring-blue-500/30',
+        'text-blue-500/5 bg-blue-400 ring-4 ring-blue-200 dark:bg-blue-650 dark:ring-blue-500/30 transition-all',
       precision: 0,
       description: '较昨日变化',
     },
@@ -118,7 +118,7 @@ function generateCardData() {
       percentage: parseFloat((5 + Math.random() * 10).toFixed(2)),
       iconClass: 'iconify ph--currency-dollar-bold text-emerald-50 dark:text-emerald-150',
       iconBgClass:
-        'text-emerald-500/5 bg-emerald-400 ring-4 ring-emerald-200 duration-300 dark:bg-emerald-650 dark:ring-emerald-500/30',
+        'text-emerald-500/5 bg-emerald-400 ring-4 ring-emerald-200 dark:bg-emerald-650 dark:ring-emerald-500/30 transition-all',
       precision: 2,
       description: '本月累计收入',
     },
@@ -128,7 +128,7 @@ function generateCardData() {
       percentage: parseFloat((-8 + Math.random() * 6).toFixed(2)),
       iconClass: 'iconify ph--shopping-cart-bold text-orange-50 dark:text-orange-150',
       iconBgClass:
-        'text-orange-500/5 bg-orange-400 ring-4 ring-orange-200 duration-300 dark:bg-orange-650 dark:ring-orange-500/30',
+        'text-orange-500/5 bg-orange-400 ring-4 ring-orange-200 dark:bg-orange-650 dark:ring-orange-500/30 transition-all',
       precision: 0,
       description: '需要及时处理',
     },
@@ -1123,7 +1123,7 @@ watch([isDark, color], () => {
       <div
         v-for="item in cardList"
         :key="item.title"
-        class="flex items-center justify-between gap-x-4 overflow-hidden rounded bg-naive-card p-6 shadow-xs duration-300 ease-naive-bezier"
+        class="flex items-center justify-between gap-x-4 overflow-hidden rounded bg-naive-card p-6 shadow-xs transition-[background-color]"
       >
         <div class="flex-1">
           <span class="text-sm font-medium text-neutral-450">{{ item.title }}</span>
@@ -1136,7 +1136,7 @@ watch([isDark, color], () => {
           </div>
           <div class="flex items-center">
             <div
-              class="flex items-center gap-x-0.5 rounded-xs px-1.5 py-0.5 text-xs duration-300"
+              class="flex items-center gap-x-0.5 rounded-xs px-1.5 py-0.5 text-xs transition-[background-color,color]"
               :class="
                 item.percentage > 0
                   ? 'bg-green-100 text-green-600 dark:bg-green-500/20 dark:text-green-400'
@@ -1168,7 +1168,7 @@ watch([isDark, color], () => {
     <div class="grid grid-cols-1 gap-4 overflow-hidden lg:grid-cols-12">
       <div class="col-span-1 lg:col-span-8">
         <div
-          class="rounded bg-naive-card px-5 pt-5 pb-4.5 shadow-xs transition-[background-color] duration-300 ease-naive-bezier"
+          class="rounded bg-naive-card px-5 pt-5 pb-4.5 shadow-xs transition-[background-color]"
           style="height: 400px"
         >
           <div
@@ -1179,7 +1179,7 @@ watch([isDark, color], () => {
       </div>
       <div class="col-span-1 lg:col-span-4">
         <div
-          class="flex flex-col rounded bg-naive-card px-5 pt-5 pb-4.5 shadow-xs transition-[background-color] duration-300 ease-naive-bezier"
+          class="flex flex-col rounded bg-naive-card px-5 pt-5 pb-4.5 shadow-xs transition-[background-color]"
           style="height: 400px"
         >
           <div
@@ -1196,7 +1196,7 @@ watch([isDark, color], () => {
     <div class="grid grid-cols-1 gap-4 overflow-hidden lg:grid-cols-12">
       <div class="col-span-1 lg:col-span-5">
         <div
-          class="rounded bg-naive-card px-5 pt-5 pb-3 shadow-xs transition-[background-color] duration-300 ease-naive-bezier"
+          class="rounded bg-naive-card px-5 pt-5 pb-3 shadow-xs transition-[background-color]"
           style="height: 340px"
         >
           <div
@@ -1207,7 +1207,7 @@ watch([isDark, color], () => {
       </div>
       <div class="col-span-1 lg:col-span-7">
         <div
-          class="rounded bg-naive-card p-5 shadow-xs transition-[background-color] duration-300 ease-naive-bezier"
+          class="rounded bg-naive-card p-5 shadow-xs transition-[background-color]"
           style="height: 340px; position: relative"
         >
           <div

+ 6 - 10
src/views/sign-in/index.vue

@@ -96,10 +96,10 @@ onUnmounted(() => {
 </script>
 <template>
   <div
-    class="relative flex h-screen items-center justify-center bg-neutral-50 transition-[background-color] duration-300 ease-naive-bezier dark:bg-neutral-900"
+    class="relative flex h-screen items-center justify-center bg-neutral-50 transition-[background-color] dark:bg-neutral-900"
   >
     <div
-      class="absolute top-0 left-0 size-full bg-neutral-200/45 transition-[background-color] duration-300 ease-naive-bezier dark:bg-neutral-800/50"
+      class="absolute top-0 left-0 size-full bg-neutral-200/45 transition-[background-color] dark:bg-neutral-800/50"
       :style="{
         'mask-image': `url(${topographySvg})`,
         '-webkit-mask-image': `url(${topographySvg})`,
@@ -110,7 +110,7 @@ onUnmounted(() => {
       }"
     />
     <div
-      class="pointer-events-none absolute inset-0 z-10 transition-[filter] duration-300 ease-naive-bezier"
+      class="pointer-events-none absolute inset-0 z-10 transition-[filter]"
       :style="{
         'background-image': `url(${topographySvg})`,
         'background-size': textureMaskParams.size,
@@ -121,7 +121,7 @@ onUnmounted(() => {
     />
     <div class="relative z-50 flex h-[480px] w-[800px] rounded shadow-lg">
       <div
-        class="flex-1 bg-neutral-50 py-6 pl-6 text-primary transition-[background-color] duration-300 ease-naive-bezier dark:bg-neutral-850"
+        class="flex-1 bg-neutral-50 py-6 pl-6 text-primary transition-[background-color] dark:bg-neutral-850"
       >
         <NCarousel
           draggable
@@ -137,7 +137,7 @@ onUnmounted(() => {
         </NCarousel>
       </div>
       <div
-        class="relative flex w-[340px] flex-col bg-white px-10 py-12 transition-[background-color] duration-300 ease-naive-bezier dark:bg-neutral-800"
+        class="relative flex w-[340px] flex-col bg-white px-10 py-12 transition-[background-color] dark:bg-neutral-800"
       >
         <div class="absolute top-0 left-0 z-50 flex w-full items-center justify-end gap-x-4 p-4">
           <ThemeColorPopover />
@@ -146,11 +146,7 @@ onUnmounted(() => {
         <div>
           <div>
             <h2 class="text-2xl">登&nbsp;录</h2>
-            <p
-              class="text-neutral-400 transition-[color] duration-300 ease-naive-bezier dark:text-neutral-500"
-            >
-              SIGN IN
-            </p>
+            <p class="text-neutral-400 transition-[color] dark:text-neutral-500">SIGN IN</p>
           </div>
           <div class="mt-12">
             <NForm