@sit-onyx/nuxt-docs 1.0.0-beta.13 → 1.0.0-beta.130

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.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <OnyxAppLayout class="onyx-grid-max-md onyx-grid-center">
2
+ <OnyxAppLayout class="onyx-grid-max-lg onyx-grid-center">
3
3
  <template #navBar>
4
4
  <NavBar />
5
5
  </template>
@@ -0,0 +1,27 @@
1
+ <script lang="ts" setup>
2
+ import { iconCircleContrast } from "@sit-onyx/icons";
3
+ import type { ColorSchemeValue } from "sit-onyx";
4
+
5
+ const colorMode = useColorMode();
6
+ const isColorSchemeDialogOpen = ref(false);
7
+
8
+ const colorScheme = computed({
9
+ get: () => {
10
+ return colorMode.preference === "system" ? "auto" : (colorMode.preference as ColorSchemeValue);
11
+ },
12
+ set: (newValue) => {
13
+ colorMode.preference = newValue === "auto" ? "system" : newValue;
14
+ },
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <OnyxIconButton
20
+ label="Toggle color scheme"
21
+ :icon="iconCircleContrast"
22
+ color="neutral"
23
+ @click="isColorSchemeDialogOpen = true"
24
+ />
25
+
26
+ <OnyxColorSchemeDialog v-model="colorScheme" v-model:open="isColorSchemeDialogOpen" />
27
+ </template>
@@ -0,0 +1,41 @@
1
+ <script lang="ts" setup>
2
+ import { iconTranslate } from "@sit-onyx/icons";
3
+ import type { SelectDialogOption } from "sit-onyx";
4
+
5
+ const { locale, setLocale, locales } = useI18n();
6
+ const isLanguageDialogOpen = ref(false);
7
+
8
+ const languageOptions = computed(() => {
9
+ return locales.value.map((locale) => {
10
+ return {
11
+ label: locale.name ?? locale.code,
12
+ value: locale.code,
13
+ } satisfies SelectDialogOption;
14
+ });
15
+ });
16
+
17
+ const currentLocaleLabel = computed(() => {
18
+ // using "!" here is safe since splitting a string will always return at least one string in the returned array
19
+ return locale.value.split("-")[0]!.split("_")[0]!.toUpperCase();
20
+ });
21
+ </script>
22
+
23
+ <template>
24
+ <OnyxButton
25
+ :label="currentLocaleLabel"
26
+ :icon="iconTranslate"
27
+ color="neutral"
28
+ mode="plain"
29
+ @click="isLanguageDialogOpen = true"
30
+ />
31
+
32
+ <OnyxSelectDialog
33
+ v-model:open="isLanguageDialogOpen"
34
+ :label="$t('onyx.languageSelect.headline')"
35
+ :model-value="locale"
36
+ :options="languageOptions"
37
+ @update:model-value="setLocale($event)"
38
+ >
39
+ <template #description> {{ $t("onyx.languageSelect.subtitle") }} </template>
40
+ </OnyxSelectDialog>
41
+ </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import type { OnyxNavBarProps, OnyxNavBarSlots } from "sit-onyx";
3
+ import ColorSchemeSwitch from "./ColorSchemeSwitch.vue";
4
+
5
+ const props = withDefaults(defineProps<OnyxNavBarProps>(), {
6
+ appName: "Documentation",
7
+ withBackButton: true,
8
+ // Vue defaults booleans to false so this explicit "undefined" is needed to correctly set the default breakpoint
9
+ mobile: undefined,
10
+ });
11
+
12
+ const slots = defineSlots<OnyxNavBarSlots>();
13
+
14
+ const router = useRouter();
15
+ const { locales } = useI18n();
16
+ const localePath = useLocalePath();
17
+ </script>
18
+
19
+ <template>
20
+ <OnyxNavBar
21
+ v-bind="props"
22
+ :app-area="props.appArea ?? { link: localePath('/') }"
23
+ @navigate-back="router.back"
24
+ >
25
+ <!-- eslint-disable vue/require-explicit-slots -- slots type is imported from onyx but eslint does not seem to be able to handle this -->
26
+ <template v-if="slots.appArea" #appArea>
27
+ <slot name="appArea"></slot>
28
+ </template>
29
+
30
+ <slot></slot>
31
+
32
+ <template v-if="slots.globalContextArea" #globalContextArea>
33
+ <slot name="globalContextArea"></slot>
34
+ </template>
35
+
36
+ <template v-if="slots.mobileActivePage" #mobileActivePage>
37
+ <slot name="mobileActivePage"></slot>
38
+ </template>
39
+
40
+ <template #contextArea>
41
+ <slot name="contextArea">
42
+ <!-- using lazy here so the locale switch code is not loaded when only one locale exists -->
43
+ <LazyLocaleSwitch v-if="locales.length > 1" />
44
+ <ColorSchemeSwitch />
45
+ </slot>
46
+ </template>
47
+ <!-- eslint-enable vue/require-explicit-slots -->
48
+ </OnyxNavBar>
49
+ </template>
@@ -0,0 +1,68 @@
1
+ <script lang="ts" setup>
2
+ import type { ContentNavigationItem } from "@nuxt/content";
3
+
4
+ const props = defineProps<{
5
+ item: ContentNavigationItem;
6
+ }>();
7
+
8
+ const localePath = useLocalePath();
9
+
10
+ const isAccordionOpen = ref(true);
11
+
12
+ const children = computed(() => {
13
+ // filter out children that are directories
14
+ return props.item.children?.filter((child) => child.page !== false);
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <OnyxSidebarItem v-if="!children" class="sidebar-item" :link="localePath(props.item.path)">
20
+ {{ props.item.title }}
21
+ </OnyxSidebarItem>
22
+
23
+ <OnyxAccordion
24
+ v-else
25
+ :model-value="isAccordionOpen ? [localePath(item.path)] : undefined"
26
+ class="sidebar-accordion"
27
+ type="nested-large"
28
+ @update:model-value="isAccordionOpen = !isAccordionOpen"
29
+ >
30
+ <OnyxAccordionItem :value="localePath(item.path)">
31
+ <template #header>{{ props.item.title }}</template>
32
+
33
+ <div class="sidebar-item__children">
34
+ <OnyxSidebarItem
35
+ v-for="child in children"
36
+ :key="localePath(child.path)"
37
+ :link="localePath(child.path)"
38
+ >
39
+ {{ child.title }}
40
+ </OnyxSidebarItem>
41
+ </div>
42
+ </OnyxAccordionItem>
43
+ </OnyxAccordion>
44
+ </template>
45
+
46
+ <style lang="scss" scoped>
47
+ .sidebar-item {
48
+ margin: var(--onyx-density-2xs) var(--onyx-density-xs);
49
+
50
+ &:first-of-type {
51
+ margin-top: var(--onyx-density-xs);
52
+ }
53
+
54
+ &__children {
55
+ display: flex;
56
+ flex-direction: column;
57
+ gap: var(--onyx-density-2xs);
58
+ }
59
+ }
60
+
61
+ .sidebar-accordion {
62
+ > .onyx-accordion-item {
63
+ :deep(> .onyx-accordion-item__panel) {
64
+ padding-top: 0;
65
+ }
66
+ }
67
+ }
68
+ </style>
@@ -13,3 +13,9 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-bottom: var(--onyx-density-lg);
20
+ }
21
+ </style>
@@ -13,3 +13,10 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-top: var(--onyx-density-lg);
20
+ margin-bottom: var(--onyx-density-xs);
21
+ }
22
+ </style>
@@ -13,3 +13,10 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-top: var(--onyx-density-lg);
20
+ margin-bottom: var(--onyx-density-2xs);
21
+ }
22
+ </style>
@@ -13,3 +13,10 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-top: var(--onyx-density-lg);
20
+ margin-bottom: var(--onyx-density-3xs);
21
+ }
22
+ </style>
@@ -13,3 +13,10 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-top: var(--onyx-density-lg);
20
+ margin-bottom: var(--onyx-density-3xs);
21
+ }
22
+ </style>
@@ -13,3 +13,10 @@ defineSlots<{
13
13
  <slot />
14
14
  </OnyxHeadline>
15
15
  </template>
16
+
17
+ <style lang="scss" scoped>
18
+ .onyx-headline {
19
+ margin-top: var(--onyx-density-lg);
20
+ margin-bottom: var(--onyx-density-3xs);
21
+ }
22
+ </style>
@@ -0,0 +1,18 @@
1
+ <script lang="ts" setup>
2
+ defineSlots<{
3
+ default(): unknown;
4
+ }>();
5
+ </script>
6
+
7
+ <template>
8
+ <ol>
9
+ <slot></slot>
10
+ </ol>
11
+ </template>
12
+
13
+ <style lang="scss" scoped>
14
+ ol {
15
+ margin-top: var(--onyx-density-xs);
16
+ margin-bottom: var(--onyx-density-xs);
17
+ }
18
+ </style>
@@ -0,0 +1,18 @@
1
+ <script lang="ts" setup>
2
+ defineSlots<{
3
+ default(): unknown;
4
+ }>();
5
+ </script>
6
+
7
+ <template>
8
+ <ul>
9
+ <slot></slot>
10
+ </ul>
11
+ </template>
12
+
13
+ <style lang="scss" scoped>
14
+ ul {
15
+ margin-top: var(--onyx-density-xs);
16
+ margin-bottom: var(--onyx-density-xs);
17
+ }
18
+ </style>
package/app/error.vue ADDED
@@ -0,0 +1,78 @@
1
+ <script setup lang="ts">
2
+ import type { NuxtError } from "#app";
3
+ import App from "./app.vue";
4
+
5
+ const props = defineProps<{
6
+ error: NuxtError;
7
+ }>();
8
+
9
+ defineSlots<{
10
+ /**
11
+ * Slot to override the default "Back to home" action(s).
12
+ *
13
+ * @params clearError - Function to clear the error and redirect to the home page
14
+ */
15
+ actions?(props: { clearError: typeof _clearError }): unknown;
16
+ /**
17
+ * Slot to override the error details section.
18
+ * By default, an accordion will be displayed that shows the technical error details.
19
+ */
20
+ details?(): unknown;
21
+ }>();
22
+
23
+ const localePath = useLocalePath();
24
+
25
+ const _clearError = () => clearError({ redirect: localePath("/") });
26
+ </script>
27
+
28
+ <template>
29
+ <App>
30
+ <div class="error">
31
+ <OnyxErrorSVG class="error__image" />
32
+
33
+ <div class="error__headline">
34
+ <OnyxHeadline is="h1">{{ props.error.message }}</OnyxHeadline>
35
+
36
+ <slot name="actions" :clear-error="_clearError">
37
+ <OnyxButton label="Back to home" @click="_clearError" />
38
+ </slot>
39
+ </div>
40
+
41
+ <slot name="details">
42
+ <OnyxAccordion>
43
+ <OnyxAccordionItem value="details">
44
+ <template #header>Technical error details</template>
45
+ <pre class="error__details">{{ JSON.stringify(props.error, null, 2) }}</pre>
46
+ </OnyxAccordionItem>
47
+ </OnyxAccordion>
48
+ </slot>
49
+ </div>
50
+ </App>
51
+ </template>
52
+
53
+ <style lang="scss" scoped>
54
+ .error {
55
+ display: flex;
56
+ flex-direction: column;
57
+ align-items: center;
58
+ gap: var(--onyx-density-3xl);
59
+
60
+ &__image {
61
+ width: 32rem;
62
+ display: block;
63
+ }
64
+
65
+ &__headline {
66
+ display: flex;
67
+ flex-direction: column;
68
+ align-items: center;
69
+ gap: var(--onyx-density-md);
70
+ }
71
+
72
+ &__details {
73
+ white-space: pre-wrap;
74
+ overflow-wrap: anywhere;
75
+ font-family: var(--onyx-font-family-mono);
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,14 @@
1
+ <script lang="ts" setup>
2
+ defineSlots<{
3
+ /**
4
+ * Main page content.
5
+ */
6
+ default(): unknown;
7
+ }>();
8
+ </script>
9
+
10
+ <template>
11
+ <OnyxPageLayout>
12
+ <slot></slot>
13
+ </OnyxPageLayout>
14
+ </template>
@@ -0,0 +1,144 @@
1
+ <script lang="ts" setup>
2
+ import type { ContentNavigationItem } from "@nuxt/content";
3
+ import { iconSearch } from "@sit-onyx/icons";
4
+ import { normalizedIncludes, type OnyxPageLayoutProps, type OnyxSidebarProps } from "sit-onyx";
5
+
6
+ const props = defineProps<
7
+ OnyxPageLayoutProps & {
8
+ sidebar?: OnyxSidebarProps;
9
+ }
10
+ >();
11
+
12
+ const slots = defineSlots<{
13
+ /**
14
+ * Main page content.
15
+ */
16
+ default(): unknown;
17
+ /**
18
+ * Page footer content.
19
+ */
20
+ footer?(): unknown;
21
+ /**
22
+ * Optional right sidebar.
23
+ */
24
+ sidebarRight?(): unknown;
25
+ /**
26
+ * Optionally override the main sidebar body content.
27
+ */
28
+ sidebarBody?(props: { items: ContentNavigationItem[] }): unknown;
29
+ /**
30
+ * Optionally override the sidebar header content.
31
+ */
32
+ sidebarHeader?(): unknown;
33
+ /**
34
+ * Sidebar footer content.
35
+ */
36
+ sidebarFooter?(): unknown;
37
+ }>();
38
+
39
+ const { locale } = useI18n();
40
+ const localePath = useLocalePath();
41
+
42
+ const navigation = await useAsyncData(
43
+ () => `navigation-${locale.value}`,
44
+ () => {
45
+ const collection = `content_${locale.value}` as const;
46
+ return queryCollectionNavigation(collection);
47
+ },
48
+ );
49
+
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
+ });
79
+ </script>
80
+
81
+ <template>
82
+ <OnyxPageLayout v-bind="props">
83
+ <template #sidebar>
84
+ <OnyxSidebar
85
+ class="sidebar"
86
+ v-bind="props.sidebar"
87
+ :label="$t('onyx.navigation.navigationHeadline')"
88
+ >
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>
102
+ </template>
103
+
104
+ <slot name="sidebarBody" :items="filteredSidebarItems">
105
+ <SidebarItem
106
+ v-for="item in filteredSidebarItems"
107
+ :key="localePath(item.path)"
108
+ :item="item"
109
+ />
110
+
111
+ <OnyxEmpty v-if="!filteredSidebarItems.length" class="sidebar__empty">
112
+ {{ $t("onyx.select.empty") }}
113
+ </OnyxEmpty>
114
+ </slot>
115
+
116
+ <template v-if="!!slots.sidebarFooter" #footer>
117
+ <slot name="sidebarFooter"></slot>
118
+ </template>
119
+ </OnyxSidebar>
120
+ </template>
121
+
122
+ <slot></slot>
123
+
124
+ <template v-if="!!slots.footer" #footer>
125
+ <slot name="footer"></slot>
126
+ </template>
127
+
128
+ <template v-if="!!slots.sidebarRight" #sidebarRight>
129
+ <slot name="sidebarRight"></slot>
130
+ </template>
131
+ </OnyxPageLayout>
132
+ </template>
133
+
134
+ <style lang="scss" scoped>
135
+ .content {
136
+ white-space: pre-line;
137
+ }
138
+
139
+ .sidebar {
140
+ &__empty {
141
+ max-width: 100%;
142
+ }
143
+ }
144
+ </style>
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ definePageMeta({ layout: "sidebar" });
3
+
4
+ const route = useRoute();
5
+ const { locale } = useI18n();
6
+
7
+ const slug = computed(() => {
8
+ const path = Array.isArray(route.params.slug)
9
+ ? route.params.slug.join("/")
10
+ : (route.params.slug ?? "");
11
+ return path.startsWith("/") ? path : `/${path}`;
12
+ });
13
+
14
+ const collection = await useAsyncData(
15
+ () => `page-${slug.value}-${locale.value}`,
16
+ () => {
17
+ const collection = `content_${locale.value}` as const;
18
+ return queryCollection(collection).path(slug.value).first();
19
+ },
20
+ );
21
+
22
+ watch(
23
+ () => collection.data.value,
24
+ (data) => {
25
+ // if data is "null", the page content was not found. "undefined" means it is not loaded yet
26
+ if (data !== null) return;
27
+ throw showError({
28
+ message: "Page not found",
29
+ statusCode: 404,
30
+ });
31
+ },
32
+ { immediate: true },
33
+ );
34
+
35
+ const data = computed(() => collection.data.value);
36
+
37
+ useSeoMeta({
38
+ title: computed(() => collection.data.value?.seo.title),
39
+ description: computed(() => collection.data.value?.seo.description),
40
+ });
41
+ </script>
42
+
43
+ <!-- eslint-disable-next-line vue/no-root-v-if -- the v-if here is theoretically not needed because we throw above it ifs undefined so the user will be redirected to the error page. However, there is still a console warning so we include the v-if here to prevent it. -->
44
+ <template>
45
+ <ContentRenderer v-if="data" :value="data" />
46
+ </template>
package/content.config.ts CHANGED
@@ -1,10 +1,16 @@
1
1
  import { defineCollection, defineContentConfig } from "@nuxt/content";
2
+ import path from "node:path";
2
3
 
3
4
  export default defineContentConfig({
4
5
  collections: {
5
- content: defineCollection({
6
+ content_en: defineCollection({
6
7
  type: "page",
7
- source: "**/*.md",
8
+ source: [
9
+ // include files from content folder of the extending app
10
+ { cwd: path.resolve("content"), include: "en/**", prefix: "" },
11
+ // include files from playground (mainly needed for this monorepo)
12
+ { cwd: path.resolve("playground/content"), include: "en/**", prefix: "" },
13
+ ],
8
14
  }),
9
15
  },
10
16
  });
package/nuxt.config.ts CHANGED
@@ -1,11 +1,23 @@
1
1
  // https://nuxt.com/docs/api/configuration/nuxt-config
2
2
  export default defineNuxtConfig({
3
+ $meta: {
4
+ // the name is used to generate import aliases so the user can easily import
5
+ // any component or file from this layer from "#layers/onyx"
6
+ // see: https://nuxt.com/docs/4.x/guide/going-further/layers#named-layer-aliases
7
+ name: "onyx",
8
+ },
3
9
  devtools: { enabled: true },
4
10
  compatibilityDate: "2025-01-20",
5
11
  typescript: { typeCheck: "build" },
6
- modules: ["@sit-onyx/nuxt", "@nuxt/content", "@nuxtjs/color-mode", "@nuxt/image"],
12
+ modules: ["@sit-onyx/nuxt", "@nuxt/content", "@nuxtjs/color-mode", "@nuxt/image", "@nuxtjs/i18n"],
7
13
  css: ["@fontsource-variable/source-code-pro", "@fontsource-variable/source-sans-3"],
8
14
  colorMode: {
9
15
  classSuffix: "",
10
16
  },
17
+ i18n: {
18
+ defaultLocale: "en",
19
+ // we explicitly don't define any default locales here so the project is fully in charge if defining which locales to use.
20
+ // Otherwise if we would e.g. add en here, the project would always be forced to register en, even if it does not plan to add en translations
21
+ // which could conflict with e.g. "const { locales } = useI18n()" to render a language switch which would always include en then
22
+ },
11
23
  });
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "name": "@sit-onyx/nuxt-docs",
3
- "type": "module",
4
- "version": "1.0.0-beta.13",
3
+ "version": "1.0.0-beta.130",
5
4
  "description": "Nuxt layer/template for creating documentations with the onyx design system",
5
+ "type": "module",
6
+ "author": "Schwarz IT KG",
6
7
  "license": "Apache-2.0",
8
+ "engines": {
9
+ "node": ">=20"
10
+ },
7
11
  "repository": {
8
12
  "type": "git",
9
- "url": "https://github.com/schwarzit/onyx",
13
+ "url": "https://github.com/SchwarzIT/onyx",
10
14
  "directory": "packages/nuxt-docs"
11
15
  },
12
16
  "bugs": {
13
- "url": "https://github.com/schwarzit/onyx/issues"
17
+ "url": "https://github.com/SchwarzIT/onyx/issues"
14
18
  },
15
19
  "main": "./nuxt.config.ts",
16
20
  "files": [
17
- "components",
18
- "composables",
19
- "layouts",
20
- "pages",
21
- "*.ts",
22
- "*.vue",
23
- "*.json"
21
+ "app",
22
+ "content.config.ts",
23
+ "nuxt.config.ts"
24
24
  ],
25
25
  "peerDependencies": {
26
26
  "@fontsource-variable/source-code-pro": ">= 5",
@@ -28,29 +28,32 @@
28
28
  "@nuxt/content": ">= 3",
29
29
  "@nuxt/image": ">= 1",
30
30
  "@nuxtjs/color-mode": ">= 3",
31
+ "@nuxtjs/i18n": ">= 10",
31
32
  "sass-embedded": ">= 1",
32
- "@sit-onyx/icons": "^1.0.0-beta.15",
33
- "@sit-onyx/nuxt": "^1.0.0-beta.202",
34
- "sit-onyx": "^1.0.0-beta.200"
33
+ "@sit-onyx/icons": "^1.0.0-beta.26",
34
+ "@sit-onyx/nuxt": "^1.0.0-beta.313",
35
+ "sit-onyx": "^1.0.0-beta.328"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@fontsource-variable/source-code-pro": ">= 5",
38
39
  "@fontsource-variable/source-sans-3": ">= 5",
39
40
  "@nuxt/content": ">= 3",
40
41
  "@nuxt/image": ">= 1",
41
- "@nuxt/test-utils": "^3.17.2",
42
+ "@nuxt/test-utils": "^3.19.2",
42
43
  "@nuxtjs/color-mode": ">= 3",
43
- "nuxt": "^3.16.2",
44
- "sass-embedded": "1.86.3",
45
- "typescript": "5.8.3",
46
- "vue": "3.5.13",
47
- "@sit-onyx/shared": "^1.0.0-beta.2",
48
- "@sit-onyx/nuxt": "^1.0.0-beta.202",
49
- "@sit-onyx/icons": "^1.0.0-beta.15",
50
- "sit-onyx": "^1.0.0-beta.200"
44
+ "@playwright/experimental-ct-vue": "1.55.0",
45
+ "@playwright/test": "1.55.0",
46
+ "nuxt": "^4.0.3",
47
+ "sass-embedded": "1.91.0",
48
+ "typescript": "5.9.2",
49
+ "vue": "3.5.20",
50
+ "@sit-onyx/icons": "^1.0.0-beta.26",
51
+ "@sit-onyx/nuxt": "^1.0.0-beta.313",
52
+ "@sit-onyx/shared": "^1.0.0-beta.4",
53
+ "sit-onyx": "^1.0.0-beta.328"
51
54
  },
52
55
  "scripts": {
53
- "dev": "nuxi dev playground",
56
+ "dev": "pnpm dev:prepare && nuxi dev playground",
54
57
  "dev:prepare": "nuxt prepare playground",
55
58
  "build": "nuxt build playground",
56
59
  "generate": "nuxt generate playground",
package/app.config.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { OnyxNavBarProps, OnyxNavItemProps } from "sit-onyx";
2
-
3
- // TYPES
4
- declare module "@nuxt/schema" {
5
- interface AppConfigInput {
6
- onyxDocs?: OnyxAppConfig;
7
- }
8
-
9
- interface AppConfig {
10
- onyxDocs: OnyxAppConfig & typeof defaultAppConfig;
11
- }
12
- }
13
-
14
- export type OnyxAppConfig = {
15
- nav?: Partial<OnyxNavBarProps> & {
16
- items?: NavItem[];
17
- };
18
- };
19
-
20
- export type NavItem = OnyxNavItemProps & { children?: NavItem[] };
21
-
22
- // CONFIG
23
- const defaultAppConfig = {
24
- nav: {
25
- appName: "Documentation",
26
- withBackButton: true,
27
- },
28
- } satisfies OnyxAppConfig;
29
-
30
- export default defineAppConfig({
31
- onyxDocs: defaultAppConfig,
32
- });
@@ -1,211 +0,0 @@
1
- <script lang="ts" setup>
2
- const props = defineProps<{
3
- title: string;
4
- }>();
5
- </script>
6
-
7
- <template>
8
- <svg
9
- class="error__image"
10
- xmlns="http://www.w3.org/2000/svg"
11
- viewBox="0 0 1119.60911 699"
12
- xmlns:xlink="http://www.w3.org/1999/xlink"
13
- role="img"
14
- >
15
- <title>{{ props.title }}</title>
16
- <circle cx="292.60911" cy="213" r="213" fill="var(--onyx-color-base-neutral-200)" />
17
- <path
18
- d="M31.39089,151.64237c0,77.49789,48.6181,140.20819,108.70073,140.20819"
19
- transform="translate(-31.39089 -100.5)"
20
- fill="var(--onyx-color-steel-900)"
21
- />
22
- <path
23
- d="M140.09162,291.85056c0-78.36865,54.255-141.78356,121.30372-141.78356"
24
- transform="translate(-31.39089 -100.5)"
25
- fill="var(--onyx-color-base-primary-500)"
26
- />
27
- <path
28
- d="M70.77521,158.66768c0,73.61476,31.00285,133.18288,69.31641,133.18288"
29
- transform="translate(-31.39089 -100.5)"
30
- fill="var(--onyx-color-base-primary-500)"
31
- />
32
- <path
33
- d="M140.09162,291.85056c0-100.13772,62.7103-181.16788,140.20819-181.16788"
34
- transform="translate(-31.39089 -100.5)"
35
- fill="var(--onyx-color-steel-900)"
36
- />
37
- <ellipse cx="198.60911" cy="424.5" rx="187" ry="25.43993" fill="var(--onyx-color-steel-800)" />
38
- <ellipse cx="198.60911" cy="424.5" rx="157" ry="21.35866" opacity="0.1" />
39
- <ellipse cx="836.60911" cy="660.5" rx="283" ry="38.5" fill="var(--onyx-color-steel-800)" />
40
- <ellipse cx="310.60911" cy="645.5" rx="170" ry="23.12721" fill="var(--onyx-color-steel-800)" />
41
- <path
42
- d="M494,726.5c90,23,263-30,282-90"
43
- transform="translate(-31.39089 -100.5)"
44
- fill="none"
45
- stroke="var(--onyx-color-steel-700)"
46
- stroke-miterlimit="10"
47
- stroke-width="2"
48
- />
49
- <path
50
- d="M341,359.5s130-36,138,80-107,149-17,172"
51
- transform="translate(-31.39089 -100.5)"
52
- fill="none"
53
- stroke="var(--onyx-color-steel-700)"
54
- stroke-miterlimit="10"
55
- stroke-width="2"
56
- />
57
- <path
58
- d="M215.40233,637.78332s39.0723-10.82,41.47675,24.04449-32.15951,44.78287-5.10946,51.69566"
59
- transform="translate(-31.39089 -100.5)"
60
- fill="none"
61
- stroke="var(--onyx-color-steel-700)"
62
- stroke-miterlimit="10"
63
- stroke-width="2"
64
- />
65
- <path
66
- d="M810.09554,663.73988,802.218,714.03505s-38.78182,20.60284-11.51335,21.20881,155.73324,0,155.73324,0,24.84461,0-14.54318-21.81478l-7.87756-52.719Z"
67
- transform="translate(-31.39089 -100.5)"
68
- fill="var(--onyx-color-steel-900)"
69
- />
70
- <path
71
- d="M785.21906,734.69812c6.193-5.51039,16.9989-11.252,16.9989-11.252l7.87756-50.2952,113.9216.10717,7.87756,49.582c9.185,5.08711,14.8749,8.987,18.20362,11.97818,5.05882-1.15422,10.58716-5.44353-18.20362-21.38921l-7.87756-52.719-113.9216,3.02983L802.218,714.03506S769.62985,731.34968,785.21906,734.69812Z"
72
- transform="translate(-31.39089 -100.5)"
73
- opacity="0.1"
74
- />
75
- <rect
76
- x="578.43291"
77
- y="212.68859"
78
- width="513.25314"
79
- height="357.51989"
80
- rx="18.04568"
81
- fill="var(--onyx-color-steel-900)"
82
- />
83
- <rect
84
- x="595.70294"
85
- y="231.77652"
86
- width="478.71308"
87
- height="267.83694"
88
- fill="var(--onyx-color-steel-800)"
89
- />
90
- <circle cx="835.05948" cy="223.29299" r="3.02983" fill="var(--onyx-color-steel-200)" />
91
- <path
92
- d="M1123.07694,621.32226V652.6628a18.04341,18.04341,0,0,1-18.04568,18.04568H627.86949A18.04341,18.04341,0,0,1,609.8238,652.6628V621.32226Z"
93
- transform="translate(-31.39089 -100.5)"
94
- fill="var(--onyx-color-steel-900)"
95
- />
96
- <polygon
97
- points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 651.452 645.651 962.312 645.651 968.978 667.466"
98
- fill="var(--onyx-color-steel-900)"
99
- />
100
- <path
101
- d="M1125.828,762.03359c-.59383,2.539-2.83591,5.21743-7.90178,7.75032-18.179,9.08949-55.1429-2.42386-55.1429-2.42386s-28.4804-4.84773-28.4804-17.573a22.72457,22.72457,0,0,1,2.49658-1.48459c7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
102
- transform="translate(-31.39089 -100.5)"
103
- fill="var(--onyx-color-steel-900)"
104
- />
105
- <path
106
- d="M1125.828,762.03359c-22.251,8.526-42.0843,9.1622-62.43871-4.975-10.26507-7.12617-19.59089-8.88955-26.58979-8.75618,7.64294-4.04351,32.98449-14.02122,77.9177.42248a18.73921,18.73921,0,0,1,8.54106,5.59715C1125.07908,756.45353,1126.50669,759.15715,1125.828,762.03359Z"
107
- transform="translate(-31.39089 -100.5)"
108
- opacity="0.1"
109
- />
110
- <ellipse
111
- cx="1066.53846"
112
- cy="654.13477"
113
- rx="7.87756"
114
- ry="2.42386"
115
- fill="var(--onyx-color-steel-200)"
116
- />
117
- <circle cx="835.05948" cy="545.66686" r="11.51335" fill="var(--onyx-color-steel-200)" />
118
- <polygon
119
- points="968.978 667.466 968.978 673.526 642.968 673.526 642.968 668.678 643.417 667.466 968.978 667.466"
120
- opacity="0.1"
121
- />
122
- <rect x="108.60911" y="159" width="208" height="242" fill="var(--onyx-color-steel-900)" />
123
- <rect x="87.60911" y="135" width="250" height="86" fill="var(--onyx-color-steel-800)" />
124
- <rect x="87.60911" y="237" width="250" height="86" fill="var(--onyx-color-steel-800)" />
125
- <rect x="87.60911" y="339" width="250" height="86" fill="var(--onyx-color-steel-800)" />
126
- <rect
127
- x="271.60911"
128
- y="150"
129
- width="16"
130
- height="16"
131
- fill="var(--onyx-color-base-primary-500)"
132
- opacity="0.4"
133
- />
134
- <rect
135
- x="294.60911"
136
- y="150"
137
- width="16"
138
- height="16"
139
- fill="var(--onyx-color-base-primary-500)"
140
- opacity="0.8"
141
- />
142
- <rect x="317.60911" y="150" width="16" height="16" fill="var(--onyx-color-base-primary-500)" />
143
- <rect
144
- x="271.60911"
145
- y="251"
146
- width="16"
147
- height="16"
148
- fill="var(--onyx-color-base-primary-500)"
149
- opacity="0.4"
150
- />
151
- <rect
152
- x="294.60911"
153
- y="251"
154
- width="16"
155
- height="16"
156
- fill="var(--onyx-color-base-primary-500)"
157
- opacity="0.8"
158
- />
159
- <rect x="317.60911" y="251" width="16" height="16" fill="var(--onyx-color-base-primary-500)" />
160
- <rect
161
- x="271.60911"
162
- y="352"
163
- width="16"
164
- height="16"
165
- fill="var(--onyx-color-base-primary-500)"
166
- opacity="0.4"
167
- />
168
- <rect
169
- x="294.60911"
170
- y="352"
171
- width="16"
172
- height="16"
173
- fill="var(--onyx-color-base-primary-500)"
174
- opacity="0.8"
175
- />
176
- <rect x="317.60911" y="352" width="16" height="16" fill="var(--onyx-color-base-primary-500)" />
177
- <circle cx="316.60911" cy="538" r="79" fill="var(--onyx-color-steel-900)" />
178
- <rect x="280.60911" y="600" width="24" height="43" fill="var(--onyx-color-steel-900)" />
179
- <rect x="328.60911" y="600" width="24" height="43" fill="var(--onyx-color-steel-900)" />
180
- <ellipse cx="300.60911" cy="643.5" rx="20" ry="7.5" fill="var(--onyx-color-steel-900)" />
181
- <ellipse cx="348.60911" cy="642.5" rx="20" ry="7.5" fill="var(--onyx-color-steel-900)" />
182
- <circle cx="318.60911" cy="518" r="27" fill="#fff" />
183
- <circle cx="318.60911" cy="518" r="9" fill="var(--onyx-color-steel-800)" />
184
- <path
185
- d="M271.36733,565.03228c-6.37889-28.56758,14.01185-57.43392,45.544-64.47477s62.2651,10.41,68.644,38.9776-14.51861,39.10379-46.05075,46.14464S277.74622,593.59986,271.36733,565.03228Z"
186
- transform="translate(-31.39089 -100.5)"
187
- fill="var(--onyx-color-base-primary-500)"
188
- />
189
- <ellipse
190
- cx="417.21511"
191
- cy="611.34365"
192
- rx="39.5"
193
- ry="12.40027"
194
- transform="translate(-238.28665 112.98044) rotate(-23.17116)"
195
- fill="var(--onyx-color-steel-900)"
196
- />
197
- <ellipse
198
- cx="269.21511"
199
- cy="664.34365"
200
- rx="39.5"
201
- ry="12.40027"
202
- transform="translate(-271.07969 59.02084) rotate(-23.17116)"
203
- fill="var(--onyx-color-steel-900)"
204
- />
205
- <path
206
- d="M394,661.5c0,7.732-19.90861,23-42,23s-43-14.268-43-22,20.90861-6,43-6S394,653.768,394,661.5Z"
207
- transform="translate(-31.39089 -100.5)"
208
- fill="#fff"
209
- />
210
- </svg>
211
- </template>
@@ -1,44 +0,0 @@
1
- <script setup lang="ts">
2
- import circleContrast from "@sit-onyx/icons/circle-contrast.svg?raw";
3
- import { extractLinkProps, type ColorSchemeValue } from "sit-onyx";
4
-
5
- const { onyxDocs } = useAppConfig();
6
- const router = useRouter();
7
- const colorMode = useColorMode();
8
-
9
- const isColorSchemeDialogOpen = ref(false);
10
-
11
- const colorScheme = computed({
12
- get: () => {
13
- return colorMode.preference === "system" ? "auto" : (colorMode.preference as ColorSchemeValue);
14
- },
15
- set: (newValue) => {
16
- colorMode.preference = newValue === "auto" ? "system" : newValue;
17
- },
18
- });
19
- </script>
20
-
21
- <template>
22
- <OnyxNavBar v-bind="onyxDocs.nav" @navigate-back="router.back">
23
- <NavItem
24
- v-for="item in onyxDocs.nav?.items"
25
- :key="extractLinkProps(item.link ?? '').href"
26
- v-bind="item"
27
- />
28
-
29
- <template #contextArea>
30
- <OnyxIconButton
31
- label="Toggle color scheme"
32
- :icon="circleContrast"
33
- color="neutral"
34
- @click="isColorSchemeDialogOpen = true"
35
- />
36
- </template>
37
-
38
- <OnyxColorSchemeDialog
39
- v-model="colorScheme"
40
- :open="isColorSchemeDialogOpen"
41
- @close="isColorSchemeDialogOpen = false"
42
- />
43
- </OnyxNavBar>
44
- </template>
@@ -1,21 +0,0 @@
1
- <script lang="ts" setup>
2
- import type { NavItem } from "../app.config";
3
-
4
- const props = defineProps<NavItem>();
5
-
6
- /**
7
- * Same as `props` but without the `children` property to prevent console warnings when using `v-bind`.
8
- */
9
- const navItemProps = computed(() => {
10
- const { children: _, ...rest } = props;
11
- return rest;
12
- });
13
- </script>
14
-
15
- <template>
16
- <OnyxNavItem v-bind="navItemProps">
17
- <template v-if="props.children?.length" #children>
18
- <NavItem v-for="child in props.children" :key="child.label" v-bind="child" />
19
- </template>
20
- </OnyxNavItem>
21
- </template>
package/error.vue DELETED
@@ -1,57 +0,0 @@
1
- <script setup lang="ts">
2
- import type { NuxtError } from "#app";
3
- import App from "./app.vue";
4
-
5
- const props = defineProps<{
6
- error: NuxtError;
7
- }>();
8
-
9
- const handleError = () => clearError({ redirect: "/" });
10
- </script>
11
-
12
- <template>
13
- <App>
14
- <div class="error">
15
- <ErrorSVG :title="props.error.message" />
16
-
17
- <div class="error__headline">
18
- <OnyxHeadline is="h1">{{ props.error.message }}</OnyxHeadline>
19
- <OnyxButton label="Back to home" @click="handleError" />
20
- </div>
21
-
22
- <OnyxAccordion>
23
- <OnyxAccordionItem value="details">
24
- <template #header>Technical error details</template>
25
- <pre class="error__details">{{ props.error }}</pre>
26
- </OnyxAccordionItem>
27
- </OnyxAccordion>
28
- </div>
29
- </App>
30
- </template>
31
-
32
- <style lang="scss" scoped>
33
- .error {
34
- display: flex;
35
- flex-direction: column;
36
- align-items: center;
37
- gap: var(--onyx-density-3xl);
38
-
39
- &__image {
40
- width: 32rem;
41
- display: block;
42
- }
43
-
44
- &__headline {
45
- display: flex;
46
- flex-direction: column;
47
- align-items: center;
48
- gap: var(--onyx-density-md);
49
- }
50
-
51
- &__details {
52
- white-space: pre-wrap;
53
- overflow-wrap: anywhere;
54
- font-family: var(--onyx-font-family-mono);
55
- }
56
- }
57
- </style>
@@ -1,7 +0,0 @@
1
- <template>
2
- <OnyxPageLayout>
3
- <div class="onyx-grid-container">
4
- <slot />
5
- </div>
6
- </OnyxPageLayout>
7
- </template>
@@ -1,19 +0,0 @@
1
- <script setup lang="ts">
2
- const route = useRoute();
3
- const collection = await useAsyncData(() => queryCollection("content").path(route.path).first());
4
-
5
- if (!collection.data.value) {
6
- throw createError({
7
- message: "Page not found",
8
- statusCode: 404,
9
- });
10
- }
11
-
12
- const data = toRef(() => collection.data.value!);
13
- useSeoMeta({ ...data.value.seo });
14
- </script>
15
-
16
- <!-- eslint-disable-next-line vue/no-root-v-if -- the v-if here is theoretically not needed because we throw above it ifs undefined so the user will be redirected to the error page. However, there is still a console warning so we include the v-if here to prevent it. -->
17
- <template>
18
- <ContentRenderer v-if="data" :value="data" />
19
- </template>
package/tsconfig.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "./playground/.nuxt/tsconfig.json"
3
- }