Base nuxt move after refactoring until no warnings
There still exists an issue with one Adobe led library ; @international-dates don't seem to compile their sourcemaps correctly. I don't think this is something I can fix however, and it may require hacks and workarounds to solve from what I've gathered
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier/skip-formatting'
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
|
||||
'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
|
||||
'cypress/support/**/*.{js,ts,jsx,tsx}'
|
||||
],
|
||||
extends: ['plugin:cypress/recommended']
|
||||
}
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest'
|
||||
},
|
||||
rules: {
|
||||
indent: ['error', 2, { SwitchCase: 1 }],
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{
|
||||
endOfLine: 'auto'
|
||||
}
|
||||
],
|
||||
'vue/multi-word-component-names': 'off'
|
||||
}
|
||||
}
|
||||
40
.gitignore
vendored
40
.gitignore
vendored
@@ -1,32 +1,24 @@
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
# Misc
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.fleet
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"Vue.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"eslint.experimental.useFlatConfig": true,
|
||||
"editor.indentSize": "tabSize",
|
||||
"editor.tabSize": 2,
|
||||
}
|
||||
78
README.md
78
README.md
@@ -1,5 +1,75 @@
|
||||
# Leim Tools
|
||||
A congregate of tools used to visualize TTRPG elements and help content creators (mostly me for now tbh) build their worlds.
|
||||
# Nuxt 3 Minimal Starter
|
||||
|
||||
## Timeline
|
||||
Visual helper for time-related data, such as events, eras and characters. Helpful to know how old a character is while something is happening in the world, or how far two events are separated in the timeline.
|
||||
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure to install the dependencies:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
```
|
||||
|
||||
## Development Server
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm run dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
|
||||
# pnpm
|
||||
pnpm run build
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm run preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||
|
||||
21
app.vue
Normal file
21
app.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { ConfigProvider } from 'radix-vue'
|
||||
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
return titleChunk ? `${titleChunk} — TTTools` : 'TTTools';
|
||||
}
|
||||
})
|
||||
|
||||
const useIdFunction = () => useId()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen">
|
||||
<NuxtLayout>
|
||||
<ConfigProvider :use-id="useIdFunction">
|
||||
<NuxtPage/>
|
||||
</ConfigProvider>
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
@@ -2,8 +2,7 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
@@ -36,7 +35,7 @@
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
:root.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
@@ -65,7 +64,6 @@
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
@@ -4,11 +4,11 @@
|
||||
"typescript": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.js",
|
||||
"css": "src/assets/main.css",
|
||||
"css": "assets/main.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true
|
||||
},
|
||||
"framework": "vite",
|
||||
"framework": "nuxt",
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils"
|
||||
|
||||
@@ -3,7 +3,6 @@ import { ref } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { areDatesIdentical, type LeimDate } from '@/models/Date'
|
||||
|
||||
import { Popover, PopoverTrigger } from '@/components/ui/popover'
|
||||
import type { CalendarEvent } from '@/models/Events'
|
||||
import CalendarEventDetails from './CalendarEventDetails.vue'
|
||||
|
||||
@@ -26,8 +25,8 @@ function handleClosePopover() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover v-model:open="isPopoverOpen">
|
||||
<PopoverTrigger as-child>
|
||||
<UiPopover v-model:open="isPopoverOpen">
|
||||
<UiPopoverTrigger as-child>
|
||||
<button
|
||||
class="text-xs px-2 py-1 block w-full text-left rounded-sm whitespace-nowrap overflow-hidden text-ellipsis"
|
||||
:class="
|
||||
@@ -58,15 +57,15 @@ function handleClosePopover() {
|
||||
>
|
||||
{{ event.title }}
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
</UiPopoverTrigger>
|
||||
|
||||
<CalendarEventDetails
|
||||
v-once
|
||||
:event
|
||||
:spans-multiple-days
|
||||
:is-start-event
|
||||
:is-end-event
|
||||
@query:close-popover="handleClosePopover"
|
||||
v-once
|
||||
/>
|
||||
</Popover>
|
||||
</UiPopover>
|
||||
</template>
|
||||
@@ -12,8 +12,6 @@ import {
|
||||
PhArrowBendDoubleUpLeft,
|
||||
PhArrowBendDoubleUpRight
|
||||
} from '@phosphor-icons/vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { PopoverContent } from '@/components/ui/popover'
|
||||
|
||||
const { defaultDate, getFormattedDateTitle, jumpToDate } = useCalendar()
|
||||
const { getRelativeEventFromEvent } = useCalendarEvents()
|
||||
@@ -51,7 +49,7 @@ function handleGotoRelativeEvent(position: 'next' | 'prev' = 'next') {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PopoverContent
|
||||
<UiPopoverContent
|
||||
class="event-details w-96"
|
||||
:align="'center'"
|
||||
:align-offset="50"
|
||||
@@ -111,21 +109,21 @@ function handleGotoRelativeEvent(position: 'next' | 'prev' = 'next') {
|
||||
<template v-if="event.category || event.secondaryCategories">
|
||||
<ul class="flex gap-1">
|
||||
<li v-if="event.category">
|
||||
<Badge class="mix-blend-luminosity font-bold bg-gray-600" variant="secondary">
|
||||
<UiBadge class="mix-blend-luminosity font-bold bg-gray-600" variant="secondary">
|
||||
{{ event.category }}
|
||||
</Badge>
|
||||
</UiBadge>
|
||||
</li>
|
||||
|
||||
<li v-for="cat in event.secondaryCategories" :key="cat">
|
||||
<Badge class="mix-blend-luminosity bg-gray-600" variant="secondary">
|
||||
<UiBadge class="mix-blend-luminosity bg-gray-600" variant="secondary">
|
||||
{{ cat }}
|
||||
</Badge>
|
||||
</UiBadge>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<template v-if="event.description">
|
||||
<hr class="border-slate-500 mt-2" />
|
||||
<hr class="border-slate-500 mt-2" >
|
||||
|
||||
<div class="mt-2 text-sm text-slate-300">
|
||||
{{ event.description }}
|
||||
@@ -134,47 +132,47 @@ function handleGotoRelativeEvent(position: 'next' | 'prev' = 'next') {
|
||||
</div>
|
||||
|
||||
<nav v-if="event.startDate && event.endDate" class="absolute -top-2 right-2 flex gap-2">
|
||||
<Badge class="hover:opacity-100 hover:bg-slate-300" as-child>
|
||||
<UiBadge class="hover:opacity-100 hover:bg-slate-300" as-child>
|
||||
<button
|
||||
class="flex gap-1"
|
||||
@click="handleJumpToDate(event.startDate!)"
|
||||
title="Naviguer au début"
|
||||
@click="handleJumpToDate(event.startDate!)"
|
||||
>
|
||||
<PhHourglassHigh size="16" weight="fill" /> Début
|
||||
</button>
|
||||
</Badge>
|
||||
<Badge class="hover:opacity-100 hover:bg-slate-300" as-child title="Naviguer à la fin">
|
||||
</UiBadge>
|
||||
<UiBadge class="hover:opacity-100 hover:bg-slate-300" as-child title="Naviguer à la fin">
|
||||
<button
|
||||
class="flex gap-1"
|
||||
@click="handleJumpToDate(event.endDate!)"
|
||||
title="Naviguer à la fin"
|
||||
@click="handleJumpToDate(event.endDate!)"
|
||||
>
|
||||
<PhHourglassLow size="16" weight="fill" /> Fin
|
||||
</button>
|
||||
</Badge>
|
||||
</UiBadge>
|
||||
</nav>
|
||||
|
||||
<nav class="mt-2 flex gap-2">
|
||||
<Badge class="hover:opacity-100 hover:bg-slate-300" as-child>
|
||||
<UiBadge class="hover:opacity-100 hover:bg-slate-300" as-child>
|
||||
<button
|
||||
class="flex gap-1"
|
||||
@click="handleGotoRelativeEvent('prev')"
|
||||
title="Évènement précédent"
|
||||
@click="handleGotoRelativeEvent('prev')"
|
||||
>
|
||||
<PhArrowBendDoubleUpLeft size="16" weight="fill" /> Précédent
|
||||
</button>
|
||||
</Badge>
|
||||
<Badge class="hover:opacity-100 hover:bg-slate-300" as-child title="Naviguer à la fin">
|
||||
</UiBadge>
|
||||
<UiBadge class="hover:opacity-100 hover:bg-slate-300" as-child title="Naviguer à la fin">
|
||||
<button
|
||||
class="flex gap-1"
|
||||
@click="handleGotoRelativeEvent('next')"
|
||||
title="Évènement suivant"
|
||||
@click="handleGotoRelativeEvent('next')"
|
||||
>
|
||||
<PhArrowBendDoubleUpRight size="16" weight="fill" /> Suivant
|
||||
</button>
|
||||
</Badge>
|
||||
</UiBadge>
|
||||
</nav>
|
||||
</PopoverContent>
|
||||
</UiPopoverContent>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -1,7 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import CalendarMenuNav from './CalendarMenuNav.vue'
|
||||
import CalendarMenuSubnav from './CalendarMenuSubnav.vue'
|
||||
@@ -29,10 +28,10 @@ const { revealAdvancedSearch } = useCalendar()
|
||||
|
||||
<menu class="flex items-center gap-2">
|
||||
<li>
|
||||
<Button search-slash @click="revealAdvancedSearch()">
|
||||
<UiButton search-slash @click="revealAdvancedSearch()">
|
||||
<PhMagnifyingGlass size="20" weight="light" />
|
||||
Recherche avancée
|
||||
</Button>
|
||||
</UiButton>
|
||||
</li>
|
||||
<li>
|
||||
<CalendarSwitch />
|
||||
@@ -2,14 +2,12 @@
|
||||
import { computed, type ComputedRef } from 'vue'
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import {
|
||||
PhCaretDoubleLeft,
|
||||
PhCaretDoubleRight,
|
||||
PhCaretLeft,
|
||||
PhCaretRight
|
||||
} from '@phosphor-icons/vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
|
||||
interface DirectionLabels {
|
||||
pastFar: string
|
||||
@@ -145,56 +143,56 @@ function toFutureFar(): void {
|
||||
|
||||
<template>
|
||||
<div class="flex items-center gap-2">
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="toPastFar()">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton variant="outline" size="icon" @click="toPastFar()">
|
||||
<PhCaretDoubleLeft size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ activeDirectionLabels.pastFar }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="toPastNear()">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton variant="outline" size="icon" @click="toPastNear()">
|
||||
<PhCaretLeft size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ activeDirectionLabels.pastNear }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="toFutureNear()">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton variant="outline" size="icon" @click="toFutureNear()">
|
||||
<PhCaretRight size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ activeDirectionLabels.futureNear }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="outline" size="icon" @click="toFutureFar()">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton variant="outline" size="icon" @click="toFutureFar()">
|
||||
<PhCaretDoubleRight size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ activeDirectionLabels.futureFar }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
</div>
|
||||
</template>
|
||||
@@ -3,9 +3,7 @@ import { daysPerMonth, monthsPerYear, type LeimDate } from '@/models/Date'
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
import { useCalendarEvents } from '@/stores/EventStore'
|
||||
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { PhArrowLineLeft, PhArrowLineRight } from '@phosphor-icons/vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
|
||||
const { currentDate, currentConfig, jumpToDate } = useCalendar()
|
||||
const { getRelativeEventFromDate } = useCalendarEvents()
|
||||
@@ -66,42 +64,42 @@ function handleGotoPreviousEventPage(position: 'next' | 'prev' = 'next') {
|
||||
<span class="text-sm">{{ currentDate.currentDateTitle }}</span>
|
||||
</div>
|
||||
<div class="border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class="rounded-t-sm rounded-b-none"
|
||||
@click="handleGotoPreviousEventPage('prev')"
|
||||
>
|
||||
<PhArrowLineLeft size="22" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>Précédente page à évènements</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
</div>
|
||||
<div class="border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
class="rounded-t-sm rounded-b-none"
|
||||
@click="handleGotoPreviousEventPage('next')"
|
||||
>
|
||||
<PhArrowLineRight size="22" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>Prochaine page à évènements</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,10 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import Button from '../ui/button/Button.vue'
|
||||
import { areDatesIdentical } from '@/models/Date'
|
||||
|
||||
const { defaultDate, selectedDate } = storeToRefs(useCalendar())
|
||||
@@ -18,16 +16,16 @@ const isDefaultDate = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button @click="jumpToDefaultDate" size="sm" :disabled="isDefaultDate">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton size="sm" :disabled="isDefaultDate" @click="jumpToDefaultDate">
|
||||
Aujourd'hui
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ defaultDateFormatted }}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
</template>
|
||||
32
components/calendar/CalendarSwitch.vue
Normal file
32
components/calendar/CalendarSwitch.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
import { PhCalendarBlank } from '@phosphor-icons/vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const { currentConfig, viewTypeOptions, getViewTypeTitle, setViewType } = useCalendar()
|
||||
|
||||
const viewTypeTitle = computed(() => getViewTypeTitle(currentConfig.viewType))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UiDropdownMenu>
|
||||
<UiDropdownMenuTrigger as-child>
|
||||
<UiButton size="sm" variant="secondary">
|
||||
<PhCalendarBlank size="18" weight="fill" />
|
||||
|
||||
{{ viewTypeTitle }}
|
||||
</UiButton>
|
||||
</UiDropdownMenuTrigger>
|
||||
<UiDropdownMenuContent :side="'bottom'" :collision-padding="30">
|
||||
<UiDropdownMenuLabel>Mode d'affichage</UiDropdownMenuLabel>
|
||||
<UiDropdownMenuSeparator />
|
||||
<UiDropdownMenuItem
|
||||
v-for="option in viewTypeOptions"
|
||||
:key="option"
|
||||
@click="setViewType(option)"
|
||||
>
|
||||
{{ getViewTypeTitle(option) }}
|
||||
</UiDropdownMenuItem>
|
||||
</UiDropdownMenuContent>
|
||||
</UiDropdownMenu>
|
||||
</template>
|
||||
@@ -12,12 +12,12 @@ const { revealAdvancedSearch } = useCalendar()
|
||||
<nav class="w-16 py-6 border-r-[1px] border-l-slate-500 grid justify-center">
|
||||
<menu class="flex flex-col gap-4">
|
||||
<li class="mb-12">
|
||||
<Button variant="ghost" size="icon" @click="console.log" class="rounded-full">
|
||||
<Button variant="ghost" size="icon" class="rounded-full" @click="console.log">
|
||||
<PhList size="27" />
|
||||
</Button>
|
||||
</li>
|
||||
<li>
|
||||
<TooltipProvider :delayDuration="100">
|
||||
<TooltipProvider :delay-duration="100">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="ghost" size="icon" class="rounded-full" as-child>
|
||||
@@ -33,7 +33,7 @@ const { revealAdvancedSearch } = useCalendar()
|
||||
</TooltipProvider>
|
||||
</li>
|
||||
<li>
|
||||
<TooltipProvider :delayDuration="100">
|
||||
<TooltipProvider :delay-duration="100">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
@@ -17,31 +17,8 @@ import { useCalendarEvents } from '@/stores/EventStore'
|
||||
import { capitalize } from '@/utils/Strings'
|
||||
import { useMagicKeys, useScroll, useStorage, whenever } from '@vueuse/core'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { searchUnifier, type SearchMode } from '../Search'
|
||||
import { searchUnifier, type SearchMode } from '../SearchMode'
|
||||
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { CommandEmpty, CommandGroup, CommandItem, CommandList } from '@/components/ui/command'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import {
|
||||
Pagination,
|
||||
PaginationEllipsis,
|
||||
PaginationFirst,
|
||||
PaginationLast,
|
||||
PaginationList,
|
||||
PaginationListItem,
|
||||
PaginationNext,
|
||||
PaginationPrev
|
||||
} from '@/components/ui/pagination'
|
||||
import {
|
||||
TagsInput,
|
||||
TagsInputInput,
|
||||
TagsInputItem,
|
||||
TagsInputItemDelete,
|
||||
TagsInputItemText
|
||||
} from '@/components/ui/tags-input'
|
||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { PhClockClockwise, PhClockCounterClockwise, PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import {
|
||||
ComboboxAnchor,
|
||||
@@ -128,7 +105,7 @@ const searchResults = computed<(Character | CalendarEvent)[]>(() => {
|
||||
|
||||
// Handle categories logic
|
||||
let hitCategories: boolean = false
|
||||
let allCategories: CalendarEventCategory[] = []
|
||||
const allCategories: CalendarEventCategory[] = []
|
||||
|
||||
if (item.category) {
|
||||
allCategories.push(item.category)
|
||||
@@ -162,7 +139,7 @@ const searchResults = computed<(Character | CalendarEvent)[]>(() => {
|
||||
|
||||
// Handle categories logic
|
||||
let hitCategories: boolean = false
|
||||
let allCategories: CharacterCategory[] = []
|
||||
const allCategories: CharacterCategory[] = []
|
||||
|
||||
if (item.category) {
|
||||
allCategories.push(item.category)
|
||||
@@ -193,16 +170,16 @@ function resetSearch() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the search dialog
|
||||
* Opens the search Uidialog
|
||||
*/
|
||||
function openDialog() {
|
||||
function openUiDialog() {
|
||||
modalOpen.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the search dialog
|
||||
* Closes the search Uidialog
|
||||
*/
|
||||
function closeDialog() {
|
||||
function closeUiDialog() {
|
||||
modalOpen.value = false
|
||||
}
|
||||
|
||||
@@ -218,7 +195,7 @@ function handleEntitySwitch() {
|
||||
const keys = useMagicKeys()
|
||||
|
||||
whenever(keys.control_period, () => {
|
||||
openDialog()
|
||||
openUiDialog()
|
||||
})
|
||||
|
||||
const searchResultsRef = ref<HTMLElement | null>(null)
|
||||
@@ -250,10 +227,10 @@ const filteredCategories = computed(() =>
|
||||
*
|
||||
* @param e Radix Change Event
|
||||
*/
|
||||
function handleCategorySelect(e: any) {
|
||||
if (typeof e.detail.value === 'string') {
|
||||
function handleCategorySelect(e: (CharacterCategory | CalendarEventCategory)) {
|
||||
if (typeof e === 'string') {
|
||||
searchCategory.value = ''
|
||||
selectedCategories.value.push(e.detail.value)
|
||||
selectedCategories.value.push(e)
|
||||
}
|
||||
|
||||
if (filteredCategories.value.length === 0) {
|
||||
@@ -263,31 +240,31 @@ function handleCategorySelect(e: any) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="modalOpen" @update:open="resetSearch()">
|
||||
<DialogContent
|
||||
<UiDialog v-model:open="modalOpen" @update:open="resetSearch()">
|
||||
<UiDialogContent
|
||||
class="flex flex-col flex-nowrap top-16 -translate-y-0 data-[state=closed]:slide-out-to-top-[5%] data-[state=open]:slide-in-from-top-[5%]"
|
||||
:class="{
|
||||
'bottom-16': searchResults.length > 0
|
||||
}"
|
||||
>
|
||||
<VisuallyHidden>
|
||||
<DialogTitle> Recherche avancée </DialogTitle>
|
||||
<UiDialogTitle> Recherche avancée </UiDialogTitle>
|
||||
</VisuallyHidden>
|
||||
<VisuallyHidden>
|
||||
<DialogDescription>
|
||||
<UiDialogDescription>
|
||||
Rechercher les données disponibles sur le calendrier
|
||||
</DialogDescription>
|
||||
</UiDialogDescription>
|
||||
</VisuallyHidden>
|
||||
|
||||
<!-- Dialog header -->
|
||||
<div class="grid gap-3" id="searchForm">
|
||||
<!-- UiDialog header -->
|
||||
<div id="searchForm" class="grid gap-3">
|
||||
<div class="relative w-full h-fit">
|
||||
<Input
|
||||
<UiInput
|
||||
id="search"
|
||||
v-model:model-value="searchQuery"
|
||||
type="text"
|
||||
placeholder="Rechercher le calendrier"
|
||||
class="pl-10 py-6 text-lg"
|
||||
v-model:model-value="searchQuery"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<span class="absolute start-1 inset-y-0 flex items-center justify-center px-2 opacity-50">
|
||||
@@ -297,28 +274,28 @@ function handleCategorySelect(e: any) {
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<ToggleGroup
|
||||
<UiToggleGroup
|
||||
v-model="selectedEntity"
|
||||
type="single"
|
||||
class="justify-start"
|
||||
v-model="selectedEntity"
|
||||
@update:model-value="handleEntitySwitch()"
|
||||
>
|
||||
<ToggleGroupItem value="events" aria-label="Uniquement les évènements" v-once>
|
||||
<UiToggleGroupItem value="events" aria-label="Uniquement les évènements">
|
||||
Évènements
|
||||
</ToggleGroupItem>
|
||||
<ToggleGroupItem value="characters" aria-label="Uniquement les personnages" v-once>
|
||||
</UiToggleGroupItem>
|
||||
<UiToggleGroupItem value="characters" aria-label="Uniquement les personnages">
|
||||
Personnages
|
||||
</ToggleGroupItem>
|
||||
</ToggleGroup>
|
||||
</UiToggleGroupItem>
|
||||
</UiToggleGroup>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<TagsInput class="px-0 gap-0 w-72" :model-value="selectedCategories">
|
||||
<UiTagsInput class="px-0 gap-0 w-72" :model-value="selectedCategories">
|
||||
<div class="flex gap-2 flex-wrap items-center px-3">
|
||||
<TagsInputItem v-for="item in selectedCategories" :key="item" :value="item">
|
||||
<TagsInputItemText class="capitalize" />
|
||||
<TagsInputItemDelete />
|
||||
</TagsInputItem>
|
||||
<UiTagsInputItem v-for="item in selectedCategories" :key="item" :value="item">
|
||||
<UiTagsInputItemText class="capitalize" />
|
||||
<UiTagsInputItemDelete />
|
||||
</UiTagsInputItem>
|
||||
</div>
|
||||
|
||||
<ComboboxRoot
|
||||
@@ -329,7 +306,7 @@ function handleCategorySelect(e: any) {
|
||||
>
|
||||
<ComboboxAnchor as-child>
|
||||
<ComboboxInput placeholder="Catégories" as-child>
|
||||
<TagsInputInput
|
||||
<UiTagsInputInput
|
||||
class="w-full px-3"
|
||||
:class="selectedCategories.length > 0 ? 'mt-2' : ''"
|
||||
@keydown.enter.prevent
|
||||
@@ -338,79 +315,79 @@ function handleCategorySelect(e: any) {
|
||||
</ComboboxAnchor>
|
||||
|
||||
<ComboboxPortal :to="'#searchForm'">
|
||||
<CommandList
|
||||
<UiCommandList
|
||||
position="popper"
|
||||
class="w-[--radix-popper-anchor-width] rounded-md mt-2 border bg-popover text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50"
|
||||
:dismissable="true"
|
||||
>
|
||||
<CommandEmpty />
|
||||
<CommandGroup>
|
||||
<CommandItem
|
||||
v-for="framework in filteredCategories"
|
||||
:key="framework"
|
||||
:value="framework"
|
||||
@select.prevent="handleCategorySelect"
|
||||
<UiCommandEmpty />
|
||||
<UiCommandGroup>
|
||||
<UiCommandItem
|
||||
v-for="cat in filteredCategories"
|
||||
:key="cat"
|
||||
:value="cat"
|
||||
@select.prevent="handleCategorySelect(cat)"
|
||||
>
|
||||
{{ capitalize(framework) }}
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
{{ capitalize(cat) }}
|
||||
</UiCommandItem>
|
||||
</UiCommandGroup>
|
||||
</UiCommandList>
|
||||
</ComboboxPortal>
|
||||
</ComboboxRoot>
|
||||
</TagsInput>
|
||||
</UiTagsInput>
|
||||
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton
|
||||
:variant="selectedOrder === 'desc' ? 'secondary' : 'outline'"
|
||||
size="icon"
|
||||
@click="setOrderDesc()"
|
||||
>
|
||||
<PhClockCounterClockwise size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>Plus ancien</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
|
||||
<TooltipProvider :delayDuration="250">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton
|
||||
:variant="selectedOrder === 'asc' ? 'secondary' : 'outline'"
|
||||
size="icon"
|
||||
@click="setOrderAsc()"
|
||||
>
|
||||
<PhClockClockwise size="18" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
</UiButton>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>Plus récent</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</UiTooltipContent>
|
||||
</UiTooltip>
|
||||
</UiTooltipProvider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<hr >
|
||||
|
||||
<div v-if="searchResults.length > 0" class="grow overflow-y-auto" ref="searchResultsRef">
|
||||
<div v-if="searchResults.length > 0" ref="searchResultsRef" class="grow overflow-y-auto">
|
||||
<SearchList
|
||||
:results="searchResults"
|
||||
:current-entity="selectedEntity"
|
||||
:order="selectedOrder"
|
||||
:start-at="startOfList"
|
||||
:end-at="endOfList"
|
||||
@jumped-to-date="closeDialog()"
|
||||
@jumped-to-date="closeUiDialog()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<Pagination
|
||||
<UiPagination
|
||||
v-model:page="currentPage"
|
||||
:total="searchResults.length"
|
||||
:items-per-page="itemsPerPage"
|
||||
@@ -418,32 +395,32 @@ function handleCategorySelect(e: any) {
|
||||
show-edges
|
||||
:default-page="1"
|
||||
>
|
||||
<PaginationList v-slot="{ items }" class="flex items-center gap-1">
|
||||
<PaginationFirst />
|
||||
<PaginationPrev />
|
||||
<UiPaginationList v-slot="{ items }" class="flex items-center gap-1">
|
||||
<UiPaginationFirst />
|
||||
<UiPaginationPrev />
|
||||
|
||||
<template v-for="(item, index) in items">
|
||||
<PaginationListItem
|
||||
<UiPaginationListItem
|
||||
v-if="item.type === 'page'"
|
||||
:key="index"
|
||||
:value="item.value"
|
||||
as-child
|
||||
>
|
||||
<Button
|
||||
<UiButton
|
||||
class="w-10 h-10 p-0"
|
||||
:variant="item.value === currentPage ? 'default' : 'outline'"
|
||||
>
|
||||
{{ item.value }}
|
||||
</Button>
|
||||
</PaginationListItem>
|
||||
<PaginationEllipsis v-else :key="item.type" :index="index" />
|
||||
</UiButton>
|
||||
</UiPaginationListItem>
|
||||
<UiPaginationEllipsis v-else :key="item.type" :index="index" />
|
||||
</template>
|
||||
|
||||
<PaginationNext />
|
||||
<PaginationLast />
|
||||
</PaginationList>
|
||||
</Pagination>
|
||||
<UiPaginationNext />
|
||||
<UiPaginationLast />
|
||||
</UiPaginationList>
|
||||
</UiPagination>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</UiDialogContent>
|
||||
</UiDialog>
|
||||
</template>
|
||||
@@ -37,13 +37,13 @@ const { getFormattedDateTitle } = useCalendar()
|
||||
|
||||
<menu class="flex gap-2 border-[1px] border-slate-700 rounded-sm w-fit">
|
||||
<li v-if="character.birth">
|
||||
<TooltipProvider :delayDuration="100">
|
||||
<TooltipProvider :delay-duration="100">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
@click="$emit('query:date-jump', character.birth!)"
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
@click="$emit('query:date-jump', character.birth!)"
|
||||
>
|
||||
<PhPlant size="16" weight="fill" />
|
||||
{{ getFormattedDateTitle(character.birth, true) }}
|
||||
@@ -57,13 +57,13 @@ const { getFormattedDateTitle } = useCalendar()
|
||||
</li>
|
||||
<span v-if="character.birth && character.death">-</span>
|
||||
<li v-if="character.death">
|
||||
<TooltipProvider :delayDuration="100">
|
||||
<TooltipProvider :delay-duration="100">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
@click="$emit('query:date-jump', character.death!)"
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
@click="$emit('query:date-jump', character.death!)"
|
||||
>
|
||||
<PhSkull size="16" weight="fill" />
|
||||
{{ getFormattedDateTitle(character.death, true) }}
|
||||
@@ -77,7 +77,7 @@ const { getFormattedDateTitle } = useCalendar()
|
||||
</li>
|
||||
</menu>
|
||||
|
||||
<hr v-if="character.description" class="border-white opacity-25" />
|
||||
<hr v-if="character.description" class="border-white opacity-25" >
|
||||
|
||||
<div v-if="character.description" class="text-sm">
|
||||
<span class="opacity-75">
|
||||
@@ -105,7 +105,7 @@ const dateDuration: string | null = props.event.endDate
|
||||
</div>
|
||||
|
||||
<div v-if="event.description" class="text-sm">
|
||||
<hr class="my-2 border-white opacity-50" />
|
||||
<hr class="my-2 border-white opacity-50" >
|
||||
<span class="opacity-75">
|
||||
{{ event.description }}
|
||||
</span>
|
||||
@@ -3,12 +3,11 @@ import { isCharacter, type Character } from '@/models/Characters'
|
||||
import { compareDates, type LeimDate, type LeimDateOrder } from '@/models/Date'
|
||||
import { isCalendarEvent, type CalendarEvent } from '@/models/Events'
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
import { computed, ref } from 'vue'
|
||||
import type { SearchMode } from '../../Search'
|
||||
import { computed } from 'vue'
|
||||
import type { SearchMode } from '../../SearchMode'
|
||||
|
||||
import CharacterCallout from './CharacterCallout.vue'
|
||||
import EventCallout from './EventCallout.vue'
|
||||
import { useScroll } from '@vueuse/core'
|
||||
|
||||
const props = defineProps<{
|
||||
results: (Character | CalendarEvent)[]
|
||||
@@ -6,7 +6,6 @@ import { useElementBounding } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, ref, type ComputedRef } from 'vue'
|
||||
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import CalendarEventButton from '../../CalendarEvent.vue'
|
||||
import type { CalendarEvent } from '@/models/Events'
|
||||
|
||||
@@ -97,15 +96,15 @@ const eventsNotDisplayed = computed(
|
||||
</li>
|
||||
|
||||
<li v-if="eventsNotDisplayed > 0" class="pointer-events-auto">
|
||||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<UiPopover>
|
||||
<UiPopoverTrigger as-child>
|
||||
<button
|
||||
class="text-xs px-2 py-1 block w-full text-left font-bold rounded-sm whitespace-nowrap overflow-hidden text-ellipsis cursor-pointer transition-colors hover:bg-slate-800"
|
||||
>
|
||||
{{ eventsNotDisplayed }} autre{{ eventsNotDisplayed > 1 ? 's' : '' }}
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-80" :align="'center'" :side="'right'">
|
||||
</UiPopoverTrigger>
|
||||
<UiPopoverContent class="w-80" :align="'center'" :side="'right'">
|
||||
<div class="text-center mb-4">
|
||||
<span
|
||||
class="inline-flex w-12 h-12 aspect-square items-center justify-center text-lg font-semibold text-slate-300 bg-slate-800 rounded-full"
|
||||
@@ -122,8 +121,8 @@ const eventsNotDisplayed = computed(
|
||||
<CalendarEventButton :event :tile-date="date" />
|
||||
</li>
|
||||
</ul>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</UiPopoverContent>
|
||||
</UiPopover>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -7,18 +7,19 @@ export const badgeVariants = cva(
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
|
||||
default:
|
||||
'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
|
||||
secondary:
|
||||
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||
destructive:
|
||||
'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
|
||||
outline: 'text-foreground'
|
||||
}
|
||||
outline: 'text-foreground',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default'
|
||||
}
|
||||
}
|
||||
variant: 'default',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
export type BadgeVariants = VariantProps<typeof badgeVariants>
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { RouterLink } from 'vue-router'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
@@ -20,7 +19,7 @@ const props = defineProps<{
|
||||
>
|
||||
<slot />
|
||||
|
||||
<RouterLink
|
||||
<NuxtLink
|
||||
v-if="props.link"
|
||||
:to="props.link"
|
||||
class="absolute inset-0 focus-visible:outline-none"
|
||||
@@ -8,7 +8,7 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('p-6 pt-0 text-muted-foreground', props.class)">
|
||||
<div :class="cn('p-6 pt-0', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -8,7 +8,7 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p :class="cn('text-sm text-muted-foreground mt-1', props.class)">
|
||||
<div :class="cn('text-sm text-muted-foreground', props.class)">
|
||||
<slot />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -8,7 +8,7 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('flex flex-col gap-y-1.5 px-6 pt-6 pb-3', props.class)">
|
||||
<div :class="cn('flex flex-col gap-y-1.5 p-6', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -8,7 +8,11 @@ const props = defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h3 :class="cn('text-2xl font-semibold leading-none tracking-tight', props.class)">
|
||||
<h3
|
||||
:class="
|
||||
cn('text-2xl font-semibold leading-none tracking-tight', props.class)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</h3>
|
||||
</template>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user