@wordup-md/nuxt-layer-shadcn-unocss 0.2.0 → 0.2.1
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 +1 -1
- package/.playground/content/3.components/2.docs/stack.md +0 -1
- package/.playground/content/4.development/1.configuration/1.overview.md +1 -1
- package/.playground/content/4.development/1.configuration/4.edit-link.md +3 -3
- package/assets/css/mdc-editor.css +13 -6
- package/components/content/Alert.vue +4 -2
- package/components/content/ButtonLink.vue +5 -0
- package/components/content/Card.vue +31 -7
- package/components/content/Hero.vue +1 -1
- package/components/content/List.vue +60 -0
- package/components/content/ProseA.vue +3 -1
- package/components/content/ProseSection.vue +59 -5
- package/components/content/Steps.vue +1 -1
- package/components/content/global/AlertEditor.vue +4 -1
- package/components/content/global/ListEditor.vue +45 -0
- package/components/content/global/ReadMoreEditor.vue +3 -3
- package/components/content/global/StepsEditor.vue +17 -5
- package/components/layout/Banner.vue +26 -26
- package/components/layout/Breadcrumb.vue +9 -0
- package/components/layout/EditLink.vue +2 -2
- package/components/layout/Footer.vue +1 -1
- package/components/layout/Header.vue +1 -2
- package/components/layout/PageFooter.vue +23 -0
- package/components/layout/PrevNext.vue +18 -2
- package/components/layout/PrevNextButton.vue +1 -1
- package/components/layout/TocTree.vue +4 -4
- package/components/ui/button/index.ts +1 -1
- package/components/ui/card/CardDescription.vue +1 -1
- package/components/ui/card/CardTitle.vue +1 -1
- package/composables/useBreadcrumb.ts +6 -3
- package/composables/useConfig.ts +5 -1
- package/composables/useEditLink.ts +3 -3
- package/index.d.ts +21 -3
- package/layouts/editorial.vue +1 -1
- package/lib/uno-preset.ts +12 -3
- package/nuxt.config.ts +1 -0
- package/package.json +1 -1
- package/pages/[...slug].vue +16 -10
- package/pages/index.vue +1 -1
- package/plugins/wordup.ts +124 -124
- package/public/content-doc.json +4 -24
- package/.playground/content/3.components/2.docs/callout.md +0 -16
- package/components/content/Callout.vue +0 -17
- package/components/layout/DocsFooter.vue +0 -6
|
@@ -100,7 +100,7 @@ export default defineAppConfig({
|
|
|
100
100
|
pattern: 'https://github.com/ZTL-UwU/shadcn-docs-nuxt/edit/main/content/:path',
|
|
101
101
|
text: 'Edit this page',
|
|
102
102
|
icon: 'lucide:square-pen',
|
|
103
|
-
placement: ['
|
|
103
|
+
placement: ['pageFooter', 'toc'],
|
|
104
104
|
},
|
|
105
105
|
codeIcon: {
|
|
106
106
|
'package.json': 'vscode-icons:file-type-node',
|
|
@@ -215,7 +215,7 @@ All configurable icons can be set to iconify icons, emojis and urls, using the [
|
|
|
215
215
|
::field{name="icon" type="string" default-value="lucide:square-pen"}
|
|
216
216
|
The icon preceding the link.
|
|
217
217
|
::
|
|
218
|
-
::field{name="placement" type="('
|
|
218
|
+
::field{name="placement" type="('pageFooter' | 'toc')[]" default-value="['pageFooter']"}
|
|
219
219
|
Where to place the edit link.
|
|
220
220
|
::
|
|
221
221
|
::
|
|
@@ -15,7 +15,7 @@ export default defineAppConfig({
|
|
|
15
15
|
pattern: 'https://github.com/ZTL-UwU/shadcn-docs-nuxt/edit/main/content/:path',
|
|
16
16
|
text: 'Edit this page on GitHub',
|
|
17
17
|
icon: 'lucide:square-pen',
|
|
18
|
-
placement: ['
|
|
18
|
+
placement: ['pageFooter', 'toc'],
|
|
19
19
|
},
|
|
20
20
|
}
|
|
21
21
|
},
|
|
@@ -29,7 +29,7 @@ export default defineAppConfig({
|
|
|
29
29
|
- The `icon` option allows you to customize the icon (default is `lucide:square-pen`)
|
|
30
30
|
|
|
31
31
|
- The `placement` option controls the places to put the edit link.
|
|
32
|
-
- `
|
|
32
|
+
- `pageFooter`: at the end of the page.
|
|
33
33
|
- `toc`: in the TOC links section.
|
|
34
34
|
|
|
35
35
|
### Front Matter
|
|
@@ -57,7 +57,7 @@ editLink: false
|
|
|
57
57
|
::field{name="icon" type="string" default-value="lucide:square-pen"}
|
|
58
58
|
The icon preceding the link.
|
|
59
59
|
::
|
|
60
|
-
::field{name="placement" type="('
|
|
60
|
+
::field{name="placement" type="('pageFooter' | 'toc')[]" default-value="['pageFooter']"}
|
|
61
61
|
Where to place the edit link.
|
|
62
62
|
::
|
|
63
63
|
::
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
outline: none;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
& > p:not(:has(span)):not(:first-child) {
|
|
11
|
+
/* & > p:not(:has(span)):not(:first-child) { */
|
|
12
|
+
& > p:not(:first-child) {
|
|
12
13
|
margin-top: 1.5rem;
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
& p a {
|
|
55
|
+
& p > a {
|
|
55
56
|
text-underline-offset: 4px;
|
|
56
57
|
text-decoration-line: underline;
|
|
57
58
|
font-weight: 600;
|
|
@@ -61,11 +62,13 @@
|
|
|
61
62
|
padding-top: 0.5rem;
|
|
62
63
|
margin-left: 1.5rem;
|
|
63
64
|
|
|
64
|
-
&:first-child
|
|
65
|
-
:not(&) + & {
|
|
65
|
+
&:first-child {
|
|
66
66
|
padding-top: 1.5rem;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
&:not(.prosemirror-flat-list) + .prosemirror-flat-list {
|
|
70
|
+
padding-top: 1.5rem;
|
|
71
|
+
}
|
|
69
72
|
|
|
70
73
|
/* CodeGroupEditor */
|
|
71
74
|
& .\[\&\:not\(\:first-child\)\]\:mt-5 {
|
|
@@ -76,16 +79,20 @@
|
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
|
|
82
|
+
.underline-none {
|
|
83
|
+
text-decoration: none !important;
|
|
84
|
+
}
|
|
85
|
+
|
|
79
86
|
.animate-scroll-fade-in-up {
|
|
80
87
|
animation: fade-in-up linear;
|
|
81
88
|
animation-timeline: view();
|
|
82
89
|
animation-range: 0 25dvh;
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
.
|
|
92
|
+
.page-content:not(.EDITOR_CONTENT) > * {
|
|
86
93
|
--una-enter-translate-y: 5dvh;
|
|
87
94
|
--una-enter-opacity: 0.5;
|
|
88
95
|
animation: una-in linear;
|
|
89
96
|
animation-timeline: view();
|
|
90
97
|
animation-range: 0 25dvh;
|
|
91
|
-
}
|
|
98
|
+
}
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
]"
|
|
10
10
|
@click="alertClick"
|
|
11
11
|
>
|
|
12
|
-
<div
|
|
12
|
+
<div
|
|
13
|
+
v-if="title"
|
|
14
|
+
class="flex flex-row gap-2"
|
|
15
|
+
>
|
|
13
16
|
<Icon
|
|
14
17
|
v-if="icon && title"
|
|
15
18
|
:name="icon"
|
|
@@ -17,7 +20,6 @@
|
|
|
17
20
|
/>
|
|
18
21
|
|
|
19
22
|
<UiAlertTitle
|
|
20
|
-
v-if="title"
|
|
21
23
|
class="font-semibold mb-3"
|
|
22
24
|
>
|
|
23
25
|
{{ title }}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<NuxtLink
|
|
3
3
|
:to="to || href"
|
|
4
4
|
:target="(blank && '_blank') || target"
|
|
5
|
+
class="button-link block"
|
|
5
6
|
>
|
|
6
7
|
<UiButton
|
|
7
8
|
:variant
|
|
@@ -12,6 +13,9 @@
|
|
|
12
13
|
:name="leftIcon"
|
|
13
14
|
class="mr-1"
|
|
14
15
|
/>
|
|
16
|
+
<span v-if="title">
|
|
17
|
+
{{ title }}
|
|
18
|
+
</span>
|
|
15
19
|
<ContentSlot unwrap="p" />
|
|
16
20
|
<Icon
|
|
17
21
|
v-if="rightIcon"
|
|
@@ -28,6 +32,7 @@ import type { ButtonVariants } from '../ui/button'
|
|
|
28
32
|
defineProps<{
|
|
29
33
|
variant?: ButtonVariants['variant']
|
|
30
34
|
size?: ButtonVariants['size']
|
|
35
|
+
title?: string
|
|
31
36
|
leftIcon?: string
|
|
32
37
|
rightIcon?: string
|
|
33
38
|
to?: string
|
|
@@ -10,14 +10,13 @@
|
|
|
10
10
|
mediaPosition === 'bottom' && 'flex-col-reverse',
|
|
11
11
|
['cover', 'center'].includes(mediaPosition) && 'bg-opacity-0',
|
|
12
12
|
mediaPosition === 'center' && 'text-center items-center flex-row p-8',
|
|
13
|
-
$attrs.class,
|
|
14
13
|
]"
|
|
15
14
|
>
|
|
16
15
|
<div
|
|
17
16
|
v-if="media || $slots.media"
|
|
18
|
-
class="overflow-hidden"
|
|
17
|
+
class="card__media overflow-hidden"
|
|
19
18
|
:class="{
|
|
20
|
-
'w-5/13 shrink-0': media && (mediaPosition === 'left' || mediaPosition === 'right'),
|
|
19
|
+
'w-5/13 shrink-0': (media || $slots.media) && (mediaPosition === 'left' || mediaPosition === 'right'),
|
|
21
20
|
'absolute inset-0': ['cover', 'center'].includes(mediaPosition),
|
|
22
21
|
}"
|
|
23
22
|
>
|
|
@@ -40,6 +39,7 @@
|
|
|
40
39
|
v-if="
|
|
41
40
|
icon || title || $slots.title || description || $slots.description
|
|
42
41
|
"
|
|
42
|
+
class="card__header"
|
|
43
43
|
:class="{
|
|
44
44
|
'flex-row gap-5': iconPosition === 'left',
|
|
45
45
|
'items-center': mediaPosition === 'center',
|
|
@@ -52,9 +52,18 @@
|
|
|
52
52
|
:class="{ 'mb-2': iconPosition !== 'left' && (title || $slots.title) }"
|
|
53
53
|
/>
|
|
54
54
|
|
|
55
|
-
<div class="flex flex-col gap-
|
|
55
|
+
<div class="flex flex-col gap-2 w-full">
|
|
56
|
+
<div
|
|
57
|
+
v-if="date"
|
|
58
|
+
class="card__date text-sm text-muted-foreground"
|
|
59
|
+
style="text-decoration: none !important"
|
|
60
|
+
>
|
|
61
|
+
{{ new Intl.DateTimeFormat(locale, { dateStyle: 'long' }).format(new Date(date)) }}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
56
64
|
<UiCardTitle
|
|
57
65
|
v-if="title || $slots.title"
|
|
66
|
+
class="card__title"
|
|
58
67
|
:class="{ 'group-hover/card:underline': to, 'pr-4': ['left', 'bottom'].includes(mediaPosition) && to }"
|
|
59
68
|
>
|
|
60
69
|
<ContentSlot
|
|
@@ -68,7 +77,10 @@
|
|
|
68
77
|
/>
|
|
69
78
|
</UiCardTitle>
|
|
70
79
|
|
|
71
|
-
<UiCardDescription
|
|
80
|
+
<UiCardDescription
|
|
81
|
+
v-if="description || $slots.description"
|
|
82
|
+
class="card__description"
|
|
83
|
+
>
|
|
72
84
|
<ContentSlot
|
|
73
85
|
:use="$slots.description"
|
|
74
86
|
unwrap="p"
|
|
@@ -86,6 +98,7 @@
|
|
|
86
98
|
|
|
87
99
|
<UiCardContent
|
|
88
100
|
v-if="content || $slots.content || $slots.default"
|
|
101
|
+
class="card__content"
|
|
89
102
|
:class="{ 'py-3': !icon && !(title || $slots.title) && !(description || $slots.description) }"
|
|
90
103
|
>
|
|
91
104
|
<ContentSlot unwrap="p" />
|
|
@@ -95,7 +108,10 @@
|
|
|
95
108
|
/>
|
|
96
109
|
</UiCardContent>
|
|
97
110
|
|
|
98
|
-
<UiCardFooter
|
|
111
|
+
<UiCardFooter
|
|
112
|
+
v-if="footer || $slots.footer"
|
|
113
|
+
class="card__footer"
|
|
114
|
+
>
|
|
99
115
|
<ContentSlot
|
|
100
116
|
:use="$slots.footer"
|
|
101
117
|
unwrap="p"
|
|
@@ -117,7 +133,9 @@
|
|
|
117
133
|
</UiCard>
|
|
118
134
|
</UseTemplate>
|
|
119
135
|
|
|
120
|
-
<div
|
|
136
|
+
<div
|
|
137
|
+
:class="cn('group/card group-has-[div]:mt-0 [&:not(:first-child)]:mt-5', String($attrs.class || ''))"
|
|
138
|
+
>
|
|
121
139
|
<NuxtLink
|
|
122
140
|
v-if="to"
|
|
123
141
|
:to
|
|
@@ -126,11 +144,14 @@
|
|
|
126
144
|
>
|
|
127
145
|
<CardInner />
|
|
128
146
|
</NuxtLink>
|
|
147
|
+
|
|
129
148
|
<CardInner v-else />
|
|
130
149
|
</div>
|
|
131
150
|
</template>
|
|
132
151
|
|
|
133
152
|
<script setup lang="ts">
|
|
153
|
+
import { cn } from '@/lib/utils'
|
|
154
|
+
|
|
134
155
|
defineOptions({
|
|
135
156
|
inheritAttrs: false,
|
|
136
157
|
})
|
|
@@ -146,6 +167,7 @@ const {
|
|
|
146
167
|
} = defineProps<{
|
|
147
168
|
title?: string
|
|
148
169
|
description?: string
|
|
170
|
+
date?: string
|
|
149
171
|
content?: string
|
|
150
172
|
footer?: string
|
|
151
173
|
|
|
@@ -164,6 +186,8 @@ const {
|
|
|
164
186
|
inStack?: boolean
|
|
165
187
|
}>()
|
|
166
188
|
|
|
189
|
+
const { locale } = useI18nDocs()
|
|
190
|
+
|
|
167
191
|
defineSlots()
|
|
168
192
|
|
|
169
193
|
const [UseTemplate, CardInner] = createReusableTemplate()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section :class="cn('flex flex-col gap-8 mt-8', String($attrs.class || ''))">
|
|
3
|
+
<ContentList
|
|
4
|
+
v-if="path.length || Object.keys(query).length"
|
|
5
|
+
:path
|
|
6
|
+
:query
|
|
7
|
+
>
|
|
8
|
+
<template #default="{ list }">
|
|
9
|
+
<component
|
|
10
|
+
:is="component || 'Card'"
|
|
11
|
+
v-for="data in sortedList(filterList(list))"
|
|
12
|
+
:key="data._path"
|
|
13
|
+
v-bind="itemProps ? { ...data, to: data._path, ...itemProps } : { ...data, to: data._path }"
|
|
14
|
+
:class="cn('mt-0!', String(itemClass))"
|
|
15
|
+
/>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<template #not-found>
|
|
19
|
+
<p>No articles found.</p>
|
|
20
|
+
</template>
|
|
21
|
+
</ContentList>
|
|
22
|
+
</section>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import type { QueryBuilderParams, ParsedContent } from '@nuxt/content'
|
|
27
|
+
import { cn } from '@/lib/utils'
|
|
28
|
+
|
|
29
|
+
type ListQuery = QueryBuilderParams & { sort?: { date?: 'ASC' | 'DESC' | 1 | -1 } }
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
path = '',
|
|
33
|
+
query = {} as ListQuery,
|
|
34
|
+
component = 'Card',
|
|
35
|
+
itemProps = {},
|
|
36
|
+
itemClass = '',
|
|
37
|
+
} = defineProps<{
|
|
38
|
+
path?: string
|
|
39
|
+
query?: ListQuery
|
|
40
|
+
component?: string
|
|
41
|
+
itemProps?: object
|
|
42
|
+
itemClass?: string
|
|
43
|
+
}>()
|
|
44
|
+
|
|
45
|
+
const filterList = (list: ParsedContent[]) => {
|
|
46
|
+
return list.filter(item => !item?._file?.includes('index.md'))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const sortedList = (list: ParsedContent[]) => {
|
|
50
|
+
if (query?.sort && 'date' in query.sort) {
|
|
51
|
+
return [...list].sort((a, b) =>
|
|
52
|
+
query.sort!.date === 'DESC' || query.sort!.date === -1
|
|
53
|
+
? new Date(b.date).getTime() - new Date(a.date).getTime()
|
|
54
|
+
: new Date(a.date).getTime() - new Date(b.date).getTime(),
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return list
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
:to="href"
|
|
4
4
|
:target="target"
|
|
5
5
|
:external="external"
|
|
6
|
-
class="font-semibold underline underline-offset-4"
|
|
6
|
+
:class="cn('font-semibold underline underline-offset-4', String($attrs.class || ''))"
|
|
7
7
|
>
|
|
8
8
|
<slot />
|
|
9
9
|
</NuxtLink>
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
12
|
<script setup lang="ts">
|
|
13
|
+
import { cn } from '@/lib/utils'
|
|
14
|
+
|
|
13
15
|
const {
|
|
14
16
|
href = '',
|
|
15
17
|
external = false,
|
|
@@ -7,21 +7,75 @@ defineOptions({
|
|
|
7
7
|
})
|
|
8
8
|
|
|
9
9
|
defineProps<{
|
|
10
|
-
|
|
10
|
+
title?: string
|
|
11
11
|
}>()
|
|
12
|
+
|
|
13
|
+
defineSlots()
|
|
12
14
|
</script>
|
|
13
15
|
|
|
14
16
|
<template>
|
|
15
17
|
<section
|
|
18
|
+
class="prose-section"
|
|
16
19
|
:class="cn(
|
|
17
20
|
'relative p-6 mt-6',
|
|
18
21
|
classToString($attrs.class),
|
|
19
|
-
color,
|
|
20
22
|
)"
|
|
21
23
|
>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
<div>
|
|
25
|
+
<div
|
|
26
|
+
v-if="$slots.before"
|
|
27
|
+
class="prose-section__before"
|
|
28
|
+
>
|
|
29
|
+
<ContentSlot
|
|
30
|
+
:use="$slots.before"
|
|
31
|
+
unwrap="p"
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<ProseH2 v-if="title">
|
|
36
|
+
{{ title }}
|
|
37
|
+
</ProseH2>
|
|
38
|
+
|
|
39
|
+
<!-- <span class="absolute bg-muted-foreground/05 -left-2 -top-1 -bottom-1 -right-2 md:-left-3 md:-top-0 md:-bottom-0 md:-right-3 -rotate-1" /> -->
|
|
40
|
+
<!-- <div class="grid grid-cols-[repeat(auto-fit,minmax(300px,auto))] gap-6 [&>*]:mt-0!"> -->
|
|
41
|
+
<div
|
|
42
|
+
v-if="$slots.default"
|
|
43
|
+
class="prose-section__content"
|
|
44
|
+
>
|
|
45
|
+
<ContentSlot
|
|
46
|
+
:use="$slots.default"
|
|
47
|
+
unwrap="p"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div
|
|
52
|
+
v-if="$slots.after"
|
|
53
|
+
class="prose-section__after"
|
|
54
|
+
>
|
|
55
|
+
<ContentSlot
|
|
56
|
+
:use="$slots.after"
|
|
57
|
+
unwrap="p"
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
25
60
|
</div>
|
|
26
61
|
</section>
|
|
27
62
|
</template>
|
|
63
|
+
|
|
64
|
+
<style scoped>
|
|
65
|
+
.grid-flex {
|
|
66
|
+
display: grid;
|
|
67
|
+
gap: 1rem;
|
|
68
|
+
grid-template-columns: repeat(auto-fit, minmax(min(var(--min-column-size, 15ch), 100%), 1fr));
|
|
69
|
+
background: #f7f7f7;
|
|
70
|
+
border: 1px solid #e5e5e5;
|
|
71
|
+
padding: 0.25rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.grid-flex > div {
|
|
75
|
+
background-color: #ffdc00;
|
|
76
|
+
border: 1px solid #665800;
|
|
77
|
+
color: #665800;
|
|
78
|
+
padding: 1rem 2rem;
|
|
79
|
+
text-align: center;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="[&>li]:step ml-4 border-l pl-8 [counter-reset:step] [&:not(:first-child)]:mt-6 [&:not(:last-child)]:mb-12"
|
|
3
|
+
class="steps [&>li]:step ml-4 border-l-2 pl-8 [counter-reset:step] [&:not(:first-child)]:mt-6 [&:not(:last-child)]:mb-12"
|
|
4
4
|
:class="levelClass[level]"
|
|
5
5
|
>
|
|
6
6
|
<slot />
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { VueNodeViewProps } from 'prosekit/vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<VueNodeViewProps>()
|
|
5
|
+
const { getComponentProps } = useMdcEditor()
|
|
6
|
+
|
|
7
|
+
const { model, mdcAttrs } = getComponentProps(props, {
|
|
8
|
+
id: {
|
|
9
|
+
type: String,
|
|
10
|
+
},
|
|
11
|
+
class: {
|
|
12
|
+
type: String,
|
|
13
|
+
},
|
|
14
|
+
path: {
|
|
15
|
+
type: String,
|
|
16
|
+
},
|
|
17
|
+
query: {
|
|
18
|
+
type: Object,
|
|
19
|
+
},
|
|
20
|
+
component: {
|
|
21
|
+
type: String,
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<div class="relative mt-8">
|
|
28
|
+
<UiEditorHorizontalControls>
|
|
29
|
+
<UiEditorInput
|
|
30
|
+
v-model="mdcAttrs.path"
|
|
31
|
+
flex-1
|
|
32
|
+
placeholder="Path to folder"
|
|
33
|
+
label="Chemin"
|
|
34
|
+
/>
|
|
35
|
+
</UiEditorHorizontalControls>
|
|
36
|
+
|
|
37
|
+
<List
|
|
38
|
+
v-if="model.path || model.query"
|
|
39
|
+
:path="model.path"
|
|
40
|
+
:query="model.query"
|
|
41
|
+
:component="model.component"
|
|
42
|
+
contenteditable="false"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
@@ -34,7 +34,7 @@ import type { VueNodeViewProps } from 'prosekit/vue'
|
|
|
34
34
|
const props = defineProps<VueNodeViewProps>()
|
|
35
35
|
const { getComponentProps } = useMdcEditor()
|
|
36
36
|
|
|
37
|
-
const { model } = getComponentProps(props, {
|
|
37
|
+
const { mdcAttrs, model } = getComponentProps(props, {
|
|
38
38
|
id: {
|
|
39
39
|
type: String,
|
|
40
40
|
},
|
|
@@ -62,9 +62,9 @@ const { model } = getComponentProps(props, {
|
|
|
62
62
|
|
|
63
63
|
function updatePrefix(event: Event) {
|
|
64
64
|
const target = event.target as HTMLDivElement
|
|
65
|
-
|
|
65
|
+
mdcAttrs.prefix = target.innerHTML
|
|
66
66
|
}
|
|
67
67
|
function updateLink(to: string) {
|
|
68
|
-
|
|
68
|
+
mdcAttrs.to = to
|
|
69
69
|
}
|
|
70
70
|
</script>
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
3
|
<UiEditorDropdown
|
|
4
|
-
v-model="
|
|
4
|
+
v-model="levelModel"
|
|
5
5
|
chevron
|
|
6
6
|
tooltip="Level"
|
|
7
7
|
placement="bottom-end"
|
|
8
|
-
:items="levels"
|
|
8
|
+
:items="levels.map(level => `H${level}`)"
|
|
9
9
|
class="absolute right-1 top-1 z-10 opacity-25 transition-opacity group-hover:opacity-100"
|
|
10
10
|
>
|
|
11
|
-
<span class="text-xs font-mono capitalize">
|
|
11
|
+
<span class="text-xs font-mono capitalize">{{ levelModel }}</span>
|
|
12
12
|
</UiEditorDropdown>
|
|
13
13
|
|
|
14
14
|
<Steps
|
|
15
15
|
v-bind="model"
|
|
16
|
-
:class="levelClass[model.level]"
|
|
16
|
+
:class="levelClass[model.level as keyof typeof levelClass]"
|
|
17
17
|
>
|
|
18
|
-
<div
|
|
18
|
+
<div
|
|
19
|
+
:ref="props.contentRef"
|
|
20
|
+
class="[&>div]:min-h-5.5 [&_p]:mt-6"
|
|
21
|
+
/>
|
|
19
22
|
</Steps>
|
|
20
23
|
</div>
|
|
21
24
|
</template>
|
|
@@ -52,4 +55,13 @@ const { model, mdcAttrs } = getComponentProps(props, {
|
|
|
52
55
|
},
|
|
53
56
|
},
|
|
54
57
|
})
|
|
58
|
+
|
|
59
|
+
const levelModel = computed({
|
|
60
|
+
get() {
|
|
61
|
+
return `H${model.level}`
|
|
62
|
+
},
|
|
63
|
+
set(value) {
|
|
64
|
+
mdcAttrs.level = value.replace('H', '')
|
|
65
|
+
},
|
|
66
|
+
})
|
|
55
67
|
</script>
|
|
@@ -2,39 +2,39 @@
|
|
|
2
2
|
<Transition>
|
|
3
3
|
<div
|
|
4
4
|
v-if="open === true"
|
|
5
|
-
class="app__banner block transition-colors bg-primary/10"
|
|
5
|
+
class="app__banner block relative h-[var(--banner-height)] transition-colors bg-primary/10"
|
|
6
6
|
:class="{
|
|
7
7
|
'hover:cursor-pointer hover:bg-primary/25': to,
|
|
8
8
|
'border-b': border,
|
|
9
9
|
}"
|
|
10
10
|
>
|
|
11
|
-
<
|
|
12
|
-
|
|
11
|
+
<NuxtLink
|
|
12
|
+
:to
|
|
13
|
+
class="container flex items-stretch w-full md:px-8 h-full"
|
|
14
|
+
@click.stop="navigate"
|
|
15
|
+
>
|
|
16
|
+
<div class="hidden lg:block" />
|
|
17
|
+
<MDC
|
|
18
|
+
:value="content"
|
|
19
|
+
class="flex items-center justify-center text-primary text-lg w-full"
|
|
20
|
+
/>
|
|
21
|
+
</NuxtLink>
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
<div class="absolute right-0 top-0 w-full h-full">
|
|
24
|
+
<div class="container h-full flex items-stretch justify-end">
|
|
25
|
+
<UiButton
|
|
26
|
+
v-if="showClose"
|
|
27
|
+
variant="ghost"
|
|
28
|
+
class="z-40 h-auto px-3 [--accent:var(--primary)] !bg-opacity-25 rounded-none"
|
|
29
|
+
aria-label="Close banner"
|
|
30
|
+
@click.stop="open = Date.now()"
|
|
31
|
+
>
|
|
32
|
+
<NuxtIcon
|
|
33
|
+
name="lucide:x"
|
|
34
|
+
size="24"
|
|
22
35
|
/>
|
|
23
|
-
</
|
|
24
|
-
</
|
|
25
|
-
|
|
26
|
-
<UiButton
|
|
27
|
-
v-if="showClose"
|
|
28
|
-
variant="ghost"
|
|
29
|
-
class="z-40 size-10 p-2 [--accent:var(--primary)] !bg-opacity-25 rounded-none"
|
|
30
|
-
aria-label="Close banner"
|
|
31
|
-
@click.prevent="open = Date.now()"
|
|
32
|
-
>
|
|
33
|
-
<NuxtIcon
|
|
34
|
-
name="lucide:x"
|
|
35
|
-
size="36"
|
|
36
|
-
/>
|
|
37
|
-
</UiButton>
|
|
36
|
+
</UiButton>
|
|
37
|
+
</div>
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
</Transition>
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
:size="breadcrumb.iconSize || config.main.breadCrumb.iconSize || 14"
|
|
17
17
|
:name="breadcrumb.icon"
|
|
18
18
|
/>
|
|
19
|
+
<Icon
|
|
20
|
+
v-if="(breadcrumb.media && showImage)"
|
|
21
|
+
:size="breadcrumb.iconSize || config.main.breadCrumb.iconSize || 14"
|
|
22
|
+
:name="breadcrumb.media"
|
|
23
|
+
/>
|
|
19
24
|
{{ breadcrumb.title }}
|
|
20
25
|
</NuxtLink>
|
|
21
26
|
</UiBreadcrumbItem>
|
|
@@ -27,6 +32,10 @@
|
|
|
27
32
|
</template>
|
|
28
33
|
|
|
29
34
|
<script setup lang="ts">
|
|
35
|
+
const { showImage = false } = defineProps<{
|
|
36
|
+
showImage?: boolean
|
|
37
|
+
}>()
|
|
38
|
+
|
|
30
39
|
const route = useRoute()
|
|
31
40
|
const config = useConfig()
|
|
32
41
|
|