Fix light theme, fix animation bugs, add programmatic scrolling, improve custom card blog component
This commit is contained in:
parent
3e39bda014
commit
2204709c0e
2
app.vue
2
app.vue
|
@ -56,6 +56,6 @@ useHead({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<LazyPortal v-model="animate" layout="#ender-layout" randomize fade />
|
<Portal v-model="animate" layout="#ender-layout" randomize fade />
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -18,19 +18,19 @@
|
||||||
|
|
||||||
.list-style-type {
|
.list-style-type {
|
||||||
&-none {
|
&-none {
|
||||||
list-style-type: none;
|
list-style-type: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-do {
|
&-do {
|
||||||
list-style-type: do;
|
list-style-type: do !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-enjoy {
|
&-enjoy {
|
||||||
list-style-type: enjoy;
|
list-style-type: enjoy !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-faq {
|
&-faq {
|
||||||
list-style-type: faq;
|
list-style-type: faq !important;
|
||||||
|
|
||||||
> li:nth-child(2n):not(:last-child) {
|
> li:nth-child(2n):not(:last-child) {
|
||||||
@apply mb-2;
|
@apply mb-2;
|
||||||
|
|
|
@ -40,6 +40,7 @@ html {
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
|
@ -52,13 +53,21 @@ html {
|
||||||
background-color: rgb(255 255 255 / 15%);
|
background-color: rgb(255 255 255 / 15%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: rgb(255 255 255 / 15%);
|
||||||
|
}
|
||||||
|
|
||||||
&.light {
|
&.light {
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background-color: rgb(255 255 255 / 15%);
|
background-color: rgb(255 255 255 / 15%);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border-radius: 8px;
|
background-color: rgb(0 0 0 / 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
background-color: rgb(0 0 0 / 30%);
|
background-color: rgb(0 0 0 / 30%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,12 +146,19 @@ body {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:not(nav) > ul {
|
:not(nav) {
|
||||||
|
> ul {
|
||||||
|
@apply ps-6;
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
padding-left: 1.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(section, article, aside).page {
|
> ol {
|
||||||
|
@apply ps-6;
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:where(section, article, aside).page {
|
||||||
:is(div, p):not(:last-child) {
|
:is(div, p):not(:last-child) {
|
||||||
@apply mb-4;
|
@apply mb-4;
|
||||||
}
|
}
|
||||||
|
@ -161,24 +177,31 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:is(ul, ol):not(:last-child) {
|
ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:where(ul, ol) {
|
||||||
|
&:not(:last-child) {
|
||||||
@apply mb-4;
|
@apply mb-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
:where(p, li) {
|
li:not(:last-child) {
|
||||||
code {
|
@apply mb-1;
|
||||||
&:hover {
|
}
|
||||||
background-color: rgb(138 71 245 / 20%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
padding: 0.25em;
|
code:not(pre *) {
|
||||||
|
@apply px-1 py-0.5 break-words cursor-pointer rounded-lg transition-ease;
|
||||||
|
|
||||||
border-radius: 0.5em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgb(83 35 162 / 10%);
|
background-color: rgb(83 35 162 / 10%);
|
||||||
|
|
||||||
transition: 0.3s ease;
|
&:hover {
|
||||||
|
background-color: rgb(138 71 245 / 20%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,56 +210,49 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
padding: 0.75em 1em;
|
@apply px-4 py-3 mb-4 border-l-4 rounded-r-xl transition-ease;
|
||||||
|
|
||||||
border-left: 0.25em solid rgb(153 153 255 / 60%);
|
|
||||||
border-top-right-radius: 0.5em;
|
|
||||||
border-bottom-right-radius: 0.5em;
|
|
||||||
|
|
||||||
|
border-left-color: rgb(153 153 255 / 60%);
|
||||||
background-color: rgb(153 153 255 / 10%);
|
background-color: rgb(153 153 255 / 10%);
|
||||||
|
|
||||||
transition: 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-left-color: rgb(153 153 255 / 100%);
|
border-left-color: rgb(153 153 255 / 100%);
|
||||||
background-color: rgb(153 153 255 / 15%);
|
background-color: rgb(153 153 255 / 15%);
|
||||||
}
|
}
|
||||||
|
|
||||||
:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
font-size: 14px;
|
@apply relative font-small overflow-auto min-h-14 max-h-[80rem] rounded-xl p-2 mb-4;
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
border-radius: 0.5em;
|
|
||||||
background-color: rgb(83 35 162 / 5%);
|
background-color: rgb(83 35 162 / 5%);
|
||||||
|
|
||||||
position: relative;
|
&:hover > .absolute {
|
||||||
|
@apply opacity-100;
|
||||||
|
}
|
||||||
|
|
||||||
overflow-x: auto;
|
> code {
|
||||||
|
@apply scroll-p-2;
|
||||||
|
|
||||||
code {
|
|
||||||
counter-reset: step;
|
counter-reset: step;
|
||||||
counter-increment: step 0;
|
counter-increment: step 0;
|
||||||
|
|
||||||
scroll-padding: 0.5em;
|
|
||||||
|
|
||||||
.line::before {
|
.line::before {
|
||||||
|
@apply inline-block w-4 mr-6 text-right;
|
||||||
|
|
||||||
content: counter(step);
|
content: counter(step);
|
||||||
counter-increment: step;
|
counter-increment: step;
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
color: rgb(238 246 250 / 40%);
|
color: rgb(238 246 250 / 40%);
|
||||||
|
|
||||||
width: 1rem;
|
|
||||||
margin-right: 1.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> span span:last-child {
|
||||||
|
@apply me-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-action {
|
||||||
|
background-color: rgb(153 153 255 / 10%);
|
||||||
|
border-color: rgb(153 153 255 / 60%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,6 +496,41 @@ rt {
|
||||||
border-color: rgb(123 123 255 / 80%);
|
border-color: rgb(123 123 255 / 80%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:is(section, article, aside).page {
|
||||||
|
code:not(pre *) {
|
||||||
|
background-color: rgb(138 71 245 / 20%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgb(83 35 162 / 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-left-color: rgb(153 153 255 / 60%);
|
||||||
|
background-color: rgb(153 153 255 / 10%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-left-color: rgb(153 153 255 / 100%);
|
||||||
|
background-color: rgb(153 153 255 / 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background-color: rgb(83 35 162 / 10%);
|
||||||
|
|
||||||
|
code {
|
||||||
|
.line::before {
|
||||||
|
color: rgb(83 85 89 / 40%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-action {
|
||||||
|
background-color: rgb(153 153 255 / 30%);
|
||||||
|
border-color: rgb(153 153 255 / 80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic classes.
|
// Dynamic classes.
|
||||||
|
|
|
@ -11,6 +11,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
&-enter-active,
|
||||||
|
&-leave-active {
|
||||||
|
transition: all 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-enter-from,
|
||||||
|
&-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.transition {
|
.transition {
|
||||||
&-ease {
|
&-ease {
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ideaIcon from '~/assets/images/icons/accent/idea.png'
|
||||||
type IconOptions = 'warning' | 'error' | 'info' | 'help' | 'checkmark' | 'idea'
|
type IconOptions = 'warning' | 'error' | 'info' | 'help' | 'checkmark' | 'idea'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
icon: {
|
type: {
|
||||||
type: String as PropType<IconOptions>,
|
type: String as PropType<IconOptions>,
|
||||||
default: 'warning',
|
default: 'warning',
|
||||||
},
|
},
|
||||||
|
@ -21,42 +21,49 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
let cardIcon = warningIcon
|
const cards = {
|
||||||
let color = 'rgb(255 246 147 / 60%)'
|
warning: {
|
||||||
|
color: 'border-warning',
|
||||||
switch (props.icon) {
|
icon: {
|
||||||
case 'error':
|
src: warningIcon,
|
||||||
cardIcon = errorIcon
|
alt: 'Warning triangle',
|
||||||
color = 'rgb(255 113 113 / 60%)'
|
},
|
||||||
break
|
},
|
||||||
|
error: {
|
||||||
case 'info':
|
color: 'border-error',
|
||||||
cardIcon = infoIcon
|
icon: {
|
||||||
color = 'rgb(94 162 255 / 60%)'
|
src: errorIcon,
|
||||||
|
alt: 'Error circle',
|
||||||
break
|
},
|
||||||
|
},
|
||||||
case 'help':
|
info: {
|
||||||
cardIcon = helpIcon
|
color: 'border-info',
|
||||||
color = 'rgb(178 104 255 / 60%)'
|
icon: {
|
||||||
|
src: infoIcon,
|
||||||
break
|
alt: 'Information circle',
|
||||||
|
},
|
||||||
case 'checkmark':
|
},
|
||||||
cardIcon = checkIcon
|
help: {
|
||||||
color = 'rgb(69 255 255 / 60%)'
|
color: 'border-help',
|
||||||
|
icon: {
|
||||||
break
|
src: helpIcon,
|
||||||
|
alt: 'Help circle',
|
||||||
case 'idea':
|
},
|
||||||
cardIcon = ideaIcon
|
},
|
||||||
color = 'rgb(255 255 255 / 60%)'
|
checkmark: {
|
||||||
|
color: 'border-checkmark',
|
||||||
break
|
icon: {
|
||||||
|
src: checkIcon,
|
||||||
case 'warning':
|
alt: 'Checkmark',
|
||||||
default:
|
},
|
||||||
break
|
},
|
||||||
|
idea: {
|
||||||
|
color: 'border-idea',
|
||||||
|
icon: {
|
||||||
|
src: ideaIcon,
|
||||||
|
alt: 'Lightbulb',
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -64,13 +71,15 @@ switch (props.icon) {
|
||||||
<div class="tilt flex flex-row items-center gap-2 mb-0 sm:mb-2 md:mb-4">
|
<div class="tilt flex flex-row items-center gap-2 mb-0 sm:mb-2 md:mb-4">
|
||||||
<img
|
<img
|
||||||
draggable="false"
|
draggable="false"
|
||||||
:src="cardIcon"
|
:src="cards[props.type].icon.src"
|
||||||
:alt="`Download`"
|
:alt="cards[props.type].icon.alt"
|
||||||
class="icon-image"
|
class="w-12 h-12"
|
||||||
/>
|
/>
|
||||||
<h3 class="whitespace-nowrap mb-0">{{ props.title }}</h3>
|
<h3 class="whitespace-nowrap mb-0">{{ props.title }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box p-4 rounded-xl mb-4">
|
<div
|
||||||
|
:class="`box p-4 mb-4 ${cards[props.type].color} border-b border-r rounded-xl`"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -79,22 +88,4 @@ switch (props.icon) {
|
||||||
.tilt {
|
.tilt {
|
||||||
transform: rotate(-2deg);
|
transform: rotate(-2deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
|
||||||
> p {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
border-bottom: 1px ridge;
|
|
||||||
border-right: 1px ridge;
|
|
||||||
border-color: v-bind(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
&-image {
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
const emit = defineEmits(['copy'])
|
||||||
|
|
||||||
|
const clicked = ref<boolean>(false)
|
||||||
|
|
||||||
|
function p() {
|
||||||
|
emit('copy')
|
||||||
|
|
||||||
|
if (!clicked.value) setTimeout(() => (clicked.value = false), 2000)
|
||||||
|
clicked.value = true
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="absolute flex flex-col justify-start top-0 left-0 w-full h-full pointer-events-none"
|
class="absolute flex flex-col justify-start top-0 left-0 w-full h-full pointer-events-none opacity-0 hover:opacity-100 transition-ease"
|
||||||
>
|
>
|
||||||
<div class="flex flex-row justify-end items-center p-2">
|
<div class="flex flex-row justify-end items-center p-2">
|
||||||
<iconify-icon icon="mdi:content-copy" inline class="button" />
|
<span
|
||||||
|
class="overlay-action flex-grow-0 pointer-events-auto cursor-pointer p-2 border rounded-xl"
|
||||||
|
@click="p"
|
||||||
|
>
|
||||||
|
<Transition name="switch" mode="out-in">
|
||||||
|
<iconify-icon v-if="!clicked" icon="mdi:content-copy" inline />
|
||||||
|
<iconify-icon
|
||||||
|
v-else
|
||||||
|
icon="mdi:check-bold"
|
||||||
|
class="text-green-500"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
|
</Transition>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.button {
|
|
||||||
@apply flex-grow-0;
|
|
||||||
|
|
||||||
pointer-events: auto;
|
|
||||||
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
background-color: rgb(153 153 255 / 10%);
|
|
||||||
|
|
||||||
border: 1px solid rgb(153 153 255 / 60%);
|
|
||||||
border-radius: 0.5em;
|
|
||||||
|
|
||||||
opacity: 0.5;
|
|
||||||
|
|
||||||
transition: 0.3s ease;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ and you are as much of a perfectionist as I am, buckle up and prepare for severa
|
||||||
|
|
||||||
::card
|
::card
|
||||||
---
|
---
|
||||||
icon: warning
|
type: warning
|
||||||
title: Before we begin
|
title: Before we begin
|
||||||
---
|
---
|
||||||
Invoking `sfc /scannow` or `dism /restorehealth` will likely interfere with your context menu,
|
Invoking `sfc /scannow` or `dism /restorehealth` will likely interfere with your context menu,
|
||||||
|
@ -141,7 +141,7 @@ Children of the `Shell` subkey are the «shell entries» — locally provided cu
|
||||||
|
|
||||||
::card
|
::card
|
||||||
---
|
---
|
||||||
icon: info
|
type: info
|
||||||
title: Clearing up the confusion
|
title: Clearing up the confusion
|
||||||
---
|
---
|
||||||
The terminology may be a little confusing, since Microsoft hasn't ever offered a standard nomenclature for the
|
The terminology may be a little confusing, since Microsoft hasn't ever offered a standard nomenclature for the
|
||||||
|
@ -195,7 +195,7 @@ with an exception to the following two macros:
|
||||||
|
|
||||||
::card
|
::card
|
||||||
---
|
---
|
||||||
icon: error
|
type: error
|
||||||
title: Inconsistency
|
title: Inconsistency
|
||||||
---
|
---
|
||||||
Keep in mind that the `%1` macro is the Batch version of `argv[1]` — the first item in the C argument vector.
|
Keep in mind that the `%1` macro is the Batch version of `argv[1]` — the first item in the C argument vector.
|
||||||
|
@ -316,7 +316,7 @@ shell entry **do not seem to correspond**.
|
||||||
|
|
||||||
::card
|
::card
|
||||||
---
|
---
|
||||||
icon: idea
|
type: idea
|
||||||
title: Tip
|
title: Tip
|
||||||
---
|
---
|
||||||
You can use the Explorer folder icon picker to acquire the icon DLL and visually calculate the offset
|
You can use the Explorer folder icon picker to acquire the icon DLL and visually calculate the offset
|
||||||
|
@ -669,7 +669,7 @@ The following are fairly common areas Winaero Tweaker doesn't cover.
|
||||||
|
|
||||||
::card
|
::card
|
||||||
---
|
---
|
||||||
icon: idea
|
type: idea
|
||||||
title: Tip
|
title: Tip
|
||||||
---
|
---
|
||||||
As a rule of thumb, whenever you're dealing with existing shell entries, I _really_ suggest
|
As a rule of thumb, whenever you're dealing with existing shell entries, I _really_ suggest
|
||||||
|
|
|
@ -53,17 +53,18 @@ onMounted(() => {
|
||||||
class="dimensions accent-background transition-ease overflow-auto flex flex-col gap-4 lm:gap-0 sm:gap-2 py-2 px-6 sm:p-4"
|
class="dimensions accent-background transition-ease overflow-auto flex flex-col gap-4 lm:gap-0 sm:gap-2 py-2 px-6 sm:p-4"
|
||||||
:class="{
|
:class="{
|
||||||
'animate__animated-sm animate__delay-1-5s animate__fadeInDown':
|
'animate__animated-sm animate__delay-1-5s animate__fadeInDown':
|
||||||
!animationComplete,
|
!reader && !animationComplete,
|
||||||
|
'animate__animated-sm animate__fadeIn': reader && !animationComplete,
|
||||||
'lm:rounded-none sm:rounded-xl sm:mt-8 lm:mt-0 lt:mt-0': !reader,
|
'lm:rounded-none sm:rounded-xl sm:mt-8 lm:mt-0 lt:mt-0': !reader,
|
||||||
'!max-h-full h-full': reader,
|
'!max-h-full h-full': reader,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<Settings v-if="animationComplete" />
|
<Settings />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<slot name="header" />
|
<slot name="header" />
|
||||||
<NuxtPage
|
<NuxtPage
|
||||||
class="sm:fade-mask flex-grow overflow-y-auto h-full sm:py-4 sm:pe-4"
|
class="sm:fade-mask flex-grow overflow-y-auto h-full sm:py-4 sm:pe-4"
|
||||||
/>
|
/>
|
||||||
<slot v-if="animationComplete" name="footer" />
|
<slot name="footer" />
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default defineNuxtRouteMiddleware((to, _from) => {
|
export default defineNuxtRouteMiddleware((to, from) => {
|
||||||
const { reader } = storeToRefs(usePageStore())
|
const { reader } = storeToRefs(usePageStore())
|
||||||
|
|
||||||
reader.value = /\/blog\/(.*)/.test(to.path)
|
reader.value = /\/blog\/(.*)/.test(to.path)
|
||||||
|
|
138
nuxt.config.ts
138
nuxt.config.ts
|
@ -1,35 +1,35 @@
|
||||||
import config from "./config";
|
import config from './config'
|
||||||
|
|
||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: config.locale || "en",
|
lang: config.locale || 'en',
|
||||||
},
|
},
|
||||||
link: [
|
link: [
|
||||||
{
|
{
|
||||||
rel: "icon",
|
rel: 'icon',
|
||||||
type: "image/x-icon",
|
type: 'image/x-icon',
|
||||||
href: "/favicon.ico",
|
href: '/favicon.ico',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
charset: "utf-8",
|
charset: 'utf-8',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "viewport",
|
name: 'viewport',
|
||||||
content: "width=device-width, initial-scale=1",
|
content: 'width=device-width, initial-scale=1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"http-equiv": "X-UA-Compatible",
|
'http-equiv': 'X-UA-Compatible',
|
||||||
content: "ie=edge",
|
content: 'ie=edge',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
pageTransition: { name: "page", mode: "out-in" },
|
pageTransition: { name: 'page', mode: 'out-in' },
|
||||||
rootId: "ender-app",
|
rootId: 'ender-app',
|
||||||
},
|
},
|
||||||
devtools: {
|
devtools: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -43,64 +43,68 @@ export default defineNuxtConfig({
|
||||||
components: {
|
components: {
|
||||||
dirs: [
|
dirs: [
|
||||||
{
|
{
|
||||||
path: "~/components",
|
path: '~/components',
|
||||||
pathPrefix: false,
|
pathPrefix: false,
|
||||||
extensions: [".vue"],
|
extensions: ['.vue'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
css: ["~/assets/styles/main.scss"],
|
css: ['~/assets/styles/main.scss'],
|
||||||
plugins: [],
|
plugins: [],
|
||||||
modules: [
|
modules: [
|
||||||
"@pinia/nuxt",
|
'@pinia/nuxt',
|
||||||
"@nuxt/content",
|
'@nuxt/content',
|
||||||
"@nuxtjs/seo",
|
'@nuxtjs/seo',
|
||||||
"@nuxtjs/google-fonts",
|
'@nuxtjs/google-fonts',
|
||||||
"@nuxtjs/tailwindcss",
|
'@nuxtjs/tailwindcss',
|
||||||
"@nuxtjs/color-mode",
|
'@nuxtjs/color-mode',
|
||||||
"@nuxt/eslint",
|
'@nuxt/eslint',
|
||||||
["@nuxtjs/stylelint-module", { failOnError: true, lintOnStart: false }],
|
['@nuxtjs/stylelint-module', { failOnError: true, lintOnStart: false }],
|
||||||
],
|
],
|
||||||
colorMode: {
|
colorMode: {
|
||||||
preference: "system",
|
preference: 'system',
|
||||||
fallback: "dark",
|
fallback: 'dark',
|
||||||
classPrefix: "",
|
classPrefix: '',
|
||||||
classSuffix: "",
|
classSuffix: '',
|
||||||
componentName: "NuxtTheme",
|
componentName: 'NuxtTheme',
|
||||||
storageKey: "ecmatheme",
|
storageKey: 'ecmatheme',
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
markdown: {
|
markdown: {
|
||||||
remarkPlugins: ["remark-reading-time"],
|
remarkPlugins: ['remark-reading-time'],
|
||||||
},
|
},
|
||||||
highlight: {
|
highlight: {
|
||||||
theme: "github-dark",
|
theme: {
|
||||||
|
default: 'github-dark',
|
||||||
|
light: 'github-light',
|
||||||
|
sepia: 'monokai',
|
||||||
|
},
|
||||||
langs: [
|
langs: [
|
||||||
"shell",
|
'shell',
|
||||||
"batch",
|
'batch',
|
||||||
"vb",
|
'vb',
|
||||||
"ini",
|
'ini',
|
||||||
"asm",
|
'asm',
|
||||||
"c",
|
'c',
|
||||||
"cpp",
|
'cpp',
|
||||||
"java",
|
'java',
|
||||||
"python",
|
'python',
|
||||||
"csv",
|
'csv',
|
||||||
"xml",
|
'xml',
|
||||||
"json",
|
'json',
|
||||||
"yaml",
|
'yaml',
|
||||||
"html",
|
'html',
|
||||||
"css",
|
'css',
|
||||||
"sass",
|
'sass',
|
||||||
"php",
|
'php',
|
||||||
"js",
|
'js',
|
||||||
"ts",
|
'ts',
|
||||||
"vue",
|
'vue',
|
||||||
"md",
|
'md',
|
||||||
"mdc",
|
'mdc',
|
||||||
"pascal",
|
'pascal',
|
||||||
"lisp",
|
'lisp',
|
||||||
"sql",
|
'sql',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -109,7 +113,7 @@ export default defineNuxtConfig({
|
||||||
crawlLinks: true,
|
crawlLinks: true,
|
||||||
autoSubfolderIndex: true,
|
autoSubfolderIndex: true,
|
||||||
failOnError: true,
|
failOnError: true,
|
||||||
routes: ["/robots.txt", "/sitemap.xml"],
|
routes: ['/robots.txt', '/sitemap.xml'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
googleFonts: {
|
googleFonts: {
|
||||||
|
@ -160,22 +164,22 @@ export default defineNuxtConfig({
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
sitemap: {
|
sitemap: {
|
||||||
sources: ["/api/__sitemap__/content"],
|
sources: ['/api/__sitemap__/content'],
|
||||||
cacheMaxAgeSeconds: 360,
|
cacheMaxAgeSeconds: 360,
|
||||||
exclude: [],
|
exclude: [],
|
||||||
credits: false,
|
credits: false,
|
||||||
xslColumns: [
|
xslColumns: [
|
||||||
{ label: "URL", width: "50%" },
|
{ label: 'URL', width: '50%' },
|
||||||
{ label: "Last Modified", select: "sitemap:lastmod", width: "25%" },
|
{ label: 'Last Modified', select: 'sitemap:lastmod', width: '25%' },
|
||||||
{ label: "Priority", select: "sitemap:priority", width: "12.5%" },
|
{ label: 'Priority', select: 'sitemap:priority', width: '12.5%' },
|
||||||
{
|
{
|
||||||
label: "Change Frequency",
|
label: 'Change Frequency',
|
||||||
select: "sitemap:changefreq",
|
select: 'sitemap:changefreq',
|
||||||
width: "12.5%",
|
width: '12.5%',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
defaults: {
|
defaults: {
|
||||||
changefreq: "yearly",
|
changefreq: 'yearly',
|
||||||
priority: 0.7,
|
priority: 0.7,
|
||||||
lastmod: config.build.date,
|
lastmod: config.build.date,
|
||||||
},
|
},
|
||||||
|
@ -194,7 +198,7 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
vue: {
|
vue: {
|
||||||
compilerOptions: {
|
compilerOptions: {
|
||||||
isCustomElement: (tag) => tag === "iconify-icon",
|
isCustomElement: (tag) => tag === 'iconify-icon',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { render } from 'vue'
|
||||||
import { CodeControls } from '#components'
|
import { CodeControls } from '#components'
|
||||||
|
|
||||||
const config = useAppConfig()
|
const config = useAppConfig()
|
||||||
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
let slug = route.params.slug
|
let slug = route.params.slug
|
||||||
|
@ -40,13 +41,11 @@ useSeoMeta({
|
||||||
|
|
||||||
const clipboard = (el: HTMLElement) => {
|
const clipboard = (el: HTMLElement) => {
|
||||||
if (el.textContent)
|
if (el.textContent)
|
||||||
navigator.clipboard
|
navigator.clipboard.writeText(el.textContent).catch(() => {
|
||||||
.writeText(el.textContent)
|
console.error(
|
||||||
.then(() => {
|
'Failed to copy element data to the clipboard! Element data:',
|
||||||
alert(`successfully copied ${el.textContent}`)
|
el,
|
||||||
})
|
)
|
||||||
.catch(() => {
|
|
||||||
alert('something went wrong')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +72,11 @@ defineOgImageComponent(
|
||||||
|
|
||||||
// Hydrate the rendered items.
|
// Hydrate the rendered items.
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
if (route.hash)
|
||||||
|
content.value
|
||||||
|
?.querySelector(route.hash.toLowerCase())
|
||||||
|
?.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
|
||||||
content.value
|
content.value
|
||||||
?.querySelectorAll('code:not(pre *)')
|
?.querySelectorAll('code:not(pre *)')
|
||||||
.forEach((code: Element) => {
|
.forEach((code: Element) => {
|
||||||
|
@ -80,10 +84,27 @@ onMounted(() => {
|
||||||
code.addEventListener('click', () => clipboard(code))
|
code.addEventListener('click', () => clipboard(code))
|
||||||
})
|
})
|
||||||
|
|
||||||
content.value?.querySelectorAll('pre').forEach((pre: HTMLElement) => {
|
content.value?.querySelectorAll('pre').forEach((pre: HTMLPreElement) => {
|
||||||
const icon = h(CodeControls)
|
const overlay = h(CodeControls, { onCopy: () => clipboard(pre) })
|
||||||
|
|
||||||
render(icon, pre)
|
render(overlay, pre)
|
||||||
|
})
|
||||||
|
|
||||||
|
content.value?.querySelectorAll('a').forEach((a: HTMLAnchorElement) => {
|
||||||
|
if (
|
||||||
|
a.hash &&
|
||||||
|
a.host === window.location.host &&
|
||||||
|
a.pathname.toLowerCase() === route.path.toLowerCase()
|
||||||
|
)
|
||||||
|
a.addEventListener('click', (e: Event) => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
content.value
|
||||||
|
?.querySelector(a.hash.toLowerCase())
|
||||||
|
?.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
|
||||||
|
history.replaceState(history.state, '', a.hash)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -117,7 +138,7 @@ useHead({
|
||||||
</div>
|
</div>
|
||||||
<article
|
<article
|
||||||
v-else-if="data"
|
v-else-if="data"
|
||||||
class="flex-grow post snap-normal fade-mask-sm flex flex-col gap-4 overflow-x-hidden overflow-y-auto sm:py-4 sm:pe-4"
|
class="flex-grow post snap-normal fade-mask-sm flex flex-col gap-4 overflow-y-auto sm:py-4 sm:pe-4"
|
||||||
>
|
>
|
||||||
<div class="grid-thumbnail grid max-w-[768px] snap-end">
|
<div class="grid-thumbnail grid max-w-[768px] snap-end">
|
||||||
<img
|
<img
|
||||||
|
|
|
@ -20,6 +20,14 @@ export default <Partial<Config>>{
|
||||||
raw: '(max-height: 996px) and (min-width: 601px) and (max-width: 1280px)',
|
raw: '(max-height: 996px) and (min-width: 601px) and (max-width: 1280px)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
colors: {
|
||||||
|
warning: '#FFF693',
|
||||||
|
error: '#FF7171',
|
||||||
|
info: '#5EA2FF',
|
||||||
|
help: '#B268FF',
|
||||||
|
checkmark: '#45FFFF',
|
||||||
|
idea: '#FFFFFF',
|
||||||
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: [
|
sans: [
|
||||||
'Lato',
|
'Lato',
|
||||||
|
|
Loading…
Reference in New Issue