Browse Source

Start work on dark-mode, fix heading scroll position

master
Riyyi 3 weeks ago
parent
commit
86e08604dd
  1. 72
      content/articles/first.md
  2. 9
      nuxt.config.ts
  3. 25
      package-lock.json
  4. 3
      package.json
  5. 2
      src/app.vue
  6. 4
      src/assets/css/style.css
  7. 2
      src/components.d.ts
  8. 10
      src/components/Shared/NavMenu.vue
  9. 23
      src/components/ToggleColorMode.vue
  10. 18
      src/components/content/ProseH1.vue
  11. 18
      src/components/content/ProseH2.vue
  12. 18
      src/components/content/ProseH3.vue
  13. 18
      src/components/content/ProseH4.vue
  14. 18
      src/components/content/ProseH5.vue
  15. 18
      src/components/content/ProseH6.vue
  16. 1
      src/layouts/default.vue
  17. 15
      src/pages/articles/[slug].vue
  18. 16
      src/stores/stateStore.ts

72
content/articles/first.md

@ -7,41 +7,6 @@ description: "This is a test article."
This is a test article. This is a test article.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum a tempor
dolor. Nullam mattis sapien vel finibus dignissim. Etiam et diam ultrices,
aliquam enim nec, commodo sem. Cras ut faucibus risus. Suspendisse vel faucibus
ipsum. Duis vel orci nec arcu porttitor fermentum eu quis est. Phasellus elit
odio, elementum ac placerat at, feugiat sit amet sapien.
Vestibulum dapibus pharetra metus. Integer volutpat lacus nec enim euismod, id
dignissim felis rhoncus. Cras commodo tempus turpis, eu vehicula mi lacinia
eget. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Integer rhoncus dolor ut dolor gravida vestibulum. Ut
dignissim orci a ornare ullamcorper. Nam facilisis mauris sit amet nunc
fermentum pretium. Nullam in nisi at risus luctus viverra. Mauris non congue
dolor, vel finibus lectus. Nam quis leo pretium, sodales augue et, dictum sem.
Curabitur velit ante, imperdiet in eros eu, iaculis gravida risus. Nullam ut
feugiat eros, viverra vehicula sem. Aliquam finibus mi magna, eu fringilla
tellus ullamcorper vel. Fusce eget auctor mi. Mauris venenatis pellentesque
arcu. Nam ac diam sem. Nulla suscipit sed risus non vehicula. Cras molestie
lectus et tincidunt tempor. Ut tempus lorem id augue semper convallis. Aliquam
vel dui quis dolor cursus faucibus eget a mi. Curabitur tempus justo diam, a
facilisis ligula tincidunt viverra. Donec sodales quis dolor at dignissim.
Nullam placerat vitae urna quis bibendum.
Integer a magna a velit bibendum mollis. Donec lobortis molestie diam at rutrum.
Nunc viverra gravida metus at facilisis. Nulla sit amet erat sodales, commodo
elit sed, ultrices magna. Aliquam vel purus fringilla, gravida enim quis,
aliquam augue. Duis interdum et erat nec feugiat. Praesent vitae lacinia leo,
non suscipit purus.
Aenean massa magna, imperdiet id ex quis, mollis auctor lectus. Cras velit
nulla, volutpat eu neque id, semper venenatis urna. Integer in blandit ex, non
scelerisque nisi. Ut sagittis tincidunt enim at volutpat. Sed hendrerit metus ac
interdum laoreet. In rutrum turpis in nulla vulputate suscipit. Nunc dictum nisl
id magna laoreet dapibus.
## Component Rendering ## Component Rendering
::ExampleComponent ::ExampleComponent
@ -78,3 +43,40 @@ Inline highlight with language `const code: string = 'highlighted code inline'`{
- An - An
- Unordered - Unordered
- List - List
## Heading With No Subheading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum a tempor
dolor. Nullam mattis sapien vel finibus dignissim. Etiam et diam ultrices,
aliquam enim nec, commodo sem. Cras ut faucibus risus. Suspendisse vel faucibus
ipsum. Duis vel orci nec arcu porttitor fermentum eu quis est. Phasellus elit
odio, elementum ac placerat at, feugiat sit amet sapien.
Vestibulum dapibus pharetra metus. Integer volutpat lacus nec enim euismod, id
dignissim felis rhoncus. Cras commodo tempus turpis, eu vehicula mi lacinia
eget. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Integer rhoncus dolor ut dolor gravida vestibulum. Ut
dignissim orci a ornare ullamcorper. Nam facilisis mauris sit amet nunc
fermentum pretium. Nullam in nisi at risus luctus viverra. Mauris non congue
dolor, vel finibus lectus. Nam quis leo pretium, sodales augue et, dictum sem.
Curabitur velit ante, imperdiet in eros eu, iaculis gravida risus. Nullam ut
feugiat eros, viverra vehicula sem. Aliquam finibus mi magna, eu fringilla
tellus ullamcorper vel. Fusce eget auctor mi. Mauris venenatis pellentesque
arcu. Nam ac diam sem. Nulla suscipit sed risus non vehicula. Cras molestie
lectus et tincidunt tempor. Ut tempus lorem id augue semper convallis. Aliquam
vel dui quis dolor cursus faucibus eget a mi. Curabitur tempus justo diam, a
facilisis ligula tincidunt viverra. Donec sodales quis dolor at dignissim.
Nullam placerat vitae urna quis bibendum.
Integer a magna a velit bibendum mollis. Donec lobortis molestie diam at rutrum.
Nunc viverra gravida metus at facilisis. Nulla sit amet erat sodales, commodo
elit sed, ultrices magna. Aliquam vel purus fringilla, gravida enim quis,
aliquam augue. Duis interdum et erat nec feugiat. Praesent vitae lacinia leo,
non suscipit purus.
Aenean massa magna, imperdiet id ex quis, mollis auctor lectus. Cras velit
nulla, volutpat eu neque id, semper venenatis urna. Integer in blandit ex, non
scelerisque nisi. Ut sagittis tincidunt enim at volutpat. Sed hendrerit metus ac
interdum laoreet. In rutrum turpis in nulla vulputate suscipit. Nunc dictum nisl
id magna laoreet dapibus.

9
nuxt.config.ts

@ -4,6 +4,9 @@ import ViteComponents from "unplugin-vue-components/vite"
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
bootstrapVueNext: {
css: false
},
compatibilityDate: "2024-11-01", compatibilityDate: "2024-11-01",
content: { content: {
build: { build: {
@ -14,12 +17,18 @@ export default defineNuxtConfig({
// https://github.com/shikijs/shiki/blob/main/packages/langs/package.json // https://github.com/shikijs/shiki/blob/main/packages/langs/package.json
"c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "shell", "ts", "vue", "yaml" "c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "shell", "ts", "vue", "yaml"
] ]
},
toc: {
title: "Table of Contents",
depth: 4, // include h4 headings
searchDepth: 2
} }
} }
} }
}, },
css: [ css: [
"bootstrap/dist/css/bootstrap.min.css", "bootstrap/dist/css/bootstrap.min.css",
"bootstrap-vue-next/dist/bootstrap-vue-next.css",
"~/assets/css/style.css" "~/assets/css/style.css"
], ],
devtools: { enabled: true }, devtools: { enabled: true },

25
package-lock.json generated

@ -16,8 +16,9 @@
}, },
"devDependencies": { "devDependencies": {
"@bootstrap-vue-next/nuxt": "^0.28.3", "@bootstrap-vue-next/nuxt": "^0.28.3",
"@iconify-json/bi": "^1.2.2",
"@iconify-json/fa": "^1.2.1", "@iconify-json/fa": "^1.2.1",
"@iconify-json/fa-regular": "^1.2.1",
"@iconify-json/fa-solid": "^1.2.1",
"@nuxt/content": "^3.4.0", "@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.2.0", "@nuxt/eslint": "^1.2.0",
"@types/bun": "latest", "@types/bun": "latest",
@ -932,18 +933,30 @@
"url": "https://github.com/sponsors/nzakas" "url": "https://github.com/sponsors/nzakas"
} }
}, },
"node_modules/@iconify-json/bi": { "node_modules/@iconify-json/fa": {
"version": "1.2.2", "version": "1.2.1",
"dev": true, "dev": true,
"license": "MIT", "license": "OFL-1.1",
"dependencies": { "dependencies": {
"@iconify/types": "*" "@iconify/types": "*"
} }
}, },
"node_modules/@iconify-json/fa": { "node_modules/@iconify-json/fa-regular": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@iconify-json/fa-regular/-/fa-regular-1.2.1.tgz",
"integrity": "sha512-wKuHQchlr/zEd/Dl0ckEaWzgEXkWDs8zm5MczCX4Z7Ysd4xo9Iqk1t1EMJi3RtjrTE8Eh0s+PyHccH6qvZbNyQ==",
"dev": true, "dev": true,
"license": "OFL-1.1", "license": "CC-BY-4.0",
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify-json/fa-solid": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@iconify-json/fa-solid/-/fa-solid-1.2.1.tgz",
"integrity": "sha512-eEcnCb6yjRJ0bZrQQZOvO9P5PYCGujz2V8PpiIxBSlm6xqoVLNtOfUyPr6xZD4zWeW7H3cmWi2ZXSzqxQ5e4lw==",
"dev": true,
"license": "CC-BY-4.0",
"dependencies": { "dependencies": {
"@iconify/types": "*" "@iconify/types": "*"
} }

3
package.json

@ -19,8 +19,9 @@
}, },
"devDependencies": { "devDependencies": {
"@bootstrap-vue-next/nuxt": "^0.28.3", "@bootstrap-vue-next/nuxt": "^0.28.3",
"@iconify-json/bi": "^1.2.2",
"@iconify-json/fa": "^1.2.1", "@iconify-json/fa": "^1.2.1",
"@iconify-json/fa-regular": "^1.2.1",
"@iconify-json/fa-solid": "^1.2.1",
"@nuxt/content": "^3.4.0", "@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.2.0", "@nuxt/eslint": "^1.2.0",
"@types/bun": "latest", "@types/bun": "latest",

2
src/app.vue

@ -7,7 +7,7 @@
<script setup lang="ts"> <script setup lang="ts">
useHead({ useHead({
titleTemplate: (titleChunk) => { titleTemplate: (titleChunk: string): string => {
return titleChunk ? `${titleChunk} - website-vue` : 'website-vue'; return titleChunk ? `${titleChunk} - website-vue` : 'website-vue';
} }
}) })

4
src/assets/css/style.css

@ -15,10 +15,6 @@ body {
background-color: #f4f4f4; background-color: #f4f4f4;
} }
nav {
box-shadow: 0 .25rem .5rem rgba(0,0,0,.28) !important;
}
/* Main content */ /* Main content */
/*----------------------------------------*/ /*----------------------------------------*/

2
src/components.d.ts vendored

@ -21,6 +21,8 @@ declare module 'vue' {
IFaHome: typeof import('~icons/fa/home')['default'] IFaHome: typeof import('~icons/fa/home')['default']
IFaLink: typeof import('~icons/fa/link')['default'] IFaLink: typeof import('~icons/fa/link')['default']
IFaLinkedinSquare: typeof import('~icons/fa/linkedin-square')['default'] IFaLinkedinSquare: typeof import('~icons/fa/linkedin-square')['default']
IFaMoonO: typeof import('~icons/fa/moon-o')['default']
IFaSolidSun: typeof import('~icons/fa-solid/sun')['default']
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default'] IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']

10
src/components/Shared/NavMenu.vue

@ -28,3 +28,13 @@
</BCollapse> </BCollapse>
</BNavbar> </BNavbar>
</template> </template>
<style scoped>
nav {
box-shadow: 0 .25rem .5rem rgba(0, 0, 0, .28);
}
[data-bs-theme=dark] nav {
box-shadow: 0 .25rem .5rem rgba(255, 0, 0, .28);
}
</style>

23
src/components/ToggleColorMode.vue

@ -0,0 +1,23 @@
<template>
<div class="position-fixed corner">
<template v-if="store.colorMode === 'dark'">
<IFaSolidSun @click="store.toggleColorMode" />
</template>
<template v-else>
<IFaMoonO @click="store.toggleColorMode" />
</template>
</div>
</template>
<style scoped>
.corner {
right: 10px;
bottom: 10px;
}
</style>
<script setup lang="ts">
import { useStateStore } from "@/stores/stateStore";
const store = useStateStore();
</script>

18
src/components/content/ProseH1.vue

@ -0,0 +1,18 @@
<template>
<h1>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h1>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h1)))
</script>

18
src/components/content/ProseH2.vue

@ -0,0 +1,18 @@
<template>
<h2>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h2>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h2)))
</script>

18
src/components/content/ProseH3.vue

@ -0,0 +1,18 @@
<template>
<h3>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h3>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h3)))
</script>

18
src/components/content/ProseH4.vue

@ -0,0 +1,18 @@
<template>
<h4>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h4>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h4)))
</script>

18
src/components/content/ProseH5.vue

@ -0,0 +1,18 @@
<template>
<h5>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h5>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h5)))
</script>

18
src/components/content/ProseH6.vue

@ -0,0 +1,18 @@
<template>
<h6>
<span :id="props.id"></span>
<a v-if="props.id && generate" :href="`#${props.id}`">
<slot />
</a>
<slot v-else />
</h6>
</template>
<script setup lang="ts">
import { computed, useRuntimeConfig } from "#imports"
const props = defineProps<{ id?: string }>()
const { headings } = useRuntimeConfig().public.mdc
const generate = computed(() => props.id && ((typeof headings?.anchorLinks === "boolean" && headings?.anchorLinks === true) || (typeof headings?.anchorLinks === "object" && headings?.anchorLinks?.h6)))
</script>

1
src/layouts/default.vue

@ -10,4 +10,5 @@
</div> </div>
<SharedFooter /> <SharedFooter />
</div> </div>
<ToggleColorMode />
</template> </template>

15
src/pages/articles/[slug].vue

@ -15,8 +15,19 @@
<style scoped> <style scoped>
/* Target element in child components with :deep */ /* Target element in child components with :deep */
/* Select any <h> */
:deep(:is(h1, h2, h3, h4, h5, h6):has(span)) {
position: relative;
}
/* Select any <span> inside a <h> */
:deep(:is(h1, h2, h3, h4, h5, h6) span) {
position: absolute;
top: -65px;
}
/* Select any <a> inside a <h> */ /* Select any <a> inside a <h> */
:deep(:is(h1, h2, h3, h4, h5, h6) > a) { :deep(:is(h1, h2, h3, h4, h5, h6) a) {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
@ -50,8 +61,6 @@
<script setup lang="ts"> <script setup lang="ts">
const { params } = useRoute(); const { params } = useRoute();
console.log(params);
const { data: article } = await useAsyncData( const { data: article } = await useAsyncData(
`article-${params.slug}`, `article-${params.slug}`,
() => queryCollection("content").path("/articles/" + params.slug).first() () => queryCollection("content").path("/articles/" + params.slug).first()

16
src/stores/stateStore.ts

@ -0,0 +1,16 @@
import { defineStore } from "pinia"
import { ref } from "vue";
export const useStateStore = defineStore("state", () => {
const colorMode = ref<string>("light");
const toggleColorMode = (): void => {
colorMode.value = colorMode.value === "dark" ? "light" : "dark";
const html = document.querySelector("html") as HTMLElement;
html.setAttribute('data-bs-theme', colorMode.value);
};
return { colorMode, toggleColorMode }
}, {
persist: process.env.NODE_ENV === 'development' ? true : false,
})
Loading…
Cancel
Save