@sit-onyx/nuxt-docs 0.7.0-dev-20260518082510 → 0.7.0-dev-20260518083349
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.
|
@@ -21,6 +21,12 @@ const props = defineProps<{
|
|
|
21
21
|
* @see https://content.nuxt.com/docs/utils/query-collection-search-sections#api
|
|
22
22
|
*/
|
|
23
23
|
options?: Parameters<typeof queryCollectionSearchSections>[1];
|
|
24
|
+
/**
|
|
25
|
+
* List of collections to include in the search.
|
|
26
|
+
*
|
|
27
|
+
* @default "content_{locale}" where `{locale}` is replaced with the current i18n locale.
|
|
28
|
+
*/
|
|
29
|
+
collections?: (keyof Collections)[];
|
|
24
30
|
}>();
|
|
25
31
|
|
|
26
32
|
const { t, locale, locales } = useI18n();
|
|
@@ -32,11 +38,21 @@ watch(isOpen, (open) => {
|
|
|
32
38
|
if (!open) searchTerm.value = "";
|
|
33
39
|
});
|
|
34
40
|
|
|
41
|
+
const collections = computed<(keyof Collections)[]>(() => {
|
|
42
|
+
if (props.collections) return props.collections;
|
|
43
|
+
return [`content_${locale.value}` as keyof Collections];
|
|
44
|
+
});
|
|
45
|
+
|
|
35
46
|
const { data, status } = await useLazyAsyncData(
|
|
36
|
-
() => `search-sections-${
|
|
37
|
-
() => {
|
|
38
|
-
const
|
|
39
|
-
|
|
47
|
+
() => `search-sections-${collections.value.join("-")}-${props.options}`,
|
|
48
|
+
async () => {
|
|
49
|
+
const sections = await Promise.all(
|
|
50
|
+
collections.value.map((collection) => {
|
|
51
|
+
return queryCollectionSearchSections(collection, props.options);
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return sections.flatMap((section) => section);
|
|
40
56
|
},
|
|
41
57
|
);
|
|
42
58
|
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
1
|
+
<script lang="ts" setup generic="TItem extends SidebarNavigationItem">
|
|
2
2
|
import type { SidebarNavigationItem } from "../composables/useSidebarNavigation.js";
|
|
3
3
|
import type { SidebarItemProps } from "./SidebarItem.vue";
|
|
4
4
|
|
|
5
5
|
const props = defineProps<{
|
|
6
|
-
item:
|
|
6
|
+
item: TItem;
|
|
7
|
+
}>();
|
|
8
|
+
|
|
9
|
+
const slots = defineSlots<{
|
|
10
|
+
/**
|
|
11
|
+
* Additional trailing content to display on the right.
|
|
12
|
+
*/
|
|
13
|
+
trailing?(props: { item: TItem }): unknown;
|
|
7
14
|
}>();
|
|
8
15
|
|
|
9
16
|
const route = useRoute();
|
|
@@ -54,7 +61,11 @@ const { icon } = useIcon(computed(() => props.item.icon));
|
|
|
54
61
|
v-if="!props.item.children?.length"
|
|
55
62
|
class="sidebar-item"
|
|
56
63
|
v-bind="getSidebarItemProps(props.item)"
|
|
57
|
-
|
|
64
|
+
>
|
|
65
|
+
<template v-if="slots.trailing" #trailing>
|
|
66
|
+
<slot name="trailing" :item="props.item"></slot>
|
|
67
|
+
</template>
|
|
68
|
+
</SidebarItem>
|
|
58
69
|
|
|
59
70
|
<OnyxAccordion
|
|
60
71
|
v-else
|
|
@@ -83,7 +94,11 @@ const { icon } = useIcon(computed(() => props.item.icon));
|
|
|
83
94
|
:show-arrow="
|
|
84
95
|
getSidebarItemProps(child).showArrow || getSidebarItemProps(props.item).showArrow
|
|
85
96
|
"
|
|
86
|
-
|
|
97
|
+
>
|
|
98
|
+
<template v-if="slots.trailing" #trailing>
|
|
99
|
+
<slot name="trailing" :item="child as TItem"></slot>
|
|
100
|
+
</template>
|
|
101
|
+
</SidebarItem>
|
|
87
102
|
</div>
|
|
88
103
|
</OnyxAccordionItem>
|
|
89
104
|
</OnyxAccordion>
|
|
@@ -15,19 +15,47 @@ export type SidebarItemProps = {
|
|
|
15
15
|
|
|
16
16
|
const props = defineProps<SidebarItemProps>();
|
|
17
17
|
|
|
18
|
+
const slots = defineSlots<{
|
|
19
|
+
/**
|
|
20
|
+
* Additional trailing content to display on the right.
|
|
21
|
+
*/
|
|
22
|
+
trailing?(): unknown;
|
|
23
|
+
}>();
|
|
24
|
+
|
|
18
25
|
const { icon } = useIcon(computed(() => props.icon));
|
|
19
26
|
</script>
|
|
20
27
|
|
|
21
28
|
<template>
|
|
22
29
|
<OnyxSidebarItem class="sidebar-item" :link="props.link">
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
<div class="sidebar-item__content">
|
|
31
|
+
<OnyxIcon v-if="icon" :icon />
|
|
32
|
+
{{ props.label }}
|
|
33
|
+
<OnyxIcon v-if="props.showArrow" :icon="iconArrowSmallRight" />
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div v-if="slots.trailing" class="sidebar-item__trailing onyx-density-compact">
|
|
37
|
+
<slot name="trailing"></slot>
|
|
38
|
+
</div>
|
|
26
39
|
</OnyxSidebarItem>
|
|
27
40
|
</template>
|
|
28
41
|
|
|
29
42
|
<style lang="scss" scoped>
|
|
30
43
|
.sidebar-item {
|
|
31
44
|
margin: var(--onyx-density-2xs) var(--onyx-density-xs);
|
|
45
|
+
flex-wrap: wrap;
|
|
46
|
+
justify-content: space-between;
|
|
47
|
+
|
|
48
|
+
&__content {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: inherit;
|
|
51
|
+
gap: inherit;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&__trailing {
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: inherit;
|
|
57
|
+
gap: inherit;
|
|
58
|
+
flex-wrap: wrap;
|
|
59
|
+
}
|
|
32
60
|
}
|
|
33
61
|
</style>
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { computed, useAsyncData, useI18n, useLocalePath, useRoute } from "#imports"; // since nuxt 4.3 the auto-imports don't work for this composable anymore; Might be related to https://github.com/nuxt/nuxt/issues/22342
|
|
2
2
|
import type { Collections, ContentNavigationItem } from "@nuxt/content";
|
|
3
3
|
|
|
4
|
-
export type SidebarNavigationItem = {
|
|
4
|
+
export type SidebarNavigationItem<TCollection extends keyof Collections = keyof Collections> = {
|
|
5
5
|
title: string;
|
|
6
6
|
/**
|
|
7
7
|
* Item path. Already localized for i18n with `useLocalePath`.
|
|
8
8
|
*/
|
|
9
9
|
path: string;
|
|
10
10
|
icon?: string;
|
|
11
|
-
children?: SidebarNavigationItem[];
|
|
11
|
+
children?: SidebarNavigationItem<TCollection>[];
|
|
12
12
|
sidebar?: SidebarNavigationOptions;
|
|
13
|
+
/**
|
|
14
|
+
* Additional fields. Must be defined when calling `useSidebarNavigation()`.
|
|
15
|
+
*/
|
|
16
|
+
fields?: Partial<Collections[TCollection]>;
|
|
13
17
|
};
|
|
14
18
|
|
|
15
19
|
/**
|
|
@@ -34,24 +38,33 @@ export type SidebarNavigationOptions = {
|
|
|
34
38
|
collapsed?: boolean;
|
|
35
39
|
};
|
|
36
40
|
|
|
37
|
-
export type UseSidebarNavigationOptions =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
export type UseSidebarNavigationOptions<TCollection extends keyof Collections = keyof Collections> =
|
|
42
|
+
{
|
|
43
|
+
/**
|
|
44
|
+
* Collection name to use for querying the navigation.
|
|
45
|
+
*/
|
|
46
|
+
collection: Ref<TCollection>;
|
|
47
|
+
/**
|
|
48
|
+
* Additional fields to include.
|
|
49
|
+
*/
|
|
50
|
+
fields?: (keyof Collections[TCollection])[];
|
|
51
|
+
};
|
|
43
52
|
|
|
44
53
|
/**
|
|
45
54
|
* Composable for querying and mapping the navigation items for a given collection.
|
|
46
55
|
*/
|
|
47
|
-
export const useSidebarNavigation = async
|
|
56
|
+
export const useSidebarNavigation = async <
|
|
57
|
+
TCollection extends keyof Collections = keyof Collections,
|
|
58
|
+
>(
|
|
59
|
+
options: UseSidebarNavigationOptions<TCollection>,
|
|
60
|
+
) => {
|
|
48
61
|
const { locale } = useI18n();
|
|
49
62
|
const localePath = useLocalePath();
|
|
50
63
|
const route = useRoute();
|
|
51
64
|
|
|
52
65
|
const { data } = await useAsyncData(
|
|
53
66
|
() => `navigation-${options.collection.value}-${locale.value}`,
|
|
54
|
-
() => queryCollectionNavigation(options.collection.value),
|
|
67
|
+
() => queryCollectionNavigation(options.collection.value, options.fields),
|
|
55
68
|
{ default: () => [] },
|
|
56
69
|
);
|
|
57
70
|
|
|
@@ -60,13 +73,23 @@ export const useSidebarNavigation = async (options: UseSidebarNavigationOptions)
|
|
|
60
73
|
*/
|
|
61
74
|
const allItems = computed(() => {
|
|
62
75
|
// map the items from "@nuxt/content" to our custom data scheme for better type support
|
|
63
|
-
const mapItem = (item: ContentNavigationItem): SidebarNavigationItem => {
|
|
76
|
+
const mapItem = (item: ContentNavigationItem): SidebarNavigationItem<TCollection> => {
|
|
77
|
+
const fields = options.fields?.reduce(
|
|
78
|
+
(obj, field) => {
|
|
79
|
+
const extraFieldValue = item[field as keyof typeof item];
|
|
80
|
+
obj[field] = extraFieldValue as Collections[TCollection][typeof field];
|
|
81
|
+
return obj;
|
|
82
|
+
},
|
|
83
|
+
{} as Collections[TCollection],
|
|
84
|
+
);
|
|
85
|
+
|
|
64
86
|
return {
|
|
65
87
|
title: item.title,
|
|
66
88
|
path: localePath(item.path),
|
|
67
89
|
children: item.children?.map(mapItem),
|
|
68
90
|
sidebar: item.sidebar && typeof item.sidebar === "object" ? item.sidebar : undefined,
|
|
69
91
|
icon: item.icon && typeof item.icon === "string" ? item.icon : undefined,
|
|
92
|
+
fields,
|
|
70
93
|
};
|
|
71
94
|
};
|
|
72
95
|
|
|
@@ -91,9 +114,9 @@ export const useSidebarNavigation = async (options: UseSidebarNavigationOptions)
|
|
|
91
114
|
* that contains the `currentPath` within its subtree.
|
|
92
115
|
*/
|
|
93
116
|
function findDeepestRoot(
|
|
94
|
-
items: SidebarNavigationItem[],
|
|
117
|
+
items: SidebarNavigationItem<TCollection>[],
|
|
95
118
|
currentPath: string,
|
|
96
|
-
): SidebarNavigationItem | undefined {
|
|
119
|
+
): SidebarNavigationItem<TCollection> | undefined {
|
|
97
120
|
/** Helper function to check if a path exists anywhere in a node's subtree */
|
|
98
121
|
const containsPath = (node: SidebarNavigationItem, path: string): boolean => {
|
|
99
122
|
if (node.path === path) return true;
|
|
@@ -125,10 +148,10 @@ export const useSidebarNavigation = async (options: UseSidebarNavigationOptions)
|
|
|
125
148
|
* @param rootStack - (Internal) Accumulator for recursion
|
|
126
149
|
*/
|
|
127
150
|
function findPreviousRootItem(
|
|
128
|
-
items: SidebarNavigationItem[],
|
|
151
|
+
items: SidebarNavigationItem<TCollection>[],
|
|
129
152
|
currentPath: string,
|
|
130
|
-
rootStack: SidebarNavigationItem[] = [],
|
|
131
|
-
): SidebarNavigationItem | undefined {
|
|
153
|
+
rootStack: SidebarNavigationItem<TCollection>[] = [],
|
|
154
|
+
): SidebarNavigationItem<TCollection> | undefined {
|
|
132
155
|
for (const item of items) {
|
|
133
156
|
const isRoot = item.sidebar?.root === true;
|
|
134
157
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sit-onyx/nuxt-docs",
|
|
3
|
-
"version": "0.7.0-dev-
|
|
3
|
+
"version": "0.7.0-dev-20260518083349",
|
|
4
4
|
"description": "Nuxt layer/template for creating documentations with the onyx design system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Schwarz IT KG",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"sass-embedded": ">= 1",
|
|
36
36
|
"@sit-onyx/icons": "^1.9.1",
|
|
37
37
|
"@sit-onyx/nuxt": "^1.0.1",
|
|
38
|
-
"sit-onyx": "^1.14.0-dev-
|
|
38
|
+
"sit-onyx": "^1.14.0-dev-20260518083349"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@fontsource-variable/source-code-pro": "^5.2.7",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@sit-onyx/icons": "^1.9.1",
|
|
54
54
|
"@sit-onyx/nuxt": "^1.0.1",
|
|
55
55
|
"@sit-onyx/shared": "^0.1.0",
|
|
56
|
-
"sit-onyx": "^1.14.0-dev-
|
|
56
|
+
"sit-onyx": "^1.14.0-dev-20260518083349"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"dev": "pnpm dev:prepare && nuxi dev playground",
|