feat: home page optimize
This commit is contained in:
4
components.d.ts
vendored
4
components.d.ts
vendored
@@ -25,12 +25,14 @@ declare module 'vue' {
|
|||||||
CalendarHeading: typeof import('./src/components/ui/calendar/CalendarHeading.vue')['default']
|
CalendarHeading: typeof import('./src/components/ui/calendar/CalendarHeading.vue')['default']
|
||||||
CalendarNextButton: typeof import('./src/components/ui/calendar/CalendarNextButton.vue')['default']
|
CalendarNextButton: typeof import('./src/components/ui/calendar/CalendarNextButton.vue')['default']
|
||||||
CalendarPrevButton: typeof import('./src/components/ui/calendar/CalendarPrevButton.vue')['default']
|
CalendarPrevButton: typeof import('./src/components/ui/calendar/CalendarPrevButton.vue')['default']
|
||||||
|
ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default']
|
||||||
ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
|
ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
|
||||||
DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
|
DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
|
||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
||||||
NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
||||||
NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default']
|
NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default']
|
||||||
|
NavBar: typeof import('./src/components/menu/NavBar.vue')['default']
|
||||||
Popover: typeof import('./src/components/ui/popover/Popover.vue')['default']
|
Popover: typeof import('./src/components/ui/popover/Popover.vue')['default']
|
||||||
PopoverAnchor: typeof import('./src/components/ui/popover/PopoverAnchor.vue')['default']
|
PopoverAnchor: typeof import('./src/components/ui/popover/PopoverAnchor.vue')['default']
|
||||||
PopoverContent: typeof import('./src/components/ui/popover/PopoverContent.vue')['default']
|
PopoverContent: typeof import('./src/components/ui/popover/PopoverContent.vue')['default']
|
||||||
@@ -55,12 +57,14 @@ declare global {
|
|||||||
const CalendarHeading: typeof import('./src/components/ui/calendar/CalendarHeading.vue')['default']
|
const CalendarHeading: typeof import('./src/components/ui/calendar/CalendarHeading.vue')['default']
|
||||||
const CalendarNextButton: typeof import('./src/components/ui/calendar/CalendarNextButton.vue')['default']
|
const CalendarNextButton: typeof import('./src/components/ui/calendar/CalendarNextButton.vue')['default']
|
||||||
const CalendarPrevButton: typeof import('./src/components/ui/calendar/CalendarPrevButton.vue')['default']
|
const CalendarPrevButton: typeof import('./src/components/ui/calendar/CalendarPrevButton.vue')['default']
|
||||||
|
const ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default']
|
||||||
const ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
|
const ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
|
||||||
const DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
|
const DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
|
||||||
const ElButton: typeof import('element-plus/es')['ElButton']
|
const ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
||||||
const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
||||||
const NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default']
|
const NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default']
|
||||||
|
const NavBar: typeof import('./src/components/menu/NavBar.vue')['default']
|
||||||
const Popover: typeof import('./src/components/ui/popover/Popover.vue')['default']
|
const Popover: typeof import('./src/components/ui/popover/Popover.vue')['default']
|
||||||
const PopoverAnchor: typeof import('./src/components/ui/popover/PopoverAnchor.vue')['default']
|
const PopoverAnchor: typeof import('./src/components/ui/popover/PopoverAnchor.vue')['default']
|
||||||
const PopoverContent: typeof import('./src/components/ui/popover/PopoverContent.vue')['default']
|
const PopoverContent: typeof import('./src/components/ui/popover/PopoverContent.vue')['default']
|
||||||
|
|||||||
@@ -26,4 +26,14 @@
|
|||||||
|
|
||||||
## 关于 Shadcn
|
## 关于 Shadcn
|
||||||
|
|
||||||
|
:::warning 警告
|
||||||
|
Shadcn 组件的样式将会被 Daisy-ui 组件样式所覆盖。阅读以下文档进行调整。
|
||||||
|
:::
|
||||||
|
|
||||||
`components/ui` 目录下是 shadcn-vue 提供的组件代码,您可以在项目中直接调用这些组件,同时也可以根据需要进行调整。
|
`components/ui` 目录下是 shadcn-vue 提供的组件代码,您可以在项目中直接调用这些组件,同时也可以根据需要进行调整。
|
||||||
|
|
||||||
|
由于 daisy-ui 和 shadcn 同时使用类似 --color-primary 的 css 变量来调整主题样式,Hucky 删除了 shadcn 在全局样式上做的调整,如果您需要调整 shadcn 中的组件样式,请通过在组件内部的 style 标签中设置 css 变量来实现。
|
||||||
|
|
||||||
|
:::tip 提示
|
||||||
|
尽管 shadcn 组件的样式确实可以调整,但仅建议对 css 掌握度较高的开发者调整。如果您不熟悉 css 及 css 变量,仍然建议您接受 shadcn 的组件使用 daisy-ui 提供的默认样式,或者不使用 shadcn 组件。
|
||||||
|
:::
|
||||||
|
|||||||
66
src/components/button/ChangeLanguageDropdownButton.vue
Normal file
66
src/components/button/ChangeLanguageDropdownButton.vue
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useGlobalLanguageHook } from "@/hooks/globalLanguageHook";
|
||||||
|
|
||||||
|
const { changeGlobalLanguage, curGlobalLanguage, optionalLanguages } =
|
||||||
|
useGlobalLanguageHook();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="dropdown dropdown-end">
|
||||||
|
<div
|
||||||
|
tabindex="0"
|
||||||
|
role="button"
|
||||||
|
class="btn btn-sm btn-ghost gap-1 px-1.5 font-bold"
|
||||||
|
aria-label="Language"
|
||||||
|
title="Change Language"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="text-base-content/70 size-4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-width="2"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
d="M12 21a9 9 0 1 0 0-18m0 18a9 9 0 1 1 0-18m0 18c2.761 0 3.941-5.163 3.941-9S14.761 3 12 3m0 18c-2.761 0-3.941-5.163-3.941-9S9.239 3 12 3M3.5 9h17m-17 6h17"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
class="mt-px hidden size-2 fill-current opacity-60 sm:inline-block"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 2048 2048"
|
||||||
|
>
|
||||||
|
<path d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
tabindex="0"
|
||||||
|
class="dropdown-content bg-base-200 text-base-content rounded-box top-px mt-14 w-56 overflow-y-auto border-[length:var(--border)] border-white/5 shadow-2xl outline-[length:var(--border)] outline-black/5"
|
||||||
|
>
|
||||||
|
<ul class="menu menu-sm w-full">
|
||||||
|
<li class="menu-title text-xs">语言</li>
|
||||||
|
<li
|
||||||
|
v-for="optionalLanguage in optionalLanguages"
|
||||||
|
:key="optionalLanguage.label"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
:class="[
|
||||||
|
curGlobalLanguage === optionalLanguage.label ? 'menu-active' : '',
|
||||||
|
]"
|
||||||
|
@click="changeGlobalLanguage(optionalLanguage.label)"
|
||||||
|
>
|
||||||
|
<span class="pe-4 font-mono font-bold opacity-40">
|
||||||
|
{{ optionalLanguage.label }}
|
||||||
|
</span>
|
||||||
|
<span class="font-[sans-serif]">{{ optionalLanguage.value }}</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -7,13 +7,18 @@ const { changeGlobalTheme, curGlobalTheme, optionalThemes } =
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="dropdown">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn m-1">
|
<div tabindex="0" role="button" class="btn btn-sm btn-ghost px-1.5">
|
||||||
主题
|
<div
|
||||||
|
class="bg-base-100 group-hover:border-base-content/20 border-base-content/10 grid shrink-0 grid-cols-2 gap-0.5 rounded-md border p-1 transition-colors"
|
||||||
|
>
|
||||||
|
<div class="bg-base-content size-1 rounded-full" />
|
||||||
|
<div class="bg-primary size-1 rounded-full" />
|
||||||
|
<div class="bg-secondary size-1 rounded-full" />
|
||||||
|
<div class="bg-accent size-1 rounded-full" />
|
||||||
|
</div>
|
||||||
<svg
|
<svg
|
||||||
width="12px"
|
class="mt-px hidden size-2 fill-current opacity-60 sm:inline-block"
|
||||||
height="12px"
|
|
||||||
class="inline-block h-2 w-2 fill-current opacity-60"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 2048 2048"
|
viewBox="0 0 2048 2048"
|
||||||
>
|
>
|
||||||
@@ -24,9 +29,14 @@ const { changeGlobalTheme, curGlobalTheme, optionalThemes } =
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
class="dropdown-content bg-base-300 rounded-box z-1 w-52 p-2 shadow-2xl max-h-84 overflow-auto"
|
class="dropdown-content bg-base-300 rounded-box z-1 w-52 p-2 shadow-2xl max-h-84 overflow-auto mt-6"
|
||||||
>
|
>
|
||||||
<li v-for="optionalTheme in optionalThemes" :key="optionalTheme">
|
<li class="menu-title text-xs my-1">主题</li>
|
||||||
|
<li
|
||||||
|
v-for="optionalTheme in optionalThemes"
|
||||||
|
:key="optionalTheme"
|
||||||
|
class="my-1"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="theme-dropdown"
|
name="theme-dropdown"
|
||||||
|
|||||||
49
src/components/menu/NavBar.vue
Normal file
49
src/components/menu/NavBar.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import ChangeLanguageDropdownButton from "@/components/button/ChangeLanguageDropdownButton.vue";
|
||||||
|
import ChangeThemeDropdownButton from "@/components/button/ChangeThemeDropdownButton.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="navbar bg-base-200 shadow-sm">
|
||||||
|
<div class="navbar-start">
|
||||||
|
<div class="dropdown">
|
||||||
|
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-5 w-5"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 6h16M4 12h8m-8 6h16"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<ul
|
||||||
|
tabindex="-1"
|
||||||
|
class="menu dropdown-content bg-base-100 rounded-box z-1 mt-5 w-52 p-2 shadow"
|
||||||
|
>
|
||||||
|
<li><a>首页</a></li>
|
||||||
|
<li><a>关于</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-ghost text-xl">daisyUI</a>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-center hidden lg:flex">
|
||||||
|
<ul class="menu menu-horizontal px-1">
|
||||||
|
<li><a>首页</a></li>
|
||||||
|
<li><a>关于</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-end">
|
||||||
|
<ChangeThemeDropdownButton />
|
||||||
|
<ChangeLanguageDropdownButton />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -1,64 +1,114 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { CalendarRootEmits, CalendarRootProps, DateValue } from "reka-ui"
|
import type { CalendarRootEmits, CalendarRootProps, DateValue } from "reka-ui";
|
||||||
import type { HTMLAttributes, Ref } from "vue"
|
import type { HTMLAttributes, Ref } from "vue";
|
||||||
import type { LayoutTypes } from "."
|
import type { LayoutTypes } from ".";
|
||||||
import { getLocalTimeZone, today } from "@internationalized/date"
|
import { getLocalTimeZone, today } from "@internationalized/date";
|
||||||
import { createReusableTemplate, reactiveOmit, useVModel } from "@vueuse/core"
|
import { createReusableTemplate, reactiveOmit, useVModel } from "@vueuse/core";
|
||||||
import { CalendarRoot, useDateFormatter, useForwardPropsEmits } from "reka-ui"
|
import { CalendarRoot, useDateFormatter, useForwardPropsEmits } from "reka-ui";
|
||||||
import { createYear, createYearRange, toDate } from "reka-ui/date"
|
import { createYear, createYearRange, toDate } from "reka-ui/date";
|
||||||
import { computed, toRaw } from "vue"
|
import { computed, toRaw } from "vue";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
import { NativeSelect, NativeSelectOption } from '@/components/ui/native-select'
|
import {
|
||||||
import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, CalendarGridHead, CalendarGridRow, CalendarHeadCell, CalendarHeader, CalendarHeading, CalendarNextButton, CalendarPrevButton } from "."
|
NativeSelect,
|
||||||
|
NativeSelectOption,
|
||||||
|
} from "@/components/ui/native-select";
|
||||||
|
import {
|
||||||
|
CalendarCell,
|
||||||
|
CalendarCellTrigger,
|
||||||
|
CalendarGrid,
|
||||||
|
CalendarGridBody,
|
||||||
|
CalendarGridHead,
|
||||||
|
CalendarGridRow,
|
||||||
|
CalendarHeadCell,
|
||||||
|
CalendarHeader,
|
||||||
|
CalendarHeading,
|
||||||
|
CalendarNextButton,
|
||||||
|
CalendarPrevButton,
|
||||||
|
} from ".";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<CalendarRootProps & { class?: HTMLAttributes["class"], layout?: LayoutTypes, yearRange?: DateValue[] }>(), {
|
const props = withDefaults(
|
||||||
modelValue: undefined,
|
defineProps<
|
||||||
layout: undefined,
|
CalendarRootProps & {
|
||||||
})
|
class?: HTMLAttributes["class"];
|
||||||
const emits = defineEmits<CalendarRootEmits>()
|
layout?: LayoutTypes;
|
||||||
|
yearRange?: DateValue[];
|
||||||
|
}
|
||||||
|
>(),
|
||||||
|
{
|
||||||
|
modelValue: undefined,
|
||||||
|
layout: undefined,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const emits = defineEmits<CalendarRootEmits>();
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, "class", "layout", "placeholder")
|
const delegatedProps = reactiveOmit(props, "class", "layout", "placeholder");
|
||||||
|
|
||||||
const placeholder = useVModel(props, "placeholder", emits, {
|
const placeholder = useVModel(props, "placeholder", emits, {
|
||||||
passive: true,
|
passive: true,
|
||||||
defaultValue: props.defaultPlaceholder ?? today(getLocalTimeZone()),
|
defaultValue: props.defaultPlaceholder ?? today(getLocalTimeZone()),
|
||||||
}) as Ref<DateValue>
|
}) as Ref<DateValue>;
|
||||||
|
|
||||||
const formatter = useDateFormatter(props.locale ?? "en")
|
const formatter = useDateFormatter(props.locale ?? "en");
|
||||||
|
|
||||||
const yearRange = computed(() => {
|
const yearRange = computed(() => {
|
||||||
return props.yearRange ?? createYearRange({
|
return (
|
||||||
start: props?.minValue ?? (toRaw(props.placeholder) ?? props.defaultPlaceholder ?? today(getLocalTimeZone()))
|
props.yearRange ??
|
||||||
.cycle("year", -100),
|
createYearRange({
|
||||||
|
start:
|
||||||
|
props?.minValue ??
|
||||||
|
(
|
||||||
|
toRaw(props.placeholder) ??
|
||||||
|
props.defaultPlaceholder ??
|
||||||
|
today(getLocalTimeZone())
|
||||||
|
).cycle("year", -100),
|
||||||
|
|
||||||
end: props?.maxValue ?? (toRaw(props.placeholder) ?? props.defaultPlaceholder ?? today(getLocalTimeZone()))
|
end:
|
||||||
.cycle("year", 10),
|
props?.maxValue ??
|
||||||
})
|
(
|
||||||
})
|
toRaw(props.placeholder) ??
|
||||||
|
props.defaultPlaceholder ??
|
||||||
|
today(getLocalTimeZone())
|
||||||
|
).cycle("year", 10),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const [DefineMonthTemplate, ReuseMonthTemplate] = createReusableTemplate<{ date: DateValue }>()
|
const [DefineMonthTemplate, ReuseMonthTemplate] = createReusableTemplate<{
|
||||||
const [DefineYearTemplate, ReuseYearTemplate] = createReusableTemplate<{ date: DateValue }>()
|
date: DateValue;
|
||||||
|
}>();
|
||||||
|
const [DefineYearTemplate, ReuseYearTemplate] = createReusableTemplate<{
|
||||||
|
date: DateValue;
|
||||||
|
}>();
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<DefineMonthTemplate v-slot="{ date }">
|
<DefineMonthTemplate v-slot="{ date }">
|
||||||
<div class="**:data-[slot=native-select-icon]:right-1">
|
<div class="**:data-[slot=native-select-icon]:right-1">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="absolute inset-0 flex h-full items-center text-sm pl-2 pointer-events-none">
|
<div
|
||||||
{{ formatter.custom(toDate(date), { month: 'short' }) }}
|
class="absolute inset-0 flex h-full items-center text-sm pl-2 pointer-events-none"
|
||||||
|
>
|
||||||
|
{{ formatter.custom(toDate(date), { month: "short" }) }}
|
||||||
</div>
|
</div>
|
||||||
<NativeSelect
|
<NativeSelect
|
||||||
class="text-xs h-8 pr-6 pl-2 text-transparent relative"
|
class="text-xs h-8 pr-6 pl-2 text-transparent relative"
|
||||||
@change="(e: Event) => {
|
@change="
|
||||||
placeholder = placeholder.set({
|
(e: Event) => {
|
||||||
month: Number((e?.target as any)?.value),
|
placeholder = placeholder.set({
|
||||||
})
|
month: Number((e?.target as any)?.value),
|
||||||
}"
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<NativeSelectOption v-for="(month) in createYear({ dateObj: date })" :key="month.toString()" :value="month.month" :selected="date.month === month.month">
|
<NativeSelectOption
|
||||||
{{ formatter.custom(toDate(month), { month: 'short' }) }}
|
v-for="month in createYear({ dateObj: date })"
|
||||||
|
:key="month.toString()"
|
||||||
|
:value="month.month"
|
||||||
|
:selected="date.month === month.month"
|
||||||
|
>
|
||||||
|
{{ formatter.custom(toDate(month), { month: "short" }) }}
|
||||||
</NativeSelectOption>
|
</NativeSelectOption>
|
||||||
</NativeSelect>
|
</NativeSelect>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,19 +118,28 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
<DefineYearTemplate v-slot="{ date }">
|
<DefineYearTemplate v-slot="{ date }">
|
||||||
<div class="**:data-[slot=native-select-icon]:right-1">
|
<div class="**:data-[slot=native-select-icon]:right-1">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="absolute inset-0 flex h-full items-center text-sm pl-2 pointer-events-none">
|
<div
|
||||||
{{ formatter.custom(toDate(date), { year: 'numeric' }) }}
|
class="absolute inset-0 flex h-full items-center text-sm pl-2 pointer-events-none"
|
||||||
|
>
|
||||||
|
{{ formatter.custom(toDate(date), { year: "numeric" }) }}
|
||||||
</div>
|
</div>
|
||||||
<NativeSelect
|
<NativeSelect
|
||||||
class="text-xs h-8 pr-6 pl-2 text-transparent relative"
|
class="text-xs h-8 pr-6 pl-2 text-transparent relative"
|
||||||
@change="(e: Event) => {
|
@change="
|
||||||
placeholder = placeholder.set({
|
(e: Event) => {
|
||||||
year: Number((e?.target as any)?.value),
|
placeholder = placeholder.set({
|
||||||
})
|
year: Number((e?.target as any)?.value),
|
||||||
}"
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<NativeSelectOption v-for="(year) in yearRange" :key="year.toString()" :value="year.year" :selected="date.year === year.year">
|
<NativeSelectOption
|
||||||
{{ formatter.custom(toDate(year), { year: 'numeric' }) }}
|
v-for="year in yearRange"
|
||||||
|
:key="year.toString()"
|
||||||
|
:value="year.year"
|
||||||
|
:selected="date.year === year.year"
|
||||||
|
>
|
||||||
|
{{ formatter.custom(toDate(year), { year: "numeric" }) }}
|
||||||
</NativeSelectOption>
|
</NativeSelectOption>
|
||||||
</NativeSelect>
|
</NativeSelect>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +154,9 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
:class="cn('p-3', props.class)"
|
:class="cn('p-3', props.class)"
|
||||||
>
|
>
|
||||||
<CalendarHeader class="pt-0">
|
<CalendarHeader class="pt-0">
|
||||||
<nav class="flex items-center gap-1 absolute top-0 inset-x-0 justify-between">
|
<nav
|
||||||
|
class="flex items-center gap-1 absolute top-0 inset-x-0 justify-between"
|
||||||
|
>
|
||||||
<CalendarPrevButton>
|
<CalendarPrevButton>
|
||||||
<slot name="calendar-prev-icon" />
|
<slot name="calendar-prev-icon" />
|
||||||
</CalendarPrevButton>
|
</CalendarPrevButton>
|
||||||
@@ -104,7 +165,12 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
</CalendarNextButton>
|
</CalendarNextButton>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<slot name="calendar-heading" :date="date" :month="ReuseMonthTemplate" :year="ReuseYearTemplate">
|
<slot
|
||||||
|
name="calendar-heading"
|
||||||
|
:date="date"
|
||||||
|
:month="ReuseMonthTemplate"
|
||||||
|
:year="ReuseYearTemplate"
|
||||||
|
>
|
||||||
<template v-if="layout === 'month-and-year'">
|
<template v-if="layout === 'month-and-year'">
|
||||||
<div class="flex items-center justify-center gap-1">
|
<div class="flex items-center justify-center gap-1">
|
||||||
<ReuseMonthTemplate :date="date" />
|
<ReuseMonthTemplate :date="date" />
|
||||||
@@ -114,12 +180,12 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
<template v-else-if="layout === 'month-only'">
|
<template v-else-if="layout === 'month-only'">
|
||||||
<div class="flex items-center justify-center gap-1">
|
<div class="flex items-center justify-center gap-1">
|
||||||
<ReuseMonthTemplate :date="date" />
|
<ReuseMonthTemplate :date="date" />
|
||||||
{{ formatter.custom(toDate(date), { year: 'numeric' }) }}
|
{{ formatter.custom(toDate(date), { year: "numeric" }) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="layout === 'year-only'">
|
<template v-else-if="layout === 'year-only'">
|
||||||
<div class="flex items-center justify-center gap-1">
|
<div class="flex items-center justify-center gap-1">
|
||||||
{{ formatter.custom(toDate(date), { month: 'short' }) }}
|
{{ formatter.custom(toDate(date), { month: "short" }) }}
|
||||||
<ReuseYearTemplate :date="date" />
|
<ReuseYearTemplate :date="date" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -133,24 +199,23 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|||||||
<CalendarGrid v-for="month in grid" :key="month.value.toString()">
|
<CalendarGrid v-for="month in grid" :key="month.value.toString()">
|
||||||
<CalendarGridHead>
|
<CalendarGridHead>
|
||||||
<CalendarGridRow>
|
<CalendarGridRow>
|
||||||
<CalendarHeadCell
|
<CalendarHeadCell v-for="day in weekDays" :key="day">
|
||||||
v-for="day in weekDays" :key="day"
|
|
||||||
>
|
|
||||||
{{ day }}
|
{{ day }}
|
||||||
</CalendarHeadCell>
|
</CalendarHeadCell>
|
||||||
</CalendarGridRow>
|
</CalendarGridRow>
|
||||||
</CalendarGridHead>
|
</CalendarGridHead>
|
||||||
<CalendarGridBody>
|
<CalendarGridBody>
|
||||||
<CalendarGridRow v-for="(weekDates, index) in month.rows" :key="`weekDate-${index}`" class="mt-2 w-full">
|
<CalendarGridRow
|
||||||
|
v-for="(weekDates, index) in month.rows"
|
||||||
|
:key="`weekDate-${index}`"
|
||||||
|
class="mt-2 w-full"
|
||||||
|
>
|
||||||
<CalendarCell
|
<CalendarCell
|
||||||
v-for="weekDate in weekDates"
|
v-for="weekDate in weekDates"
|
||||||
:key="weekDate.toString()"
|
:key="weekDate.toString()"
|
||||||
:date="weekDate"
|
:date="weekDate"
|
||||||
>
|
>
|
||||||
<CalendarCellTrigger
|
<CalendarCellTrigger :day="weekDate" :month="month.value" />
|
||||||
:day="weekDate"
|
|
||||||
:month="month.value"
|
|
||||||
/>
|
|
||||||
</CalendarCell>
|
</CalendarCell>
|
||||||
</CalendarGridRow>
|
</CalendarGridRow>
|
||||||
</CalendarGridBody>
|
</CalendarGridBody>
|
||||||
|
|||||||
@@ -1,21 +1,28 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { CalendarCellProps } from "reka-ui"
|
import type { CalendarCellProps } from "reka-ui";
|
||||||
import type { HTMLAttributes } from "vue"
|
import type { HTMLAttributes } from "vue";
|
||||||
import { reactiveOmit } from "@vueuse/core"
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
import { CalendarCell, useForwardProps } from "reka-ui"
|
import { CalendarCell, useForwardProps } from "reka-ui";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
const props = defineProps<CalendarCellProps & { class?: HTMLAttributes["class"] }>()
|
const props = defineProps<
|
||||||
|
CalendarCellProps & { class?: HTMLAttributes["class"] }
|
||||||
|
>();
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, "class")
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
|
||||||
const forwardedProps = useForwardProps(delegatedProps)
|
const forwardedProps = useForwardProps(delegatedProps);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CalendarCell
|
<CalendarCell
|
||||||
data-slot="calendar-cell"
|
data-slot="calendar-cell"
|
||||||
:class="cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent', props.class)"
|
:class="
|
||||||
|
cn(
|
||||||
|
'relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent',
|
||||||
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
v-bind="forwardedProps"
|
v-bind="forwardedProps"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
|||||||
@@ -1,37 +1,42 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { CalendarCellTriggerProps } from "reka-ui"
|
import type { CalendarCellTriggerProps } from "reka-ui";
|
||||||
import type { HTMLAttributes } from "vue"
|
import type { HTMLAttributes } from "vue";
|
||||||
import { reactiveOmit } from "@vueuse/core"
|
import { reactiveOmit } from "@vueuse/core";
|
||||||
import { CalendarCellTrigger, useForwardProps } from "reka-ui"
|
import { CalendarCellTrigger, useForwardProps } from "reka-ui";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
import { buttonVariants } from '@/components/ui/button'
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes["class"] }>(), {
|
const props = withDefaults(
|
||||||
as: "button",
|
defineProps<CalendarCellTriggerProps & { class?: HTMLAttributes["class"] }>(),
|
||||||
})
|
{
|
||||||
|
as: "button",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, "class")
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
|
|
||||||
const forwardedProps = useForwardProps(delegatedProps)
|
const forwardedProps = useForwardProps(delegatedProps);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CalendarCellTrigger
|
<CalendarCellTrigger
|
||||||
data-slot="calendar-cell-trigger"
|
data-slot="calendar-cell-trigger"
|
||||||
:class="cn(
|
:class="
|
||||||
buttonVariants({ variant: 'ghost' }),
|
cn(
|
||||||
'size-8 p-0 font-normal aria-selected:opacity-100 cursor-default',
|
buttonVariants({ variant: 'ghost' }),
|
||||||
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',
|
'size-8 p-0 font-normal aria-selected:opacity-100 cursor-default',
|
||||||
// Selected
|
'[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-content',
|
||||||
'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground',
|
// Selected
|
||||||
// Disabled
|
'data-[selected]:bg-primary data-[selected]:text-primary-content data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-content data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-content',
|
||||||
'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',
|
// Disabled
|
||||||
// Unavailable
|
'data-[disabled]:text-muted-content data-[disabled]:opacity-50',
|
||||||
'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',
|
// Unavailable
|
||||||
// Outside months
|
'data-[unavailable]:text-destructive-content data-[unavailable]:line-through',
|
||||||
'data-[outside-view]:text-muted-foreground',
|
// Outside months
|
||||||
props.class,
|
'data-[outside-view]:text-muted-content',
|
||||||
)"
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
v-bind="forwardedProps"
|
v-bind="forwardedProps"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { AcceptableValue } from "reka-ui"
|
import type { AcceptableValue } from "reka-ui";
|
||||||
import type { HTMLAttributes } from "vue"
|
import type { HTMLAttributes } from "vue";
|
||||||
import { reactiveOmit, useVModel } from "@vueuse/core"
|
import { reactiveOmit, useVModel } from "@vueuse/core";
|
||||||
import { ChevronDownIcon } from "lucide-vue-next"
|
import { ChevronDownIcon } from "lucide-vue-next";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
const props = defineProps<{ modelValue?: AcceptableValue | AcceptableValue[], class?: HTMLAttributes["class"] }>()
|
const props = defineProps<{
|
||||||
|
modelValue?: AcceptableValue | AcceptableValue[];
|
||||||
|
class?: HTMLAttributes["class"];
|
||||||
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
"update:modelValue": AcceptableValue
|
"update:modelValue": AcceptableValue;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const modelValue = useVModel(props, "modelValue", emit, {
|
const modelValue = useVModel(props, "modelValue", emit, {
|
||||||
passive: true,
|
passive: true,
|
||||||
defaultValue: "",
|
defaultValue: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, "class")
|
const delegatedProps = reactiveOmit(props, "class");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -32,12 +35,14 @@ const delegatedProps = reactiveOmit(props, "class")
|
|||||||
v-bind="{ ...$attrs, ...delegatedProps }"
|
v-bind="{ ...$attrs, ...delegatedProps }"
|
||||||
v-model="modelValue"
|
v-model="modelValue"
|
||||||
data-slot="native-select"
|
data-slot="native-select"
|
||||||
:class="cn(
|
:class="
|
||||||
'border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 h-9 w-full min-w-0 appearance-none rounded-md border bg-transparent px-3 py-2 pr-9 text-sm shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:cursor-not-allowed',
|
cn(
|
||||||
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
'border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 h-9 w-full min-w-0 appearance-none rounded-md border bg-transparent px-3 py-2 pr-9 text-sm shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:cursor-not-allowed',
|
||||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
||||||
props.class,
|
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||||
)"
|
props.class,
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -2,14 +2,17 @@
|
|||||||
<!-- @strictTemplates true -->
|
<!-- @strictTemplates true -->
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { HTMLAttributes } from "vue"
|
import type { HTMLAttributes } from "vue";
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
|
const props = defineProps<{ class?: HTMLAttributes["class"] }>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<option data-slot="native-select-option" :class="cn('bg-popover text-popover-foreground', props.class)">
|
<option
|
||||||
|
data-slot="native-select-option"
|
||||||
|
:class="cn('bg-popover text-popover-foreground text-black', props.class)"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</option>
|
</option>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
27
src/hooks/globalLanguageHook.ts
Normal file
27
src/hooks/globalLanguageHook.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import {
|
||||||
|
useLanguageStore,
|
||||||
|
GlobalLanguage,
|
||||||
|
languageMap,
|
||||||
|
} from "@/stores/LanguageStore";
|
||||||
|
|
||||||
|
const languageStore = useLanguageStore();
|
||||||
|
|
||||||
|
export const optionalLanguages = Object.entries(languageMap).map(
|
||||||
|
([key, value]) => ({
|
||||||
|
label: key as GlobalLanguage,
|
||||||
|
value,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 一定不要通过改变 curGlobalLanguage 来改变语言,而要通过 changeGlobalLanguage 来改变语言
|
||||||
|
const curGlobalLanguage = computed(() => languageStore.language);
|
||||||
|
|
||||||
|
function changeGlobalLanguage(language: GlobalLanguage) {
|
||||||
|
languageStore.setLanguage(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useGlobalLanguageHook = () => ({
|
||||||
|
optionalLanguages,
|
||||||
|
curGlobalLanguage,
|
||||||
|
changeGlobalLanguage,
|
||||||
|
});
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// 存在一个重要问题: 不清楚 daisyui 是怎么替换主题的 目前没有做任何配置
|
||||||
import { useThemeStore, GlobalTheme } from "@/stores/ThemeStore";
|
import { useThemeStore, GlobalTheme } from "@/stores/ThemeStore";
|
||||||
|
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ChangeThemeDropdownButton from "@/components/button/ChangeThemeDropdownButton.vue";
|
|
||||||
import DatePicker from "@/components/date-picker/DatePicker.vue";
|
import DatePicker from "@/components/date-picker/DatePicker.vue";
|
||||||
import { useGlobalThemeHook } from "@/hooks/globalThemeHook";
|
import NavBar from "@/components/menu/NavBar.vue";
|
||||||
|
|
||||||
const { curGlobalTheme } = useGlobalThemeHook();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="hero min-h-screen" :data-theme="curGlobalTheme">
|
<div>
|
||||||
<div class="hero-content text-center">
|
<NavBar />
|
||||||
<div class="max-w-md">
|
<div class="mt-4">
|
||||||
<h1 class="text-5xl font-bold pb-6">Hucky</h1>
|
<div>路由系统加载进度:100%</div>
|
||||||
<p class="pb-6">自动路由系统已加载</p>
|
<DatePicker />
|
||||||
<ChangeThemeDropdownButton class="pb-6" />
|
|
||||||
<DatePicker />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
31
src/stores/LanguageStore.ts
Normal file
31
src/stores/LanguageStore.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { ref } from "vue";
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
export enum GlobalLanguage {
|
||||||
|
ZH = "ZH",
|
||||||
|
EN = "EN",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const languageMap = {
|
||||||
|
[GlobalLanguage.ZH]: "简体中文",
|
||||||
|
[GlobalLanguage.EN]: "English",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useLanguageStore = defineStore(
|
||||||
|
"language",
|
||||||
|
() => {
|
||||||
|
const language = ref<GlobalLanguage>(GlobalLanguage.ZH);
|
||||||
|
|
||||||
|
const setLanguage = (newLanguage: GlobalLanguage) => {
|
||||||
|
language.value = newLanguage;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
language,
|
||||||
|
setLanguage,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
persist: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
116
src/style.css
116
src/style.css
@@ -33,118 +33,4 @@
|
|||||||
scrollbar-color: rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.05);
|
scrollbar-color: rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
// 关于 shadcn 的主题, 请进入组件内部通过 style 设置 css 变量
|
||||||
--radius-sm: calc(var(--radius) - 4px);
|
|
||||||
--radius-md: calc(var(--radius) - 2px);
|
|
||||||
--radius-lg: var(--radius);
|
|
||||||
--radius-xl: calc(var(--radius) + 4px);
|
|
||||||
--color-background: var(--background);
|
|
||||||
--color-foreground: var(--foreground);
|
|
||||||
--color-card: var(--card);
|
|
||||||
--color-card-foreground: var(--card-foreground);
|
|
||||||
--color-popover: var(--popover);
|
|
||||||
--color-popover-foreground: var(--popover-foreground);
|
|
||||||
--color-primary: var(--primary);
|
|
||||||
--color-primary-foreground: var(--primary-foreground);
|
|
||||||
--color-secondary: var(--secondary);
|
|
||||||
--color-secondary-foreground: var(--secondary-foreground);
|
|
||||||
--color-muted: var(--muted);
|
|
||||||
--color-muted-foreground: var(--muted-foreground);
|
|
||||||
--color-accent: var(--accent);
|
|
||||||
--color-accent-foreground: var(--accent-foreground);
|
|
||||||
--color-destructive: var(--destructive);
|
|
||||||
--color-border: var(--border);
|
|
||||||
--color-input: var(--input);
|
|
||||||
--color-ring: var(--ring);
|
|
||||||
--color-chart-1: var(--chart-1);
|
|
||||||
--color-chart-2: var(--chart-2);
|
|
||||||
--color-chart-3: var(--chart-3);
|
|
||||||
--color-chart-4: var(--chart-4);
|
|
||||||
--color-chart-5: var(--chart-5);
|
|
||||||
--color-sidebar: var(--sidebar);
|
|
||||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
||||||
--color-sidebar-primary: var(--sidebar-primary);
|
|
||||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
||||||
--color-sidebar-accent: var(--sidebar-accent);
|
|
||||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
||||||
--color-sidebar-border: var(--sidebar-border);
|
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--radius: 0.625rem;
|
|
||||||
--background: oklch(1 0 0);
|
|
||||||
--foreground: oklch(0.145 0 0);
|
|
||||||
--card: oklch(1 0 0);
|
|
||||||
--card-foreground: oklch(0.145 0 0);
|
|
||||||
--popover: oklch(1 0 0);
|
|
||||||
--popover-foreground: oklch(0.145 0 0);
|
|
||||||
--primary: oklch(0.205 0 0);
|
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
|
||||||
--secondary: oklch(0.97 0 0);
|
|
||||||
--secondary-foreground: oklch(0.205 0 0);
|
|
||||||
--muted: oklch(0.97 0 0);
|
|
||||||
--muted-foreground: oklch(0.556 0 0);
|
|
||||||
--accent: oklch(0.97 0 0);
|
|
||||||
--accent-foreground: oklch(0.205 0 0);
|
|
||||||
--destructive: oklch(0.577 0.245 27.325);
|
|
||||||
--border: oklch(0.922 0 0);
|
|
||||||
--input: oklch(0.922 0 0);
|
|
||||||
--ring: oklch(0.708 0 0);
|
|
||||||
--chart-1: oklch(0.646 0.222 41.116);
|
|
||||||
--chart-2: oklch(0.6 0.118 184.704);
|
|
||||||
--chart-3: oklch(0.398 0.07 227.392);
|
|
||||||
--chart-4: oklch(0.828 0.189 84.429);
|
|
||||||
--chart-5: oklch(0.769 0.188 70.08);
|
|
||||||
--sidebar: oklch(0.985 0 0);
|
|
||||||
--sidebar-foreground: oklch(0.145 0 0);
|
|
||||||
--sidebar-primary: oklch(0.205 0 0);
|
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
||||||
--sidebar-accent: oklch(0.97 0 0);
|
|
||||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
||||||
--sidebar-border: oklch(0.922 0 0);
|
|
||||||
--sidebar-ring: oklch(0.708 0 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
--background: oklch(0.145 0 0);
|
|
||||||
--foreground: oklch(0.985 0 0);
|
|
||||||
--card: oklch(0.205 0 0);
|
|
||||||
--card-foreground: oklch(0.985 0 0);
|
|
||||||
--popover: oklch(0.205 0 0);
|
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
|
||||||
--primary: oklch(0.922 0 0);
|
|
||||||
--primary-foreground: oklch(0.205 0 0);
|
|
||||||
--secondary: oklch(0.269 0 0);
|
|
||||||
--secondary-foreground: oklch(0.985 0 0);
|
|
||||||
--muted: oklch(0.269 0 0);
|
|
||||||
--muted-foreground: oklch(0.708 0 0);
|
|
||||||
--accent: oklch(0.269 0 0);
|
|
||||||
--accent-foreground: oklch(0.985 0 0);
|
|
||||||
--destructive: oklch(0.704 0.191 22.216);
|
|
||||||
--border: oklch(1 0 0 / 10%);
|
|
||||||
--input: oklch(1 0 0 / 15%);
|
|
||||||
--ring: oklch(0.556 0 0);
|
|
||||||
--chart-1: oklch(0.488 0.243 264.376);
|
|
||||||
--chart-2: oklch(0.696 0.17 162.48);
|
|
||||||
--chart-3: oklch(0.769 0.188 70.08);
|
|
||||||
--chart-4: oklch(0.627 0.265 303.9);
|
|
||||||
--chart-5: oklch(0.645 0.246 16.439);
|
|
||||||
--sidebar: oklch(0.205 0 0);
|
|
||||||
--sidebar-foreground: oklch(0.985 0 0);
|
|
||||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
||||||
--sidebar-accent: oklch(0.269 0 0);
|
|
||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
||||||
--sidebar-border: oklch(1 0 0 / 10%);
|
|
||||||
--sidebar-ring: oklch(0.556 0 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
|
||||||
* {
|
|
||||||
@apply border-border outline-ring/50;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
@apply bg-background text-foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user