Compare commits

8 Commits
main ... dev

Author SHA1 Message Date
Alexis
5ee9c25a25 Fixed number held alignment 2025-12-29 16:14:28 +01:00
Alexis
45cf92757c Adjusted some styles 2025-12-29 16:06:07 +01:00
Alexis
cae6e464f7 Updated package 2025-12-29 15:44:08 +01:00
Alexis
508f4cbea5 Fixed styles for tailwind 4 2025-12-29 15:41:00 +01:00
Alexis
8a629cbdf6 Added pnpm workspace 2025-12-28 21:54:55 +01:00
Alexis
e1168e2b9e Updated dependencies 2024-05-08 18:35:32 +02:00
Alexis
aa75260a33 Changed old component structures 2024-05-08 18:02:53 +02:00
Alexis
0011b31424 Removed useless files
I won't have the time nor patience to write tests for these, so
2024-05-08 18:02:40 +02:00
38 changed files with 4927 additions and 4709 deletions

View File

@@ -1,3 +0,0 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

View File

@@ -1,8 +0,0 @@
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
baseUrl: 'http://localhost:4173'
}
})

View File

@@ -1,8 +0,0 @@
// https://on.cypress.io/api
describe('My First Test', () => {
it('visits the app root url', () => {
cy.visit('/')
cy.contains('h1', 'You did it!')
})
})

View File

@@ -1,10 +0,0 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["./**/*", "../support/**/*"],
"compilerOptions": {
"isolatedModules": false,
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
}
}

View File

@@ -1,5 +0,0 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -1,39 +0,0 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
export {}

View File

@@ -1,20 +0,0 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

5802
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +1,43 @@
{
"name": "vue-template",
"version": "0.0.0",
"name": "yorha-ui",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check build-only",
"preview": "vite preview",
"test:unit": "vitest",
"test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@vueuse/core": "^10.1.2",
"pinia": "^2.0.35",
"sass": "^1.62.1",
"vue": "^3.3.1",
"vue-router": "^4.1.6"
"@phosphor-icons/vue": "^2.2.1",
"@vueuse/core": "^14.1.0",
"pinia": "^3.0.4",
"sass": "^1.97.1",
"vue": "^3.5.26",
"vue-router": "^4.6.4"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.2.0",
"@tsconfig/node18": "^2.0.0",
"@types/jsdom": "^21.1.1",
"@types/node": "^18.16.3",
"@vitejs/plugin-vue": "^4.2.1",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.3.2",
"@vue/tsconfig": "^0.3.2",
"autoprefixer": "^10.4.14",
"cypress": "^12.11.0",
"eslint": "^8.39.0",
"eslint-plugin-cypress": "^2.13.3",
"eslint-plugin-vue": "^9.11.0",
"jsdom": "^22.0.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.23",
"prettier": "^2.8.8",
"start-server-and-test": "^2.0.0",
"tailwindcss": "^3.3.2",
"typescript": "~5.0.4",
"vite": "^4.3.5",
"vitest": "^0.31.0",
"vue-tsc": "^1.6.4"
"@rushstack/eslint-patch": "^1.15.0",
"@tailwindcss/postcss": "^4.1.18",
"@tailwindcss/vite": "^4.1.18",
"@tsconfig/node20": "^20.1.8",
"@types/node": "^25.0.3",
"@vitejs/plugin-vue": "^6.0.3",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.6.0",
"@vue/tsconfig": "^0.8.1",
"eslint": "^9.39.2",
"eslint-plugin-vue": "^10.6.2",
"postcss": "^8.5.6",
"prettier": "^3.7.4",
"start-server-and-test": "^2.1.3",
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3",
"vite": "^7.3.0",
"vue-tsc": "^3.2.1"
}
}

3301
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

4
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,4 @@
onlyBuiltDependencies:
- '@parcel/watcher'
- esbuild
- vue-demi

View File

@@ -1,6 +1,5 @@
module.exports = {
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
'@tailwindcss/postcss': {},
}
}

View File

@@ -1,14 +0,0 @@
.fade {
&-enter-from,
&-leave-to {
opacity: 0;
}
&-enter-to,
&-leave-from {
opacity: 1;
}
&-enter-active,
&-leave-active {
transition: all 0.2s ease;
}
}

View File

@@ -1,8 +0,0 @@
body {
@apply relative min-h-screen min-w-full text-y-beige-700 bg-y-beige-400 tracking-[-0.03em];
word-spacing: 0.5em;
&::before {
@apply absolute content-[''] h-full w-full bg-[url('/backgrounds/tile-bg.svg')] bg-[length:4px_4px] z-50 opacity-5 pointer-events-none select-none
}
}

57
src/assets/main.css Normal file
View File

@@ -0,0 +1,57 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@200;300;400;500;700&display=swap');
@import "tailwindcss";
@theme {
--color-y-beige: #B0AB97;
--color-y-beige-50: #FFFFFF;
--color-y-beige-100: #F6F6F4;
--color-y-beige-200: #E5E3DD;
--color-y-beige-300: #D8D2B8;
--color-y-beige-400: #cbc5af;
--color-y-beige-500: #b0ab97;
--color-y-beige-600: #767563;
--color-y-beige-700: #4c4940;
--color-y-beige-800: #3A382C;
--color-y-beige-900: #2d2c21;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.2s ease;
}
.y-scrollbar::-webkit-scrollbar-button {
display: none;
}
body {
position: relative;
min-height: 100dvh;
min-width: 100dvw;
color: var(--color-y-beige-700);
background-color: var(--color-y-beige-400);
letter-spacing: -0.03em;
word-spacing: 0.5em;
}
body::before {
position: absolute;
content: '';
height: 100%;
width: 100%;
background-size: 4px 4px;
background-image: url('/backgrounds/tile-bg.svg');
z-index: 50;
opacity: 5%;
pointer-events: none;
user-select: none;
}

View File

@@ -1,18 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans:wght@200;300;400;500;700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
@import 'base/body';
}
@layer utilities {
@import 'utilities/scrollbar';
}
/**
* ANIMATIONS FOR TRANSITIONS
*/
@import 'animations/fade'

View File

@@ -1,5 +0,0 @@
.y-scrollbar {
&::-webkit-scrollbar-button {
display: none;
}
}

View File

@@ -1,9 +1,10 @@
<script lang="ts" setup>
import YrhButton from '@/components/atoms/YrhButton.vue'
import type { MenuItem } from '@/models/YrhNavItem'
import { useBannerStore } from '@/stores/banner'
import { storeToRefs } from 'pinia'
import { ref } from 'vue'
import YrhButton from './YrhButton.vue'
const { bannerText } = storeToRefs(useBannerStore())
@@ -42,11 +43,11 @@ function handleInactiveState() {
<template>
<div class="relative">
<menu v-if="props.items">
<menu v-if="props.items" class="pl-11">
<li
v-for="item in props.items"
:key="item.id"
class="transition-all"
class="transition-all *:not-first:mt-3"
:class="item.id === clickedKey ? 'w-full' : 'w-11/12'"
>
<YrhButton
@@ -70,11 +71,6 @@ function handleInactiveState() {
<style lang="scss" scoped>
menu {
position: relative;
@apply pl-11;
li:not(:first-child) {
@apply mt-3;
}
&::before {
display: block;

View File

@@ -1,9 +1,10 @@
<script lang="ts" setup>
import { PhSquare } from '@phosphor-icons/vue'
import { useElementHover, useFocus } from '@vueuse/core'
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useAppConfig } from '@/stores/configStore'
const router = useRouter()
const { globalSound } = useAppConfig()
@@ -65,12 +66,6 @@ function handleClick(e: MouseEvent) {
}
}
function handleMouseOver() {
if (!isBtnFocused.value) {
playHoverSfx()
}
}
function handleFocusin() {
if (!isBtnHovered.value) {
playHoverSfx()
@@ -83,7 +78,7 @@ function handleFocusin() {
ref="btnRef"
:is="elementTag"
v-bind="attributes"
class="btn inline-block w-full p-1 px-2 text-left"
class="btn flex w-full items-center p-1 px-2 text-left"
:class="{
active: isActive,
'bg-y-beige-500 hover:shadow-md focus-visible:shadow-md': !noBg,
@@ -93,7 +88,6 @@ function handleFocusin() {
@keyup.enter="handleClick"
@keyup.space="handleClick"
@focusin="handleFocusin"
@mouseover="handleMouseOver"
>
<Transition name="fade" :duration="{ enter: 100, leave: 100 }">
<img
@@ -106,8 +100,9 @@ function handleFocusin() {
alt=""
/>
</Transition>
<span class="mr-1" v-if="hasSquare">
<font-awesome-icon :icon="['fas', 'square']" />
<PhSquare />
</span>
<slot />
</component>

View File

@@ -18,8 +18,8 @@ const props = defineProps<{
</span>
</header>
<figure v-if="slots.image" class="mx-4">
<div class="h-full bg-y-beige-500 grid place-items-center">
<figure v-if="slots.image" class="mx-4 after:content-[''] after:block after:w-full after:h-[0.1rem] after:my-3 after:bg-y-beige-500">
<div class="h-full bg-y-beige-500 relative *:absolute *:top-1/2 *:left-1/2 *:-translate-1/2">
<slot name="image" />
</div>
</figure>
@@ -38,7 +38,6 @@ const props = defineProps<{
figure {
&::after {
content: '';
@apply block w-full h-[0.1rem] my-3 bg-y-beige-500;
}
}
</style>

View File

@@ -3,8 +3,8 @@ import YrhAudioSlider from './YrhAudioSlider.vue'
</script>
<template>
<menu>
<li>
<menu class="pl-11">
<li class="*:not-first:mt-3">
<YrhAudioSlider>Volume</YrhAudioSlider>
</li>
</menu>
@@ -13,11 +13,6 @@ import YrhAudioSlider from './YrhAudioSlider.vue'
<style lang="scss" scoped>
menu {
position: relative;
@apply pl-11;
li:not(:first-child) {
@apply mt-3;
}
&::before {
display: block;

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import YrhButton from '../YrhButton.vue'
import YrhButton from '@/components/atoms/YrhButton.vue'
</script>
<template>

View File

@@ -1,7 +1,9 @@
<script lang="ts" setup>
import YrhCard from '@/components/atoms/YrhCard.vue'
import { PhSquare } from '@phosphor-icons/vue'
import { useStatusStore } from '@/stores/datas/statusStore'
import { storeToRefs } from 'pinia'
import YrhCard from '../YrhCard.vue'
const { androidData } = storeToRefs(useStatusStore())
</script>
@@ -51,20 +53,7 @@ const { androidData } = storeToRefs(useStatusStore())
</div>
<div class="mt-2 text-y-beige-500 flex justify-around">
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<font-awesome-icon :icon="['far', 'square']" />
<PhSquare v-for="i in 14" :key="i" v-once />
</div>
<hr class="mt-2 mb-0 border-t-2 border-y-beige-500" />
</template>

View File

@@ -1,5 +1,6 @@
<script lang="ts" setup>
import YrhButton from '@/components/YrhButton.vue'
import YrhButton from '@/components/atoms/YrhButton.vue'
import type { GameItem } from '@/models/YrhGameItem'
import { useItemStore } from '@/stores/datas/itemStore'
import { storeToRefs } from 'pinia'
@@ -16,9 +17,9 @@ function handleSelectedItem(item: GameItem) {
</script>
<template>
<div class="h-full relative pl-11">
<div class="h-full relative pl-6">
<menu
class="h-[calc(100%-16px)] overflow-auto py-2 bg-y-beige-300 max-h-full shadow-sharpest y-scrollbar"
class="h-[calc(100%-16px)] overflow-auto py-2 bg-y-beige-300 max-h-full shadow-sharpest y-scrollbar after:-top-2 after:-bottom-2 after:w-4"
>
<li v-for="item in props.items" :key="item.name" class="mb-2 last:mb-0">
<YrhButton
@@ -27,7 +28,7 @@ function handleSelectedItem(item: GameItem) {
@clicked="handleSelectedItem(item)"
:is-active="item.name === currentItem?.name"
>
<span class="flex justify-between">
<span class="flex justify-between w-full">
<span class="flex items-center">
<span v-if="item.category">
<img
@@ -40,7 +41,7 @@ function handleSelectedItem(item: GameItem) {
</span>
<span>{{ item.name }}</span>
</span>
<span v-if="item.numberHeld">{{ item.numberHeld }}</span>
<span v-if="item.numberHeld" class="px-1 font-medium">{{ item.numberHeld }}</span>
</span>
</YrhButton>
</li>
@@ -51,7 +52,9 @@ function handleSelectedItem(item: GameItem) {
<style lang="scss" scoped>
menu {
&::before {
@apply block absolute -top-2 -bottom-2 left-0 w-4;
display: block;
position: absolute;
left: 0;
content: '';
border-left-width: 8px;
border-right-width: 2px;

View File

@@ -1,20 +1,11 @@
import './assets/main.scss'
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faSquare } from '@fortawesome/free-solid-svg-icons'
import { faSquare as faSquareHollow } from '@fortawesome/free-regular-svg-icons'
/* add icons to the library */
library.add(faSquare, faSquareHollow)
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.component('font-awesome-icon', FontAwesomeIcon)
app.mount('#app')

View File

@@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeVue from '../views/Home.vue'
import DataVue from '../views/Data.vue'
import HomeVue from '@/views/Home.vue'
import DataVue from '@/views/Data.vue'
import ItemsVue from '@/views/datas/Items.vue'
import ConfigVue from '@/views/Config.vue'

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import YrhBanner from '@/components/YrhBanner.vue'
import YrhHeading from '@/components/YrhHeading.vue'
import YrhBanner from '@/components/atoms/YrhBanner.vue'
import YrhHeading from '@/components/atoms/YrhHeading.vue'
import YrhNav from '@/components/YrhNav.vue'
import YrhAudioMenu from '@/components/config/YrhAudioMenu.vue'
import type { MenuItem } from '@/models/YrhNavItem'
@@ -34,7 +34,7 @@ onMounted(() => {
</script>
<template>
<main class="container grid grid-rows-[auto_1fr_5vh]">
<main class="grid grid-rows-[auto_1fr_5vh]">
<YrhHeading> SYSTEM CONFIGURATION </YrhHeading>
<div class="grid grid-cols-4 items-center">
<div>

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup>
import YrhBanner from '@/components/YrhBanner.vue'
import YrhBanner from '@/components/atoms/YrhBanner.vue'
import { useBannerStore } from '@/stores/banner'
import { storeToRefs } from 'pinia'
@@ -7,7 +7,7 @@ const { bannerText } = storeToRefs(useBannerStore())
</script>
<template>
<main class="container max-h-screen grid grid-rows-[auto_1fr_auto] overflow-auto">
<main class="max-h-screen grid grid-rows-[auto_1fr_auto] overflow-auto">
<RouterView v-slot="{ Component }">
<Transition name="fade" mode="out-in">
<component :is="Component" />

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import YrhBanner from '@/components/YrhBanner.vue'
import YrhHeading from '@/components/YrhHeading.vue'
import YrhBanner from '@/components/atoms/YrhBanner.vue'
import YrhHeading from '@/components/atoms/YrhHeading.vue'
import YrhNav from '@/components/YrhNav.vue'
import type { MenuItem } from '@/models/YrhNavItem'
import { useBannerStore } from '@/stores/banner'
@@ -68,7 +68,7 @@ onMounted(() => {
</script>
<template>
<main class="container grid grid-rows-[auto_1fr_5vh]">
<main class="grid grid-rows-[auto_1fr_5vh]">
<YrhHeading> YORHA SYSTEM </YrhHeading>
<div class="grid grid-cols-4 items-center">
<div>

View File

@@ -1,6 +1,6 @@
<script lang="ts" setup>
import YrhCard from '@/components/YrhCard.vue'
import YrhHeading from '@/components/YrhHeading.vue'
import YrhCard from '@/components/atoms/YrhCard.vue'
import YrhHeading from '@/components/atoms/YrhHeading.vue'
import YrhStatusCard from '@/components/datas/YrhStatusCard.vue'
import ItemSelection from '@/components/datas/items/ItemSelection.vue'
import { useBannerStore } from '@/stores/banner'
@@ -34,10 +34,12 @@ onMounted(() => {
ITEMS
<template #subtitle> All items </template>
</YrhHeading>
<section class="grid grid-cols-3 gap-x-10 my-14 overflow-auto">
<div class="items-container max-h-full overflow-hidden">
<div class="grid grid-cols-3 gap-x-4 my-8 overflow-auto">
<div class="items-container max-h-full overflow-hidden after:ml-6 before:ml-6 after:h-2 before:h-2 after:left-14 before:left-14 after:-right-14 before:-right-14 after:bg-y-beige-300 before:bg-y-beige-300 before:border-b-2 after:border-t-2">
<ItemSelection :items="availableItems" />
</div>
<div class="max-h-full">
<Transition name="fade" mode="out-in">
<YrhCard v-if="currentItem" breathe-bottom>
@@ -60,26 +62,30 @@ onMounted(() => {
<YrhStatusCard />
</div>
</div>
</section>
</div>
</template>
<style lang="scss" scoped>
.items-container {
@apply relative overflow-x-hidden;
position: relative;
overflow-x: hidden;
&::before,
&::after {
display: block;
position: sticky;
width: 100%;
content: '';
height: 0.1rem;
@apply block sticky ml-11 w-full h-2 left-14 -right-14 z-10 bg-y-beige-300;
height: .1rem;
border-color: rgba(45, 44, 33, 0.33);
z-index: 10;
}
&::before {
@apply top-0 border-b-2;
top: 0;
}
&::after {
@apply bottom-0 border-t-2;
bottom: 0;
}
}
</style>

View File

@@ -1,57 +1,42 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
container: {
padding: '2rem',
center: true
},
fontFamily: {
sans: ['Noto Sans', 'ui-sans-serif', 'system-ui'],
serif: ['ui-serif', 'Georgia'],
mono: ['ui-monospace', 'SFMono-Regular'],
display: ['Oswald'],
body: ['Noto Sans']
},
extend: {
colors: {
'y-beige': {
DEFAULT: '#B0AB97',
50: '#FFFFFF',
100: '#F6F6F4',
200: '#E5E3DD',
300: '#D8D2B8',
400: '#cbc5af',
500: '#b0ab97',
600: '#767563',
700: '#4c4940',
800: '#3A382C',
900: '#2d2c21'
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
container: {
padding: '2rem',
center: true
},
fontFamily: {
sans: ['Noto Sans', 'ui-sans-serif', 'system-ui'],
serif: ['ui-serif', 'Georgia'],
mono: ['ui-monospace', 'SFMono-Regular'],
display: ['Oswald'],
body: ['Noto Sans']
},
extend: {
boxShadow: {
sharpest: '2px 2px #2d2c2150'
}
}
},
boxShadow: {
sharpest: '2px 2px #2d2c2150'
}
}
},
plugins: [
function ({ addBase, theme }) {
function extractColorVars(colorObj, colorGroup = '') {
return Object.keys(colorObj).reduce((vars, colorKey) => {
const value = colorObj[colorKey]
const newVars =
typeof value === 'string'
? { [`--color${colorGroup}-${colorKey}`]: value }
: extractColorVars(value, `-${colorKey}`)
return { ...vars, ...newVars }
}, {})
}
addBase({
':root': extractColorVars(theme('colors'))
})
}
]
},
plugins: [
function ({ addBase, theme }) {
function extractColorVars(colorObj, colorGroup = '') {
return Object.keys(colorObj).reduce((vars, colorKey) => {
const value = colorObj[colorKey]
const newVars =
typeof value === 'string'
? { [`--color${colorGroup}-${colorKey}`]: value }
: extractColorVars(value, `-${colorKey}`)
return { ...vars, ...newVars }
}, {})
}
addBase({
':root': extractColorVars(theme('colors'))
})
}
]
}

View File

@@ -6,9 +6,6 @@
},
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.vitest.json"
}
]
}

View File

@@ -1,9 +1,8 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"],
"extends": "@tsconfig/node20/tsconfig.json",
"include": ["vite.config.*"],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"types": ["node"]
}
}

View File

@@ -1,9 +0,0 @@
{
"extends": "./tsconfig.app.json",
"exclude": [],
"compilerOptions": {
"composite": true,
"lib": [],
"types": ["node", "jsdom"]
}
}

View File

@@ -1,14 +1,15 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from "@tailwindcss/vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
plugins: [vue(), tailwindcss()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
},
})

View File

@@ -1,15 +0,0 @@
import { fileURLToPath } from 'node:url'
import { mergeConfig } from 'vite'
import { configDefaults, defineConfig } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(
viteConfig,
defineConfig({
test: {
environment: 'jsdom',
exclude: [...configDefaults.exclude, 'e2e/*'],
root: fileURLToPath(new URL('./', import.meta.url))
}
})
)