mirror of
https://github.com/bdnugget/alpine-chemistry.git
synced 2026-11-07 03:17:27 +00:00
feat: back-to-top and article badges (#122)
Co-authored-by: Yaël Guilloux <yael.guilloux@gmail.com>
This commit is contained in:
1 parent
52dd186841
commit
6584e87155
9 files changed
+711
-202
No files matched your search
@@ -87,6 +87,12 @@ defineAppConfig({
|
||||
navigation: false, // possible value are : true | false
|
||||
position: 'center', // possible value are : 'none' | 'left' | 'center' | 'right'
|
||||
message: 'Follow me on' // string that will be displayed on the footer (leave empty or delete to disable)
|
||||
}
|
||||
// Disable back to top button: false
|
||||
backToTop: {
|
||||
text: 'Back to top',
|
||||
icon: 'material-symbols:arrow-upward'
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
@@ -91,6 +91,22 @@ description: Another description
|
||||
|
||||
You are now ready to edit your article and create new ones!
|
||||
|
||||
## Optional Arguments
|
||||
|
||||
In the frontmatter block, you can pass additional options for displaying your article, such as displaying badges on the image:
|
||||
|
||||
```md
|
||||
---
|
||||
cover: path/to/cover
|
||||
date: 2022-08-23
|
||||
badges: [{
|
||||
color: 'white',
|
||||
bg: 'rgba(0, 0, 0, 0.3)',
|
||||
content: 'Technology'
|
||||
}]
|
||||
---
|
||||
```
|
||||
|
||||
## Read more
|
||||
|
||||
Alpine is a Nuxt theme using the Content module in `documentDriven` mode.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"nuxt": "^3.4.3",
|
||||
"nuxt": "^3.5.0",
|
||||
"@nuxt-themes/alpine": "^1.5.4",
|
||||
"@nuxtjs/plausible": "^0.2.1",
|
||||
"@nuxt/devtools": "^0.4.6",
|
||||
|
||||
@@ -36,6 +36,10 @@ export default defineAppConfig({
|
||||
},
|
||||
form: {
|
||||
successMessage: 'Message sent. Thank you!'
|
||||
},
|
||||
backToTop: {
|
||||
text: 'Back to top',
|
||||
icon: 'material-symbols:arrow-upward'
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -6,6 +6,7 @@ type Article = {
|
||||
title: string
|
||||
date: string
|
||||
description: string
|
||||
badges?: { bg: string, text: string, content: string }[]
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
@@ -30,15 +31,40 @@ const id = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article v-if="article._path && article.title" :class="{ 'featured': featured }" :data-content-id="id">
|
||||
<article
|
||||
v-if="article._path && article.title"
|
||||
:class="{ 'featured': featured }"
|
||||
:data-content-id="id"
|
||||
>
|
||||
<div class="image">
|
||||
<div v-if="article?.badges">
|
||||
<span
|
||||
v-for="(badge, index) in article.badges"
|
||||
:key="index"
|
||||
:style="{
|
||||
backgroundColor: badge?.bg || 'rgba(0, 0, 0, 0.3)',
|
||||
color: badge?.color || 'white'
|
||||
}"
|
||||
>
|
||||
{{ typeof badge === 'string' ? badge : badge.content }}
|
||||
</span>
|
||||
</div>
|
||||
<NuxtLink :to="article._path">
|
||||
<NuxtImg v-if="article.cover" :src="article.cover" :alt="article.title" width="16" height="9" />
|
||||
<NuxtImg
|
||||
v-if="article.cover"
|
||||
:src="article.cover"
|
||||
:alt="article.title"
|
||||
width="16"
|
||||
height="9"
|
||||
/>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<NuxtLink :to="article._path" class="headline">
|
||||
<NuxtLink
|
||||
:to="article._path"
|
||||
class="headline"
|
||||
>
|
||||
<h1>
|
||||
{{ article.title }}
|
||||
</h1>
|
||||
@@ -74,6 +100,20 @@ css({
|
||||
},
|
||||
'.image': {
|
||||
flex: 1,
|
||||
div: {
|
||||
position: 'absolute',
|
||||
display: 'flex',
|
||||
flexWrap: true,
|
||||
gap: '{space.2}',
|
||||
marginTop: '{space.2}',
|
||||
marginLeft: '{space.2}',
|
||||
span: {
|
||||
padding: '{space.1}',
|
||||
borderRadius: '{radii.sm}',
|
||||
text: 'xs',
|
||||
fontWeight: 700
|
||||
}
|
||||
}
|
||||
},
|
||||
'.content': {
|
||||
display: 'flex',
|
||||
|
||||
+43
-6
@@ -1,23 +1,41 @@
|
||||
<template>
|
||||
<article>
|
||||
<article ref="article">
|
||||
<!-- TODO: could be refactored as a transparent ButtonLink -->
|
||||
<NuxtLink :to="parentPath" class="back">
|
||||
<NuxtLink
|
||||
:to="parentPath"
|
||||
class="back"
|
||||
>
|
||||
<Icon name="ph:arrow-left" />
|
||||
<span class="text-primary-900 dark:text-primary-100">
|
||||
<span>
|
||||
Back
|
||||
</span>
|
||||
</NuxtLink>
|
||||
<header>
|
||||
<h1 v-if="page?.title" class="title">
|
||||
<h1
|
||||
v-if="page?.title"
|
||||
class="title"
|
||||
>
|
||||
{{ page.title }}
|
||||
</h1>
|
||||
<time v-if="page?.date" class="text-primary-700 dark:text-primary-400" :datetime="page.date">
|
||||
<time
|
||||
v-if="page?.date"
|
||||
:datetime="page.date"
|
||||
>
|
||||
{{ formatDate(page.date) }}
|
||||
</time>
|
||||
</header>
|
||||
|
||||
<div class="prose">
|
||||
<slot />
|
||||
<div
|
||||
v-if="alpine?.backToTop"
|
||||
class="back-to-top"
|
||||
>
|
||||
<ProseA @click.prevent.stop="onBackToTop">
|
||||
{{ alpine?.backToTop?.text || 'Back to top' }}
|
||||
<Icon :name="alpine?.backToTop?.icon || 'material-symbols:arrow-upward'" />
|
||||
</ProseA>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
@@ -25,6 +43,9 @@
|
||||
<script setup lang="ts">
|
||||
const { page } = useContent()
|
||||
const route = useRoute()
|
||||
const alpine = useAppConfig().alpine
|
||||
|
||||
const article = ref<HTMLElement | null>(null)
|
||||
|
||||
if (page.value && page.value.cover) {
|
||||
useHead({
|
||||
@@ -41,6 +62,12 @@ const parentPath = computed(
|
||||
return pathTabl.join('/')
|
||||
}
|
||||
)
|
||||
|
||||
const onBackToTop = () => {
|
||||
article.value?.scrollIntoView({
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="ts">
|
||||
@@ -77,9 +104,19 @@ css({
|
||||
color: '{elements.text.secondary.color.static}'
|
||||
},
|
||||
'.prose': {
|
||||
'.back-to-top': {
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
a: {
|
||||
cursor: 'pointer',
|
||||
fontSize: '{text.lg.fontSize}'
|
||||
}
|
||||
},
|
||||
'& :deep(h1)': {
|
||||
display: 'none'
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -169,6 +169,15 @@ export default defineNuxtSchema({
|
||||
* Success message.
|
||||
*/
|
||||
successMessage: 'Message sent. Thank you!'
|
||||
},
|
||||
/**
|
||||
* Back to top button configuration.
|
||||
*
|
||||
* @studioIcon material-symbols:arrow-upward
|
||||
*/
|
||||
backToTop: {
|
||||
icon: 'material-symbols:arrow-upward',
|
||||
text: 'Back to top',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -36,13 +36,13 @@
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint-config": "^0.1.1",
|
||||
"@nuxtjs/plausible": "^0.2.1",
|
||||
"@types/node": "^20.1.2",
|
||||
"@types/node": "^20.1.5",
|
||||
"eslint": "^8.40.0",
|
||||
"nuxt": "^3.4.3",
|
||||
"nuxt": "^3.5.0",
|
||||
"release-it": "^15.10.3",
|
||||
"typescript": "^5.0.4",
|
||||
"vite-plugin-inspect": "^0.7.26",
|
||||
"vue": "^3.2.47"
|
||||
"vue": "^3.3.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
|
||||
Generated
+586
-189
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user