zhou zhou
20 小时以前 5454bbe86b1a22e9f05b6bc43f7ed7e9d6c4dc14
rsf-design/src/components/core/views/login/AuthTopBar.vue
@@ -3,9 +3,8 @@
  <div
    class="absolute w-full flex-cb top-4.5 z-10 flex-c !justify-end max-[1180px]:!justify-between"
  >
    <div class="flex-cc !hidden max-[1180px]:!flex ml-2 max-sm:ml-6">
      <ArtLogo class="icon" size="46" />
      <h1 class="text-xl ont-mediumf ml-2">{{ AppConfig.systemInfo.name }}</h1>
    <div class="brand flex-cc !hidden max-[1180px]:!flex ml-2 max-sm:ml-6">
      <ArtLogo class="icon" fill />
    </div>
    <div class="flex-cc gap-1.5 mr-2 max-sm:mr-5">
@@ -31,35 +30,35 @@
          />
        </div>
      </div>
      <ElDropdown
      <div
        v-if="shouldShowLanguage"
        @command="changeLanguage"
        popper-class="langDropDownStyle"
        class="language-picker relative flex-c"
        @mouseenter="showLanguageMenu = true"
        @mouseleave="showLanguageMenu = false"
      >
        <div class="btn language-btn h-8 w-8 c-p flex-cc tad-300">
        <div class="btn language-btn h-8 w-8 c-p flex-cc tad-300" @click="toggleLanguageMenu">
          <ArtSvgIcon
            icon="ri:translate-2"
            class="text-[19px] text-g-800 transition-colors duration-300"
          />
        </div>
        <template #dropdown>
          <ElDropdownMenu>
            <div v-for="lang in languageOptions" :key="lang.value" class="lang-btn-item">
              <ElDropdownItem
                :command="lang.value"
                :class="{ 'is-selected': locale === lang.value }"
              >
                <span class="menu-txt">{{ lang.label }}</span>
                <ArtSvgIcon icon="ri:check-fill" class="text-base" v-if="locale === lang.value" />
              </ElDropdownItem>
            </div>
          </ElDropdownMenu>
        </template>
      </ElDropdown>
        <div class="language-menu absolute right-0 top-10" :class="{ 'is-open': showLanguageMenu }">
          <div
            v-for="lang in languageOptions"
            :key="lang.value"
            class="language-menu-item flex-cb c-p"
            :class="{ 'is-selected': locale === lang.value }"
            @click="changeLanguage(lang.value)"
          >
            <span class="menu-txt">{{ lang.label }}</span>
            <ArtSvgIcon icon="ri:check-fill" class="text-base" v-if="locale === lang.value" />
          </div>
        </div>
      </div>
      <div
        v-if="shouldShowThemeToggle"
        class="btn theme-btn h-8 w-8 c-p flex-cc tad-300"
        @click="themeAnimation"
        @click="handleThemeAnimation"
      >
        <ArtSvgIcon
          :icon="isDark ? 'ri:sun-fill' : 'ri:moon-line'"
@@ -71,22 +70,23 @@
</template>
<script setup>
  import AppConfig from '@/config'
  import { useI18n } from 'vue-i18n'
  import { languageOptions } from '@/locales/language-options'
  import { useSettingStore } from '@/store/modules/setting'
  import { useUserStore } from '@/store/modules/user'
  import { useHeaderBar } from '@/hooks/core/useHeaderBar'
  import { themeAnimation } from '@/utils/ui/animation'
  import { languageOptions } from '@/locales'
  import AppConfig from '@/config'
  defineOptions({ name: 'AuthTopBar' })
  const settingStore = useSettingStore()
  const userStore = useUserStore()
  const { isDark, systemThemeColor } = storeToRefs(settingStore)
  const { shouldShowThemeToggle, shouldShowLanguage } = useHeaderBar()
  const { locale } = useI18n()
  const showLanguageMenu = ref(false)
  const mainColors = AppConfig.systemMainColor
  const color = systemThemeColor
  const changeLanguage = (lang) => {
    showLanguageMenu.value = false
    if (locale.value === lang) return
    locale.value = lang
    userStore.setLanguage(lang)
@@ -96,9 +96,26 @@
    settingStore.setElementTheme(color2)
    settingStore.reload()
  }
  const handleThemeAnimation = async (event) => {
    const { themeAnimation } = await import('@/utils/ui/animation')
    themeAnimation(event)
  }
  const toggleLanguageMenu = () => {
    showLanguageMenu.value = !showLanguageMenu.value
  }
</script>
<style scoped>
  .brand {
    width: 132px;
    height: 34px;
  }
  .icon {
    width: 100%;
    height: 100%;
  }
  .color-dots {
    pointer-events: none;
    backdrop-filter: blur(10px);
@@ -137,6 +154,50 @@
    box-shadow: none;
  }
  .language-menu {
    min-width: 130px;
    padding: 6px;
    pointer-events: none;
    background-color: var(--default-box-color);
    border-radius: 12px;
    box-shadow: 0 2px 12px var(--art-gray-300);
    opacity: 0;
    transform: translateY(8px);
    transition:
      opacity 0.2s ease,
      transform 0.2s ease;
  }
  .language-menu.is-open {
    pointer-events: auto;
    opacity: 1;
    transform: translateY(0);
  }
  .language-menu-item {
    height: 34px;
    padding: 0 12px;
    color: var(--art-text-gray-800);
    border-radius: 10px;
    transition:
      background-color 0.2s ease,
      color 0.2s ease;
  }
  .language-menu-item:hover,
  .language-menu-item.is-selected {
    background-color: var(--art-gray-100);
  }
  .menu-txt {
    font-size: 13px;
  }
  .dark .language-menu {
    background-color: var(--art-gray-200);
    box-shadow: none;
  }
  .color-picker-expandable:hover .palette-btn :deep(.art-svg-icon) {
    color: v-bind(color);
  }