@sit-onyx/nuxt-docs 0.1.0-dev-20251112123258 → 0.1.0-dev-20251112124157

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.
@@ -2,6 +2,13 @@
2
2
  import { iconCircleContrast } from "@sit-onyx/icons";
3
3
  import type { ColorSchemeValue } from "sit-onyx";
4
4
 
5
+ defineSlots<{
6
+ /**
7
+ * Optional slot to override the trigger slot.
8
+ */
9
+ default?(props: { trigger: typeof trigger }): unknown;
10
+ }>();
11
+
5
12
  const colorMode = useColorMode();
6
13
  const isColorSchemeDialogOpen = ref(false);
7
14
 
@@ -13,15 +20,21 @@ const colorScheme = computed({
13
20
  colorMode.preference = newValue === "auto" ? "system" : newValue;
14
21
  },
15
22
  });
23
+
24
+ const trigger = {
25
+ onClick: () => (isColorSchemeDialogOpen.value = true),
26
+ };
16
27
  </script>
17
28
 
18
29
  <template>
19
- <OnyxIconButton
20
- label="Toggle color scheme"
21
- :icon="iconCircleContrast"
22
- color="neutral"
23
- @click="isColorSchemeDialogOpen = true"
24
- />
30
+ <slot :trigger>
31
+ <OnyxIconButton
32
+ :label="$t('onyx.colorScheme.headline')"
33
+ :icon="iconCircleContrast"
34
+ color="neutral"
35
+ v-bind="trigger"
36
+ />
37
+ </slot>
25
38
 
26
39
  <OnyxColorSchemeDialog v-model="colorScheme" v-model:open="isColorSchemeDialogOpen" />
27
40
  </template>
@@ -0,0 +1,133 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ iconCircleContrast,
4
+ iconFile,
5
+ iconSearch,
6
+ iconToolText,
7
+ iconTranslate,
8
+ } from "@sit-onyx/icons";
9
+ import { mergeVueProps, normalizedIncludes, type OnyxGlobalSearchOptionProps } from "sit-onyx";
10
+
11
+ type SearchGroup = {
12
+ label: string;
13
+ options: OnyxGlobalSearchOptionProps[];
14
+ };
15
+
16
+ const { t, locale, locales } = useI18n();
17
+ const localePath = useLocalePath();
18
+
19
+ const isOpen = ref(false);
20
+ const searchTerm = ref("");
21
+ watch(isOpen, (open) => {
22
+ if (!open) searchTerm.value = "";
23
+ });
24
+
25
+ const { data, status } = await useLazyAsyncData(
26
+ () => `search-sections-${locale.value}`,
27
+ () => {
28
+ const collection = `content_${locale.value}` as const;
29
+ return queryCollectionSearchSections(collection);
30
+ },
31
+ );
32
+
33
+ const searchResults = computed<SearchGroup[]>(() => {
34
+ const map = new Map<string, OnyxGlobalSearchOptionProps[]>();
35
+
36
+ data.value?.forEach((section) => {
37
+ const parent =
38
+ section.level === 1
39
+ ? section.title
40
+ : (section.titles.at(0) ?? t("onyx.globalSearch.searchResults"));
41
+ const options = map.get(parent) ?? [];
42
+
43
+ let icon = iconToolText;
44
+ if (section.level === 1) icon = iconFile;
45
+
46
+ const option: OnyxGlobalSearchOptionProps = {
47
+ label: section.content ? `${section.title} > ${section.content}` : section.title,
48
+ value: section.id,
49
+ link: localePath(section.id),
50
+ icon,
51
+ };
52
+
53
+ // prevent duplicates
54
+ if (options.find((o) => o.value === option.value) || (section.level === 1 && options.length))
55
+ return;
56
+
57
+ options.push(option);
58
+ map.set(parent, options);
59
+ });
60
+
61
+ const groups = map
62
+ .entries()
63
+ .toArray()
64
+ .map<SearchGroup>(([label, options]) => ({ label, options }));
65
+
66
+ // add custom system wide actions
67
+ groups.push({
68
+ label: t("onyx.globalSearch.system"),
69
+ options: [
70
+ { label: t("onyx.languageSelect.headline"), value: "locale", icon: iconTranslate },
71
+ { label: t("onyx.colorScheme.headline"), value: "colorScheme", icon: iconCircleContrast },
72
+ ],
73
+ });
74
+
75
+ return groups;
76
+ });
77
+
78
+ const filteredSearchResults = computed(() => {
79
+ // if no search term is entered, we want to show all results so the search is never empty
80
+ if (!searchTerm.value) return searchResults.value;
81
+
82
+ return searchResults.value
83
+ .map<SearchGroup>((group) => {
84
+ return {
85
+ ...group,
86
+ options: group.options.filter((option) =>
87
+ normalizedIncludes(option.label, searchTerm.value),
88
+ ),
89
+ };
90
+ })
91
+ .filter((group) => group.options.length);
92
+ });
93
+ </script>
94
+
95
+ <template>
96
+ <OnyxIconButton
97
+ :label="$t('onyx.globalSearch.label')"
98
+ :icon="iconSearch"
99
+ color="neutral"
100
+ @click="isOpen = true"
101
+ />
102
+
103
+ <OnyxUnstableGlobalSearch
104
+ v-model="searchTerm"
105
+ v-model:open="isOpen"
106
+ :loading="status === 'pending'"
107
+ >
108
+ <template v-if="filteredSearchResults.length" #default>
109
+ <OnyxUnstableGlobalSearchGroup
110
+ v-for="group in filteredSearchResults"
111
+ :key="group.label"
112
+ :label="group.label"
113
+ :skeleton="status === 'pending'"
114
+ >
115
+ <template v-for="option in group.options" :key="option.value">
116
+ <LazyLocaleSwitch v-if="option.value === 'locale' && locales.length > 1">
117
+ <template #default="{ trigger }">
118
+ <OnyxUnstableGlobalSearchOption v-bind="mergeVueProps(trigger, option)" />
119
+ </template>
120
+ </LazyLocaleSwitch>
121
+
122
+ <ColorSchemeSwitch v-else-if="option.value === 'colorScheme'">
123
+ <template #default="{ trigger }">
124
+ <OnyxUnstableGlobalSearchOption v-bind="mergeVueProps(trigger, option)" />
125
+ </template>
126
+ </ColorSchemeSwitch>
127
+
128
+ <OnyxUnstableGlobalSearchOption v-else v-bind="option" @click="isOpen = false" />
129
+ </template>
130
+ </OnyxUnstableGlobalSearchGroup>
131
+ </template>
132
+ </OnyxUnstableGlobalSearch>
133
+ </template>
@@ -2,6 +2,13 @@
2
2
  import { iconTranslate } from "@sit-onyx/icons";
3
3
  import type { SelectDialogOption } from "sit-onyx";
4
4
 
5
+ defineSlots<{
6
+ /**
7
+ * Optional slot to override the trigger slot.
8
+ */
9
+ default?(props: { trigger: typeof trigger }): unknown;
10
+ }>();
11
+
5
12
  const { locale, setLocale, locales } = useI18n();
6
13
  const isLanguageDialogOpen = ref(false);
7
14
 
@@ -18,16 +25,22 @@ const currentLocaleLabel = computed(() => {
18
25
  // using "!" here is safe since splitting a string will always return at least one string in the returned array
19
26
  return locale.value.split("-")[0]!.split("_")[0]!.toUpperCase();
20
27
  });
28
+
29
+ const trigger = {
30
+ onClick: () => (isLanguageDialogOpen.value = true),
31
+ };
21
32
  </script>
22
33
 
23
34
  <template>
24
- <OnyxButton
25
- :label="currentLocaleLabel"
26
- :icon="iconTranslate"
27
- color="neutral"
28
- mode="plain"
29
- @click="isLanguageDialogOpen = true"
30
- />
35
+ <slot :trigger>
36
+ <OnyxButton
37
+ :label="currentLocaleLabel"
38
+ :icon="iconTranslate"
39
+ color="neutral"
40
+ mode="plain"
41
+ v-bind="trigger"
42
+ />
43
+ </slot>
31
44
 
32
45
  <OnyxSelectDialog
33
46
  v-model:open="isLanguageDialogOpen"
@@ -29,8 +29,10 @@ const localePath = useLocalePath();
29
29
 
30
30
  <slot></slot>
31
31
 
32
- <template v-if="slots.globalContextArea" #globalContextArea>
33
- <slot name="globalContextArea"></slot>
32
+ <template #globalContextArea>
33
+ <slot name="globalContextArea">
34
+ <GlobalSearch />
35
+ </slot>
34
36
  </template>
35
37
 
36
38
  <template v-if="slots.mobileActivePage" #mobileActivePage>
@@ -1,7 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import type { ContentNavigationItem } from "@nuxt/content";
3
- import { iconSearch } from "@sit-onyx/icons";
4
- import { normalizedIncludes, type OnyxPageLayoutProps, type OnyxSidebarProps } from "sit-onyx";
3
+ import { type OnyxPageLayoutProps, type OnyxSidebarProps } from "sit-onyx";
5
4
 
6
5
  const props = defineProps<
7
6
  OnyxPageLayoutProps & {
@@ -47,35 +46,7 @@ const navigation = await useAsyncData(
47
46
  },
48
47
  );
49
48
 
50
- const searchTerm = ref("");
51
-
52
- const allSidebarItems = computed(() => navigation.data.value ?? []);
53
-
54
- const filterItem = (
55
- item: ContentNavigationItem,
56
- search: string,
57
- ): ContentNavigationItem | undefined => {
58
- if (!item.children) {
59
- return normalizedIncludes(item.title, search) ? item : undefined;
60
- }
61
-
62
- const children = item.children
63
- .map((child) => filterItem(child, search))
64
- .filter((child) => child != undefined);
65
-
66
- if (!children.length) return undefined;
67
- return { ...item, children };
68
- };
69
-
70
- const filteredSidebarItems = computed(() => {
71
- if (!searchTerm.value) return allSidebarItems.value;
72
-
73
- const items = allSidebarItems.value
74
- .map((item) => filterItem(item, searchTerm.value))
75
- .filter((item) => item != undefined);
76
-
77
- return items;
78
- });
49
+ const sidebarItems = computed(() => navigation.data.value ?? []);
79
50
  </script>
80
51
 
81
52
  <template>
@@ -86,29 +57,14 @@ const filteredSidebarItems = computed(() => {
86
57
  v-bind="props.sidebar"
87
58
  :label="$t('onyx.navigation.navigationHeadline')"
88
59
  >
89
- <template #header>
90
- <slot name="sidebarHeader">
91
- <OnyxInput
92
- v-model="searchTerm"
93
- :label="$t('onyx.select.searchPlaceholder')"
94
- hide-label
95
- :placeholder="$t('onyx.select.searchPlaceholder')"
96
- >
97
- <template #leading>
98
- <OnyxIcon :icon="iconSearch" />
99
- </template>
100
- </OnyxInput>
101
- </slot>
60
+ <template v-if="slots.sidebarHeader" #header>
61
+ <slot name="sidebarHeader"> </slot>
102
62
  </template>
103
63
 
104
- <slot name="sidebarBody" :items="filteredSidebarItems">
105
- <SidebarItem
106
- v-for="item in filteredSidebarItems"
107
- :key="localePath(item.path)"
108
- :item="item"
109
- />
64
+ <slot name="sidebarBody" :items="sidebarItems">
65
+ <SidebarItem v-for="item in sidebarItems" :key="localePath(item.path)" :item="item" />
110
66
 
111
- <OnyxEmpty v-if="!filteredSidebarItems.length" class="sidebar__empty">
67
+ <OnyxEmpty v-if="!sidebarItems.length" class="sidebar__empty">
112
68
  {{ $t("onyx.select.empty") }}
113
69
  </OnyxEmpty>
114
70
  </slot>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sit-onyx/nuxt-docs",
3
- "version": "0.1.0-dev-20251112123258",
3
+ "version": "0.1.0-dev-20251112124157",
4
4
  "description": "Nuxt layer/template for creating documentations with the onyx design system",
5
5
  "type": "module",
6
6
  "author": "Schwarz IT KG",
@@ -30,9 +30,9 @@
30
30
  "@nuxtjs/color-mode": ">= 3",
31
31
  "@nuxtjs/i18n": ">= 10",
32
32
  "sass-embedded": ">= 1",
33
- "@sit-onyx/icons": "^1.2.0-dev-20251112123258",
33
+ "@sit-onyx/icons": "^1.2.0-dev-20251112124157",
34
34
  "@sit-onyx/nuxt": "^1.0.1",
35
- "sit-onyx": "^1.4.0-dev-20251112123258"
35
+ "sit-onyx": "^1.4.0-dev-20251112124157"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@fontsource-variable/source-code-pro": ">= 5",
@@ -47,10 +47,10 @@
47
47
  "sass-embedded": "1.93.3",
48
48
  "typescript": "5.9.3",
49
49
  "vue": "3.5.23",
50
- "@sit-onyx/icons": "^1.2.0-dev-20251112123258",
51
- "@sit-onyx/nuxt": "^1.0.1",
52
50
  "@sit-onyx/shared": "^0.1.0",
53
- "sit-onyx": "^1.4.0-dev-20251112123258"
51
+ "@sit-onyx/nuxt": "^1.0.1",
52
+ "@sit-onyx/icons": "^1.2.0-dev-20251112124157",
53
+ "sit-onyx": "^1.4.0-dev-20251112124157"
54
54
  },
55
55
  "scripts": {
56
56
  "dev": "pnpm dev:prepare && nuxi dev playground",