Skip to content

Commit 1e0c7df

Browse files
committed
feat: mobile support!
1 parent b20126a commit 1e0c7df

File tree

16 files changed

+306
-124
lines changed

16 files changed

+306
-124
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@
4242
"json",
4343
"jsonc",
4444
"yaml"
45-
]
45+
],
46+
"unocss.include": []
4647
}

docs/.vitepress/theme/components/IconSet.vue

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,16 @@ function selectColor(c: Color) {
144144

145145
<ClientOnly>
146146
<Teleport to="#widget" defer>
147-
<div class="nq-raw" h-full f-pb-md flex="~ col">
148-
<header v-if="!selectedIcon" flex="col gap-16 items-start">
147+
<div class="nq-raw" h-full f-pb-md flex="~ col" max-md:f-p-xs of-y-auto>
148+
<header v-if="!selectedIcon" flex="~ md:col gap-16 items-start">
149149
<div stack f-p-md rounded-16 outline="dashed 3 offset--3 neutral-300" w-max>
150150
<div size-64 />
151151
</div>
152-
<p f-mt-sm f-text-xs pl-4 text-neutral-800 font-semibold>
152+
<p f-mt-sm f-text-xs pl-4 text-neutral-800 font-semibold shrink-0>
153153
Select an icon
154154
</p>
155155

156-
<div flex="~ items-center gap-12" f-mt-sm>
156+
<div flex="~ wrap items-center gap-12" f-mt-sm>
157157
<button
158158
v-for="c in colors" :key="c" shrink-0 size-21 rounded-full outline="~ 1 neutral/20"
159159
:data-active="activeColor === c ? '' : undefined"
@@ -168,7 +168,7 @@ function selectColor(c: Color) {
168168
</header>
169169
<template v-else>
170170
<header
171-
flex="col gap-16 items-start"
171+
flex="~ md:col gap-16 items-start"
172172
:style="`--c: rgb(var(--nq-${activeColor}));--c2: rgb(var(--nq-${activeColor}-400));`"
173173
>
174174
<div
@@ -182,25 +182,31 @@ function selectColor(c: Color) {
182182
>
183183
<Icon :icon="selectedIcon" text="$c" />
184184
</div>
185-
<div flex="~ items-center gap-12" f-mt-sm>
186-
<button
187-
v-for="c in colors" :key="c" shrink-0 size-21 rounded-full outline="~ 1 neutral/20"
188-
:data-active="activeColor === c ? '' : undefined"
189-
:class="{ 'op-30 hocus:op-80': c !== activeColor || (isLogo && !isMono) }" transition-colors
190-
:style="`background-color: rgba(var(--nq-${c}));`" @click="selectColor(c)"
191-
/>
192-
193-
<button v-if="isLogo" stack bg="neutral-500 data-active:neutral" text-neutral-0 size-21 transition-opacity aspect-square rounded-full :data-state="!isMono ? 'active' : ''" @click="rotateLogoIcon">
194-
<span block :class="isMono ? 'i-tabler:paint' : isWhite ? 'i-tabler:paint-off' : !hasWhite ? 'i-nimiq:moon' : 'i-tabler:paint-off'" />
195-
</button>
185+
<div>
186+
<div flex="~ items-center wrap gap-12" f-mt-sm>
187+
<button
188+
v-for="c in colors" :key="c" shrink-0 size-21 rounded-full outline="~ 1 neutral/20"
189+
:data-active="activeColor === c ? '' : undefined"
190+
:class="{ 'op-30 hocus:op-80': c !== activeColor || (isLogo && !isMono) }" transition-colors
191+
:style="`background-color: rgba(var(--nq-${c}));`" @click="selectColor(c)"
192+
/>
193+
194+
<button v-if="isLogo" stack bg="neutral-500 data-active:neutral" text-neutral-0 size-21 transition-opacity aspect-square rounded-full :data-state="!isMono ? 'active' : ''" @click="rotateLogoIcon">
195+
<span block :class="isMono ? 'i-tabler:paint' : isWhite ? 'i-tabler:paint-off' : !hasWhite ? 'i-nimiq:moon' : 'i-tabler:paint-off'" />
196+
</button>
197+
</div>
198+
199+
<p md:hidden mt-10 font-semibold>
200+
<CodeBlock text-13 :code="`i-${selectedIcon}`" />
201+
</p>
196202
</div>
197203
</header>
198204

199205
<template v-if="!missingLogoVariant">
200206
<p f-mt-md nq-label text="9 neutral-700">
201207
Copy as
202208
</p>
203-
<p mt-4 font-semibold>
209+
<p mt-4 font-semibold max-md:hidden>
204210
<CodeBlock text-13 :code="`i-${selectedIcon}`" />
205211
</p>
206212
<div flex="~ items-center gap-$f-gap" f-my-2xs f="$gap $gap-min-8 $gap-max-12">

packages/nimiq-icons/src/flags/icons.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@
12681268
"body": "<mask id=\"nimiq-flags-zw-hexagon-pbk987\" width=\"32\" height=\"28\" x=\"0\" y=\"2\" maskUnits=\"userSpaceOnUse\" style=\"mask-type:alpha\"><path fill=\"#fff\" d=\"M31.15 14.71 24.707 3.54a2.58 2.58 0 00-2.234-1.29H9.582c-.92 0-1.77.49-2.23 1.29L.907 14.71c-.46.8-.46 1.78 0 2.58l6.445 11.17c.46.8 1.31 1.29 2.23 1.29h12.89c.92 0 1.77-.49 2.23-1.29l6.445-11.17c.464-.8.464-1.78.004-2.58\"/></mask><g fill=\"none\"><g mask=\"url(#nimiq-flags-zw-hexagon-pbk987)\"><path fill=\"#6DA544\" d=\"M1.962 0H32v32H1.962z\"/><path fill=\"#FFDA44\" d=\"M3.613 4.581H32v4.582l-4.069 6.875 4.07 6.875v4.58H3.612z\"/><path fill=\"#D80027\" d=\"M8.25 9.162H32v4.582l-1.687 2.25L32 18.325v4.581H8.25z\"/><path fill=\"#EEE\" d=\"M0 0v32l17.488-16z\"/><path fill=\"#D80027\" d=\"m6.437 11.825 1.032 3.188h3.35l-2.713 1.975 1.038 3.187-2.713-1.969-2.712 1.969 1.037-3.187-2.712-1.976h3.35z\"/><path fill=\"#FFDA44\" d=\"m9.281 16.263-2.7-.957-.212-1.937a1.044 1.044 0 10-2.032.475l-.75.756h1.344c0 1.4-1.044 1.4-1.044 2.794l.575 1.387h3.482l.58-1.387q.086-.198.107-.413c.5-.2.65-.719.65-.719\"/><path fill=\"#333\" d=\"m1.963 0 13.75 13.75H32v4.575H15.638L1.962 32H0l16-16L0 0z\"/><path fill=\"url(#nimiq-flags-zw-hexagon-pbk987)\" d=\"M31.15 14.71 24.707 3.54a2.58 2.58 0 00-2.234-1.29H9.582c-.92 0-1.77.49-2.23 1.29L.907 14.71c-.46.8-.46 1.78 0 2.58l6.445 11.17c.46.8 1.31 1.29 2.23 1.29h12.89c.92 0 1.77-.49 2.23-1.29l6.445-11.17c.464-.8.464-1.78.004-2.58\"/></g><defs><radialGradient id=\"nimiq-flags-zw-hexagon-pbk987\" cx=\"0\" cy=\"0\" r=\"1\" gradientTransform=\"matrix(30.943 0 0 30.9452 23.829 29.395)\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#1D1D1B\" stop-opacity=\".3\"/><stop offset=\"1\" stop-color=\"#E9B213\" stop-opacity=\"0\"/></radialGradient></defs></g>"
12691269
}
12701270
},
1271-
"lastModified": 1747582181,
1271+
"lastModified": 1747638902,
12721272
"width": 32,
12731273
"height": 32
12741274
}

packages/nimiq-icons/src/icons/icons.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,7 @@
15671567
"hidden": true
15681568
}
15691569
},
1570-
"lastModified": 1747582181,
1570+
"lastModified": 1747638902,
15711571
"width": 12,
15721572
"height": 12
15731573
}

packages/nimiq-vitepress-theme/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
"minisearch": "catalog:",
7878
"nimiq-icons": "workspace:*",
7979
"reka-ui": "catalog:",
80+
"vaul-vue": "catalog:",
8081
"vue": "catalog:",
8182
"vue-router": "catalog:"
8283
},

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function getSpan({ span, bgColor }: NqCardInGrid): CardSpan | undefined {
1717
</script>
1818

1919
<template>
20-
<ul v-if="cards.length > 0" grid="~ cols-6 gap-16" class="nq-grid nq-raw" f-my-md>
20+
<ul v-if="cards.length > 0" grid="~ cols-2 md:cols-6 gap-8 md:gap-16" class="nq-grid nq-raw" f-my-md>
2121
<slot>
2222
<li v-for="(card, index) in cards" :key="index" :data-span="getSpan(card)">
2323
<component :is="largeCards ? NqLargeCard : NqCard" v-bind="card" />
@@ -29,11 +29,11 @@ function getSpan({ span, bgColor }: NqCardInGrid): CardSpan | undefined {
2929
<style scoped>
3030
ul.nq-grid {
3131
[data-span='full'] {
32-
--uno: 'col-span-6';
32+
--uno: 'md:col-span-6';
3333
}
3434
3535
[data-span='half'] {
36-
--uno: 'col-span-3';
36+
--uno: 'md:col-span-3';
3737
}
3838
3939
[data-span='default'] {

packages/nimiq-vitepress-theme/src/composables/useBreadcrumbs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export function useBreadcrumbs() {
2424
const breadcrumbs = computed<Breadcrumb[]>(() => {
2525
const items: Breadcrumb[] = []
2626

27+
if (!currentDocModule.value)
28+
return items
29+
2730
// 1. Add module info with link
2831
items.push({
2932
text: currentDocModule.value.text,

packages/nimiq-vitepress-theme/src/composables/useCurrentModule.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export const useCurrentModule = createSharedComposable(() => {
88

99
const route = useRoute()
1010

11-
const currentDocModule = computed<NimiqVitepressThemeNav>(() => {
12-
const module = theme.value.modules.find(module => route.path.startsWith(withBase(`/${module.subpath}`))) || theme.value.modules[0]
11+
const currentDocModule = computed<NimiqVitepressThemeNav | undefined>(() => {
12+
const module = theme.value.modules.find(module => route.path.startsWith(withBase(`/${module.subpath}`)))
1313
return module
1414
})
1515

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<script setup lang="ts">
2+
import { useBreakpoints } from '@vueuse/core'
23
import { useData } from 'vitepress'
34
import { computed } from 'vue'
45
import { useSecondarySidebar } from '../composables/useSecondarySidebar'
6+
import MobileNav from './MobileNav.vue'
57
import PageContent from './PageContent.vue'
68
import SecondarySidebar from './SecondarySidebar.vue'
79
import Sidebar from './Sidebar.vue'
@@ -17,36 +19,34 @@ const showSidebar = computed(() => {
1719
})
1820
1921
const { showSecondarySidebar } = useSecondarySidebar()
22+
23+
const breakpoints = useBreakpoints({ md: 768 })
24+
const isMobile = breakpoints.smaller('md')
2025
</script>
2126

2227
<template>
23-
<div id="viewport" class="flex">
28+
<div id="viewport" flex relative var:nq-sidebar-width:100vw md:var:--nq-sidebar-width:288px>
2429
<!-- TODO Add skip -->
25-
<Sidebar v-if="showSidebar" />
26-
27-
<main
28-
:class="{
29-
'mx-$nq-sidebar-width': !showSidebar && !showSecondarySidebar,
30-
'ml-$nq-sidebar-width': showSidebar,
31-
}" class="min-h-screen"
32-
>
33-
<PageContent />
34-
</main>
35-
<SecondarySidebar v-if="showSecondarySidebar" />
30+
<template v-if="!isMobile">
31+
<Sidebar v-if="showSidebar" w="$nq-sidebar-width" shrink-0 />
32+
<main
33+
min-h-screen flex-1 :class="{
34+
'md:max-w-1220 md:mx-auto': !showSidebar && !showSecondarySidebar,
35+
'md:ml-$nq-sidebar-width': showSidebar,
36+
}"
37+
>
38+
<PageContent />
39+
</main>
40+
41+
<SecondarySidebar v-if="showSecondarySidebar" />
42+
</template>
43+
<template v-else>
44+
<main min-h-screen w-full mb-56>
45+
<PageContent />
46+
</main>
47+
48+
<!-- <SecondarySidebar v-if="showSecondarySidebar" /> -->
49+
<MobileNav fixed bottom-0 />
50+
</template>
3651
</div>
3752
</template>
38-
39-
<style>
40-
:root {
41-
--nq-sidebar-width: 288px;
42-
}
43-
44-
aside {
45-
width: var(--nq-sidebar-width);
46-
flex-shrink: 0;
47-
}
48-
49-
main {
50-
flex: 1;
51-
}
52-
</style>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<script setup lang="ts">
2+
import { watchDebounced } from '@vueuse/core'
3+
import { DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTrigger } from 'vaul-vue'
4+
import { useRouter, withBase } from 'vitepress'
5+
import { ref, watch } from 'vue'
6+
import { useSecondarySidebar } from '../composables/useSecondarySidebar'
7+
import SecondarySidebar from './SecondarySidebar.vue'
8+
import Sidebar from './Sidebar.vue'
9+
10+
const open = ref(false)
11+
const openSecondarySidebar = ref(false)
12+
13+
const shouldTeleport = ref(false)
14+
watchDebounced(
15+
() => openSecondarySidebar.value,
16+
(val) => {
17+
shouldTeleport.value = val
18+
},
19+
{ debounce: 200 },
20+
)
21+
22+
const { showSecondarySidebar } = useSecondarySidebar()
23+
24+
const { route } = useRouter()
25+
26+
watch(route, () => {
27+
open.value = false
28+
openSecondarySidebar.value = false
29+
})
30+
31+
const { showWidget } = useSecondarySidebar()
32+
</script>
33+
34+
<template>
35+
<div>
36+
<div v-if="showWidget" id="widget" fixed bottom-64 rounded-4 outline="~ 1.5 offset--1.5 neutral-400" h-20vh bg-neutral-50 shadow w="[calc(100vw-16px)]" inset-x-8 />
37+
<nav w-screen border="t neutral-300" nq-raw bg-neutral-0 z-10 :data-sidebar="open ? '' : undefined">
38+
<ul grid="~ items-center" :class="showSecondarySidebar ? 'cols-4' : 'cols-3'" children:children:h-56>
39+
<li>
40+
<a :href="withBase('')" stack>
41+
<div i-tabler:home text-20 />
42+
</a>
43+
</li>
44+
45+
<li v-if="showSecondarySidebar">
46+
<DrawerRoot v-model:open="openSecondarySidebar">
47+
<DrawerTrigger stack bg-transparent>
48+
<div i-nimiq:widget text-18 />
49+
</DrawerTrigger>
50+
<DrawerPortal>
51+
<DrawerOverlay fixed inset-0 bg-neutral bg-opacity-20 />
52+
<DrawerContent mt-24 max-h="96%" h-80vh fixed bottom-56 left-0 right-0>
53+
<SecondarySidebar :with-widget="false" bg-neutral-100 w-screen f-pt-sm rounded-t-12 />
54+
</DrawerContent>
55+
</DrawerPortal>
56+
</DrawerRoot>
57+
</li>
58+
59+
<li px-8>
60+
<a :href="withBase('')" nq-pill-blue nq-pill-lg h-48="!" w-full outline="~ 1.5 offset--1.5 white/8">
61+
<div i-nimiq:magnifying-glass />
62+
</a>
63+
</li>
64+
65+
<li>
66+
<DrawerRoot v-model:open="open">
67+
<DrawerTrigger stack bg-transparent>
68+
<div i-tabler:menu-2 text-20 />
69+
</DrawerTrigger>
70+
<DrawerPortal>
71+
<DrawerOverlay fixed inset-0 bg-neutral bg-opacity-20 />
72+
<DrawerContent mt-24 max-h="96%" h-80vh fixed bottom-56 left-0 right-0>
73+
<Sidebar :search="false" w-screen f-pt-sm rounded-t-12 />
74+
</DrawerContent>
75+
</DrawerPortal>
76+
</DrawerRoot>
77+
</li>
78+
</ul>
79+
</nav>
80+
</div>
81+
</template>
82+
83+
<style scoped>
84+
nav:not([data-sidebar]) {
85+
box-shadow:
86+
0px -18px 38px rgba(var(--nq-neutral) / 0.07),
87+
0px -7px 8.5px rgba(var(--nq-neutral) / 0.04),
88+
0px -2px 2.5px rgba(var(--nq-neutral) / 0.02);
89+
}
90+
</style>

0 commit comments

Comments
 (0)