This commit is contained in:
2023-05-10 22:18:22 +02:00
parent fed5006110
commit 9703d24784
14 changed files with 283 additions and 42 deletions

View File

@@ -36,7 +36,7 @@
"@types/node": "^18",
"@unocss/eslint-config": "^0.51.8",
"@unocss/nuxt": "^0.51.8",
"@unocss/transformer-directives": "^0.51.8",
"@unocss/transformer-directives": "^0.51.12",
"@unocss/transformer-variant-group": "^0.51.8",
"@vueuse/core": "^10.1.0",
"@vueuse/nuxt": "^10.1.0",

View File

@@ -1,4 +1,5 @@
body {
font-family: 'DM Sans', sans-serif;
@apply bg-gray-100 dark:bg-dark-900 dark:text-white duration-200
@apply bg-white dark:bg-dark-900 dark:text-white duration-200
}

View File

@@ -0,0 +1,12 @@
<script setup lang="ts">
const { $trpc } = useNuxtApp()
const announcement = await $trpc.announcement.announcement.query()
</script>
<template>
<div v-if="announcement" flex justify-center>
<div dark:hover:bg="dark-800/50" hover:bg="gray-100/50" shadow-announcement-light dark:shadow-announcement-dark rounded-md p-4 duration-300 dark:bg-dark-900>
<p v-html="announcement.content" />
</div>
</div>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<footer>
Footer
</footer>
</template>

89
src/components/Header.vue Normal file
View File

@@ -0,0 +1,89 @@
<script setup lang="ts">
const { getThemeTextColor } = useTheme()
const { y } = useWindowScroll()
const color = useColorMode()
const toggleColor = () => {
color.preference = color.value === 'dark' ? 'light' : 'dark'
}
</script>
<template>
<header
sticky top-0 h-16 duration-300
:class="{ 'backdrop-blur-10px backdrop-saturate-180 shadow-header-active-light dark:shadow-header-active-dark': y > 8 }"
>
<div h-full flex items-center justify-between px-32>
<div>
Logo
</div>
<div flex items-center space-x-4>
<nav flex space-x-4>
<NuxtLink to="/about">
About
</NuxtLink>
<NuxtLink to="/writings">
Blog
</NuxtLink>
<NuxtLink to="/work">
Work
</NuxtLink>
<NuxtLink to="/contact">
Contact
</NuxtLink>
<NuxtLink to="/test">
TEST
</NuxtLink>
</nav>
<div h-24px w-1px bg-gray-300 dark:bg-dark-300 />
<button
role="switch" type="button"
relative block h-22px w-10 shrink-0
border-1 border-gray-400 rounded-11px border-solid
transition-colors-250
dark:border-dark-300 hover:border-gray-600 dark:hover:border-dark-100
@click.prevent="toggleColor()"
>
<span
rounded="1/2" absolute left-1px top-1px h-18px w-18px transition-transform-250
:style="{ transform: `translateX(${color.preference === 'light' ? 0 : 18}px)` }"
>
<span relative block h-18px w-18px overflow-hidden rounded="1/2" bg-gray-100 dark:bg-dark-400>
<Icon
name="material-symbols:dark-mode-outline" size="12"
:class="color.preference === 'light' ? 'opacity-0' : 'opacity-100'"
absolute left-3px top-3px text-black duration-200 dark:text-white
/>
<Icon
name="material-symbols:light-mode-outline" size="12"
:class="color.preference === 'light' ? 'opacity-100' : 'opacity-0'"
absolute left-3px top-3px text-black duration-200 dark:text-white
/>
</span>
</span>
</button>
<div h-24px w-1px bg-gray-300 dark:bg-dark-300 />
<div flex space-x-4>
<NuxtLink
href="https://github.com/ArthurDanjou" target="_blank" text-gray-700 duration-300 dark:text-gray-400
:class="`hover:${getThemeTextColor}`"
>
<Icon name="mdi:github" size="24" />
</NuxtLink>
<NuxtLink
href="https://twitter.com/ArthurDanj" target="_blank" text-gray-700 duration-300 dark:text-gray-400
:class="`hover:${getThemeTextColor}`"
>
<Icon name="mdi:twitter" size="24" />
</NuxtLink>
</div>
</div>
</div>
</header>
</template>
<style lang="scss">
a.router-link-exact-active {
color: v-bind(getThemeTextColor)
}
</style>

View File

@@ -0,0 +1,76 @@
<script lang="ts" setup>
defineProps<{
active: boolean
}>()
defineEmits<{
(e: 'click'): void
}>()
</script>
<template>
<button
type="button"
class="menu-burger"
:class="{ active }"
@click="$emit('click')"
>
<span class="container">
<span class="top" />
<span class="middle" />
<span class="bottom" />
</span>
</button>
</template>
<style scoped>
.menu-burger {
display: flex;
justify-content: center;
align-items: center;
width: 48px;
height: var(--vp-nav-height);
}
@media (min-width: 768px) {
.menu-burger {
display: none;
}
}
.container {
position: relative;
width: 16px;
height: 14px;
overflow: hidden;
}
.menu-burger:hover .top { top: 0; left: 0; transform: translateX(4px); }
.menu-burger:hover .middle { top: 6px; left: 0; transform: translateX(0); }
.menu-burger:hover .bottom { top: 12px; left: 0; transform: translateX(8px); }
.menu-burger.active .top { top: 6px; transform: translateX(0) rotate(225deg); }
.menu-burger.active .middle { top: 6px; transform: translateX(16px); }
.menu-burger.active .bottom { top: 6px; transform: translateX(0) rotate(135deg); }
.menu-burger.active:hover .top,
.menu-burger.active:hover .middle,
.menu-burger.active:hover .bottom {
background-color: var(--vp-c-text-2);
transition: top .25s, background-color .25s, transform .25s;
}
.top,
.middle,
.bottom {
position: absolute;
width: 16px;
height: 2px;
background-color: var(--vp-c-text-1);
transition: top .25s, background-color .5s, transform .25s;
}
.top { top: 0; left: 0; transform: translateX(0); }
.middle { top: 6px; left: 0; transform: translateX(8px); }
.bottom { top: 12px; left: 0; transform: translateX(4px); }
</style>

9
src/layouts/default.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<Header />
<slot />
<Footer />
</template>
<style>
@import '@unocss/reset/tailwind.css';
</style>

View File

@@ -1,42 +1,13 @@
<script setup lang="ts">
import { useThemeStore } from '~/store/theme'
const { getColor, getTheme, swapColor, nextTheme } = useThemeStore()
const { getThemeTextColor, getThemeBackgroundColor } = useTheme()
const { swapColor } = useThemeStore()
onMounted(() => swapColor())
const color = useColorMode()
const { query } = useRoute()
const { $trpc } = useNuxtApp()
const user = await $trpc.hello.query({ name: query.name?.toString() })
</script>
<template>
<section>
<h1 :class="`${getThemeTextColor}`" duration="1000">
Main page
</h1>
<h1 :class="`${getThemeBackgroundColor}`" duration="1000">
Main Page
</h1>
<div>
Current color : {{ getColor }}
</div>
<div my-12>
<div>Theme symbol : {{ getTheme.symbol }}</div>
<div>Theme Name : {{ getTheme.name }}</div>
<div>Theme colors : {{ getTheme.colors.map((color) => color.charAt(0).toUpperCase() + color.slice(1)).join(', ') }}</div>
</div>
<div @click="nextTheme()">
setNextTheme()
</div>
<div @click="color.preference = color.value === 'dark' ? 'light' : 'dark'">
toggleDarkMode()
</div>
<div>
{{ user.greeting }}
</div>
Hey
<Announcement />
</section>
</template>

42
src/pages/test.vue Normal file
View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
import { useThemeStore } from '~/store/theme'
const { getColor, getTheme, swapColor, nextTheme } = useThemeStore()
const { getThemeTextColor, getThemeBackgroundColor } = useTheme()
onMounted(() => swapColor())
const color = useColorMode()
const { query } = useRoute()
const { $trpc } = useNuxtApp()
const user = await $trpc.hello.query({ name: query.name?.toString() })
</script>
<template>
<section>
<h1 mt-16 :class="`${getThemeTextColor}`" duration="1500">
Main page
</h1>
<h1 :class="`${getThemeBackgroundColor}`" duration="1500">
Main Page
</h1>
<div>
Current color : {{ getColor }}
</div>
<div my-12>
<div>Theme symbol : {{ getTheme.symbol }}</div>
<div>Theme Name : {{ getTheme.name }}</div>
<div>Theme colors : {{ getTheme.colors.map((color) => color.charAt(0).toUpperCase() + color.slice(1)).join(', ') }}</div>
</div>
<div @click="nextTheme()">
setNextTheme()
</div>
<div @click="color.preference = color.value === 'dark' ? 'light' : 'dark'">
toggleDarkMode()
</div>
<div my-48 h-32>
{{ user.greeting }}
</div>
</section>
</template>

View File

@@ -0,0 +1,12 @@
import { publicProcedure, router } from '~/server/trpc/trpc'
export default router({
announcement: publicProcedure
.query(async ({ ctx }) => {
return await ctx.prisma.announcement.findFirst({
orderBy: {
createdAt: 'desc',
},
})
}),
})

View File

@@ -1,4 +1,5 @@
import { z } from 'zod'
import announcement from './announcement'
import { publicProcedure, router } from '~/server/trpc/trpc'
export const appRouter = router({
@@ -11,6 +12,7 @@ export const appRouter = router({
greeting: `Hello ${input.name ?? 'World'}!`,
}
}),
announcement,
})
export type AppRouter = typeof appRouter

View File

@@ -7,7 +7,7 @@ export const useThemeStore = defineStore(
() => {
const currentTheme = ref<Theme>(Themes[THEMES.RainbowTheme])
const currentColor = ref<ColorsTheme>(currentTheme.value.colors[0])
let intervalId: NodeJS.Timeout | null = null
const intervalId = ref<NodeJS.Timeout | null>(null)
const isAvailable = (next: Theme): boolean => {
if (!next.availability)
@@ -23,10 +23,10 @@ export const useThemeStore = defineStore(
}
const swapColor = () => {
if (intervalId !== null)
clearInterval(intervalId)
if (intervalId.value !== null)
clearInterval(intervalId.value)
intervalId = setInterval(() => {
intervalId.value = setInterval(() => {
const colors = currentTheme.value.colors
const currentIndex = colors.indexOf(currentColor.value)
const nextIndex = (currentIndex + 1) % colors.length

View File

@@ -1,9 +1,8 @@
import {
defineConfig, presetAttributify, presetIcons,
presetTypography, presetUno, presetWind,
transformerDirectives, transformerVariantGroup,
} from 'unocss'
import transformerVariantGroup from '@unocss/transformer-variant-group'
import transformerDirectives from '@unocss/transformer-directives'
import { presetScrollbar } from 'unocss-preset-scrollbar'
import { ColorsTheme } from './types'
@@ -18,17 +17,27 @@ export default defineConfig({
dark: 'class',
}),
],
theme: {
boxShadow: {
'header-active-light': 'inset 0 -1px 0 0 #eaeaea',
'header-active-dark': 'inset 0 -1px 0 0 #333',
'announcement-light': '0 0 0 1px rgba(0,0,0,.03), 0 2px 4px rgba(0,0,0,.05), 0 4px 16px rgba(0,0,0,.05)',
'announcement-dark': '0 0 0 1px rgba(150,150,150,.06), 0 2px 4px rgba(150,150,150,.1), 0 4px 16px rgba(150,150,150,.1)',
},
},
transformers: [
transformerDirectives(),
transformerVariantGroup(),
transformerDirectives(),
],
safelist: [
// Theme text colors
...Object.values(ColorsTheme).map(color => `text-${color}-500`),
...Object.values(ColorsTheme).map(color => `hover:text-${color}-500`),
...'bg-black dark:bg-white dark:text-black text-white'.split(' '),
// Theme background colors
...Object.values(ColorsTheme).map(color => `bg-${color}-500`),
...Object.values(ColorsTheme).map(color => `hover:bg-${color}-500`),
...'text-black dark:text-white'.split(' '),
],
})

View File

@@ -1573,6 +1573,11 @@
resolved "https://registry.yarnpkg.com/@unocss/core/-/core-0.31.17.tgz#e4f74f0495b8c395f6b0090dbcb371d3ce5d40c7"
integrity sha512-DJ3Uk2ePVXvV1qQmgoLK44aqB6f0s+naOEvouI97nzVXDZgxDQPBxIPB/L4vvE4U+gQxEiHwwE3gJ75iPqVzXw==
"@unocss/core@0.51.12":
version "0.51.12"
resolved "https://registry.yarnpkg.com/@unocss/core/-/core-0.51.12.tgz#4090deafb62787a7d46429616a9f3fd03905042a"
integrity sha512-H8mLy6ZKu9nGZe5jlHhLPIVwh2G3cCDSBGl5aIZJFI1qpmDC+Zb3iueBGigNpX75IzkjaGKZiK1WUWq8TShjtA==
"@unocss/core@0.51.8":
version "0.51.8"
resolved "https://registry.yarnpkg.com/@unocss/core/-/core-0.51.8.tgz#f44ff566efd0f109f580d8acad069ff1a70eb859"
@@ -1745,7 +1750,7 @@
dependencies:
"@unocss/core" "0.51.8"
"@unocss/transformer-directives@0.51.8", "@unocss/transformer-directives@^0.51.8":
"@unocss/transformer-directives@0.51.8":
version "0.51.8"
resolved "https://registry.yarnpkg.com/@unocss/transformer-directives/-/transformer-directives-0.51.8.tgz#4fee9fa3fb97dbacc744a21f88b45eff5e835698"
integrity sha512-Q1vG0dZYaxbdz0pVnvpuFreGoSqmrk7TgKUHNuJP/XzTi04sriQoDSpC2QMIAuOyU7FyGpSjUORiaBm0/VNURw==
@@ -1753,6 +1758,14 @@
"@unocss/core" "0.51.8"
css-tree "^2.3.1"
"@unocss/transformer-directives@^0.51.12":
version "0.51.12"
resolved "https://registry.yarnpkg.com/@unocss/transformer-directives/-/transformer-directives-0.51.12.tgz#f33afbf2472c20bb2624fb8bd8abcb4a5dca3913"
integrity sha512-xC1s7BQ2KwiLv2ChsvszELnQYo9DXOpunCkZerjZJm8ptCQJ3D+Zo1HM1C+asc4L4tIZ7BATzhQRGGlpsd37fw==
dependencies:
"@unocss/core" "0.51.12"
css-tree "^2.3.1"
"@unocss/transformer-variant-group@0.51.8", "@unocss/transformer-variant-group@^0.51.8":
version "0.51.8"
resolved "https://registry.yarnpkg.com/@unocss/transformer-variant-group/-/transformer-variant-group-0.51.8.tgz#342fdade1ece77a0874fd6ff9903c111de1bdfe0"