starlight-theme-apple 0.7.0 → 0.9.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +47 -5
  3. package/components/Footer.astro +19 -0
  4. package/components/Header.astro +55 -0
  5. package/components/NavLink.astro +24 -0
  6. package/components/PageFrame.astro +11 -0
  7. package/components/PageTitle.astro +24 -40
  8. package/components/Pagination.astro +22 -29
  9. package/components/Sidebar.astro +27 -0
  10. package/components/SiteFooter.astro +61 -0
  11. package/components/SocialIcons.astro +22 -0
  12. package/components.ts +10 -0
  13. package/index.ts +81 -120
  14. package/libs/breadcrumbs.ts +80 -0
  15. package/libs/config.ts +54 -0
  16. package/libs/expressive-code.ts +246 -0
  17. package/libs/links.ts +38 -0
  18. package/package.json +11 -5
  19. package/styles/base.css +35 -53
  20. package/styles/code.css +7 -83
  21. package/styles/components.css +599 -0
  22. package/styles/content.css +224 -425
  23. package/styles/header.css +217 -62
  24. package/styles/reference.css +332 -0
  25. package/styles/search.css +87 -73
  26. package/styles/sidebar.css +77 -56
  27. package/styles/toc.css +51 -44
  28. package/styles/tokens.css +130 -93
  29. package/styles.css +4 -4
  30. package/translations.ts +31 -0
  31. package/user-components/Availability.astro +21 -0
  32. package/user-components/Declaration.astro +16 -0
  33. package/user-components/Figure.astro +58 -0
  34. package/user-components/Parameter.astro +14 -0
  35. package/user-components/ParameterList.astro +11 -0
  36. package/user-components/ReferenceEntry.astro +12 -0
  37. package/user-components/ReferenceMeta.astro +30 -0
  38. package/user-components/TopicLink.astro +17 -0
  39. package/user-components/TopicList.astro +5 -0
  40. package/user-components/ValueList.astro +20 -0
  41. package/virtual.d.ts +10 -0
  42. package/styles/controls.css +0 -190
  43. package/styles/responsive.css +0 -157
package/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ ## 0.8.0
4
+
5
+ A redesign that brings the theme much closer to Apple’s developer documentation and moves common site structure into the theme.
6
+
7
+ ### Added
8
+
9
+ - Full-width site footer outside the article columns, with optional `footer.groups` navigation columns. Without groups it renders a compact bottom row. A thin `PageFrame` wrapper preserves Starlight’s native frame and places the site footer after it. Article metadata and pagination stay in `Footer`.
10
+
11
+ - Theme-provided `Header`, `Sidebar`, `SocialIcons`, and `Footer` components. Header links, an optional emphasized action, and footer links are configured through new plugin options: `nav`, `action`, `socialAttrs`, and `footer`.
12
+ - Header links are repeated at the top of the small-screen navigation menu.
13
+ - Reference components exported from `starlight-theme-apple/components`: `ReferenceEntry`, `Declaration`, `ReferenceMeta`, `ParameterList`, `Parameter`, `ValueList`, `Availability`, `TopicList`, `TopicLink`, and `Figure`, plus the equivalent `apple-*` HTML classes for generated Markdown.
14
+ - Breadcrumbs link sidebar groups to their overview page when the group has one.
15
+ - Xcode-inspired code colors, applied through Expressive Code’s `styleOverrides` instead of `!important` CSS.
16
+
17
+ ### Changed
18
+
19
+
20
+ - Typography, palette, spacing, sidebar, table of contents, asides, cards, buttons, tabs, steps, badges, search, and the splash hero follow Apple’s documentation more closely. Dark mode uses Apple’s black background.
21
+ - The appearance control is Starlight’s native `ThemeSelect`, shown as an icon button. It keeps Light, Dark, and Auto.
22
+ - Component overrides set by you or by earlier plugins now take precedence over the theme’s components. Previously `PageTitle` and `Pagination` were always replaced.
23
+ - The theme stylesheet is loaded before your `customCss`.
24
+ - Layout uses Starlight’s own `--sl-content-width` and `--sl-sidebar-width` instead of fighting Starlight’s layout. The content column is 51.25rem.
25
+ - Shell code blocks render as plain listings rather than empty terminal windows. Add `frame="terminal"` to restore the terminal frame.
26
+ - Peer dependencies are now `@astrojs/starlight >=0.41.0` and `astro >=7.0.0`.
27
+
28
+ ### Removed and renamed tokens
29
+
30
+ - `--apple-content-width`: use `--sl-content-width`.
31
+ - `--apple-header-height`: use `--sl-nav-height`.
32
+ - `--apple-sidebar-width`, `--apple-toc-width`: use `--sl-sidebar-width`; the table of contents follows Starlight’s layout.
33
+ - `--apple-hover-surface`, `--apple-active-surface`, `--apple-surface`, `--apple-card-background`, `--apple-navigator-background`: use `--apple-fill-secondary`, `--apple-fill`, and `--apple-secondary-background`.
34
+ - `--apple-aside-background`, `--apple-header-background`: replaced by `--apple-secondary-background` and `--apple-background`.
35
+ - `--apple-control-primary-text`: renamed `--apple-button-foreground`.
36
+ - `--apple-warning`: renamed `--apple-caution`; `--apple-tip` and `--apple-note` were added.
37
+ - `--apple-border`, `--apple-link-hover`, `--apple-row-height`, `--apple-section-spacing`, `--apple-disabled-opacity`: removed.
package/README.md CHANGED
@@ -1,15 +1,57 @@
1
1
  # `starlight-theme-apple`
2
2
 
3
- An Astro Starlight theme inspired by Apple Developer Documentation.
3
+ An [Astro Starlight](https://starlight.astro.build) theme modeled on Apple’s developer documentation: system typography on Apple’s documentation scale, a quiet navigator, breadcrumbs, a hairline “On this page” rail, Xcode-colored code, and components for dense API and configuration references. Light and dark appearances are both included.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install starlight-theme-apple
9
+ ```
10
+
11
+ ```js
12
+ // astro.config.mjs
13
+ import starlight from "@astrojs/starlight";
14
+ import starlightThemeApple from "starlight-theme-apple";
15
+
16
+ export default {
17
+ integrations: [starlight({ title: "My Docs", plugins: [starlightThemeApple()] })],
18
+ };
19
+ ```
20
+
21
+ That is the whole setup. No custom CSS is required.
22
+
23
+ ## Optional configuration
24
+
25
+ ```js
26
+ starlightThemeApple({
27
+ nav: [{ label: "Guides", link: "/guides/" }], // header links, also shown in the mobile menu
28
+ action: { label: "Download", link: "https://example.com/download" }, // emphasized header button
29
+ socialAttrs: { github: { "data-analytics": "github" } }, // attributes for Starlight social links
30
+ footer: {
31
+ links: [{ label: "GitHub", link: "https://github.com/example/project" }],
32
+ copyright: "© 2026 Example",
33
+ },
34
+ });
35
+ ```
36
+
37
+ Paths starting with `/` are resolved against Astro’s `base`.
38
+
39
+ ## Reference components
40
+
41
+ ```mdx
42
+ import { ReferenceEntry, Declaration, ReferenceMeta } from "starlight-theme-apple/components";
43
+ ```
44
+
45
+ `ReferenceEntry`, `Declaration`, `ReferenceMeta`, `ParameterList`, `Parameter`, `ValueList`, `Availability`, `TopicList`, `TopicLink`, and `Figure`. Generators that write Markdown can emit the equivalent `apple-*` HTML classes instead.
4
46
 
5
47
  ## Documentation
6
48
 
7
- Want to get started immediately?
49
+ See the [documentation site](https://acsandmann.github.io/starlight-theme-apple/) for configuration, customization tokens, component overrides, and examples.
8
50
 
9
- Check out the `starlight-theme-apple` getting started guide.
51
+ Requires Starlight 0.41 or later and Astro 7. Not affiliated with Apple Inc.
10
52
 
11
53
  ## License
12
54
 
13
- Licensed under the MIT license, Copyright © acsandmann.
55
+ MIT © acsandmann. See [LICENSE](https://github.com/acsandmann/starlight-theme-apple/blob/main/LICENSE).
14
56
 
15
- See [LICENSE](https://github.com/acsandmann/starlight-theme-apple/blob/main/LICENSE) for more information.
57
+ The site footer spans the page below article navigation. Use `footer.groups` for columns (`{ label, links }`); without groups it renders only the bottom row. `footer.links` and `footer.copyright` populate the bottom row. The theme’s `PageFrame` wrapper supplies this outer footer, while the `Footer` override supplies article metadata and pagination.
@@ -0,0 +1,19 @@
1
+ ---
2
+ import EditLink from "virtual:starlight/components/EditLink";
3
+ import LastUpdated from "virtual:starlight/components/LastUpdated";
4
+ import Pagination from "virtual:starlight/components/Pagination";
5
+
6
+ const { editUrl, lastUpdated } = Astro.locals.starlightRoute;
7
+ ---
8
+
9
+ <div class="apple-footer">
10
+ {
11
+ (editUrl || lastUpdated) && (
12
+ <div class="apple-footer__meta">
13
+ <EditLink />
14
+ <LastUpdated />
15
+ </div>
16
+ )
17
+ }
18
+ <Pagination />
19
+ </div>
@@ -0,0 +1,55 @@
1
+ ---
2
+ import config from "virtual:starlight/user-config";
3
+ import LanguageSelect from "virtual:starlight/components/LanguageSelect";
4
+ import Search from "virtual:starlight/components/Search";
5
+ import SiteTitle from "virtual:starlight/components/SiteTitle";
6
+ import SocialIcons from "virtual:starlight/components/SocialIcons";
7
+ import ThemeSelect from "virtual:starlight/components/ThemeSelect";
8
+ import themeConfig from "virtual:starlight-theme-apple/config";
9
+ import NavLink from "./NavLink.astro";
10
+
11
+ const shouldRenderSearch =
12
+ config.pagefind ||
13
+ config.components.Search !== "@astrojs/starlight/components/Search.astro";
14
+ const { nav, action } = themeConfig;
15
+ const hasSocial = (config.social ?? []).length > 0;
16
+ ---
17
+
18
+ <div class="apple-header">
19
+ <div class="apple-header__title">
20
+ <SiteTitle />
21
+ </div>
22
+
23
+ {
24
+ nav.length > 0 && (
25
+ <nav
26
+ class="apple-header__nav print:hidden"
27
+ aria-label={Astro.locals.t("starlightThemeApple.primaryNav")}
28
+ >
29
+ <ul>
30
+ {nav.map((item) => (
31
+ <li>
32
+ <NavLink item={item} />
33
+ </li>
34
+ ))}
35
+ </ul>
36
+ </nav>
37
+ )
38
+ }
39
+
40
+ <div class="apple-header__end print:hidden">
41
+ {shouldRenderSearch && <Search />}
42
+ <div class="apple-header__controls">
43
+ {
44
+ hasSocial && (
45
+ <div class="social-icons">
46
+ <SocialIcons />
47
+ </div>
48
+ )
49
+ }
50
+ <ThemeSelect />
51
+ <LanguageSelect />
52
+ </div>
53
+ {action && <NavLink item={action} class="apple-header__action" />}
54
+ </div>
55
+ </div>
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { Icon } from "@astrojs/starlight/components";
3
+ import type { StarlightThemeAppleLink } from "../libs/config";
4
+ import { linkProps } from "../libs/links";
5
+
6
+ interface Props {
7
+ item: StarlightThemeAppleLink;
8
+ class?: string;
9
+ }
10
+
11
+ const { item, class: className } = Astro.props;
12
+ const { href, current, external, attrs } = linkProps(item, Astro.url.pathname);
13
+ ---
14
+
15
+ <a
16
+ href={href}
17
+ class:list={["apple-nav-link", className]}
18
+ aria-current={current ? "true" : undefined}
19
+ rel={external ? "noopener" : undefined}
20
+ {...attrs}
21
+ >
22
+ {item.icon && <Icon name={item.icon} />}
23
+ <span>{item.label}</span>
24
+ </a>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import Default from "@astrojs/starlight/components/PageFrame.astro";
3
+ import SiteFooter from "./SiteFooter.astro";
4
+ ---
5
+
6
+ <Default>
7
+ <slot name="header" slot="header" />
8
+ <slot name="sidebar" slot="sidebar" />
9
+ <slot />
10
+ </Default>
11
+ <SiteFooter />
@@ -1,45 +1,29 @@
1
1
  ---
2
+ import { breadcrumbs } from "../libs/breadcrumbs";
3
+
2
4
  const { entry, sidebar, siteTitle, siteTitleHref } =
3
5
  Astro.locals.starlightRoute;
4
- const title = entry.data.title;
5
-
6
- type Crumb = { href?: string; label: string };
7
- type SidebarItem =
8
- | { type: "link"; isCurrent: boolean }
9
- | { type: "group"; label: string; entries: SidebarItem[] };
10
-
11
- function findCurrentPath(
12
- entries: SidebarItem[],
13
- ancestors: Crumb[] = []
14
- ): Crumb[] | undefined {
15
- for (const item of entries) {
16
- if (item.type === "link" && item.isCurrent) return ancestors;
17
- if (item.type === "group") {
18
- const path = findCurrentPath(item.entries, [
19
- ...ancestors,
20
- { label: item.label },
21
- ]);
22
- if (path) return path;
23
- }
24
- }
25
- }
26
-
27
- const parents = findCurrentPath(sidebar as SidebarItem[]) ?? [];
6
+ const crumbs = breadcrumbs(sidebar, siteTitle, siteTitleHref);
28
7
  ---
29
8
 
30
- <nav class="apple-breadcrumbs" aria-label="Breadcrumb">
31
- <a href={siteTitleHref}>{siteTitle}</a>
32
- {
33
- parents.map((parent) => (
34
- <>
35
- <span aria-hidden="true">›</span>
36
- {parent.href ? (
37
- <a href={parent.href}>{parent.label}</a>
38
- ) : (
39
- <span>{parent.label}</span>
40
- )}
41
- </>
42
- ))
43
- }
44
- </nav>
45
- <h1 id="_top">{title}</h1>
9
+ {
10
+ crumbs.length > 0 && (
11
+ <nav
12
+ class="apple-breadcrumbs"
13
+ aria-label={Astro.locals.t("starlightThemeApple.breadcrumbs")}
14
+ >
15
+ <ol>
16
+ {crumbs.map((crumb) => (
17
+ <li>
18
+ {crumb.href ? (
19
+ <a href={crumb.href}>{crumb.label}</a>
20
+ ) : (
21
+ <span>{crumb.label}</span>
22
+ )}
23
+ </li>
24
+ ))}
25
+ </ol>
26
+ </nav>
27
+ )
28
+ }
29
+ <h1 id="_top" class="apple-page-title">{entry.data.title}</h1>
@@ -1,34 +1,27 @@
1
1
  ---
2
2
  const { dir, pagination } = Astro.locals.starlightRoute;
3
3
  const { prev, next } = pagination;
4
- const isRtl = dir === "rtl";
5
4
  ---
6
5
 
7
- <div class="pagination-links print:hidden" dir={dir}>
8
- {
9
- prev && (
10
- <a href={prev.href} rel="prev">
11
- <span class="pagination-arrow" aria-hidden="true">
12
- {isRtl ? "→" : "←"}
13
- </span>
14
- <span>
15
- <small>{Astro.locals.t("page.previousLink")}</small>
16
- <span class="link-title">{prev.label}</span>
17
- </span>
18
- </a>
19
- )
20
- }
21
- {
22
- next && (
23
- <a href={next.href} rel="next">
24
- <span>
25
- <small>{Astro.locals.t("page.nextLink")}</small>
26
- <span class="link-title">{next.label}</span>
27
- </span>
28
- <span class="pagination-arrow" aria-hidden="true">
29
- {isRtl ? "←" : "→"}
30
- </span>
31
- </a>
32
- )
33
- }
34
- </div>
6
+ {
7
+ (prev || next) && (
8
+ <div class="apple-pagination print:hidden" dir={dir}>
9
+ {prev && (
10
+ <a href={prev.href} rel="prev">
11
+ <span class="apple-pagination__label">
12
+ {Astro.locals.t("page.previousLink")}
13
+ </span>
14
+ <span class="apple-pagination__title">{prev.label}</span>
15
+ </a>
16
+ )}
17
+ {next && (
18
+ <a href={next.href} rel="next">
19
+ <span class="apple-pagination__label">
20
+ {Astro.locals.t("page.nextLink")}
21
+ </span>
22
+ <span class="apple-pagination__title">{next.label}</span>
23
+ </a>
24
+ )}
25
+ </div>
26
+ )
27
+ }
@@ -0,0 +1,27 @@
1
+ ---
2
+ import Default from "@astrojs/starlight/components/Sidebar.astro";
3
+ import themeConfig from "virtual:starlight-theme-apple/config";
4
+ import NavLink from "./NavLink.astro";
5
+
6
+ const { nav, action } = themeConfig;
7
+ const items = action ? [...nav, action] : nav;
8
+ ---
9
+
10
+ {
11
+ /* Header links are repeated at the top of the small-screen navigation menu. */
12
+ items.length > 0 && (
13
+ <nav
14
+ class="apple-menu-nav md:sl-hidden"
15
+ aria-label={Astro.locals.t("starlightThemeApple.primaryNav")}
16
+ >
17
+ <ul>
18
+ {items.map((item) => (
19
+ <li>
20
+ <NavLink item={item} />
21
+ </li>
22
+ ))}
23
+ </ul>
24
+ </nav>
25
+ )
26
+ }
27
+ <Default />
@@ -0,0 +1,61 @@
1
+ ---
2
+ import { Icon } from "@astrojs/starlight/components";
3
+ import config from "virtual:starlight/user-config";
4
+ import themeConfig from "virtual:starlight-theme-apple/config";
5
+ import NavLink from "./NavLink.astro";
6
+
7
+ const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute;
8
+ const { groups: configuredGroups, links, copyright } = themeConfig.footer;
9
+ const groups = configuredGroups;
10
+ ---
11
+
12
+ <footer class="apple-site-footer" data-directory={groups.length > 0 ? "" : undefined} data-pagefind-ignore>
13
+ <div class="apple-site-footer__inner">
14
+ {
15
+ groups.length > 0 && (
16
+ <nav
17
+ class="apple-site-footer__directory"
18
+ aria-label={Astro.locals.t("starlightThemeApple.footerNav")}
19
+ >
20
+ {groups.map((group) => (
21
+ <div class="apple-site-footer__group">
22
+ <h2>{group.label}</h2>
23
+ <ul>
24
+ {group.links.map((item) => (
25
+ <li>
26
+ <NavLink item={item} />
27
+ </li>
28
+ ))}
29
+ </ul>
30
+ </div>
31
+ ))}
32
+ </nav>
33
+ )
34
+ }
35
+ <div class="apple-site-footer__bottom">
36
+ <p>{copyright ?? <a href={siteTitleHref}>{siteTitle}</a>}</p>
37
+ {
38
+ links.length > 0 && (
39
+ <ul>
40
+ {links.map((item) => (
41
+ <li>
42
+ <NavLink item={item} />
43
+ </li>
44
+ ))}
45
+ </ul>
46
+ )
47
+ }
48
+ {
49
+ config.credits && (
50
+ <a
51
+ class="apple-site-footer__credits"
52
+ href="https://starlight.astro.build"
53
+ >
54
+ <Icon name="starlight" />
55
+ {Astro.locals.t("builtWithStarlight.label")}
56
+ </a>
57
+ )
58
+ }
59
+ </div>
60
+ </div>
61
+ </footer>
@@ -0,0 +1,22 @@
1
+ ---
2
+ import { Icon } from "@astrojs/starlight/components";
3
+ import config from "virtual:starlight/user-config";
4
+ import themeConfig from "virtual:starlight-theme-apple/config";
5
+
6
+ const links = config.social ?? [];
7
+ ---
8
+
9
+ {
10
+ links.map(({ label, href, icon }) => (
11
+ <a
12
+ href={href}
13
+ rel="me"
14
+ class="sl-flex apple-social-link"
15
+ title={label}
16
+ {...themeConfig.socialAttrs[icon]}
17
+ >
18
+ <span class="sr-only">{label}</span>
19
+ <Icon name={icon} />
20
+ </a>
21
+ ))
22
+ }
package/components.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { default as Availability } from "./user-components/Availability.astro";
2
+ export { default as Declaration } from "./user-components/Declaration.astro";
3
+ export { default as Figure } from "./user-components/Figure.astro";
4
+ export { default as Parameter } from "./user-components/Parameter.astro";
5
+ export { default as ParameterList } from "./user-components/ParameterList.astro";
6
+ export { default as ReferenceEntry } from "./user-components/ReferenceEntry.astro";
7
+ export { default as ReferenceMeta } from "./user-components/ReferenceMeta.astro";
8
+ export { default as TopicLink } from "./user-components/TopicLink.astro";
9
+ export { default as TopicList } from "./user-components/TopicList.astro";
10
+ export { default as ValueList } from "./user-components/ValueList.astro";