coherent-docs-theme 1.0.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/README.md +314 -0
- package/assets/gameface-ui-header-dark.svg +5 -0
- package/assets/gameface-ui-header-light.svg +5 -0
- package/components/Api.astro +29 -0
- package/components/BeforeAfter.astro +124 -0
- package/components/Details.astro +37 -0
- package/components/Enhancement.astro +29 -0
- package/components/Feature.astro +29 -0
- package/components/Figure.astro +107 -0
- package/components/Fix.astro +29 -0
- package/components/GallerySlider.astro +260 -0
- package/components/If.astro +6 -0
- package/components/IfEnv.astro +5 -0
- package/components/IfNot.astro +6 -0
- package/components/IncludeSnippets.astro +13 -0
- package/components/Internal.astro +3 -0
- package/components/ProductName.astro +13 -0
- package/components/Release.astro +68 -0
- package/components/SideBarWithDropdown.astro +8 -0
- package/components/Typeref.astro +35 -0
- package/index.ts +152 -0
- package/internal/overrideComponents.ts +29 -0
- package/internal/themeConfig.ts +21 -0
- package/internal-components/ChangelogRow.astro +39 -0
- package/internal-components/NavLinks.astro +253 -0
- package/internal-components/ProgressIndicator.astro +53 -0
- package/overrides/Footer.astro +103 -0
- package/overrides/Header.astro +91 -0
- package/overrides/Search.astro +234 -0
- package/overrides/ThemeSelect.astro +218 -0
- package/package.json +46 -0
- package/remark-directives/if.ts +51 -0
- package/remark-directives/includeSnippets.ts +120 -0
- package/remark-directives/index.ts +13 -0
- package/remark-directives/internal.ts +20 -0
- package/remark-directives/release.ts +29 -0
- package/styles.css +452 -0
- package/utils/changelogSideBar.ts +105 -0
- package/utils/changelogSideBarMultipleDocs.ts +119 -0
- package/utils/coherentReleases.ts +62 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
import ChangelogRow, {
|
|
3
|
+
type ChangelogProps,
|
|
4
|
+
} from "../internal-components/ChangelogRow.astro";
|
|
5
|
+
|
|
6
|
+
interface Props extends ChangelogProps {}
|
|
7
|
+
|
|
8
|
+
const { engine, description } = Astro.props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
Astro.slots.has("default") ? (
|
|
13
|
+
<ChangelogRow
|
|
14
|
+
badgeText="Fix"
|
|
15
|
+
badgeVariant="danger"
|
|
16
|
+
engine={engine}
|
|
17
|
+
description={description}
|
|
18
|
+
>
|
|
19
|
+
<slot />
|
|
20
|
+
</ChangelogRow>
|
|
21
|
+
) : (
|
|
22
|
+
<ChangelogRow
|
|
23
|
+
badgeText="Fix"
|
|
24
|
+
badgeVariant="danger"
|
|
25
|
+
engine={engine}
|
|
26
|
+
description={description}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { Icon } from "@astrojs/starlight/components";
|
|
5
|
+
import { Image } from "astro:assets";
|
|
6
|
+
import type { ImageMetadata } from "astro";
|
|
7
|
+
|
|
8
|
+
type CustomSlide = {
|
|
9
|
+
src: string | ImageMetadata;
|
|
10
|
+
link?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
alt?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type GalleryItem = string | ImageMetadata | CustomSlide;
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
dir?: string;
|
|
19
|
+
images?: GalleryItem[];
|
|
20
|
+
width?: string;
|
|
21
|
+
height?: string;
|
|
22
|
+
autoSlide?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
dir,
|
|
27
|
+
images = [],
|
|
28
|
+
width = "100%",
|
|
29
|
+
height = "300px",
|
|
30
|
+
autoSlide = 0,
|
|
31
|
+
} = Astro.props;
|
|
32
|
+
|
|
33
|
+
let slides: CustomSlide[] = [];
|
|
34
|
+
|
|
35
|
+
if (dir) {
|
|
36
|
+
const publicPath = path.join(process.cwd(), "public", dir);
|
|
37
|
+
try {
|
|
38
|
+
if (fs.existsSync(publicPath)) {
|
|
39
|
+
const files = fs.readdirSync(publicPath);
|
|
40
|
+
const imageFiles = files.filter((file) =>
|
|
41
|
+
/\.(png|jpe?g|gif|svg|webp)$/i.test(file),
|
|
42
|
+
);
|
|
43
|
+
slides.push(
|
|
44
|
+
...imageFiles.map((file) => ({ src: `/${dir}/${file}` }))
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error(`[Gallery] Error while reading the dir: ${publicPath}`, e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
images.forEach((item: any) => {
|
|
53
|
+
if (typeof item === "string") {
|
|
54
|
+
slides.push({ src: item });
|
|
55
|
+
} else if (
|
|
56
|
+
item.format !== undefined &&
|
|
57
|
+
item.width !== undefined &&
|
|
58
|
+
item.height !== undefined &&
|
|
59
|
+
item.description === undefined
|
|
60
|
+
) {
|
|
61
|
+
slides.push({ src: item as ImageMetadata });
|
|
62
|
+
} else {
|
|
63
|
+
slides.push(item as CustomSlide);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (slides.length === 0) {
|
|
68
|
+
console.warn("[Gallery] No images found.");
|
|
69
|
+
}
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
<gallery-slider data-auto-slide={autoSlide}>
|
|
73
|
+
<div class="slide-window" style={`width: ${width}; height: ${height};`}>
|
|
74
|
+
<ul class="slides-list">
|
|
75
|
+
{
|
|
76
|
+
slides.map((slide) => {
|
|
77
|
+
const isLocal = typeof slide.src === "object";
|
|
78
|
+
const altText = slide.alt || "Gallery slide";
|
|
79
|
+
|
|
80
|
+
const imgContent = isLocal ? (
|
|
81
|
+
<Image src={slide.src as ImageMetadata} alt={altText} class="slide-img" />
|
|
82
|
+
) : (
|
|
83
|
+
<img src={slide.src as string} alt={altText} class="slide-img" />
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const slideBody = slide.link ? (
|
|
87
|
+
<a href={slide.link} target="_blank" rel="noopener noreferrer" class="slide-link">
|
|
88
|
+
{imgContent}
|
|
89
|
+
</a>
|
|
90
|
+
) : (
|
|
91
|
+
imgContent
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<li class="slide">
|
|
96
|
+
{slideBody}
|
|
97
|
+
|
|
98
|
+
{slide.description && (
|
|
99
|
+
<div class="slide-caption">
|
|
100
|
+
<p>{slide.description}</p>
|
|
101
|
+
</div>
|
|
102
|
+
)}
|
|
103
|
+
</li>
|
|
104
|
+
);
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
</ul>
|
|
108
|
+
|
|
109
|
+
<button class="nav left" aria-label="Previous image">
|
|
110
|
+
<Icon name="left-arrow" size="2rem" />
|
|
111
|
+
</button>
|
|
112
|
+
<button class="nav right" aria-label="Next image">
|
|
113
|
+
<Icon name="right-arrow" size="2rem" />
|
|
114
|
+
</button>
|
|
115
|
+
</div>
|
|
116
|
+
</gallery-slider>
|
|
117
|
+
|
|
118
|
+
<style>
|
|
119
|
+
gallery-slider {
|
|
120
|
+
display: block;
|
|
121
|
+
margin: 2rem auto;
|
|
122
|
+
max-width: 100%;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.slide-window {
|
|
126
|
+
position: relative;
|
|
127
|
+
overflow: hidden;
|
|
128
|
+
border-radius: 8px;
|
|
129
|
+
box-shadow: var(--sl-shadow-md);
|
|
130
|
+
background-color: var(--sl-color-gray-6);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.slides-list {
|
|
134
|
+
display: flex;
|
|
135
|
+
width: 100%;
|
|
136
|
+
height: 100%;
|
|
137
|
+
margin: 0 !important;
|
|
138
|
+
padding: 0 !important;
|
|
139
|
+
list-style: none !important;
|
|
140
|
+
transition: transform 0.5s ease-in-out;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.slide {
|
|
144
|
+
flex: 0 0 100%;
|
|
145
|
+
height: 100%;
|
|
146
|
+
position: relative;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.slide-link {
|
|
150
|
+
display: block;
|
|
151
|
+
width: 100%;
|
|
152
|
+
height: 100%;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.slide-img {
|
|
156
|
+
width: 100%;
|
|
157
|
+
height: 100%;
|
|
158
|
+
object-fit: contain;
|
|
159
|
+
display: block;
|
|
160
|
+
user-select: none;
|
|
161
|
+
margin-bottom: 0 !important;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.slide-caption {
|
|
165
|
+
position: absolute;
|
|
166
|
+
bottom: 0;
|
|
167
|
+
left: 0;
|
|
168
|
+
width: 100%;
|
|
169
|
+
background-color: rgba(0, 0, 0, 0.75);
|
|
170
|
+
color: white;
|
|
171
|
+
padding: 1rem 1.5rem;
|
|
172
|
+
text-align: center;
|
|
173
|
+
box-sizing: border-box;
|
|
174
|
+
pointer-events: none;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.slide-caption p {
|
|
178
|
+
margin: 0 !important;
|
|
179
|
+
font-size: 0.95rem;
|
|
180
|
+
line-height: 1.4;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.nav {
|
|
184
|
+
position: absolute;
|
|
185
|
+
top: 50%;
|
|
186
|
+
transform: translateY(-50%);
|
|
187
|
+
background: rgba(0, 0, 0, 0.5);
|
|
188
|
+
color: white;
|
|
189
|
+
border: none;
|
|
190
|
+
border-radius: 50%;
|
|
191
|
+
width: 3rem;
|
|
192
|
+
height: 3rem;
|
|
193
|
+
display: flex;
|
|
194
|
+
align-items: center;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
cursor: pointer;
|
|
197
|
+
z-index: 10;
|
|
198
|
+
transition: background 0.2s ease;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.nav:hover {
|
|
202
|
+
background: rgba(0, 0, 0, 0.9);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.nav.left { left: 1rem; }
|
|
206
|
+
.nav.right { right: 1rem; }
|
|
207
|
+
</style>
|
|
208
|
+
|
|
209
|
+
<script>
|
|
210
|
+
class GallerySlider extends HTMLElement {
|
|
211
|
+
currentSlide: number = 0;
|
|
212
|
+
slidesList: HTMLElement | undefined;
|
|
213
|
+
slides: NodeListOf<Element> | undefined;
|
|
214
|
+
totalSlides: number = 0;
|
|
215
|
+
autoSlide: number = 0;
|
|
216
|
+
interval: NodeJS.Timeout | null = null;
|
|
217
|
+
|
|
218
|
+
connectedCallback() {
|
|
219
|
+
this.currentSlide = 0;
|
|
220
|
+
this.slidesList = this.querySelector(".slides-list") as HTMLElement;
|
|
221
|
+
this.slides = this.querySelectorAll(".slide");
|
|
222
|
+
this.totalSlides = this.slides.length;
|
|
223
|
+
this.autoSlide = parseInt(this.dataset.autoSlide || "0", 10);
|
|
224
|
+
this.interval = null;
|
|
225
|
+
|
|
226
|
+
if (this.totalSlides === 0) return;
|
|
227
|
+
|
|
228
|
+
this.querySelector(".left")?.addEventListener("click", () => this.move("back"));
|
|
229
|
+
this.querySelector(".right")?.addEventListener("click", () => this.move("forward"));
|
|
230
|
+
|
|
231
|
+
this.resetAutoSlide();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
move(direction: "back" | "forward") {
|
|
235
|
+
if (direction === "back") {
|
|
236
|
+
this.currentSlide = (this.currentSlide - 1 + this.totalSlides) % this.totalSlides;
|
|
237
|
+
} else {
|
|
238
|
+
this.currentSlide = (this.currentSlide + 1) % this.totalSlides;
|
|
239
|
+
}
|
|
240
|
+
this.updateDOM();
|
|
241
|
+
this.resetAutoSlide();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
updateDOM() {
|
|
245
|
+
if (this.slidesList)
|
|
246
|
+
this.slidesList.style.transform = `translateX(-${this.currentSlide * 100}%)`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
resetAutoSlide() {
|
|
250
|
+
if (this.autoSlide > 0) {
|
|
251
|
+
if (this.interval) clearInterval(this.interval);
|
|
252
|
+
this.interval = setInterval(() => this.move("forward"), this.autoSlide) as any;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!customElements.get("gallery-slider")) {
|
|
258
|
+
customElements.define("gallery-slider", GallerySlider);
|
|
259
|
+
}
|
|
260
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
const rawProduct = import.meta.env.DOCS_PRODUCT || 'gameface';
|
|
3
|
+
|
|
4
|
+
function humanize(str: string) {
|
|
5
|
+
if (!str) return '';
|
|
6
|
+
const cleanStr = str.replace(/[-_]/g, ' ');
|
|
7
|
+
return cleanStr.charAt(0).toUpperCase() + cleanStr.slice(1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const productName = humanize(rawProduct);
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
{productName}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
date: string;
|
|
4
|
+
version: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const { date } = Astro.props;
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<div class="release-container">
|
|
11
|
+
<hr />
|
|
12
|
+
<div class="release-date">
|
|
13
|
+
<a
|
|
14
|
+
href="https://coherent-labs.com/get-in-touch/"
|
|
15
|
+
target="_blank"
|
|
16
|
+
rel="noopener noreferrer"
|
|
17
|
+
>
|
|
18
|
+
<span>Released {date}</span>
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="table-wrapper">
|
|
23
|
+
<table class="table table-striped">
|
|
24
|
+
<tbody>
|
|
25
|
+
<slot />
|
|
26
|
+
</tbody>
|
|
27
|
+
</table>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<style>
|
|
32
|
+
.release-container {
|
|
33
|
+
margin-bottom: 2rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.release-date {
|
|
37
|
+
margin-bottom: 1.5rem;
|
|
38
|
+
font-size: 0.95rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.table-wrapper {
|
|
42
|
+
overflow-x: auto;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.table-wrapper :global(.table-striped td:first-child),
|
|
46
|
+
.table-wrapper :global(.table-striped th:first-child) {
|
|
47
|
+
padding-inline-start: 1rem !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.table-wrapper :global(.table-striped td:last-child),
|
|
51
|
+
.table-wrapper :global(.table-striped th:last-child) {
|
|
52
|
+
padding-inline-end: 1rem !important;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.table-wrapper :global(.table-striped td) {
|
|
56
|
+
padding-block: 0.75rem;
|
|
57
|
+
vertical-align: middle;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.table-striped {
|
|
61
|
+
width: 100%;
|
|
62
|
+
border-collapse: collapse;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.table-striped :global(tbody tr:nth-of-type(odd)) {
|
|
66
|
+
background-color: var(--sl-color-gray-6);
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
nativeRef?: string;
|
|
5
|
+
unityRef?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { title, nativeRef = "", unityRef = "" } = Astro.props;
|
|
9
|
+
|
|
10
|
+
const currentType = import.meta.env.DOCS_TYPE || "";
|
|
11
|
+
|
|
12
|
+
let resolvedPath = "";
|
|
13
|
+
|
|
14
|
+
if (currentType === "cxx" && nativeRef !== "") {
|
|
15
|
+
resolvedPath = nativeRef;
|
|
16
|
+
} else if (currentType === "unity3d" && unityRef !== "") {
|
|
17
|
+
resolvedPath = unityRef;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (resolvedPath.endsWith(".mdx")) {
|
|
21
|
+
resolvedPath = resolvedPath.replace(/\.mdx$/, "");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (resolvedPath.endsWith(".md")) {
|
|
25
|
+
resolvedPath = resolvedPath.replace(/\.md$/, "");
|
|
26
|
+
}
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
{
|
|
30
|
+
resolvedPath !== "" ? (
|
|
31
|
+
<a href={resolvedPath}>{title}</a>
|
|
32
|
+
) : (
|
|
33
|
+
<Fragment>{title}</Fragment>
|
|
34
|
+
)
|
|
35
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
2
|
+
import { overrideComponents } from './internal/overrideComponents';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import starlightHeadingBadges from 'starlight-heading-badges';
|
|
6
|
+
import generateChangelogMultiple from './utils/changelogSideBarMultipleDocs';
|
|
7
|
+
import generateChangelog from './utils/changelogSideBar';
|
|
8
|
+
import type { CoherentThemeOptions } from './internal/themeConfig';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { directives } from './remark-directives';
|
|
11
|
+
import { getSortedCoherentReleases } from './utils/coherentReleases';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
const defaultHeaderLinks = [
|
|
16
|
+
{ href: 'https://docs.coherent-labs.com/cpp-gameface', label: 'Gameface' },
|
|
17
|
+
{ href: 'https://docs.coherent-labs.com/cpp-prysm', label: 'Prysm' },
|
|
18
|
+
{ href: 'https://starter.coherent-labs.com/', label: 'UI Starter Guide' },
|
|
19
|
+
{ href: 'https://frontend-tools.coherent-labs.com', label: 'UI Tools' },
|
|
20
|
+
{ href: 'https://gameface-ui.coherent-labs.com', label: 'Gameface UI' },
|
|
21
|
+
{ href: 'https://coherent-labs.com/Documentation/ExporterLTS/', label: 'Adobe CC Tools' },
|
|
22
|
+
];
|
|
23
|
+
const defaultMergeIndex = [
|
|
24
|
+
{
|
|
25
|
+
bundlePath: "https://gameface-ui.coherent-labs.com/pagefind",
|
|
26
|
+
indexWeight: 0.5,
|
|
27
|
+
mergeFilter: {
|
|
28
|
+
resource: "Gameface UI"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
bundlePath: "https://frontend-tools.coherent-labs.com/pagefind",
|
|
33
|
+
indexWeight: 0.5,
|
|
34
|
+
mergeFilter: {
|
|
35
|
+
resource: "UI Tools"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
export default function coherentThemePlugin(options: CoherentThemeOptions = { documentationSearchTag: '' }): StarlightPlugin[] {
|
|
41
|
+
if (!options?.documentationSearchTag) {
|
|
42
|
+
throw new Error('Coherent docs theme plugin requires "documentationSearchTag"!')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let navLinks = defaultHeaderLinks;
|
|
46
|
+
for (const link of options.navLinks ?? []) {
|
|
47
|
+
navLinks.push(link)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
showPageProgress = false,
|
|
52
|
+
disableDefaultLogo = false,
|
|
53
|
+
} = options;
|
|
54
|
+
|
|
55
|
+
const corePlugin: StarlightPlugin = {
|
|
56
|
+
name: 'coherent-docs-theme',
|
|
57
|
+
hooks: {
|
|
58
|
+
'config:setup'({ config, logger, updateConfig, addIntegration }) {
|
|
59
|
+
logger.info('Initializing Coherent Theme...');
|
|
60
|
+
|
|
61
|
+
addIntegration({
|
|
62
|
+
name: 'coherent-docs-theme-integration',
|
|
63
|
+
hooks: {
|
|
64
|
+
'astro:config:setup': ({ updateConfig }) => {
|
|
65
|
+
updateConfig({
|
|
66
|
+
markdown: {
|
|
67
|
+
remarkPlugins: [...directives],
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
process.env.COHERENT_THEME_CONFIG = JSON.stringify({ showPageProgress, navLinks, documentationSearchTag: options.documentationSearchTag });
|
|
75
|
+
|
|
76
|
+
const configUpdates: any = {
|
|
77
|
+
customCss: [...(config.customCss ?? []), 'coherent-docs-theme/styles'],
|
|
78
|
+
components: overrideComponents(
|
|
79
|
+
config,
|
|
80
|
+
['Header', 'ThemeSelect', 'Footer', 'Search'],
|
|
81
|
+
logger,
|
|
82
|
+
),
|
|
83
|
+
head: config.head || [],
|
|
84
|
+
};
|
|
85
|
+
if (!disableDefaultLogo && !config.logo) {
|
|
86
|
+
configUpdates.logo = {
|
|
87
|
+
dark: path.join(__dirname, 'assets/gameface-ui-header-dark.svg'),
|
|
88
|
+
light: path.join(__dirname, 'assets/gameface-ui-header-light.svg'),
|
|
89
|
+
replacesTitle: options.replacesTitle ?? true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
configUpdates.head.push({
|
|
94
|
+
tag: 'meta',
|
|
95
|
+
attrs: {
|
|
96
|
+
'data-pagefind-filter': 'resource[content]',
|
|
97
|
+
content: options.documentationSearchTag
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
configUpdates.pagefind = {
|
|
102
|
+
indexWeight: 2,
|
|
103
|
+
mergeIndex: defaultMergeIndex.filter(merge => {
|
|
104
|
+
const resource = merge.mergeFilter.resource;
|
|
105
|
+
return resource !== options.documentationSearchTag;
|
|
106
|
+
})
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
updateConfig(configUpdates);
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const plugins = [
|
|
115
|
+
starlightHeadingBadges(),
|
|
116
|
+
corePlugin,
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
return plugins
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function generateVersion(version: string, link?: string) {
|
|
123
|
+
const config: { label: string; link: string; attrs?: { target: string }; badge?: { text: string; variant: "note" | "danger" | "success" | "caution" | "tip" | "default" } } = {
|
|
124
|
+
label: 'Version:',
|
|
125
|
+
link: '/',
|
|
126
|
+
badge: {
|
|
127
|
+
text: `${version}`,
|
|
128
|
+
variant: 'tip',
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (link) {
|
|
133
|
+
config.link = link;
|
|
134
|
+
config.attrs = { target: '_blank' };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return config;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function generateVersionWithPackageJSON(packagePath: string, link?: string) {
|
|
141
|
+
if (!fs.existsSync(packagePath)) throw new Error(`Version not found in ${packagePath}`);
|
|
142
|
+
const packageContent = fs.readFileSync(packagePath, 'utf-8');
|
|
143
|
+
const packageJson = JSON.parse(packageContent);
|
|
144
|
+
const version = packageJson?.version;
|
|
145
|
+
if (!version) throw new Error(`Version not defined in ${packagePath}`);
|
|
146
|
+
|
|
147
|
+
return generateVersion(version, link);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const generateMultipleDocsChangelog = generateChangelogMultiple;
|
|
151
|
+
export const generateDocsChangelog = generateChangelog;
|
|
152
|
+
export const getCoherentReleases = getSortedCoherentReleases;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HookParameters } from '@astrojs/starlight/types'
|
|
2
|
+
import type { AstroIntegrationLogger } from 'astro'
|
|
3
|
+
|
|
4
|
+
export function overrideComponents(
|
|
5
|
+
starlightConfig: StarlightUserConfig,
|
|
6
|
+
overrides: ComponentOverride[],
|
|
7
|
+
logger: AstroIntegrationLogger,
|
|
8
|
+
): StarlightUserConfig['components'] {
|
|
9
|
+
const components = { ...starlightConfig.components }
|
|
10
|
+
|
|
11
|
+
for (const override of overrides) {
|
|
12
|
+
const name = typeof override === 'string' ? override : override.name
|
|
13
|
+
if (starlightConfig.components?.[name]) {
|
|
14
|
+
logger.info(`Overriding coherent-docs-theme's \`<${name}>\` component with \`${starlightConfig.components?.[name]}\`.`)
|
|
15
|
+
continue
|
|
16
|
+
}
|
|
17
|
+
components[name] = `coherent-docs-theme/overrides/${name}.astro`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return components
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type StarlightUserConfig = HookParameters<'config:setup'>['config']
|
|
24
|
+
|
|
25
|
+
type ComponentOverride =
|
|
26
|
+
| keyof NonNullable<StarlightUserConfig['components']>
|
|
27
|
+
| {
|
|
28
|
+
name: keyof NonNullable<StarlightUserConfig['components']>
|
|
29
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface CoherentThemeOptions {
|
|
2
|
+
documentationSearchTag: string
|
|
3
|
+
showPageProgress?: boolean;
|
|
4
|
+
navLinks?: Array<{ label: string; href: string }>;
|
|
5
|
+
disableDefaultLogo?: boolean;
|
|
6
|
+
replacesTitle?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function getThemeConfig(): CoherentThemeOptions {
|
|
10
|
+
let themeConfig = { documentationSearchTag: '', showPageProgress: false, navLinks: [], disableDefaultLogo: false } as CoherentThemeOptions;
|
|
11
|
+
|
|
12
|
+
if (process.env.COHERENT_THEME_CONFIG) {
|
|
13
|
+
try {
|
|
14
|
+
themeConfig = { ...themeConfig, ...JSON.parse(process.env.COHERENT_THEME_CONFIG) };
|
|
15
|
+
} catch (e) {
|
|
16
|
+
console.error("Failed to parse Coherent Theme config");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return themeConfig;
|
|
21
|
+
}
|