This commit is contained in:
taskylizard 2025-06-28 08:38:06 +00:00
parent b1da9e7563
commit 887ad08707
No known key found for this signature in database
GPG key ID: 1820131ED1A24120
8 changed files with 162 additions and 95 deletions

View file

@ -3,10 +3,7 @@
"verbatimModuleSyntax": true,
"module": "esnext",
"target": "esnext",
"lib": [
"DOM",
"ESNext"
],
"lib": ["DOM", "ESNext"],
"strict": true,
"jsx": "preserve",
"esModuleInterop": true,
@ -16,13 +13,9 @@
"noUnusedLocals": true,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"types": [
"vitepress"
]
"types": ["vitepress"]
},
"exclude": [
"node_modules"
],
"exclude": ["node_modules"],
"include": [
"website/**/*.ts",
"website/**/*.d.ts",

View file

@ -72,14 +72,14 @@ async function generateImage({
const _page = getPage(url)
const title =
frontmatter.layout === 'home'
? frontmatter.hero.name ?? frontmatter.title
? (frontmatter.hero.name ?? frontmatter.title)
: frontmatter.title
? frontmatter.title
: _page?.title
const description =
frontmatter.layout === 'home'
? frontmatter.hero.tagline ?? frontmatter.description
? (frontmatter.hero.tagline ?? frontmatter.description)
: frontmatter.description
? frontmatter.description
: _page?.description

View file

@ -85,21 +85,30 @@ const handleColorChange = (value: string) => {
:style="{ backgroundColor: colors[selectedColor][500] }"
/>
</div>
<SelectRoot :model-value="selectedColor" @update:model-value="handleColorChange">
<SelectTrigger
class="color-input-text"
aria-label="Select theme color">
<SelectRoot
:model-value="selectedColor"
@update:model-value="handleColorChange"
>
<SelectTrigger class="color-input-text" aria-label="Select theme color">
<SelectValue :placeholder="normalizeColorName(selectedColor)" />
</SelectTrigger>
<SelectPortal>
<SelectContent class="bg-bg-elv border border-div rounded-md shadow-lg z-50 max-h-60 overflow-hidden z-9999"
:side-offset="4">
<SelectContent
class="bg-bg-elv border border-div rounded-md shadow-lg z-50 max-h-60 overflow-hidden z-9999"
:side-offset="4"
>
<SelectViewport class="p-1">
<SelectItem v-for="color in colorOptions" :key="color" :value="color"
class="relative flex items-center gap-2 px-3 py-2 text-sm cursor-pointer hover:bg-bg-alt rounded-sm outline-none data-[highlighted]:bg-bg-alt data-[state=checked]:bg-bg-alt data-[state=checked]:text-text">
<span class="inline-block w-4 h-4 rounded-full border border-div"
:style="{ backgroundColor: colors[color][500] }" />
<SelectItem
v-for="color in colorOptions"
:key="color"
:value="color"
class="relative flex items-center gap-2 px-3 py-2 text-sm cursor-pointer hover:bg-bg-alt rounded-sm outline-none data-[highlighted]:bg-bg-alt data-[state=checked]:bg-bg-alt data-[state=checked]:text-text"
>
<span
class="inline-block w-4 h-4 rounded-full border border-div"
:style="{ backgroundColor: colors[color][500] }"
/>
<SelectItemText>
{{ normalizeColorName(color) }}
</SelectItemText>
@ -158,10 +167,13 @@ const handleColorChange = (value: string) => {
text-align: left;
border-radius: 8px;
cursor: text;
transition: border-color 0.25s, background 0.4s ease;
transition:
border-color 0.25s,
background 0.4s ease;
}
.color-picker:hover, .color-picker:focus {
.color-picker:hover,
.color-picker:focus {
border-color: var(--vp-c-brand);
background: var(--vp-c-bg-alt);
}

View file

@ -134,24 +134,36 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
<template>
<template v-if="props.heading">
<button @click="toggleCard()"
class="bg-$vp-c-default-soft text-primary border-$vp-c-default-soft hover:border-primary ml-3 inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md border-2 border-solid px-1.5 py-3.5 text-sm font-medium transition-all duration-300 sm:h-6">
<span :class="isCardShown === false ? `i-lucide:mail` : `i-lucide:mail-x`" />
<button
@click="toggleCard()"
class="bg-$vp-c-default-soft text-primary border-$vp-c-default-soft hover:border-primary ml-3 inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md border-2 border-solid px-1.5 py-3.5 text-sm font-medium transition-all duration-300 sm:h-6"
>
<span
:class="isCardShown === false ? `i-lucide:mail` : `i-lucide:mail-x`"
/>
</button>
</template>
<template v-else>
<div
class="mt-2 p-4 border-2 border-solid bg-brand-50 border-brand-300 dark:bg-brand-950 dark:border-brand-800 rounded-xl col-span-3 transition-colors duration-250">
class="mt-2 p-4 border-2 border-solid bg-brand-50 border-brand-300 dark:bg-brand-950 dark:border-brand-800 rounded-xl col-span-3 transition-colors duration-250"
>
<div class="flex items-start md:items-center gap-3">
<div class="pt-1 md:pt-0">
<div class="w-10 h-10 rounded-full flex items-center justify-center bg-brand-500 dark:bg-brand-400">
<span :class="isCardShown === false
<div
class="w-10 h-10 rounded-full flex items-center justify-center bg-brand-500 dark:bg-brand-400"
>
<span
:class="
isCardShown === false
? `i-lucide:mail w-6 h-6 text-white dark:text-brand-950`
: `i-lucide:mail-x w-6 h-6 text-white dark:text-brand-950`
" />
"
/>
</div>
</div>
<div class="flex-grow flex items-start md:items-center gap-3 flex-col md:flex-row">
<div
class="flex-grow flex items-start md:items-center gap-3 flex-col md:flex-row"
>
<div class="flex-grow">
<div class="font-semibold text-brand-950 dark:text-brand-50">
Got feedback?
@ -163,7 +175,8 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
<div>
<button
class="inline-block text-center rounded-full px-4 py-2.5 text-sm font-medium border-2 border-solid text-brand-700 border-brand-300 dark:text-brand-100 dark:border-brand-800"
@click="toggleCard()">
@click="toggleCard()"
>
Share Feedback
</button>
</div>
@ -173,17 +186,22 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
</template>
<Transition name="fade" mode="out-in">
<div v-if="isCardShown"
class="border-$vp-c-divider bg-$vp-c-bg-alt b-rd-4 m-[2rem 0] mt-4 border-2 border-solid p-6">
<div
v-if="isCardShown"
class="border-$vp-c-divider bg-$vp-c-bg-alt b-rd-4 m-[2rem 0] mt-4 border-2 border-solid p-6"
>
<Transition name="fade" mode="out-in">
<div v-if="!feedback.type">
<p class="heading">
{{ helpfulText }}
</p>
<div class="flex flex-wrap gap-2">
<button v-for="item in feedbackOptions" :key="item.value"
<button
v-for="item in feedbackOptions"
:key="item.value"
class="bg-bg border-$vp-c-default-soft hover:border-primary mt-2 select-none rounded border-2 border-solid font-bold transition-all duration-250 rounded-lg text-[14px] font-500 leading-normal m-0 px-3 py-1.5 text-center align-middle whitespace-nowrap"
@click="handleSubmit(item.value)">
@click="handleSubmit(item.value)"
>
<span>{{ item.label }}</span>
</button>
</div>
@ -203,23 +221,30 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
<strong>🕹 Emulators</strong>
<p class="desc">
They're already on the
<a class="text-primary text-underline font-bold"
href="https://emulation.gametechwiki.com/index.php/Main_Page">
<a
class="text-primary text-underline font-bold"
href="https://emulation.gametechwiki.com/index.php/Main_Page"
>
Game Tech Wiki.
</a>
</p>
<strong>🔻 Leeches</strong>
<p class="desc">
They're already on the
<a class="text-primary text-underline font-bold"
href="https://filehostlist.miraheze.org/wiki/Free_Premium_Leeches">
<a
class="text-primary text-underline font-bold"
href="https://filehostlist.miraheze.org/wiki/Free_Premium_Leeches"
>
File Hosting Wiki.
</a>
</p>
<strong>🐧 Distros</strong>
<p class="desc">
They're already on
<a class="text-primary text-underline font-bold" href="https://distrowatch.com/">
<a
class="text-primary text-underline font-bold"
href="https://distrowatch.com/"
>
DistroWatch.
</a>
</p>
@ -234,25 +259,35 @@ const toggleCard = () => (isCardShown.value = !isCardShown.value)
</p>
</details>
</div>
<textarea v-model="feedback.message" autofocus
<textarea
v-model="feedback.message"
autofocus
class="bg-$vp-c-bg-alt text-$vp-c-text-2 w-full h-[100px] border border-$vp-c-divider rounded px-3 py-1.5 border-$vp-c-divider bg-$vp-c-bg-alt b-rd-4 border-2 border-solid"
placeholder="What a lovely wiki!" />
placeholder="What a lovely wiki!"
/>
<p class="desc mb-2">
Add your Discord handle if you would like a response, or if we need
more information from you, otherwise join our
<a class="text-primary text-underline font-semibold" href="https://rentry.co/FMHY-Invite/">
<a
class="text-primary text-underline font-semibold"
href="https://rentry.co/FMHY-Invite/"
>
Discord.
</a>
</p>
<div class="flex flex-row gap-2">
<button
class="bg-$vp-c-default-soft text-primary border-$vp-c-default-soft inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md border-2 border-solid px-1.5 py-3.5 text-sm font-medium transition-all duration-300 sm:h-6"
@click="feedback.type = undefined">
@click="feedback.type = undefined"
>
<span class="i-lucide:panel-left-close">close</span>
</button>
<button type="submit"
<button
type="submit"
class="border border-div rounded-lg transition-colors duration-250 inline-block text-14px font-500 leading-1.5 px-3 py-3 text-center align-middle whitespace-nowrap disabled:opacity-50 text-text-2 bg-brand-100 dark:bg-brand-700 border-brand-800 dark:border-brand-700 disabled:bg-brand-100 dark:disabled:bg-brand-900 hover:border-brand-900 dark:hover:border-brand-800 hover:bg-brand-200 dark:hover:bg-brand-800"
:disabled="isDisabled" @click="handleSubmit()">
:disabled="isDisabled"
@click="handleSubmit()"
>
Send Feedback 📩
</button>
</div>

View file

@ -7,7 +7,8 @@ import ToggleStarred from './ToggleStarred.vue'
<template>
<div
class="bg-$vp-c-bg border-$vp-c-default-soft hover:border-primary transition-border relative z-0 rounded-lg border-2 border-solid p-5 duration-500">
class="bg-$vp-c-bg border-$vp-c-default-soft hover:border-primary transition-border relative z-0 rounded-lg border-2 border-solid p-5 duration-500"
>
<div class="align-center mb-4 flex justify-between">
<div class="text-$vp-c-text-1 lh-relaxed text-sm font-bold">
Emoji Legend
@ -24,14 +25,10 @@ import ToggleStarred from './ToggleStarred.vue'
<ToggleStarred />
</template>
</InputField>
<InputField
id="icon-color"
label="Color"
>
<InputField id="icon-color" label="Color">
<template #display>
<ColorPicker class="ml-auto" />
</template>
</InputField>
</div>
</template>

View file

@ -134,14 +134,22 @@ const processedItems = computed(() => {
<template>
<div v-if="theme === 'brand'" class="VPButtonDropdown" ref="dropdownRef">
<div class="VPButtonWrapper">
<component :is="component" class="VPButton VPButtonMain" :class="[size, theme]"
:href="href ? normalizeLink(href) : undefined" :target="props.target ?? (isExternal ? '_blank' : undefined)"
:rel="props.rel ?? (isExternal ? 'noreferrer' : undefined)">
<component
:is="component"
class="VPButton VPButtonMain"
:class="[size, theme]"
:href="href ? normalizeLink(href) : undefined"
:target="props.target ?? (isExternal ? '_blank' : undefined)"
:rel="props.rel ?? (isExternal ? 'noreferrer' : undefined)"
>
<slot>{{ text }}</slot>
</component>
<button
class="bg-$vp-c-default-soft text-text border-$vp-c-default-soft hover:bg-$vp-c-default-hover active:bg-$vp-c-default-active inline-flex items-center justify-center whitespace-nowrap rounded-md border-2 border-solid px-2.5 py-5 text-md font-medium sm:h-7 VPButtonTrigger"
@click="toggleDropdown" :aria-expanded="isDropdownOpen" aria-label="Toggle dropdown menu">
@click="toggleDropdown"
:aria-expanded="isDropdownOpen"
aria-label="Toggle dropdown menu"
>
<span class="i-lucide:menu"></span>
</button>
</div>
@ -151,12 +159,22 @@ const processedItems = computed(() => {
<template v-for="item in processedItems" :key="item.text">
<div v-if="'items' in item" class="VPButtonDropdownSection">
<div class="VPButtonDropdownSectionTitle" v-html="item.text"></div>
<a v-for="subItem in item.items" :key="subItem.text" :href="subItem.link" class="VPButtonDropdownItem"
@click="closeDropdown">
<a
v-for="subItem in item.items"
:key="subItem.text"
:href="subItem.link"
class="VPButtonDropdownItem"
@click="closeDropdown"
>
<span v-html="subItem.displayText"></span>
</a>
</div>
<a v-else :href="item.link" class="VPButtonDropdownItem" @click="closeDropdown">
<a
v-else
:href="item.link"
class="VPButtonDropdownItem"
@click="closeDropdown"
>
<span v-html="item.displayText"></span>
</a>
</template>
@ -164,9 +182,15 @@ const processedItems = computed(() => {
</div>
</div>
<component v-else :is="component" class="VPButton" :class="[size, theme]"
:href="href ? normalizeLink(href) : undefined" :target="props.target ?? (isExternal ? '_blank' : undefined)"
:rel="props.rel ?? (isExternal ? 'noreferrer' : undefined)">
<component
v-else
:is="component"
class="VPButton"
:class="[size, theme]"
:href="href ? normalizeLink(href) : undefined"
:target="props.target ?? (isExternal ? '_blank' : undefined)"
:rel="props.rel ?? (isExternal ? 'noreferrer' : undefined)"
>
<slot>{{ text }}</slot>
</component>
</template>
@ -178,11 +202,17 @@ const processedItems = computed(() => {
text-align: center;
font-weight: 600;
white-space: nowrap;
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
transition:
color 0.25s,
border-color 0.25s,
background-color 0.25s;
}
.VPButton:active {
transition: color 0.1s, border-color 0.1s, background-color 0.1s;
transition:
color 0.1s,
border-color 0.1s,
background-color 0.1s;
}
.VPButton.medium {
@ -282,7 +312,9 @@ const processedItems = computed(() => {
background-color: var(--vp-c-bg-elv);
border: 1px solid var(--vp-c-divider);
border-radius: 12px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
box-shadow:
0 12px 32px rgba(0, 0, 0, 0.1),
0 2px 6px rgba(0, 0, 0, 0.08);
min-width: 280px;
max-height: 400px;
overflow-y: auto;
@ -332,14 +364,14 @@ const processedItems = computed(() => {
flex-shrink: 0;
}
.VPButtonDropdownItem span :deep([class*="i-"]) {
.VPButtonDropdownItem span :deep([class*='i-']) {
width: 16px;
height: 16px;
flex-shrink: 0;
margin-right: 8px;
}
.VPButtonDropdownSectionTitle :deep([class*="i-"]) {
.VPButtonDropdownSectionTitle :deep([class*='i-']) {
width: 14px;
height: 14px;
flex-shrink: 0;

View file

@ -133,7 +133,6 @@
text-decoration-style: solid;
}
::selection {
background-color: var(--vp-c-brand-400, #5586a6);
@ -195,7 +194,6 @@
}
}
#VPContent strong > a {
font-weight: bold;
}