Skip to content

Commit 87fe93a

Browse files
committed
feat: refactor NqCard and NqGrid components, update styles, and improve layout structure
1 parent 8cd06e7 commit 87fe93a

File tree

10 files changed

+116
-157
lines changed

10 files changed

+116
-157
lines changed

docs/vitepress-theme/components/card.md

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ A simple card that can turn any boring content into something that looks intenti
1717
The component also supports using slots for custom content instead of props.
1818

1919
> [!TIP]
20-
> Remember to [register `NqCard`](/vitepress-theme/#register-the-components) in your app. It's like introducing your components to a party - they need to be on the guest list!
20+
> Remember to [register `NqCard`](/vitepress-theme/#register-the-components) in your app.
2121
2222
## Examples
2323

@@ -74,21 +74,3 @@ The component also supports using slots for custom content instead of props.
7474
/>
7575

7676
</ComponentPreview>
77-
78-
## With Markdown Content
79-
80-
<ComponentPreview lang="vue">
81-
82-
<NqCard>
83-
84-
### The Markdown Card
85-
86-
I'm a card with markdown content. I can be used to display formatted text, lists, and even images!
87-
88-
- Item 1
89-
- Item 2
90-
- Item 3
91-
92-
</NqCard>
93-
94-
</ComponentPreview>

packages/nimiq-css/src/css/utilities.css

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
color: rgba(var(--nq-neutral-800));
66
}
77

8-
.nq-basic {
9-
font-size: 12px;
10-
color: pink;
11-
}
12-
138
.nq-label {
149
text-transform: uppercase;
1510
letter-spacing: 0.17em;
@@ -655,7 +650,7 @@
655650
background-image: radial-gradient(at 100% 100%, var(--nq-gradient-from) 0%, var(--nq-gradient-to) 100%);
656651
color: rgb(var(--nq-neutral));
657652
border-radius: 0.5rem;
658-
outline: 1.5px solid rgb(var(--nq-neutral) / 0.06);
653+
outline: 1.5px solid rgb(var(--nq-neutral) / 0.04);
659654
outline-offset: -1.5px;
660655
display: flex;
661656
flex-direction: column;

packages/nimiq-vitepress-theme/src/assets/typography.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.nq-prose {
2-
h1:not(.vp-raw *) {
2+
h1:not(.nq-raw *) {
33
--font-size-min: 32;
44
--font-size-max: 40;
55
margin-bottom: 1.5rem;
@@ -16,23 +16,23 @@
1616
}
1717
}
1818

19-
h2:not(.vp-raw *) {
19+
h2:not(.nq-raw *) {
2020
--font-size-min: 28;
2121
--font-size-max: 32;
2222
margin-bottom: 1rem;
2323
margin-top: 3rem;
2424
font-weight: 600;
2525
}
2626

27-
h3:not(.vp-raw *) {
27+
h3:not(.nq-raw *) {
2828
--font-size-min: 20;
2929
--font-size-max: 24;
3030
margin-bottom: 1rem;
3131
margin-top: 2.5rem;
3232
font-weight: 600;
3333
}
3434

35-
h4:not(.vp-raw *) {
35+
h4:not(.nq-raw *) {
3636
--font-size-min: 16;
3737
--font-size-max: 20;
3838
margin-bottom: 1rem;
Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
<script lang="ts">
2-
</script>
3-
4-
<script setup lang="ts">
5-
import { computed } from 'vue'
6-
72
export type CardColor = 'green' | 'blue' | 'red' | 'gold' | 'orange'
83
export interface NqCardProps {
94
icon?: string
@@ -13,6 +8,10 @@ export interface NqCardProps {
138
description?: string
149
label?: string
1510
}
11+
</script>
12+
13+
<script setup lang="ts">
14+
import { computed } from 'vue'
1615
1716
const { bgColor, icon, href } = defineProps<NqCardProps>()
1817
@@ -23,44 +22,20 @@ const colors: Partial<Record<CardColor, string>> = { blue: '#0E65C9', green: '#1
2322

2423
<template>
2524
<component
26-
:is="hasLink ? 'a' : 'div'" :href group :data-inverted="bgColor ? '' : undefined" class="nq-raw"
27-
f-mt-md relative :style="`background-image: ${bgColor ? `var(--nq-${bgColor}-gradient)` : ''}`" :data-card="bgColor ? 'colored' : 'default'"
25+
:is="hasLink ? 'a' : 'div'"
26+
:href class="nq-raw" group relative
27+
:style="`background-image: ${bgColor ? `var(--nq-${bgColor}-gradient)` : ''}`"
28+
:data-inverted="bgColor ? '' : undefined"
29+
:data-card="bgColor ? 'colored' : 'default'"
2830
:target="hasLink && href?.startsWith('http') ? '_blank' : undefined"
29-
:class="{ 'nq-hoverable': hasLink, 'nq-card': !hasLink, 'children:max-w-[max(50%,240px)]': bgColor, 'bg-neutral-300': !bgColor }"
31+
:class="[
32+
hasLink ? 'nq-hoverable' : 'nq-card',
33+
{ 'children:max-w-[max(50%,240px)]' : bgColor }
34+
]"
3035
>
3136
<div v-if="icon" :class="icon" f-size="~ max-160 min-120" absolute right--12 :style="`color: ${colors[bgColor!]}`" />
32-
<slot>
33-
<span nq-label>{{ label }}</span>
34-
<h2>{{ title }}</h2>
35-
<p>{{ description }}</p>
36-
</slot>
37+
<span nq-label text-12 mb-4 text="neutral-700 data-inverted:white/50" data-inverted:mb-8>{{ label }}</span>
38+
<h2 font-semibold f-text="xl data-inverted:2xl" data-inverted:text-white>{{ title }}</h2>
39+
<p text="data-inverted:white/60" data-inverted:f-text-lg data-inverted:mt-4>{{ description }}</p>
3740
</component>
3841
</template>
39-
40-
<style>
41-
@layer nq-vp {
42-
[data-card] {
43-
.nq-label {
44-
--uno: 'text-12 mb-4 text-neutral-700';
45-
}
46-
47-
:where(h2, h3, h4, h5, h6):not(.nq-label) {
48-
--uno: 'font-semibold f-text-xl ';
49-
}
50-
51-
[data-inverted] * {
52-
&.nq-label {
53-
--uno: 'text-white/50 mb-8';
54-
}
55-
56-
&:where(h2, h3, h4, h5, h6):not(.nq-label) {
57-
--uno: 'text-white f-text-2xl';
58-
}
59-
60-
&:where(p) {
61-
--uno: 'text-white/60 f-text-lg f-mt-4';
62-
}
63-
}
64-
}
65-
}
66-
</style>

packages/nimiq-vitepress-theme/src/components/NqGrid.vue

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,43 +9,40 @@ const { cards } = defineProps<{ cards?: NqCardInGrid[] }>()
99
function getSpan({ span, bgColor }: NqCardInGrid): CardSpan | undefined {
1010
if (span === undefined && bgColor)
1111
return 'half'
12-
return span
12+
return span || 'default'
1313
}
1414
</script>
1515

1616
<template>
1717
<ul grid="~ cols-6 gap-16" class="nq-grid nq-raw">
1818
<slot>
19-
<li v-for="(card, index) in cards" :key="index" data-card="default" :data-span="getSpan(card)">
19+
<li v-for="(card, index) in cards" :key="index" :data-span="getSpan(card)">
2020
<NqCard v-bind="card" />
2121
</li>
2222
</slot>
2323
</ul>
2424
</template>
2525

26-
<style>
27-
.nq-grid {
28-
[data-card='colored'] {
29-
--uno: 'col-span-3';
26+
<style scoped>
27+
ul.nq-grid {
28+
[data-span='full'] {
29+
--uno: 'col-span-6';
3030
}
3131
32-
[data-card='default'] {
33-
--uno: 'col-span-2';
32+
[data-span='half'] {
33+
--uno: 'col-span-3';
3434
}
3535
36-
[data-card='half'] {
36+
[data-span='default'] {
3737
--uno: 'col-span-2';
3838
}
3939
40-
[data-card][data-span='full'] {
41-
--uno: 'col-span-6';
40+
li {
41+
--uno: 'mt-0 flex';
4242
}
43+
}
4344
44-
[data-card][data-span='half'] {
45-
--uno: 'col-span-3';
46-
}
47-
[data-card] {
48-
--uno: 'mt-0';
49-
}
45+
:global(ul.nq-grid li > *) {
46+
--uno: 'flex-1';
5047
}
5148
</style>

packages/nimiq-vitepress-theme/src/components/NqLargeCard.vue

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,15 @@ const hasLink = computed(() => !!href)
1313

1414
<template>
1515
<component
16-
:is="hasLink ? 'a' : 'div'" :href group class="nq-raw" data-card="large"
17-
f-mt-md bg-neutral-300 relative flex="~ items-center col justify-center" f-p-xl
16+
:is="hasLink ? 'a' : 'div'"
17+
:href class="nq-raw" group bg-neutral-300 relative f-p-xl
18+
flex="~ items-center col justify-center"
19+
data-card="large"
1820
:target="hasLink && href?.startsWith('http') ? '_blank' : undefined"
1921
:class="{ 'nq-hoverable': hasLink, 'nq-card': !hasLink }"
2022
>
2123
<div :class="icon" f-size="~ max-64 min-80" mx-auto f-mb-lg op="70 group-hocus:100" transition-opacity />
22-
<slot>
23-
<h2>{{ title }}</h2>
24-
<p>{{ description }}</p>
25-
</slot>
24+
<h2 font-semibold f-text-2xl text-center>{{ title }}</h2>
25+
<p f-text-lg text-center text-neutral-800 f-mt-xs>{{ description }}</p>
2626
</component>
2727
</template>
28-
29-
<style scoped>
30-
:deep(:where(h2, h3, h4, h5, h6):not(.nq-label)) {
31-
--uno: 'font-semibold f-text-2xl text-center';
32-
}
33-
34-
:deep(p) {
35-
--uno: 'f-text-lg text-center text-neutral-800 f-mt-xs';
36-
}
37-
</style>

packages/nimiq-vitepress-theme/src/layout/Layout.vue

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,28 @@ const showSidebar = computed(() =>
1212
</script>
1313

1414
<template>
15-
<div flex="~" w-full>
15+
<div class="flex" id="viewport">
1616
<!-- TODO Add skip -->
17-
<Sidebar v-if="showSidebar" max-w="$nq-sidebar-width" data-sidebar />
17+
<Sidebar v-if="showSidebar" />
1818

19-
<main flex-1 min-h-screen ml="$nq-sidebar-width" max-w="[calc(100vw-var(--nq-sidebar-width))]">
19+
<main class="min-h-screen">
2020
<PageContent />
2121
</main>
2222
</div>
2323
</template>
2424

2525
<style>
26-
@propery --nq-sidebar-width {
27-
syntax: '<length>';
28-
initial-value: 0px;
26+
:root {
27+
--nq-sidebar-width: 288px;
2928
}
3029
31-
:root:has(sidebar[data-sidebar]) {
32-
--nq-sidebar-width: 288px;
30+
aside {
31+
width: var(--nq-sidebar-width);
32+
flex-shrink: 0;
33+
}
34+
35+
main {
36+
flex: 1;
37+
margin-left: var(--nq-sidebar-width);
3338
}
3439
</style>

packages/nimiq-vitepress-theme/src/layout/PageContent.vue

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import type { NimiqVitepressThemeConfig } from '../types'
55
import { useTimeAgo } from '@vueuse/core'
66
import { useData, useRoute } from 'vitepress'
77
import { computed, onMounted, ref, watch } from 'vue'
8-
import { useOutline } from '../composables/useOutline'
8+
import SecondarySidebar from './SecondarySidebar.vue'
99
import { data } from '../lib/git.data'
1010
import '../assets/code-blocks.css'
1111
import '../assets/typography.css'
1212
import '../assets/github-callouts.css'
1313
14-
const { theme, lang, frontmatter } = useData<NimiqVitepressThemeConfig>()
14+
const { theme, lang } = useData<NimiqVitepressThemeConfig>()
1515
1616
const route = useRoute()
1717
@@ -41,28 +41,6 @@ onMounted(() => {
4141
4242
const showEditContent = computed(() => theme.value.showEditContent !== false)
4343
const showLastUpdated = computed(() => theme.value.showLastUpdated !== false)
44-
45-
const { headingTree, isHeadingActive } = useOutline()
46-
47-
const showOutline = computed(() => {
48-
// Explicit setting in frontmatter takes precedence
49-
if (frontmatter.value.outline !== undefined)
50-
return !!frontmatter.value.outline
51-
// Default: show if there are headings
52-
return headingTree.value.length > 0
53-
})
54-
55-
const showWidget = computed(() =>
56-
frontmatter.value.widget !== false,
57-
)
58-
59-
const showSecondarySidebar = computed(() => {
60-
// Explicit setting in frontmatter takes precedence
61-
if (frontmatter.value.secondarySidebar !== undefined)
62-
return !!frontmatter.value.secondarySidebar
63-
// Default: show if there's content to display
64-
return showOutline.value || showWidget.value
65-
})
6644
</script>
6745

6846
<template>
@@ -97,26 +75,6 @@ const showSecondarySidebar = computed(() => {
9775
</p>
9876
</div>
9977
</div>
100-
<div v-if="showSecondarySidebar" f-text-xs sticky f="$h $h-min-60 $h-max-90" h="[calc(100vh-var(--f-h))]" f-top-xl f-px-sm w="[calc(var(--nq-sidebar-width)+24px)]" of-y-auto f-pb-xs>
101-
<div v-if="showOutline" text-neutral-700 flex="~ gap-8 items-center">
102-
<div i-tabler:align-left />
103-
On this page
104-
</div>
105-
<ol v-if="showOutline" list-none f-mt-xs text-neutral-800 w-max>
106-
<li v-for="h2 in headingTree" :key="h2.hashPath" flex="~ col" pb-4>
107-
<a :href="`#${h2.hashPath}`" px-6 py-4 :class="{ 'text-blue font-semibold': isHeadingActive(h2.hashPath) }">{{ h2.text
108-
}}</a>
109-
<ol v-if="h2.items.length">
110-
<li v-for="h3 in h2.items" :key="h3.hashPath" flex="~ col">
111-
<a
112-
:href="`#${h3.hashPath}`" font-normal p-4 pl-14
113-
:class="{ 'text-blue font-semibold': isHeadingActive(h3.hashPath) }"
114-
>{{ h3.text }}</a>
115-
</li>
116-
</ol>
117-
</li>
118-
</ol>
119-
<div v-if="showWidget" id="widget" max-w-full :class="{ 'f-mt-md': showOutline }" h-full />
120-
</div>
78+
<SecondarySidebar />
12179
</div>
12280
</template>

0 commit comments

Comments
 (0)