aboutsummaryrefslogtreecommitdiff
path: root/website/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-02 21:48:02 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-02 21:48:02 +0300
commitb751d102f158968aab681cb663d27b4c32197f62 (patch)
tree85d03609314559df7705c2cb0ab4e37ab6d9715f /website/src
parent295b09ca25edbccac65401ee84fa420dd3888aad (diff)
feat: add preview update channel
Diffstat (limited to 'website/src')
-rw-r--r--website/src/components/Header.astro149
-rw-r--r--website/src/content.config.ts3
2 files changed, 151 insertions, 1 deletions
diff --git a/website/src/components/Header.astro b/website/src/components/Header.astro
new file mode 100644
index 00000000..982efd2e
--- /dev/null
+++ b/website/src/components/Header.astro
@@ -0,0 +1,149 @@
+---
+import config from 'virtual:starlight/user-config';
+
+import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
+import Search from 'virtual:starlight/components/Search';
+import SiteTitle from 'virtual:starlight/components/SiteTitle';
+import SocialIcons from 'virtual:starlight/components/SocialIcons';
+import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
+
+const shouldRenderSearch =
+ config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
+
+const pathname = Astro.url.pathname;
+const isDocs = pathname === '/docs/' || pathname.startsWith('/docs/');
+const isPreview = pathname === '/docs/preview/' || pathname.startsWith('/docs/preview/');
+const stableHref = isPreview ? pathname.replace(/^\/docs\/preview\/?/, '/docs/') : pathname;
+const previewHref = isPreview
+ ? pathname
+ : pathname === '/docs/'
+ ? '/docs/preview/'
+ : pathname.replace(/^\/docs\/?/, '/docs/preview/');
+---
+
+<div class="header">
+ <div class="title-wrapper sl-flex">
+ <SiteTitle />
+ </div>
+ <div class="sl-flex print:hidden search-wrapper">
+ {isDocs && (
+ <nav class="docs-channel-switcher" aria-label="Documentation channel">
+ <a href={stableHref} aria-current={!isPreview ? 'page' : undefined}>Stable</a>
+ <a href={previewHref} aria-current={isPreview ? 'page' : undefined}>Preview</a>
+ </nav>
+ )}
+ {shouldRenderSearch && <Search />}
+ </div>
+ <div class="sl-hidden md:sl-flex print:hidden right-group">
+ <div class="sl-flex social-icons">
+ <SocialIcons />
+ </div>
+ <ThemeSelect />
+ <LanguageSelect />
+ </div>
+</div>
+
+<style>
+ @layer starlight.core {
+ .header {
+ display: flex;
+ gap: var(--sl-nav-gap);
+ justify-content: space-between;
+ align-items: center;
+ height: 100%;
+ }
+
+ .title-wrapper {
+ overflow: clip;
+ padding: 0.25rem;
+ margin: -0.25rem;
+ min-width: 0;
+ }
+
+ .search-wrapper {
+ align-items: center;
+ gap: 0.75rem;
+ min-width: 0;
+ }
+
+ .docs-channel-switcher {
+ display: flex;
+ align-items: center;
+ border: 1px solid var(--sl-color-hairline);
+ border-radius: 4px;
+ overflow: hidden;
+ background: var(--sl-color-bg-nav);
+ font-size: var(--sl-text-xs);
+ font-weight: 700;
+ line-height: 1;
+ white-space: nowrap;
+ }
+
+ .docs-channel-switcher a {
+ color: var(--sl-color-gray-2);
+ text-decoration: none;
+ padding: 0.45rem 0.6rem;
+ }
+
+ .docs-channel-switcher a + a {
+ border-inline-start: 1px solid var(--sl-color-hairline);
+ }
+
+ .docs-channel-switcher a[aria-current="page"] {
+ color: var(--sl-color-accent-high);
+ background: color-mix(in srgb, var(--sl-color-accent) 14%, transparent);
+ }
+
+ .docs-channel-switcher a:hover {
+ color: var(--sl-color-accent-high);
+ }
+
+ .right-group,
+ .social-icons {
+ gap: 1rem;
+ align-items: center;
+ }
+
+ .social-icons::after {
+ content: "";
+ height: 2rem;
+ border-inline-end: 1px solid var(--sl-color-gray-5);
+ }
+
+ @media (max-width: 38rem) {
+ .docs-channel-switcher {
+ display: none;
+ }
+ }
+
+ @media (min-width: 50rem) {
+ :global(:root[data-has-sidebar]) {
+ --__sidebar-pad: calc(2 * var(--sl-nav-pad-x));
+ }
+
+ :global(:root:not([data-has-toc])) {
+ --__toc-width: 0rem;
+ }
+
+ .header {
+ --__sidebar-width: max(0rem, var(--sl-content-inline-start, 0rem) - var(--sl-nav-pad-x));
+ --__main-column-fr: calc(
+ (
+ 100% + var(--__sidebar-pad, 0rem) - var(--__toc-width, var(--sl-sidebar-width)) -
+ (2 * var(--__toc-width, var(--sl-nav-pad-x))) - var(--sl-content-inline-start, 0rem) -
+ var(--sl-content-width)
+ ) / 2
+ );
+ display: grid;
+ grid-template-columns:
+ minmax(
+ calc(var(--__sidebar-width) + max(0rem, var(--__main-column-fr) - var(--sl-nav-gap))),
+ auto
+ )
+ 1fr
+ auto;
+ align-content: center;
+ }
+ }
+ }
+</style>
diff --git a/website/src/content.config.ts b/website/src/content.config.ts
index c9a9b8fd..834d37cf 100644
--- a/website/src/content.config.ts
+++ b/website/src/content.config.ts
@@ -5,7 +5,8 @@ import { docsSchema } from '@astrojs/starlight/schema';
function docsPath({ entry }: { entry: string }) {
const slug = entry.replace(/\.(md|mdx|markdown|mdown|mkdn|mkd|mdwn)$/i, '');
- return slug === 'index' ? 'docs' : `docs/${slug}`;
+ const normalized = slug.replace(/\/index$/, '');
+ return normalized === 'index' ? 'docs' : `docs/${normalized}`;
}
export const collections = {