@wordup-md/nuxt-layer-shadcn-unocss 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.playground/app.config.ts +3 -3
- package/.playground/content/1.getting-started/1.introduction.md +7 -1
- package/.playground/content/2.content-elements/11.tables.md +17 -1
- package/.playground/content/3.components/2.docs/badge.md +18 -39
- package/.playground/content/3.components/2.docs/button-link.md +12 -12
- package/.playground/content/3.components/3.page/accordion.md +1 -1
- package/.playground/content/3.components/3.page/file-download.md +6 -0
- package/.playground/content/3.components/3.page/hero.md +1 -1
- package/.playground/content/3.components/3.page/list.md +42 -0
- package/.playground/content/index.md +1 -0
- package/.playground/content/layout.md +1 -1
- package/.playground/content/test.md +24 -1
- package/README.md +2 -2
- package/components/content/Badge.vue +7 -0
- package/components/content/ButtonLink.vue +11 -8
- package/components/content/ButtonLogin.vue +19 -0
- package/components/content/FileDownload.vue +103 -0
- package/components/content/List.vue +26 -7
- package/components/content/Menu.vue +43 -0
- package/components/content/MenuItem.vue +22 -0
- package/components/content/global/CardGroupEditor.vue +1 -1
- package/components/content/global/ListEditor.vue +11 -0
- package/components/layout/Block404.vue +24 -0
- package/components/layout/Footer.vue +2 -11
- package/i18n/i18n.config.ts +180 -2
- package/index.d.ts +1 -1
- package/middleware/admin.global.ts +12 -0
- package/package.json +1 -1
- package/pages/[...slug].vue +47 -12
- package/pages/admin/[...slug].vue +17 -38
- package/pages/admin/login.vue +51 -0
- package/public/content-doc.json +56 -14
- package/scripts/buildContentDoc.ts +5 -3
- package/.playground/content/_menu-footer.md +0 -12
|
@@ -78,7 +78,7 @@ export default defineAppConfig({
|
|
|
78
78
|
}],
|
|
79
79
|
links: [{
|
|
80
80
|
icon: 'lucide:twitter',
|
|
81
|
-
to: 'https://x.com/
|
|
81
|
+
to: 'https://x.com/wordup_md',
|
|
82
82
|
target: '_blank',
|
|
83
83
|
}],
|
|
84
84
|
},
|
|
@@ -97,7 +97,7 @@ export default defineAppConfig({
|
|
|
97
97
|
codeCopyToast: true,
|
|
98
98
|
editLink: {
|
|
99
99
|
enable: true,
|
|
100
|
-
pattern: 'https://github.com/wordup-md/nuxt-layer-shadcn-unocss/edit/main/content/:path',
|
|
100
|
+
pattern: 'https://github.com/wordup-md/nuxt-layer-shadcn-unocss/edit/main/.playground/content/:path',
|
|
101
101
|
text: 'Edit this page',
|
|
102
102
|
icon: 'lucide:square-pen',
|
|
103
103
|
placement: ['pageFooter', 'toc'],
|
|
@@ -147,7 +147,7 @@ export default defineAppConfig({
|
|
|
147
147
|
},
|
|
148
148
|
},
|
|
149
149
|
footer: {
|
|
150
|
-
credits: 'Made with ❤️ by [**Emmanuel Salomon**](https://github.com/ManUtopiK/) with [
|
|
150
|
+
credits: 'Made with ❤️ by [**Emmanuel Salomon**](https://github.com/ManUtopiK/) with [WordUp](https://wordup.md)',
|
|
151
151
|
links: [
|
|
152
152
|
{
|
|
153
153
|
title: 'shadcn-vue',
|
|
@@ -22,4 +22,20 @@ icon: lucide:table
|
|
|
22
22
|
| 2 | Wonderful | Data |
|
|
23
23
|
| 3 | Wonderful | Website |
|
|
24
24
|
```
|
|
25
|
-
::
|
|
25
|
+
::
|
|
26
|
+
|
|
27
|
+
## Alignment
|
|
28
|
+
|
|
29
|
+
::stack
|
|
30
|
+
:::div{.p-4}
|
|
31
|
+
| Default (left) | Left | Center | Right |
|
|
32
|
+
| -------------- | :---------------- | :-----------------: | -----------------: |
|
|
33
|
+
| default text | left aligned text | center aligned text | right aligned text |
|
|
34
|
+
:::
|
|
35
|
+
|
|
36
|
+
```md
|
|
37
|
+
| Default (left) | Left | Center | Right |
|
|
38
|
+
| -------------- | :---------------- | :-----------------: | -----------------: |
|
|
39
|
+
| default text | left aligned text | center aligned text | right aligned text |
|
|
40
|
+
```
|
|
41
|
+
::
|
|
@@ -40,7 +40,7 @@ badges:
|
|
|
40
40
|
|
|
41
41
|
### Types
|
|
42
42
|
|
|
43
|
-
::stack
|
|
43
|
+
::stack
|
|
44
44
|
::div{class="p-3"}
|
|
45
45
|
:badge[Default]
|
|
46
46
|
:badge[Primary]{type="primary"}
|
|
@@ -64,46 +64,24 @@ badges:
|
|
|
64
64
|
|
|
65
65
|
### Variants
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
::
|
|
67
|
+
|Default|Fill|Outline|Text|
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
|:badge[Default]|:badge[Default]{variant="fill"}|:badge[Default]{variant="outline"}|:badge[Default]{variant="text"}|
|
|
70
|
+
|:badge[Primary]{type="primary"}|:badge[Primary]{type="primary" variant="fill"}|:badge[Primary]{type="primary" variant="outline"}|:badge[Primary]{type="primary" variant="text"}|
|
|
71
|
+
|:badge[Secondary]{type="secondary"}|:badge[Secondary]{type="secondary" variant="fill"}|:badge[Secondary]{type="secondary" variant="outline"}|:badge[Secondary]{type="secondary" variant="text"}|
|
|
72
|
+
|:badge[Info]{type="info"}|:badge[Info]{type="info" variant="fill"}|:badge[Info]{type="info" variant="outline"}|:badge[Info]{type="info" variant="text"}|
|
|
73
|
+
|:badge[Warning]{type="warning"}|:badge[Warning]{type="warning" variant="fill"}|:badge[Warning]{type="warning" variant="outline"}|:badge[Warning]{type="warning" variant="text"}|
|
|
74
|
+
|:badge[Success]{type="success"}|:badge[Success]{type="success" variant="fill"}|:badge[Success]{type="success" variant="outline"}|:badge[Success]{type="success" variant="text"}|
|
|
75
|
+
|:badge[Danger]{type="danger"}|:badge[Danger]{type="danger" variant="fill"}|:badge[Danger]{type="danger" variant="outline"}|:badge[Danger]{type="danger" variant="text"}|
|
|
76
|
+
|:badge[New]{type="new"}|:badge[New]{type="new" variant="fill"}|:badge[New]{type="new" variant="outline"}|:badge[New]{type="new" variant="text"}|
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
:badge[Default]{variant="outline"}
|
|
81
|
-
:badge[Primary]{type="primary" variant="outline"}
|
|
82
|
-
:badge[Secondary]{type="secondary" variant="outline"}
|
|
83
|
-
:badge[Info]{type="info" variant="outline"}
|
|
84
|
-
:badge[Warning]{type="warning" variant="outline"}
|
|
85
|
-
:badge[Success]{type="success" variant="outline"}
|
|
86
|
-
:badge[Danger]{type="danger" variant="outline"}
|
|
87
|
-
:badge[New]{type="new" variant="outline"}
|
|
88
|
-
::
|
|
78
|
+
**Examples:**
|
|
89
79
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
:badge[Warning]{type="warning" variant="text"}
|
|
96
|
-
:badge[Success]{type="success" variant="text"}
|
|
97
|
-
:badge[Danger]{type="danger" variant="text"}
|
|
98
|
-
:badge[New]{type="new" variant="text"}
|
|
99
|
-
::
|
|
100
|
-
|
|
101
|
-
```mdc
|
|
102
|
-
:badge[...]{type="..." variant="fill"}
|
|
103
|
-
:badge[...]{type="..." variant="outline"}
|
|
104
|
-
:badge[...]{type="..." variant="text"}
|
|
105
|
-
```
|
|
106
|
-
::
|
|
80
|
+
```mdc
|
|
81
|
+
:badge[Some text]{type="info" variant="fill"}
|
|
82
|
+
:badge[Some text]{type="danger" variant="outline"}
|
|
83
|
+
:badge[Some text]{type="new" variant="text"}
|
|
84
|
+
```
|
|
107
85
|
|
|
108
86
|
### Link
|
|
109
87
|
|
|
@@ -123,6 +101,7 @@ badges:
|
|
|
123
101
|
## Props
|
|
124
102
|
|
|
125
103
|
::field-group
|
|
104
|
+
:field{name="title" type="string"}[Can be used to set the label of the badge instead of the content]
|
|
126
105
|
:field{name="type" type="'default' | 'info' | 'warning' | 'success' | 'danger' | 'lime'" default-value="'default'"}
|
|
127
106
|
:field{name="variant" type="'default' | 'secondary' | 'destructive' | 'outline'" default-value="'default'"}
|
|
128
107
|
:field{name="size" type="'md' | 'sm'" default-value="'md'"}
|
|
@@ -16,26 +16,26 @@ badges:
|
|
|
16
16
|
|
|
17
17
|
::stack
|
|
18
18
|
::div{class="p-3 flex gap-4"}
|
|
19
|
-
::button-link{
|
|
20
|
-
Get Started
|
|
21
|
-
::
|
|
22
|
-
::button-link{left-icon="lucide:github" variant="outline" to="https://github.com/wordup-md/nuxt-layer-shadcn-unocss" target="_blank"}
|
|
19
|
+
::button-link{icon="lucide:github" variant="outline" to="https://github.com/wordup-md/nuxt-layer-shadcn-unocss" target="_blank"}
|
|
23
20
|
GitHub
|
|
24
21
|
::
|
|
25
|
-
::button-link{
|
|
22
|
+
::button-link{icon="lucide:ghost" variant="ghost" href="https://github.com/wordup-md/nuxt-layer-shadcn-unocss" blank}
|
|
26
23
|
Ghost
|
|
27
24
|
::
|
|
28
|
-
::
|
|
29
|
-
```mdc
|
|
30
|
-
::button-link{right-icon="lucide:arrow-up-right" to="/getting-started" target="_blank"}
|
|
25
|
+
::button-link{trailing-icon="lucide:arrow-up-right" to="/getting-started" target="_blank"}
|
|
31
26
|
Get Started
|
|
32
27
|
::
|
|
33
|
-
::
|
|
28
|
+
::
|
|
29
|
+
```mdc
|
|
30
|
+
::button-link{icon="lucide:github" variant="outline" to="https://github.com/wordup-md/nuxt-layer-shadcn-unocss" target="_blank"}
|
|
34
31
|
GitHub
|
|
35
32
|
::
|
|
36
|
-
::button-link{
|
|
33
|
+
::button-link{icon="lucide:ghost" variant="ghost" href="https://github.com/wordup-md/nuxt-layer-shadcn-unocss" blank}
|
|
37
34
|
Ghost
|
|
38
35
|
::
|
|
36
|
+
::button-link{trailing-icon="lucide:arrow-up-right" to="/getting-started" target="_blank"}
|
|
37
|
+
Get Started
|
|
38
|
+
::
|
|
39
39
|
```
|
|
40
40
|
::
|
|
41
41
|
|
|
@@ -44,8 +44,8 @@ badges:
|
|
|
44
44
|
::field-group
|
|
45
45
|
:field{name="variant" type="'default' | 'secondary' | 'link' | 'destructive' | 'outline' | 'ghost'" default-value="'default'"}
|
|
46
46
|
:field{name="size" type="'default' | 'icon' | 'sm' | 'xs' | 'lg'" default-value="'default'"}
|
|
47
|
-
:field{name="
|
|
48
|
-
:field{name="
|
|
47
|
+
:field{name="icon" type="string"}[Icon on the left]
|
|
48
|
+
:field{name="trailingIcon" type="string"}[Icon on the right]
|
|
49
49
|
:field{name="to" type="string"}[Link URL]
|
|
50
50
|
:field{name="href" type="string"}[Alias to `to`]
|
|
51
51
|
:field{name="target" type="Target"}[A `target` attribute value to apply on the link]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dynamic List
|
|
3
|
+
icon: i-lucide:layout-list
|
|
4
|
+
badges:
|
|
5
|
+
- value: Source
|
|
6
|
+
icon: lucide:code
|
|
7
|
+
to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/List.vue
|
|
8
|
+
target: _blank
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
::stack
|
|
14
|
+
::div{class="p-4"}
|
|
15
|
+
::list
|
|
16
|
+
---
|
|
17
|
+
path: /components/
|
|
18
|
+
query:
|
|
19
|
+
limit: 3
|
|
20
|
+
component: card
|
|
21
|
+
---
|
|
22
|
+
::
|
|
23
|
+
::
|
|
24
|
+
```mdc
|
|
25
|
+
::list
|
|
26
|
+
---
|
|
27
|
+
path: /components/
|
|
28
|
+
query:
|
|
29
|
+
limit: 3
|
|
30
|
+
component: card
|
|
31
|
+
---
|
|
32
|
+
::
|
|
33
|
+
```
|
|
34
|
+
::
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
|
|
38
|
+
::field-group
|
|
39
|
+
:field{name="path" type="string"}[Path to the list]
|
|
40
|
+
:field{name="query" type="object"}[Query parameters]
|
|
41
|
+
:field{name="component" type="string"}[Component to use for each item]
|
|
42
|
+
::
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Test
|
|
3
3
|
layout: editorial
|
|
4
4
|
header:
|
|
5
5
|
position: over
|
|
6
|
+
sidebarRight:
|
|
7
|
+
enable: true
|
|
8
|
+
components:
|
|
9
|
+
- ButtonLink:
|
|
10
|
+
title: GitHub
|
|
11
|
+
variant: outline
|
|
12
|
+
to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss
|
|
13
|
+
icon: lucide:github
|
|
14
|
+
class: w-full
|
|
15
|
+
- Menu:
|
|
16
|
+
title: Menu test
|
|
17
|
+
items:
|
|
18
|
+
- /getting-started
|
|
19
|
+
- title: Menu
|
|
20
|
+
to: /getting-started
|
|
21
|
+
icon: lucide:menu
|
|
22
|
+
- Alert:
|
|
23
|
+
title: New
|
|
24
|
+
to: /getting-started
|
|
25
|
+
icon: lucide:party-popper
|
|
26
|
+
navBadges:
|
|
27
|
+
- value: New
|
|
28
|
+
type: new
|
|
6
29
|
---
|
|
7
30
|
|
|
8
31
|
::hero
|
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@ npx create-nuxt-app <project-name>
|
|
|
12
12
|
|
|
13
13
|
- Install the layer
|
|
14
14
|
```bash
|
|
15
|
-
pnpm add @
|
|
15
|
+
pnpm add @wordup-md/nuxt-layer-shadcn-unocss
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
- Extend the layer in your nuxt.config.ts
|
|
19
19
|
```ts
|
|
20
20
|
defineNuxtConfig({
|
|
21
|
-
extends: '@
|
|
21
|
+
extends: '@wordup-md/nuxt-layer-shadcn-unocss'
|
|
22
22
|
})
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
&& 'rounded-md px-1.5 py-0.5 text-xs font-normal leading-none',
|
|
15
15
|
]"
|
|
16
16
|
>
|
|
17
|
+
<span v-if="title">
|
|
18
|
+
{{ title }}
|
|
19
|
+
</span>
|
|
17
20
|
<ContentSlot unwrap="p" />
|
|
18
21
|
</UiBadge>
|
|
19
22
|
</NuxtLink>
|
|
@@ -32,6 +35,9 @@
|
|
|
32
35
|
&& 'px-3 text-base',
|
|
33
36
|
]"
|
|
34
37
|
>
|
|
38
|
+
<span v-if="title">
|
|
39
|
+
{{ title }}
|
|
40
|
+
</span>
|
|
35
41
|
<ContentSlot unwrap="p" />
|
|
36
42
|
</UiBadge>
|
|
37
43
|
</span>
|
|
@@ -44,6 +50,7 @@ const {
|
|
|
44
50
|
size = 'md',
|
|
45
51
|
} = defineProps<{
|
|
46
52
|
type?: 'default' | 'primary' | 'secondary' | 'info' | 'warning' | 'success' | 'danger' | 'new'
|
|
53
|
+
title?: string
|
|
47
54
|
to?: string
|
|
48
55
|
target?: Target
|
|
49
56
|
variant?: 'default' | 'fill' | 'outline' | 'text'
|
|
@@ -7,20 +7,23 @@
|
|
|
7
7
|
<UiButton
|
|
8
8
|
:variant
|
|
9
9
|
:size
|
|
10
|
+
:class="String($attrs.class || '')"
|
|
10
11
|
>
|
|
11
12
|
<Icon
|
|
12
|
-
v-if="
|
|
13
|
-
:name="
|
|
14
|
-
class="mr-
|
|
13
|
+
v-if="icon"
|
|
14
|
+
:name="icon"
|
|
15
|
+
class="mr-2"
|
|
15
16
|
/>
|
|
17
|
+
|
|
16
18
|
<span v-if="title">
|
|
17
19
|
{{ title }}
|
|
18
20
|
</span>
|
|
19
21
|
<ContentSlot unwrap="p" />
|
|
22
|
+
|
|
20
23
|
<Icon
|
|
21
|
-
v-if="
|
|
22
|
-
:name="
|
|
23
|
-
class="ml-
|
|
24
|
+
v-if="trailingIcon"
|
|
25
|
+
:name="trailingIcon"
|
|
26
|
+
class="ml-2"
|
|
24
27
|
/>
|
|
25
28
|
</UiButton>
|
|
26
29
|
</NuxtLink>
|
|
@@ -33,8 +36,8 @@ defineProps<{
|
|
|
33
36
|
variant?: ButtonVariants['variant']
|
|
34
37
|
size?: ButtonVariants['size']
|
|
35
38
|
title?: string
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
icon?: string
|
|
40
|
+
trailingIcon?: string
|
|
38
41
|
to?: string
|
|
39
42
|
href?: string
|
|
40
43
|
target?: Target
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useUnpress } from '#imports'
|
|
3
|
+
|
|
4
|
+
const { client, logout, login } = useUnpress()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<UiButton
|
|
9
|
+
variant="ghost"
|
|
10
|
+
class="flex gap-2"
|
|
11
|
+
@click="!!client ? logout() : login()"
|
|
12
|
+
>
|
|
13
|
+
<Icon
|
|
14
|
+
:name="!!client ? 'lucide:log-out' : 'lucide:log-in'"
|
|
15
|
+
:size="20"
|
|
16
|
+
/>
|
|
17
|
+
{{ !!client ? $t('Logout') : $t('Login') }}
|
|
18
|
+
</UiButton>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
path: string
|
|
4
|
+
title?: string
|
|
5
|
+
size?: number
|
|
6
|
+
icon?: string
|
|
7
|
+
inStack?: boolean
|
|
8
|
+
external?: boolean
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
// Get the asset
|
|
12
|
+
const { data } = await useFetch(props.path)
|
|
13
|
+
|
|
14
|
+
// Compute size
|
|
15
|
+
const size = computed(() => {
|
|
16
|
+
return props.size ?? data.value?.size
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// onMounted(async () => {
|
|
20
|
+
// // Download the asset and get the size
|
|
21
|
+
// const size = await fetch(data.value?.url).then(res => res.headers.get('content-length'))
|
|
22
|
+
// console.log(size.value)
|
|
23
|
+
// })
|
|
24
|
+
|
|
25
|
+
const files = {
|
|
26
|
+
pdf: 'i-mdi-file-pdf-outline',
|
|
27
|
+
jpeg: 'i-mdi-file-image',
|
|
28
|
+
svg: 'i-mdi-file-image',
|
|
29
|
+
}
|
|
30
|
+
function ext(name: string) {
|
|
31
|
+
const ext = name.split('.').slice(-1)
|
|
32
|
+
if (files[ext]) return files[ext]
|
|
33
|
+
return 'i-mdi-file'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function fileSize(size: number) {
|
|
37
|
+
if (props.size) return props.size
|
|
38
|
+
if (!size) return null
|
|
39
|
+
if (size < 1024)
|
|
40
|
+
return `${size} octets`
|
|
41
|
+
if (size < 1024 * 1024)
|
|
42
|
+
return `${(size / 1024).toFixed(2)} Ko`
|
|
43
|
+
return `${(size / 1024 / 1024).toFixed(2)} Mo`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const _icon = computed(() => {
|
|
47
|
+
return props.icon ?? ext(props.path.split('/').pop() ?? '')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const _title = computed(() => {
|
|
51
|
+
return props.title ?? props.path.split('/').pop()
|
|
52
|
+
})
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<template>
|
|
56
|
+
<UiAlert
|
|
57
|
+
class="transition-all [&:not(:first-child)]:mt-5 group/card"
|
|
58
|
+
:class="[
|
|
59
|
+
path && 'hover:bg-muted/50',
|
|
60
|
+
path && 'cursor-pointer',
|
|
61
|
+
inStack && 'm-0 rounded-none border-none',
|
|
62
|
+
]"
|
|
63
|
+
>
|
|
64
|
+
<a
|
|
65
|
+
:href="path"
|
|
66
|
+
:target="external ? '_blank' : undefined"
|
|
67
|
+
:download="external ? undefined : path"
|
|
68
|
+
>
|
|
69
|
+
<div
|
|
70
|
+
v-if="_title"
|
|
71
|
+
class="flex flex-row gap-2 items-center"
|
|
72
|
+
>
|
|
73
|
+
<Icon
|
|
74
|
+
v-if="_icon && _title"
|
|
75
|
+
:name="_icon"
|
|
76
|
+
:size="20"
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
<UiAlertTitle
|
|
80
|
+
class="mb-0 flex flex-row gap-2"
|
|
81
|
+
>
|
|
82
|
+
<span class="font-semibold">{{ _title }}</span>
|
|
83
|
+
<span
|
|
84
|
+
v-if="size"
|
|
85
|
+
class="text-sm font-normal text-muted-foreground"
|
|
86
|
+
>
|
|
87
|
+
( {{ fileSize(size) }} )
|
|
88
|
+
</span>
|
|
89
|
+
</UiAlertTitle>
|
|
90
|
+
</div>
|
|
91
|
+
</a>
|
|
92
|
+
|
|
93
|
+
<div
|
|
94
|
+
v-if="path"
|
|
95
|
+
class="absolute right-3 top-3 flex z-1 p-1 transition bg-background/50 rounded group-hover/card:translate-y-1"
|
|
96
|
+
>
|
|
97
|
+
<NuxtIcon
|
|
98
|
+
name="i-mdi-download"
|
|
99
|
+
:size="20"
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
</UiAlert>
|
|
103
|
+
</template>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section :class="cn('flex flex-col gap-
|
|
2
|
+
<section :class="cn('flex flex-col gap-4 mt-4', String($attrs.class || ''))">
|
|
3
3
|
<ContentList
|
|
4
|
-
v-if="path.length || Object.keys(
|
|
4
|
+
v-if="path.length || Object.keys(normalizedQuery).length"
|
|
5
5
|
:path
|
|
6
|
-
:query
|
|
6
|
+
:query="normalizedQuery"
|
|
7
7
|
>
|
|
8
8
|
<template #default="{ list }">
|
|
9
9
|
<component
|
|
10
10
|
:is="component || 'Card'"
|
|
11
|
-
v-for="data in sortedList(
|
|
11
|
+
v-for="data in sortedList(list)"
|
|
12
12
|
:key="data._path"
|
|
13
13
|
v-bind="itemProps ? { ...data, to: data._path, ...itemProps } : { ...data, to: data._path }"
|
|
14
14
|
:class="cn('mt-0!', String(itemClass))"
|
|
@@ -42,9 +42,28 @@ const {
|
|
|
42
42
|
itemClass?: string
|
|
43
43
|
}>()
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// const { data } = await useAsyncData('homeiiii', () =>
|
|
46
|
+
// queryContent(path)
|
|
47
|
+
// // regex should exclude .../index.md file
|
|
48
|
+
// .where({ _type: { $not: 'yaml' }, _id: { $not: { $regex: /index\.md$/ } } })
|
|
49
|
+
// .find(),
|
|
50
|
+
// )
|
|
51
|
+
// console.log(data.value)
|
|
52
|
+
|
|
53
|
+
const normalizedQuery = computed(() => {
|
|
54
|
+
const _query = { ...query }
|
|
55
|
+
// Extends query.where
|
|
56
|
+
_query.where = {
|
|
57
|
+
..._query.where,
|
|
58
|
+
_type: { $not: 'yaml' },
|
|
59
|
+
_id: { $not: { $regex: /index\.md$/ } },
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
..._query,
|
|
64
|
+
limit: _query.limit ? Number(_query.limit) : undefined,
|
|
65
|
+
}
|
|
66
|
+
})
|
|
48
67
|
|
|
49
68
|
const sortedList = (list: ParsedContent[]) => {
|
|
50
69
|
if (query?.sort && 'date' in query.sort) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { NavItem } from '@nuxt/content'
|
|
3
|
+
|
|
4
|
+
const { items, title } = defineProps<{
|
|
5
|
+
title?: string
|
|
6
|
+
items: NavItem[]
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const { navigation } = useContent()
|
|
10
|
+
|
|
11
|
+
const _links = computed(() => {
|
|
12
|
+
return items?.map((link) => {
|
|
13
|
+
if (typeof link === 'string') {
|
|
14
|
+
return {
|
|
15
|
+
...navigation.value?.find(n => n._path === link),
|
|
16
|
+
_path: link,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
...link,
|
|
22
|
+
_path: link.to || link._path,
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<div>
|
|
30
|
+
<p
|
|
31
|
+
v-if="title"
|
|
32
|
+
class="mb-2 text-base font-semibold"
|
|
33
|
+
>
|
|
34
|
+
{{ title }}
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<MenuItem
|
|
38
|
+
v-for="link in _links"
|
|
39
|
+
:key="link._path"
|
|
40
|
+
:link="link"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<NuxtLink
|
|
3
|
+
:to="link._path"
|
|
4
|
+
class="flex items-center gap-2 rounded-md p-2 text-sm text-foreground/80 hover:bg-muted hover:text-primary"
|
|
5
|
+
:class="[
|
|
6
|
+
isActive && 'bg-muted !text-primary',
|
|
7
|
+
!!link.navTruncate && 'h-8',
|
|
8
|
+
]"
|
|
9
|
+
>
|
|
10
|
+
<LayoutAsideTreeItemButton :link />
|
|
11
|
+
</NuxtLink>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import type { NavItem } from '@nuxt/content'
|
|
16
|
+
|
|
17
|
+
const { link } = defineProps<{
|
|
18
|
+
link: NavItem
|
|
19
|
+
}>()
|
|
20
|
+
|
|
21
|
+
const isActive = computed(() => link._path === useRoute().path)
|
|
22
|
+
</script>
|