@baybreezy/docd 0.1.12 → 0.3.0
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/app/app.config.ts +8 -0
- package/app/app.vue +1 -0
- package/app/assets/css/shadcn.css +103 -47
- package/app/components/docs/DocsMobileNav.vue +2 -4
- package/app/components/docs/DocsPageTransition.vue +10 -8
- package/app/composables/useDocd.ts +9 -0
- package/app/composables/useUIConfig.ts +4 -0
- package/app/layouts/docs.vue +4 -5
- package/app/pages/[...slug].vue +3 -2
- package/index.d.ts +2 -0
- package/modules/css.ts +65 -6
- package/package.json +10 -13
package/app/app.config.ts
CHANGED
|
@@ -153,6 +153,14 @@ export type DocdConfig = {
|
|
|
153
153
|
/** Logo configuration for the header. */
|
|
154
154
|
logo?: DocLogoConfig;
|
|
155
155
|
};
|
|
156
|
+
body?: {
|
|
157
|
+
/**
|
|
158
|
+
* Maximum width for the main content area.
|
|
159
|
+
*
|
|
160
|
+
* @default "1280px"
|
|
161
|
+
*/
|
|
162
|
+
maxWidth?: `${number}px`;
|
|
163
|
+
};
|
|
156
164
|
footer?: {
|
|
157
165
|
/**
|
|
158
166
|
* Whether to hide the theme customizer in the sidebar
|
package/app/app.vue
CHANGED
|
@@ -111,12 +111,18 @@
|
|
|
111
111
|
--scroll-fade-t: 0px;
|
|
112
112
|
}
|
|
113
113
|
to {
|
|
114
|
-
--scroll-fade-t: var(
|
|
114
|
+
--scroll-fade-t: var(
|
|
115
|
+
--_scroll-fade-size-t,
|
|
116
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
117
|
+
);
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
120
|
@keyframes scroll-fade-reveal-b {
|
|
118
121
|
from {
|
|
119
|
-
--scroll-fade-b: var(
|
|
122
|
+
--scroll-fade-b: var(
|
|
123
|
+
--_scroll-fade-size-b,
|
|
124
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
125
|
+
);
|
|
120
126
|
}
|
|
121
127
|
to {
|
|
122
128
|
--scroll-fade-b: 0px;
|
|
@@ -127,12 +133,18 @@
|
|
|
127
133
|
--scroll-fade-s: 0px;
|
|
128
134
|
}
|
|
129
135
|
to {
|
|
130
|
-
--scroll-fade-s: var(
|
|
136
|
+
--scroll-fade-s: var(
|
|
137
|
+
--_scroll-fade-size-s,
|
|
138
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
139
|
+
);
|
|
131
140
|
}
|
|
132
141
|
}
|
|
133
142
|
@keyframes scroll-fade-reveal-e {
|
|
134
143
|
from {
|
|
135
|
-
--scroll-fade-e: var(
|
|
144
|
+
--scroll-fade-e: var(
|
|
145
|
+
--_scroll-fade-size-e,
|
|
146
|
+
var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
|
|
147
|
+
);
|
|
136
148
|
}
|
|
137
149
|
to {
|
|
138
150
|
--scroll-fade-e: 0px;
|
|
@@ -320,10 +332,7 @@
|
|
|
320
332
|
@supports (animation-timeline: scroll()) {
|
|
321
333
|
animation: scroll-fade-reveal-b 1ms ease-in-out;
|
|
322
334
|
animation-timeline: scroll(self y);
|
|
323
|
-
animation-range: calc(
|
|
324
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
325
|
-
)
|
|
326
|
-
100%;
|
|
335
|
+
animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
327
336
|
animation-fill-mode: both;
|
|
328
337
|
}
|
|
329
338
|
|
|
@@ -383,10 +392,7 @@
|
|
|
383
392
|
@supports (animation-timeline: scroll()) {
|
|
384
393
|
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
385
394
|
animation-timeline: scroll(self x);
|
|
386
|
-
animation-range: calc(
|
|
387
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
388
|
-
)
|
|
389
|
-
100%;
|
|
395
|
+
animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
390
396
|
animation-fill-mode: both;
|
|
391
397
|
}
|
|
392
398
|
|
|
@@ -462,10 +468,7 @@
|
|
|
462
468
|
@supports (animation-timeline: scroll()) {
|
|
463
469
|
animation: scroll-fade-reveal-e 1ms ease-in-out;
|
|
464
470
|
animation-timeline: scroll(self inline);
|
|
465
|
-
animation-range: calc(
|
|
466
|
-
100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
|
|
467
|
-
)
|
|
468
|
-
100%;
|
|
471
|
+
animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
|
|
469
472
|
animation-fill-mode: both;
|
|
470
473
|
}
|
|
471
474
|
|
|
@@ -532,21 +535,16 @@
|
|
|
532
535
|
@utility shimmer {
|
|
533
536
|
--_spread: var(--shimmer-spread, calc(3ch + 40px));
|
|
534
537
|
--_base: currentColor;
|
|
535
|
-
--_highlight: var(
|
|
536
|
-
--shimmer-color,
|
|
537
|
-
oklch(from currentColor l c h / calc(alpha* 0.2))
|
|
538
|
-
);
|
|
538
|
+
--_highlight: var(--shimmer-color, oklch(from currentColor l c h / calc(alpha* 0.2)));
|
|
539
539
|
|
|
540
540
|
background-image: var(
|
|
541
541
|
--shimmer-image,
|
|
542
542
|
linear-gradient(
|
|
543
543
|
calc(90deg + var(--shimmer-angle)),
|
|
544
544
|
var(--_base) calc(50% - var(--_spread)),
|
|
545
|
-
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
546
|
-
calc(50% - var(--_spread) * 0.5),
|
|
545
|
+
color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% - var(--_spread) * 0.5),
|
|
547
546
|
var(--_highlight) 50%,
|
|
548
|
-
color-mix(in oklch, var(--_highlight), var(--_base) 50%)
|
|
549
|
-
calc(50% + var(--_spread) * 0.5),
|
|
547
|
+
color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% + var(--_spread) * 0.5),
|
|
550
548
|
var(--_base) calc(50% + var(--_spread))
|
|
551
549
|
)
|
|
552
550
|
);
|
|
@@ -613,45 +611,103 @@
|
|
|
613
611
|
}
|
|
614
612
|
}
|
|
615
613
|
|
|
616
|
-
|
|
617
614
|
/* Message entrance animations for the MessageScroller demos. */
|
|
618
615
|
@keyframes ms-anim-fade {
|
|
619
|
-
from {
|
|
620
|
-
|
|
616
|
+
from {
|
|
617
|
+
opacity: 0;
|
|
618
|
+
}
|
|
619
|
+
to {
|
|
620
|
+
opacity: 1;
|
|
621
|
+
}
|
|
621
622
|
}
|
|
622
623
|
@keyframes ms-anim-slide-up {
|
|
623
|
-
from {
|
|
624
|
-
|
|
624
|
+
from {
|
|
625
|
+
opacity: 0;
|
|
626
|
+
transform: translateY(10px);
|
|
627
|
+
}
|
|
628
|
+
to {
|
|
629
|
+
opacity: 1;
|
|
630
|
+
transform: translateY(0);
|
|
631
|
+
}
|
|
625
632
|
}
|
|
626
633
|
@keyframes ms-anim-slide-side {
|
|
627
|
-
from {
|
|
628
|
-
|
|
634
|
+
from {
|
|
635
|
+
opacity: 0;
|
|
636
|
+
transform: translateX(18px);
|
|
637
|
+
}
|
|
638
|
+
to {
|
|
639
|
+
opacity: 1;
|
|
640
|
+
transform: translateX(0);
|
|
641
|
+
}
|
|
629
642
|
}
|
|
630
643
|
@keyframes ms-anim-pop {
|
|
631
|
-
from {
|
|
632
|
-
|
|
644
|
+
from {
|
|
645
|
+
opacity: 0;
|
|
646
|
+
transform: translateY(6px) scale(0.94);
|
|
647
|
+
}
|
|
648
|
+
to {
|
|
649
|
+
opacity: 1;
|
|
650
|
+
transform: translateY(0) scale(1);
|
|
651
|
+
}
|
|
633
652
|
}
|
|
634
653
|
@keyframes ms-anim-spring-bounce {
|
|
635
|
-
0% {
|
|
636
|
-
|
|
637
|
-
|
|
654
|
+
0% {
|
|
655
|
+
opacity: 0;
|
|
656
|
+
transform: translateY(12px) scale(0.96);
|
|
657
|
+
}
|
|
658
|
+
60% {
|
|
659
|
+
opacity: 1;
|
|
660
|
+
transform: translateY(-2px) scale(1.01);
|
|
661
|
+
}
|
|
662
|
+
100% {
|
|
663
|
+
opacity: 1;
|
|
664
|
+
transform: translateY(0) scale(1);
|
|
665
|
+
}
|
|
638
666
|
}
|
|
639
667
|
@keyframes ms-anim-blur-fade {
|
|
640
|
-
from {
|
|
641
|
-
|
|
668
|
+
from {
|
|
669
|
+
opacity: 0;
|
|
670
|
+
filter: blur(4px);
|
|
671
|
+
transform: translateY(6px);
|
|
672
|
+
}
|
|
673
|
+
to {
|
|
674
|
+
opacity: 1;
|
|
675
|
+
filter: blur(0);
|
|
676
|
+
transform: translateY(0);
|
|
677
|
+
}
|
|
642
678
|
}
|
|
643
679
|
@keyframes ms-anim-scale-fade {
|
|
644
|
-
from {
|
|
645
|
-
|
|
680
|
+
from {
|
|
681
|
+
opacity: 0;
|
|
682
|
+
transform: scale(0.98);
|
|
683
|
+
}
|
|
684
|
+
to {
|
|
685
|
+
opacity: 1;
|
|
686
|
+
transform: scale(1);
|
|
687
|
+
}
|
|
646
688
|
}
|
|
647
689
|
|
|
648
|
-
.ms-anim-fade {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
.ms-anim-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
.ms-anim-
|
|
690
|
+
.ms-anim-fade {
|
|
691
|
+
animation: ms-anim-fade 0.26s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
692
|
+
}
|
|
693
|
+
.ms-anim-slide-up {
|
|
694
|
+
animation: ms-anim-slide-up 0.26s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
695
|
+
}
|
|
696
|
+
.ms-anim-slide-side {
|
|
697
|
+
animation: ms-anim-slide-side 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
698
|
+
}
|
|
699
|
+
.ms-anim-pop {
|
|
700
|
+
animation: ms-anim-pop 0.28s cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
701
|
+
}
|
|
702
|
+
.ms-anim-spring-bounce {
|
|
703
|
+
animation: ms-anim-spring-bounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
|
|
704
|
+
}
|
|
705
|
+
.ms-anim-blur-fade {
|
|
706
|
+
animation: ms-anim-blur-fade 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
707
|
+
}
|
|
708
|
+
.ms-anim-scale-fade {
|
|
709
|
+
animation: ms-anim-scale-fade 0.24s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
710
|
+
}
|
|
655
711
|
|
|
656
712
|
@media (prefers-reduced-motion: reduce) {
|
|
657
713
|
[class*="ms-anim-"] {
|
|
@@ -15,11 +15,9 @@
|
|
|
15
15
|
</UiDrawerClose>
|
|
16
16
|
</UiDrawerHeader>
|
|
17
17
|
|
|
18
|
-
<
|
|
19
|
-
class="min-h-0 flex-1 mask-[linear-gradient(to_bottom,transparent,white_12px,white_calc(100%-12px),transparent)] px-4 py-4"
|
|
20
|
-
>
|
|
18
|
+
<div class="min-h-0 flex-1 scroll-fade overflow-y-auto px-4 py-4">
|
|
21
19
|
<DocsNav v-if="navigation" :items="navigation" />
|
|
22
|
-
</
|
|
20
|
+
</div>
|
|
23
21
|
|
|
24
22
|
<div
|
|
25
23
|
class="mt-auto flex h-(--header-height) items-center justify-between gap-3 border-t px-2"
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
class="w-full min-w-0 overflow-x-clip"
|
|
4
4
|
:class="[isAnimating && 'pointer-events-none overflow-clip']"
|
|
5
5
|
>
|
|
6
|
-
<AnimatePresence mode="wait"
|
|
6
|
+
<AnimatePresence mode="wait">
|
|
7
7
|
<Motion
|
|
8
|
-
:key="
|
|
8
|
+
:key="$router.currentRoute.value.path"
|
|
9
9
|
:initial="preset.initial"
|
|
10
10
|
:animate="animate"
|
|
11
11
|
:exit="preset.exit"
|
|
@@ -20,13 +20,15 @@
|
|
|
20
20
|
|
|
21
21
|
<script lang="ts" setup>
|
|
22
22
|
const route = useRoute();
|
|
23
|
+
const activeRoute = computed(() => route.path);
|
|
23
24
|
const { preset, animate, duration, easing } = useDocd();
|
|
24
25
|
|
|
25
26
|
const isAnimating = ref(false);
|
|
26
|
-
watch(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
watch(activeRoute, () => {
|
|
28
|
+
isAnimating.value = true;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
useNuxtApp().hook("page:finish", () => {
|
|
32
|
+
isAnimating.value = false;
|
|
33
|
+
});
|
|
32
34
|
</script>
|
|
@@ -38,6 +38,12 @@ export function useDocd() {
|
|
|
38
38
|
const headerTitle = computed(() => header.value.title ?? "");
|
|
39
39
|
const hideSearch = computed(() => header.value.hideSearch ?? false);
|
|
40
40
|
|
|
41
|
+
/* =====================================
|
|
42
|
+
= Body. =
|
|
43
|
+
===================================== */
|
|
44
|
+
const body = useUIConfig("body");
|
|
45
|
+
const maxWidth = computed(() => body.value.maxWidth ?? "1280px");
|
|
46
|
+
|
|
41
47
|
/* =====================================
|
|
42
48
|
= Logo =
|
|
43
49
|
===================================== */
|
|
@@ -107,5 +113,8 @@ export function useDocd() {
|
|
|
107
113
|
// footer
|
|
108
114
|
hideThemeCustomizer,
|
|
109
115
|
hideLightDarkToggle,
|
|
116
|
+
// body
|
|
117
|
+
body,
|
|
118
|
+
maxWidth,
|
|
110
119
|
};
|
|
111
120
|
}
|
|
@@ -6,6 +6,9 @@ interface DocdUIMap {
|
|
|
6
6
|
hideSearch?: boolean;
|
|
7
7
|
logo?: DocLogoConfig;
|
|
8
8
|
};
|
|
9
|
+
body: {
|
|
10
|
+
maxWidth?: `${number}px`;
|
|
11
|
+
};
|
|
9
12
|
footer?: {
|
|
10
13
|
hideThemeCustomizer?: boolean;
|
|
11
14
|
hideLightDarkToggle?: boolean;
|
|
@@ -30,6 +33,7 @@ export function useUIConfig<K extends keyof DocdUIMap>(section: K): ComputedRef<
|
|
|
30
33
|
|
|
31
34
|
const defaultValues: DocdUIMap = {
|
|
32
35
|
header: {},
|
|
36
|
+
body: { maxWidth: "1280px" },
|
|
33
37
|
toc: { title: "On this page", icon: "lucide:list" },
|
|
34
38
|
borderType: "dashed",
|
|
35
39
|
transition: { name: "fade", duration: 0.35, easing: "easeOut" },
|
package/app/layouts/docs.vue
CHANGED
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
<DocsSearchButton v-if="!hideSearch" />
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
|
-
<
|
|
17
|
-
class="h-[calc(100dvh-calc(var(--header-height)*2))] flex-1
|
|
16
|
+
<div
|
|
17
|
+
class="h-[calc(100dvh-calc(var(--header-height)*2))] flex-1 scroll-fade overflow-y-auto px-4"
|
|
18
18
|
>
|
|
19
19
|
<DocsNav v-if="navigation" :items="navigation" />
|
|
20
|
-
</
|
|
20
|
+
</div>
|
|
21
21
|
<div
|
|
22
22
|
class="mt-auto flex h-(--header-height) items-center justify-between gap-3 border-t px-2"
|
|
23
23
|
:class="isDashed ? 'border-dashed' : ''"
|
|
@@ -60,6 +60,5 @@
|
|
|
60
60
|
|
|
61
61
|
<script lang="ts" setup>
|
|
62
62
|
const { navigation } = await useDocPage();
|
|
63
|
-
const { isDashed,
|
|
64
|
-
useDocd();
|
|
63
|
+
const { isDashed, hasGithub, hideSearch, hideLightDarkToggle, hideThemeCustomizer } = useDocd();
|
|
65
64
|
</script>
|
package/app/pages/[...slug].vue
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
>
|
|
10
10
|
<div
|
|
11
11
|
v-if="page"
|
|
12
|
-
class="container prose prose-base
|
|
12
|
+
class="container prose prose-base min-w-0 py-5 dark:prose-invert prose-headings:scroll-mt-20 prose-headings:tracking-tight prose-h2:mt-6 prose-h2:border-b prose-h2:pb-3 first:prose-h2:mt-10 prose-a:text-primary prose-a:no-underline prose-a:hover:underline prose-a:hover:underline-offset-2 prose-pre:my-0 prose-pre:rounded-sm prose-pre:p-2 prose-pre:px-0 prose-pre:text-base"
|
|
13
13
|
:class="[isDashed ? 'prose-headings:border-dashed' : '']"
|
|
14
|
+
:style="{ maxWidth: maxWidth }"
|
|
14
15
|
>
|
|
15
16
|
<PageHeader />
|
|
16
17
|
<ContentRenderer :value="page" />
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
const route = useRoute();
|
|
29
30
|
|
|
30
31
|
const { page, navigation, headline, breadcrumbs } = await useDocPage();
|
|
31
|
-
const { isDashed } = useDocd();
|
|
32
|
+
const { isDashed, maxWidth } = useDocd();
|
|
32
33
|
|
|
33
34
|
if (!page.value) {
|
|
34
35
|
throw createError({ statusCode: 404, statusMessage: "Page not found", fatal: true });
|
package/index.d.ts
CHANGED
package/modules/css.ts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve as resolvePath } from "node:path";
|
|
2
4
|
|
|
3
|
-
import { addVitePlugin, createResolver, defineNuxtModule } from "@nuxt/kit";
|
|
5
|
+
import { addVitePlugin, createResolver, defineNuxtModule, logger } from "@nuxt/kit";
|
|
6
|
+
import { defu } from "defu";
|
|
4
7
|
|
|
5
|
-
export
|
|
8
|
+
export interface CssModuleOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Paths (relative to the consuming app root, or absolute) to CSS files that
|
|
11
|
+
* should be merged into the layer's Tailwind entry.
|
|
12
|
+
*
|
|
13
|
+
* Files that only use `@apply` already work without this — they get
|
|
14
|
+
* `@reference` injected automatically.
|
|
15
|
+
*
|
|
16
|
+
* Use `extend` for anything that needs
|
|
17
|
+
* more than that (`@theme`, `@utility`, `@custom-variant`, etc.), since those
|
|
18
|
+
* only take effect when the file is part of the same Tailwind build as the
|
|
19
|
+
* layer, not a separate one started by its own `@import "tailwindcss"`.
|
|
20
|
+
*/
|
|
21
|
+
extend?: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const defaults: Required<CssModuleOptions> = {
|
|
25
|
+
extend: [],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const log = logger.withTag("Docd");
|
|
29
|
+
|
|
30
|
+
export default defineNuxtModule<CssModuleOptions>({
|
|
6
31
|
meta: {
|
|
7
32
|
name: "docd:css",
|
|
8
33
|
},
|
|
@@ -12,11 +37,30 @@ export default defineNuxtModule({
|
|
|
12
37
|
// Absolute path to the layer's tailwind entry — resolved from this module's
|
|
13
38
|
// location so it stays correct whether docd is local or installed from npm.
|
|
14
39
|
const tailwindCssPath = resolver.resolve("../app/assets/css/tailwind.css").replace(/\\/g, "/");
|
|
40
|
+
const tailwindCssDir = dirname(tailwindCssPath);
|
|
15
41
|
|
|
16
42
|
// Absolute paths that Tailwind needs to scan.
|
|
17
43
|
const rootDir = nuxt.options.rootDir.replace(/\\/g, "/");
|
|
18
44
|
const layerAppDir = resolver.resolve("../app").replace(/\\/g, "/");
|
|
19
45
|
|
|
46
|
+
const options = defu(
|
|
47
|
+
(nuxt.options as unknown as { docd?: { css?: CssModuleOptions } }).docd?.css,
|
|
48
|
+
defaults
|
|
49
|
+
) as Required<CssModuleOptions>;
|
|
50
|
+
|
|
51
|
+
// Resolve and validate consumer-provided files that opt into being merged
|
|
52
|
+
// into the layer's single Tailwind build.
|
|
53
|
+
const extendPaths = options.extend
|
|
54
|
+
.map((file) =>
|
|
55
|
+
(isAbsolute(file) ? file : resolvePath(nuxt.options.rootDir, file)).replace(/\\/g, "/")
|
|
56
|
+
)
|
|
57
|
+
.filter((file) => {
|
|
58
|
+
if (existsSync(file)) return true;
|
|
59
|
+
log.warn(`docd.css.extend: CSS file not found, skipping: ${file}`);
|
|
60
|
+
return false;
|
|
61
|
+
});
|
|
62
|
+
const extendPathSet = new Set(extendPaths);
|
|
63
|
+
|
|
20
64
|
// Use the `load` hook rather than `transform` so our modified source is
|
|
21
65
|
// visible to @tailwindcss/vite's transform hook (which has enforce:"pre"
|
|
22
66
|
// and is registered earlier). Vite always runs `load` before `transform`.
|
|
@@ -28,10 +72,21 @@ export default defineNuxtModule({
|
|
|
28
72
|
if (cleanId !== tailwindCssPath) return null;
|
|
29
73
|
|
|
30
74
|
const code = await readFile(tailwindCssPath, "utf8");
|
|
75
|
+
|
|
76
|
+
// `@import` each consumer-registered file so it's part of this same
|
|
77
|
+
// Tailwind compilation (one theme/base/utilities pass) instead of
|
|
78
|
+
// starting its own via a separate `@import "tailwindcss"`.
|
|
79
|
+
const extendImports = extendPaths.map((file) => {
|
|
80
|
+
this.addWatchFile(file);
|
|
81
|
+
const rel = relative(tailwindCssDir, file).replace(/\\/g, "/");
|
|
82
|
+
return `@import ${JSON.stringify(rel.startsWith(".") ? rel : `./${rel}`)};`;
|
|
83
|
+
});
|
|
84
|
+
|
|
31
85
|
return [
|
|
32
86
|
code,
|
|
33
87
|
`@source ${JSON.stringify(`${rootDir}/**/*`)};`,
|
|
34
88
|
`@source ${JSON.stringify(`${layerAppDir}/**/*`)};`,
|
|
89
|
+
...extendImports,
|
|
35
90
|
].join("\n");
|
|
36
91
|
},
|
|
37
92
|
});
|
|
@@ -48,6 +103,10 @@ export default defineNuxtModule({
|
|
|
48
103
|
if (!cleanId?.endsWith(".css")) return null;
|
|
49
104
|
// Skip the layer's own tailwind entry — it already has @import "tailwindcss".
|
|
50
105
|
if (cleanId === tailwindCssPath) return null;
|
|
106
|
+
// Skip files merged in via `docd.css.extend` — they're already `@import`ed
|
|
107
|
+
// into the tailwind entry above, so injecting `@reference` back to that
|
|
108
|
+
// same entry here would create a circular import.
|
|
109
|
+
if (extendPathSet.has(cleanId)) return null;
|
|
51
110
|
// Only touch files inside the consuming app root, not node_modules or the layer.
|
|
52
111
|
if (!cleanId.startsWith(`${rootDir}/`)) return null;
|
|
53
112
|
if (cleanId.startsWith(`${layerAppDir}/`)) return null;
|
|
@@ -76,11 +135,11 @@ export default defineNuxtModule({
|
|
|
76
135
|
|
|
77
136
|
// Suppress noisy Vite warnings produced during Tailwind's build pass.
|
|
78
137
|
nuxt.hook("vite:extendConfig", (config) => {
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
138
|
+
const viteLogger = config.customLogger;
|
|
139
|
+
if (!viteLogger) return;
|
|
81
140
|
const ignore = ["@tailwindcss/vite:generate:build", "nuxt:module-preload-polyfill"];
|
|
82
|
-
const originalWarn =
|
|
83
|
-
|
|
141
|
+
const originalWarn = viteLogger.warn.bind(viteLogger);
|
|
142
|
+
viteLogger.warn = (msg, options) => {
|
|
84
143
|
if (ignore.some((p) => msg.includes(p))) return;
|
|
85
144
|
originalWarn(msg, options);
|
|
86
145
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baybreezy/docd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A Nuxt layer for building documentation sites with UI Thing.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,24 +31,21 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@baybreezy/file-extension-icon": "^0.0.5",
|
|
34
|
-
"@iconify-json/lucide": "^1.2.116",
|
|
35
|
-
"@iconify-json/material-icon-theme": "^1.2.69",
|
|
36
|
-
"@iconify-json/simple-icons": "^1.2.89",
|
|
37
34
|
"@iconify/utils": "^3.1.4",
|
|
38
35
|
"@morev/vue-transitions": "^3.0.5",
|
|
39
36
|
"@nuxt/content": "3.15.0",
|
|
40
37
|
"@nuxt/fonts": "^0.14.0",
|
|
41
38
|
"@nuxt/icon": "^2.3.1",
|
|
42
39
|
"@nuxt/image": "2.0.0",
|
|
43
|
-
"@nuxt/kit": "^4.
|
|
40
|
+
"@nuxt/kit": "^4.5.0",
|
|
44
41
|
"@nuxtjs/color-mode": "^4.0.1",
|
|
45
|
-
"@nuxtjs/mcp-toolkit": "^0.
|
|
46
|
-
"@nuxtjs/mdc": "^0.22.
|
|
42
|
+
"@nuxtjs/mcp-toolkit": "^0.18.0",
|
|
43
|
+
"@nuxtjs/mdc": "^0.22.2",
|
|
47
44
|
"@nuxtjs/robots": "^6.1.2",
|
|
48
45
|
"@tailwindcss/forms": "^0.5.11",
|
|
49
46
|
"@tailwindcss/typography": "^0.5.20",
|
|
50
|
-
"@tailwindcss/vite": "^4.3.
|
|
51
|
-
"@takumi-rs/core": "^2.0
|
|
47
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
48
|
+
"@takumi-rs/core": "^2.3.0",
|
|
52
49
|
"@vueuse/core": "^14.3.0",
|
|
53
50
|
"@vueuse/nuxt": "^14.3.0",
|
|
54
51
|
"better-sqlite3": "^12.11.1",
|
|
@@ -57,7 +54,7 @@
|
|
|
57
54
|
"lodash-es": "^4.18.1",
|
|
58
55
|
"mermaid": "^11.16.0",
|
|
59
56
|
"motion-v": "^2.3.0",
|
|
60
|
-
"nuxt-component-meta": "^0.
|
|
57
|
+
"nuxt-component-meta": "^0.18.0",
|
|
61
58
|
"nuxt-gtag": "4.1.0",
|
|
62
59
|
"nuxt-llms": "^0.2.0",
|
|
63
60
|
"nuxt-og-image": "^6.7.2",
|
|
@@ -66,7 +63,7 @@
|
|
|
66
63
|
"shiki": "^4.3.1",
|
|
67
64
|
"tailwind-merge": "^3.6.0",
|
|
68
65
|
"tailwind-variants": "^3.2.2",
|
|
69
|
-
"tailwindcss": "^4.3.
|
|
66
|
+
"tailwindcss": "^4.3.3",
|
|
70
67
|
"tw-animate-css": "^1.4.0",
|
|
71
68
|
"ufo": "^1.6.4",
|
|
72
69
|
"vaul-vue": "^0.4.1",
|
|
@@ -76,10 +73,10 @@
|
|
|
76
73
|
},
|
|
77
74
|
"devDependencies": {
|
|
78
75
|
"@types/lodash-es": "^4.17.12",
|
|
79
|
-
"nuxt": "^4.
|
|
76
|
+
"nuxt": "^4.5.0",
|
|
80
77
|
"typescript": "^6.0.3",
|
|
81
78
|
"vue": "latest",
|
|
82
|
-
"vue-router": "^5.
|
|
79
|
+
"vue-router": "^5.2.0"
|
|
83
80
|
},
|
|
84
81
|
"packageManager": "bun@1.3.14",
|
|
85
82
|
"trustedDependencies": [
|