@nu-appdev/northwestern-starlight-theme 1.4.0 → 1.5.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/CHANGELOG.md CHANGED
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.5.0] - 2026-03-31
11
+
12
+ ### Added
13
+
14
+ - **[`defineNorthwesternConfig`](http://starlight-theme.entapp.northwestern.edu/getting-started/#configuration) config helper.** Single function that returns a complete Astro config with integration ordering (mermaid → starlight), plugin registration, and Expressive Code. Replaces the manual `defineConfig` + `starlight()` + `northwesternMermaid()` wiring. New `./config` package export.
15
+ - **Automatic Expressive Code line numbers.** `defineNorthwesternConfig` injects `pluginLineNumbers()` and GitHub syntax themes (`github-dark` / `github-light`). No `ec.config.mjs` file needed. A Vite plugin separates serializable config from plugin instances so the `<Code>` Astro component continues to work.
16
+ - Type declarations (`.d.ts`) shipped for all public exports.
17
+ - OG images for changelog version pages with multi-line titles (e.g., "Changelog / 1.4.0").
18
+ - JSON-LD structured data on each page.
19
+ - Unit test suite (Vitest) covering `config.ts`, `expressive-code.ts`, `mermaid.ts`, and `rehype-table-scroll.ts`. E2E tests moved to `tests/e2e/`. CI runs unit tests in a dedicated job.
20
+
21
+ ### Fixed
22
+
23
+ - Replaced `astro-og-canvas` + `canvaskit-wasm` with `satori` + `@resvg/resvg-wasm`. pnpm users no longer need `canvaskit-wasm` as a direct dependency.
24
+ - OG image generation logs a warning and disables when Starlight `title` is empty or `site` is not set, instead of crashing or producing broken URLs.
25
+ - OG font buffer uses correct `Uint8Array` offset slicing instead of casting the full backing `ArrayBuffer`.
26
+ - Larger OG text: title 48→56px, description 28→32px, logo 60→80px. Separate vertical (60px) and horizontal (220px) padding to avoid clipping.
27
+ - Runtime config validation now catches invalid theme, Mermaid, and config-helper options with friendly errors at the public API boundary instead of failing later with cryptic behavior.
28
+ - Rehype table scroll skips tables already inside `.nu-table-scroll`, preventing double-wrapping on incremental rebuilds.
29
+ - Aside borders use solid brand colors (`#5091cd`, `#008656`, `#ffc520`, `#ef553f`) and a 3px left accent stripe instead of a translucent 1px box border. Dark mode borders match the text accent for each variant.
30
+
31
+ ### Changed
32
+
33
+ - `h1` keeps `Noto Serif`; `h2`–`h6` switched to `Poppins`.
34
+ - Package `exports` map includes `types` fields pointing to `dist/*.d.ts` for all entry points.
35
+
10
36
  ## [1.4.0] - 2026-03-31
11
37
 
12
38
  ### Added
@@ -153,7 +179,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
153
179
  - OpenAPI plugin compatibility with method badge preservation
154
180
  - Reduced motion support for transitions
155
181
 
156
- [Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.4.0...HEAD
182
+ [Unreleased]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.5.0...HEAD
183
+ [1.5.0]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.4.0...v1.5.0
157
184
  [1.4.0]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.2...v1.4.0
158
185
  [1.3.2]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.1...v1.3.2
159
186
  [1.3.1]: https://github.com/NIT-Administrative-Systems/northwestern-starlight-theme/compare/v1.3.0...v1.3.1
package/README.md CHANGED
@@ -20,21 +20,17 @@ pnpm add @nu-appdev/northwestern-starlight-theme
20
20
  ```
21
21
 
22
22
  ```ts
23
- import starlight from "@astrojs/starlight";
24
- import { defineConfig } from "astro/config";
25
- import northwesternTheme from "@nu-appdev/northwestern-starlight-theme";
26
-
27
- export default defineConfig({
28
- integrations: [
29
- starlight({
30
- plugins: [northwesternTheme()],
31
- title: "My Docs",
32
- }),
33
- ],
23
+ import { defineNorthwesternConfig } from "@nu-appdev/northwestern-starlight-theme/config";
24
+
25
+ export default defineNorthwesternConfig({
26
+ site: "https://docs.example.northwestern.edu",
27
+ starlight: {
28
+ title: "My Docs",
29
+ },
34
30
  });
35
31
  ```
36
32
 
37
- The plugin applies Northwestern's purple palette, Akkurat Pro + Poppins typography, branded navigation, styled components, and full dark mode support. No additional CSS or configuration required.
33
+ The helper applies Northwestern's purple palette, Akkurat Pro + Poppins typography, branded navigation, styled components, and dark mode. It handles integration ordering, plugin registration, and Mermaid setup.
38
34
 
39
35
  See the **[documentation](https://starlight-theme.entapp.northwestern.edu)** for setup options, customization, and component examples.
40
36
 
package/config.ts ADDED
@@ -0,0 +1,308 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { join } from "node:path";
4
+ import starlight from "@astrojs/starlight";
5
+ import type { StarlightExpressiveCodeOptions } from "@astrojs/starlight/expressive-code";
6
+ import type { StarlightPlugin, StarlightUserConfig } from "@astrojs/starlight/types";
7
+ import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
8
+ import type { AstroIntegration, AstroUserConfig } from "astro";
9
+ import type { NorthwesternThemeConfig } from "./index";
10
+ import northwesternTheme from "./index";
11
+ import { type NorthwesternMermaidOptions, northwesternMermaid } from "./mermaid";
12
+ import { northwesternConfigOptionsSchema, validateSchema } from "./src/config-schema";
13
+
14
+ /**
15
+ * Vite plugin that enables `pluginLineNumbers` for both markdown code blocks
16
+ * and the `<Code>` component without requiring a manual `ec.config.mjs` file.
17
+ *
18
+ * Expressive Code serializes inline config via JSON.stringify for the `<Code>`
19
+ * component's virtual module. Plugin instances aren't serializable, causing a
20
+ * build error when any page uses `<Code>`.
21
+ *
22
+ * This plugin:
23
+ * 1. Strips non-serializable `plugins` from the virtual config module
24
+ * (so the `<Code>` component's serialization check passes)
25
+ * 2. Provides a virtual `ec.config.mjs` that re-exports the plugins
26
+ * (so the `<Code>` component picks them up at render time via merge)
27
+ *
28
+ * If the user has a real `ec.config.mjs` on disk, this plugin does nothing.
29
+ */
30
+ function northwesternEcVitePlugin() {
31
+ const _require = createRequire(import.meta.url);
32
+ const resolvedPluginPath = _require.resolve("@expressive-code/plugin-line-numbers").replaceAll("\\", "/");
33
+ let hasRealEcConfig = false;
34
+
35
+ return {
36
+ name: "northwestern-ec-compat",
37
+ configResolved(config: { root: string }) {
38
+ hasRealEcConfig = existsSync(join(config.root, "ec.config.mjs"));
39
+ },
40
+ resolveId(id: string) {
41
+ if (!hasRealEcConfig && id === "./ec.config.mjs") {
42
+ return "\0northwestern-virtual-ec-config";
43
+ }
44
+ },
45
+ load(id: string) {
46
+ if (id === "\0northwestern-virtual-ec-config") {
47
+ return [
48
+ `import { pluginLineNumbers } from "${resolvedPluginPath}";`,
49
+ "export default { plugins: [pluginLineNumbers()] };",
50
+ ].join("\n");
51
+ }
52
+ },
53
+ transform(code: string, id: string) {
54
+ if (!hasRealEcConfig && id === "\0virtual:astro-expressive-code/config") {
55
+ return code.replace(/export const ecIntegrationOptions = ({.*})/, (match: string, json: string) => {
56
+ try {
57
+ const parsed = JSON.parse(json);
58
+ delete parsed.plugins;
59
+ return `export const ecIntegrationOptions = ${JSON.stringify(parsed)}`;
60
+ } catch {
61
+ return match;
62
+ }
63
+ });
64
+ }
65
+ },
66
+ };
67
+ }
68
+
69
+ function hasOptionalPackage(id: string): boolean {
70
+ const _require = createRequire(import.meta.url);
71
+
72
+ try {
73
+ _require.resolve(id);
74
+ return true;
75
+ } catch (error) {
76
+ // Some ESM-only packages expose only an `import` condition, so
77
+ // `require.resolve()` can fail even when the package is installed.
78
+ if (error && typeof error === "object" && "code" in error && error.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
79
+ return true;
80
+ }
81
+
82
+ return false;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Merge helper-managed and migrated Starlight plugins into a stable order.
88
+ *
89
+ * The Northwestern theme plugin is always first. Existing `starlight.plugins`
90
+ * are preserved next for migration compatibility, and helper-level `plugins`
91
+ * are appended last. Named plugins are deduped by first occurrence.
92
+ *
93
+ * @internal
94
+ */
95
+ export function mergeStarlightPlugins(
96
+ themePlugin: StarlightPlugin,
97
+ starlightPlugins: StarlightPlugin[],
98
+ helperPlugins: StarlightPlugin[],
99
+ ): StarlightPlugin[] {
100
+ const seenNamedPlugins = new Set<string>();
101
+ const deduped: StarlightPlugin[] = [];
102
+
103
+ for (const plugin of [themePlugin, ...starlightPlugins, ...helperPlugins]) {
104
+ if (!plugin.name) {
105
+ deduped.push(plugin);
106
+ continue;
107
+ }
108
+
109
+ if (seenNamedPlugins.has(plugin.name)) {
110
+ continue;
111
+ }
112
+
113
+ seenNamedPlugins.add(plugin.name);
114
+ deduped.push(plugin);
115
+ }
116
+
117
+ return deduped;
118
+ }
119
+
120
+ /**
121
+ * Configuration options for {@link defineNorthwesternConfig}.
122
+ *
123
+ * Extends Astro's config (minus `integrations`) with Northwestern-specific
124
+ * keys for Starlight, theming, and Mermaid. Integration ordering is handled
125
+ * automatically. Use the `integrations` escape hatch only when you need
126
+ * to inject integrations before or after the managed ones.
127
+ */
128
+ export type NorthwesternConfigOptions = Omit<AstroUserConfig, "integrations"> & {
129
+ /** Full Starlight configuration. Supports all Starlight options with autocompletion. */
130
+ starlight: StarlightUserConfig;
131
+
132
+ /**
133
+ * Northwestern theme plugin options (hero layout, OG images, etc.).
134
+ *
135
+ * @see {@link NorthwesternThemeConfig}
136
+ */
137
+ theme?: NorthwesternThemeConfig;
138
+
139
+ /**
140
+ * Mermaid diagram support.
141
+ *
142
+ * - `true` (default) — adds `northwesternMermaid()` before `starlight()` with
143
+ * default options (branded colors, toolbar, dark mode). Requires `astro-mermaid`
144
+ * and `mermaid` to be installed.
145
+ * - `false` — disable Mermaid entirely
146
+ * - `object` — adds `northwesternMermaid(options)` before `starlight()` with
147
+ * custom options (toolbar, theme overrides, etc.)
148
+ */
149
+ mermaid?: boolean | NorthwesternMermaidOptions;
150
+
151
+ /**
152
+ * Additional Starlight plugins to register alongside the Northwestern theme.
153
+ *
154
+ * The theme plugin is always first; these are appended after it.
155
+ */
156
+ plugins?: StarlightPlugin[];
157
+
158
+ /**
159
+ * Escape hatch for advanced integration ordering.
160
+ *
161
+ * - `before` — added before Mermaid and Starlight
162
+ * - `after` — added after Starlight
163
+ */
164
+ integrations?: {
165
+ before?: AstroIntegration[];
166
+ after?: AstroIntegration[];
167
+ };
168
+ };
169
+
170
+ /**
171
+ * Create a complete Astro config with Northwestern Starlight theme defaults.
172
+ *
173
+ * Handles integration ordering (mermaid → starlight), plugin registration,
174
+ * and Expressive Code (GitHub themes, line-numbers plugin). The return
175
+ * value is a standard `AstroUserConfig` ready to
176
+ * `export default` from `astro.config.ts`.
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * import { defineNorthwesternConfig } from "@nu-appdev/northwestern-starlight-theme/config";
181
+ *
182
+ * export default defineNorthwesternConfig({
183
+ * site: "https://docs.example.northwestern.edu",
184
+ * starlight: {
185
+ * title: "My Docs",
186
+ * sidebar: [{ label: "Guide", autogenerate: { directory: "guide" } }],
187
+ * },
188
+ * });
189
+ * ```
190
+ */
191
+ export function defineNorthwesternConfig(options: NorthwesternConfigOptions): AstroUserConfig {
192
+ const validatedOptions = validateSchema(northwesternConfigOptionsSchema, options, "config helper options");
193
+ const {
194
+ starlight: starlightConfig,
195
+ theme,
196
+ mermaid = true,
197
+ plugins = [],
198
+ integrations: extraIntegrations,
199
+ ...astroConfig
200
+ } = validatedOptions as NorthwesternConfigOptions;
201
+
202
+ const {
203
+ expressiveCode: userExpressiveCode,
204
+ plugins: starlightPlugins = [],
205
+ ...restStarlightConfig
206
+ } = starlightConfig;
207
+ const helperPlugins = plugins;
208
+
209
+ // Warn if user manually added northwesternTheme in plugins
210
+ for (const plugin of [...starlightPlugins, ...helperPlugins]) {
211
+ if (plugin.name === "northwestern-starlight-theme") {
212
+ console.warn(
213
+ "[northwestern-starlight-theme] `northwesternTheme()` was found in `plugins` — " +
214
+ "the config helper adds it automatically. Remove it from `plugins` to avoid " +
215
+ "double-registration. Use the `theme` key for options instead.",
216
+ );
217
+ }
218
+ }
219
+
220
+ if (starlightPlugins.length > 0) {
221
+ console.warn(
222
+ "[northwestern-starlight-theme] `starlight.plugins` was found in the helper config. Those plugins will be preserved, " +
223
+ "but the helper's top-level `plugins` key is the preferred API for new configs.",
224
+ );
225
+ }
226
+
227
+ if (theme?.mermaid !== undefined) {
228
+ console.warn(
229
+ "[northwestern-starlight-theme] `theme.mermaid` is ignored by `defineNorthwesternConfig()`. " +
230
+ "Use the helper's top-level `mermaid` option instead.",
231
+ );
232
+ }
233
+
234
+ // Build theme config, handling mermaid dual-path.
235
+ // The standalone northwesternMermaid() integration MUST be added before starlight()
236
+ // so its remark plugin processes mermaid code blocks before expressive-code.
237
+ // The theme's built-in mermaid (via addIntegration inside config:setup) runs too late.
238
+ const themeConfig: NorthwesternThemeConfig = { ...theme };
239
+ let mermaidIntegration: AstroIntegration | undefined;
240
+ const hasAstroMermaid = hasOptionalPackage("astro-mermaid");
241
+ const hasMermaid = hasOptionalPackage("mermaid");
242
+
243
+ if (mermaid && (!hasAstroMermaid || !hasMermaid)) {
244
+ const missingPackages = [
245
+ ...(!hasAstroMermaid ? ['"astro-mermaid"'] : []),
246
+ ...(!hasMermaid ? ['"mermaid"'] : []),
247
+ ];
248
+ console.warn(
249
+ `[northwestern-starlight-theme] Mermaid support was requested, but ${missingPackages.join(" and ")} ${
250
+ missingPackages.length === 1 ? "is" : "are"
251
+ } not installed. Mermaid integration will be skipped. Install the missing package(s) to enable Mermaid support.`,
252
+ );
253
+ }
254
+
255
+ if (typeof mermaid === "object" && hasAstroMermaid && hasMermaid) {
256
+ // Standalone integration with custom options; disable the theme's built-in
257
+ themeConfig.mermaid = false;
258
+ mermaidIntegration = northwesternMermaid(mermaid);
259
+ } else if (mermaid && hasAstroMermaid && hasMermaid) {
260
+ // Auto-detect: add standalone integration (handles toolbar + dark mode),
261
+ // disable theme's built-in to prevent double-registration
262
+ themeConfig.mermaid = false;
263
+ mermaidIntegration = northwesternMermaid();
264
+ } else {
265
+ themeConfig.mermaid = false;
266
+ }
267
+
268
+ // Build Expressive Code config: GitHub themes + line-numbers plugin.
269
+ // Merge with any user-provided expressiveCode settings.
270
+ const expressiveCodeConfig: StarlightExpressiveCodeOptions = {
271
+ plugins: [pluginLineNumbers()],
272
+ defaultProps: { showLineNumbers: false },
273
+ themes: ["github-dark", "github-light"],
274
+ useStarlightUiThemeColors: true,
275
+ ...(typeof userExpressiveCode === "object" ? userExpressiveCode : {}),
276
+ };
277
+ const mergedPlugins = mergeStarlightPlugins(northwesternTheme(themeConfig), starlightPlugins, helperPlugins);
278
+
279
+ // Build integration array: before → [mermaid] → starlight → after
280
+ const integrations: AstroIntegration[] = [
281
+ ...(extraIntegrations?.before ?? []),
282
+ ...(mermaidIntegration ? [mermaidIntegration] : []),
283
+ starlight({
284
+ ...restStarlightConfig,
285
+ expressiveCode: expressiveCodeConfig,
286
+ plugins: mergedPlugins,
287
+ }),
288
+ ...(extraIntegrations?.after ?? []),
289
+ ];
290
+
291
+ const existingViteConfig = (astroConfig.vite ?? {}) as {
292
+ plugins?: unknown | unknown[];
293
+ };
294
+ const existingVitePlugins = Array.isArray(existingViteConfig.plugins)
295
+ ? existingViteConfig.plugins
296
+ : existingViteConfig.plugins
297
+ ? [existingViteConfig.plugins]
298
+ : [];
299
+
300
+ return {
301
+ ...astroConfig,
302
+ integrations,
303
+ vite: {
304
+ ...existingViteConfig,
305
+ plugins: [...existingVitePlugins, northwesternEcVitePlugin()],
306
+ },
307
+ };
308
+ }
@@ -0,0 +1,82 @@
1
+ import type { StarlightPlugin, StarlightUserConfig } from "@astrojs/starlight/types";
2
+ import type { AstroIntegration, AstroUserConfig } from "astro";
3
+ import type { NorthwesternThemeConfig } from "./index";
4
+ import { type NorthwesternMermaidOptions } from "./mermaid";
5
+ /**
6
+ * Merge helper-managed and migrated Starlight plugins into a stable order.
7
+ *
8
+ * The Northwestern theme plugin is always first. Existing `starlight.plugins`
9
+ * are preserved next for migration compatibility, and helper-level `plugins`
10
+ * are appended last. Named plugins are deduped by first occurrence.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function mergeStarlightPlugins(themePlugin: StarlightPlugin, starlightPlugins: StarlightPlugin[], helperPlugins: StarlightPlugin[]): StarlightPlugin[];
15
+ /**
16
+ * Configuration options for {@link defineNorthwesternConfig}.
17
+ *
18
+ * Extends Astro's config (minus `integrations`) with Northwestern-specific
19
+ * keys for Starlight, theming, and Mermaid. Integration ordering is handled
20
+ * automatically. Use the `integrations` escape hatch only when you need
21
+ * to inject integrations before or after the managed ones.
22
+ */
23
+ export type NorthwesternConfigOptions = Omit<AstroUserConfig, "integrations"> & {
24
+ /** Full Starlight configuration. Supports all Starlight options with autocompletion. */
25
+ starlight: StarlightUserConfig;
26
+ /**
27
+ * Northwestern theme plugin options (hero layout, OG images, etc.).
28
+ *
29
+ * @see {@link NorthwesternThemeConfig}
30
+ */
31
+ theme?: NorthwesternThemeConfig;
32
+ /**
33
+ * Mermaid diagram support.
34
+ *
35
+ * - `true` (default) — adds `northwesternMermaid()` before `starlight()` with
36
+ * default options (branded colors, toolbar, dark mode). Requires `astro-mermaid`
37
+ * and `mermaid` to be installed.
38
+ * - `false` — disable Mermaid entirely
39
+ * - `object` — adds `northwesternMermaid(options)` before `starlight()` with
40
+ * custom options (toolbar, theme overrides, etc.)
41
+ */
42
+ mermaid?: boolean | NorthwesternMermaidOptions;
43
+ /**
44
+ * Additional Starlight plugins to register alongside the Northwestern theme.
45
+ *
46
+ * The theme plugin is always first; these are appended after it.
47
+ */
48
+ plugins?: StarlightPlugin[];
49
+ /**
50
+ * Escape hatch for advanced integration ordering.
51
+ *
52
+ * - `before` — added before Mermaid and Starlight
53
+ * - `after` — added after Starlight
54
+ */
55
+ integrations?: {
56
+ before?: AstroIntegration[];
57
+ after?: AstroIntegration[];
58
+ };
59
+ };
60
+ /**
61
+ * Create a complete Astro config with Northwestern Starlight theme defaults.
62
+ *
63
+ * Handles integration ordering (mermaid → starlight), plugin registration,
64
+ * and Expressive Code (GitHub themes, line-numbers plugin). The return
65
+ * value is a standard `AstroUserConfig` ready to
66
+ * `export default` from `astro.config.ts`.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { defineNorthwesternConfig } from "@nu-appdev/northwestern-starlight-theme/config";
71
+ *
72
+ * export default defineNorthwesternConfig({
73
+ * site: "https://docs.example.northwestern.edu",
74
+ * starlight: {
75
+ * title: "My Docs",
76
+ * sidebar: [{ label: "Guide", autogenerate: { directory: "guide" } }],
77
+ * },
78
+ * });
79
+ * ```
80
+ */
81
+ export declare function defineNorthwesternConfig(options: NorthwesternConfigOptions): AstroUserConfig;
82
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAErF,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,KAAK,0BAA0B,EAAuB,MAAM,WAAW,CAAC;AA2EjF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACjC,WAAW,EAAE,eAAe,EAC5B,gBAAgB,EAAE,eAAe,EAAE,EACnC,aAAa,EAAE,eAAe,EAAE,GACjC,eAAe,EAAE,CAmBnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,GAAG;IAC5E,wFAAwF;IACxF,SAAS,EAAE,mBAAmB,CAAC;IAE/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAEhC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,0BAA0B,CAAC;IAE/C;;;;OAIG;IACH,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAE5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;QAC5B,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;KAC9B,CAAC;CACL,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,eAAe,CAqH5F"}
@@ -0,0 +1,21 @@
1
+ import type { StarlightExpressiveCodeOptions } from "@astrojs/starlight/expressive-code";
2
+ /**
3
+ * Pre-configured Expressive Code options for the Northwestern Starlight theme.
4
+ *
5
+ * Adds the line-numbers plugin and sets sensible defaults. Pass your own
6
+ * options to merge with the Northwestern defaults.
7
+ *
8
+ * **Note:** `defineNorthwesternConfig` includes these options.
9
+ * This helper is only needed for manual setups using `northwesternTheme()` directly.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // ec.config.mjs (manual setup only)
14
+ * import { defineEcConfig } from "@astrojs/starlight/expressive-code";
15
+ * import { northwesternExpressiveCode } from "@nu-appdev/northwestern-starlight-theme/expressive-code";
16
+ *
17
+ * export default defineEcConfig(northwesternExpressiveCode());
18
+ * ```
19
+ */
20
+ export declare function northwesternExpressiveCode(config?: StarlightExpressiveCodeOptions): StarlightExpressiveCodeOptions;
21
+ //# sourceMappingURL=expressive-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expressive-code.d.ts","sourceRoot":"","sources":["../expressive-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AAGzF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CACtC,MAAM,GAAE,8BAAmC,GAC5C,8BAA8B,CAWhC"}
@@ -0,0 +1,123 @@
1
+ import type { StarlightPlugin } from "@astrojs/starlight/types";
2
+ /**
3
+ * Configuration for the homepage hero section.
4
+ *
5
+ * Controls hero layout, title visibility, and image sizing. Passed as the
6
+ * `homepage` property of {@link NorthwesternThemeConfig}.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * northwesternTheme({
11
+ * homepage: {
12
+ * layout: "split",
13
+ * showTitle: false,
14
+ * imageWidth: "750px",
15
+ * },
16
+ * })
17
+ * ```
18
+ */
19
+ export interface NorthwesternHomepageConfig {
20
+ /**
21
+ * Hero layout style.
22
+ *
23
+ * - `"centered"` (default) — image above title, everything centered
24
+ * - `"split"` — text + buttons on the left, image on the right (60/40 split)
25
+ */
26
+ layout?: "centered" | "split";
27
+ /**
28
+ * Whether to display the page title in the hero.
29
+ *
30
+ * Set to `false` when the hero image is a lockup that already contains the title.
31
+ *
32
+ * @default true
33
+ */
34
+ showTitle?: boolean;
35
+ /**
36
+ * Maximum width of the hero image in the centered layout, in pixels.
37
+ *
38
+ * Use a larger value for wide lockup images (e.g., `"750px"`, `"1000px"`).
39
+ *
40
+ * @default "500px"
41
+ */
42
+ imageWidth?: string;
43
+ }
44
+ /**
45
+ * Top-level configuration for the Northwestern Starlight theme plugin.
46
+ *
47
+ * With `defineNorthwesternConfig`, pass these as the `theme` key.
48
+ * With `northwesternTheme()` directly, pass them as the function argument.
49
+ * All properties are optional.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * defineNorthwesternConfig({
54
+ * starlight: { title: "My Docs" },
55
+ * theme: { homepage: { layout: "split" } },
56
+ * })
57
+ * ```
58
+ *
59
+ * @see {@link NorthwesternHomepageConfig} for homepage hero options
60
+ */
61
+ export interface NorthwesternThemeConfig {
62
+ /**
63
+ * Homepage hero layout configuration.
64
+ *
65
+ * @see {@link NorthwesternHomepageConfig}
66
+ */
67
+ homepage?: NorthwesternHomepageConfig;
68
+ /**
69
+ * Mermaid diagram support.
70
+ *
71
+ * - `true` (default) — auto-detect: enables Mermaid if `astro-mermaid` and `mermaid`
72
+ * are installed, skips silently if they are not
73
+ * - `false` — disables Mermaid entirely
74
+ * - `object` — enables Mermaid with custom Mermaid config merged with Northwestern defaults
75
+ *
76
+ * @default true
77
+ */
78
+ mermaid?: boolean | Record<string, unknown>;
79
+ /**
80
+ * Open Graph image generation.
81
+ *
82
+ * Generates branded OG images (1200x630 PNG) for every docs page with the
83
+ * page title and description on a Northwestern purple background.
84
+ *
85
+ * Requires `site` to be set in `astro.config.ts` for absolute image URLs.
86
+ *
87
+ * @default true
88
+ */
89
+ ogImage?: boolean;
90
+ }
91
+ /**
92
+ * Create a Northwestern-branded Starlight theme plugin.
93
+ *
94
+ * Registers Northwestern typography (Akkurat Pro, Poppins), purple color palette,
95
+ * component overrides (Hero, ThemeToggle, EditLink), and optional Mermaid diagram
96
+ * support with branded color schemes.
97
+ *
98
+ * **Recommended:** Use {@link https://github.com/NUAppDev/northwestern-starlight-theme | defineNorthwesternConfig}
99
+ * from `@nu-appdev/northwestern-starlight-theme/config` instead. It handles
100
+ * integration ordering, Mermaid, and Expressive Code (line numbers, GitHub themes).
101
+ *
102
+ * @param config - Theme configuration. All properties optional.
103
+ * @returns A Starlight plugin to pass to `plugins` in your Starlight config.
104
+ *
105
+ * @example Manual setup
106
+ * ```ts
107
+ * starlight({ plugins: [northwesternTheme()] })
108
+ * ```
109
+ *
110
+ * @example Split hero with Mermaid disabled
111
+ * ```ts
112
+ * starlight({
113
+ * plugins: [
114
+ * northwesternTheme({
115
+ * homepage: { layout: "split", showTitle: false },
116
+ * mermaid: false,
117
+ * }),
118
+ * ],
119
+ * })
120
+ * ```
121
+ */
122
+ export default function northwesternTheme(config?: NorthwesternThemeConfig): StarlightPlugin;
123
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,0BAA0B;IACvC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAE9B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,uBAAuB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,0BAA0B,CAAC;IAEtC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5C;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AA6BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,MAAM,GAAE,uBAA4B,GAAG,eAAe,CAkP/F"}