starlight-theme-nova 0.10.0 → 0.11.1
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/lib/styles.css +1 -2
- package/lib/tailwind.css +130 -0
- package/lib/tailwind.gen.css +1313 -0
- package/package.json +13 -17
- package/src/components/CodeCopy.astro +7 -5
- package/src/components/CodeTabs.astro +4 -19
- package/src/components/Header.astro +19 -7
- package/src/components/LinkButton.astro +15 -7
- package/src/components/LinkButtonIcon.astro +11 -9
- package/src/components/LinkCard.astro +17 -3
- package/src/components/MobileMenuFooter.astro +1 -1
- package/src/components/MobileMenuToggle.astro +12 -2
- package/src/components/MobileTableOfContents.astro +1 -1
- package/src/components/PageFrame.astro +18 -21
- package/src/components/Pagination.astro +5 -2
- package/src/components/PaginationLink.astro +17 -8
- package/src/components/Search.astro +3 -2
- package/src/components/SiteTitle.astro +5 -1
- package/src/components/SocialIcons.astro +5 -1
- package/src/components/ThemeSelect.astro +8 -4
- package/src/constants.ts +2 -0
- package/src/icons/lucide-arrow-left.svg +1 -0
- package/src/icons/lucide-arrow-right.svg +1 -0
- package/src/icons/lucide-check.svg +1 -0
- package/src/icons/lucide-chevron-left.svg +1 -0
- package/src/icons/lucide-chevron-right.svg +1 -0
- package/src/icons/lucide-clipboard.svg +1 -0
- package/src/icons/lucide-menu.svg +1 -0
- package/src/icons/lucide-search.svg +1 -0
- package/src/icons/lucide-x.svg +1 -0
- package/src/icons/tabler-moon-filled.svg +1 -0
- package/src/icons/tabler-sun-high-filled.svg +1 -0
- package/src/index.ts +43 -2
- package/src/shiki-transformer-container.ts +6 -3
- package/src/user-options.ts +16 -0
- package/lib/styles.gen.css +0 -214
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starlight-theme-nova",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.11.1",
|
|
5
5
|
"description": "A beautiful theme for Astro Starlight",
|
|
6
6
|
"author": "ocavue <ocavue@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@aria-ui/core": "^0.0.22",
|
|
30
30
|
"@pagefind/default-ui": "^1.4.0",
|
|
31
|
-
"@shikijs/transformers": "^3.
|
|
32
|
-
"@shikijs/twoslash": "^3.
|
|
33
|
-
"@shikijs/types": "^3.
|
|
31
|
+
"@shikijs/transformers": "^3.21.0",
|
|
32
|
+
"@shikijs/twoslash": "^3.21.0",
|
|
33
|
+
"@shikijs/types": "^3.21.0",
|
|
34
34
|
"@types/hast": "^3.0.4",
|
|
35
35
|
"astro-theme-toggle": "^0.8.0",
|
|
36
36
|
"hast-util-is-element": "^3.0.0",
|
|
@@ -47,21 +47,17 @@
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@astrojs/starlight": "^0.
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
54
|
-
"@iconify-json/tabler": "^1.2.23",
|
|
55
|
-
"@ocavue/tsconfig": "^0.5.0",
|
|
50
|
+
"@astrojs/starlight": "^0.37.2",
|
|
51
|
+
"@ocavue/tsconfig": "^0.6.2",
|
|
52
|
+
"@tailwindcss/cli": "^4.1.18",
|
|
53
|
+
"@tailwindcss/vite": "^4.1.18",
|
|
56
54
|
"@types/node": "^20.17.30",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"typescript": "^5.9.3"
|
|
60
|
-
"unocss": "^66.5.5",
|
|
61
|
-
"unocss-preset-animations": "^1.3.0"
|
|
55
|
+
"astro": "^5.16.8",
|
|
56
|
+
"tailwindcss": "^4.1.18",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
62
58
|
},
|
|
63
59
|
"scripts": {
|
|
64
|
-
"
|
|
65
|
-
"build": "
|
|
60
|
+
"build": "pnpm run build:tailwindcss",
|
|
61
|
+
"build:tailwindcss": "tailwindcss -i ./lib/tailwind.css -o ./lib/tailwind.gen.css"
|
|
66
62
|
}
|
|
67
63
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import ClipboardIcon from '../icons/lucide-clipboard.svg?raw'
|
|
3
|
+
import CheckIcon from '../icons/lucide-check.svg?raw'
|
|
4
4
|
|
|
5
5
|
class CodeCopyButton extends HTMLElement {
|
|
6
6
|
constructor() {
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
connectedCallback() {
|
|
11
|
-
this.innerHTML = DEFAULT_HTML
|
|
12
|
-
|
|
13
11
|
const update = () => {
|
|
14
|
-
|
|
12
|
+
const iconHtml = state === 'ready' ? ClipboardIcon : CheckIcon
|
|
13
|
+
this.innerHTML =
|
|
14
|
+
'<span class="w-full h-full block [&_svg]:w-full [&_svg]:h-full">' +
|
|
15
|
+
iconHtml +
|
|
16
|
+
'</span>'
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
let state: 'ready' | 'success' = 'ready'
|
|
@@ -20,10 +20,8 @@ const processedHtml = processCodeTabs(originalHtml)
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
<style is:global>
|
|
23
|
-
@layer
|
|
23
|
+
@layer utilities {
|
|
24
24
|
.sl-markdown-content .code-tabs {
|
|
25
|
-
overflow: hidden;
|
|
26
|
-
|
|
27
25
|
&.code-tabs-border {
|
|
28
26
|
border-color: var(--sl-color-gray-5);
|
|
29
27
|
border-width: 1px;
|
|
@@ -31,17 +29,11 @@ const processedHtml = processCodeTabs(originalHtml)
|
|
|
31
29
|
border-radius: 0.5rem;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
[role='tablist'] {
|
|
33
|
+
border-bottom-width: 1px;
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
.tablist-wrapper {
|
|
39
|
-
scrollbar-width: none;
|
|
40
|
-
|
|
41
|
-
[role='tablist'] {
|
|
42
|
-
border-bottom-width: 1px;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
37
|
[role='tab'] {
|
|
46
38
|
font-family: var(--sl-font-system-mono);
|
|
47
39
|
padding-top: 0.5rem;
|
|
@@ -50,13 +42,6 @@ const processedHtml = processCodeTabs(originalHtml)
|
|
|
50
42
|
padding-right: 0.75rem;
|
|
51
43
|
font-size: 0.875rem;
|
|
52
44
|
white-space: nowrap;
|
|
53
|
-
|
|
54
|
-
border-bottom-style: solid;
|
|
55
|
-
border-bottom-width: 0px;
|
|
56
|
-
|
|
57
|
-
&[aria-selected='true'] {
|
|
58
|
-
border-bottom-width: 3px;
|
|
59
|
-
}
|
|
60
45
|
}
|
|
61
46
|
}
|
|
62
47
|
|
|
@@ -68,7 +53,7 @@ const processedHtml = processCodeTabs(originalHtml)
|
|
|
68
53
|
border-radius: 0;
|
|
69
54
|
}
|
|
70
55
|
|
|
71
|
-
|
|
56
|
+
[data-nova-code-container] {
|
|
72
57
|
border-radius: 0;
|
|
73
58
|
border-width: 0;
|
|
74
59
|
border-color: transparent;
|
|
@@ -16,30 +16,42 @@ const nav = options.nav ?? []
|
|
|
16
16
|
const route = Astro.locals.starlightRoute
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
<div class="
|
|
20
|
-
<div
|
|
19
|
+
<div class="box-border flex h-full items-center gap-2">
|
|
20
|
+
<div
|
|
21
|
+
class:list={[
|
|
22
|
+
/* Prevent long titles overflowing and covering the search and menu buttons on narrow viewports. */
|
|
23
|
+
/* Avoid clipping focus ring around link inside title wrapper. */
|
|
24
|
+
'-m-3 overflow-clip p-3',
|
|
25
|
+
'flex min-w-0',
|
|
26
|
+
]}
|
|
27
|
+
>
|
|
21
28
|
<SiteTitle />
|
|
22
29
|
</div>
|
|
23
|
-
<nav
|
|
30
|
+
<nav
|
|
31
|
+
class="flex flex-1 flex-row gap-4 overflow-x-auto py-3 pr-4 pl-4 text-sm font-medium max-md:**:hidden xl:gap-6 xl:pl-6"
|
|
32
|
+
>
|
|
24
33
|
{
|
|
25
34
|
nav.map((item) => (
|
|
26
|
-
<a
|
|
35
|
+
<a
|
|
36
|
+
class="-m-1.5 rounded-md p-1.5 text-(--sl-color-gray-3) no-underline hover:text-(--sl-color-white) focus-visible:outline-offset-0"
|
|
37
|
+
href={getI18nText(item.href, route)}
|
|
38
|
+
>
|
|
27
39
|
{getI18nText(item.label, route)}
|
|
28
40
|
</a>
|
|
29
41
|
))
|
|
30
42
|
}
|
|
31
43
|
</nav>
|
|
32
|
-
<div class="
|
|
44
|
+
<div class="flex md:max-w-60 md:flex-1 print:hidden">
|
|
33
45
|
<Search />
|
|
34
46
|
</div>
|
|
35
|
-
<div class="
|
|
47
|
+
<div class="hidden items-center gap-2 md:flex print:hidden">
|
|
36
48
|
<SocialIcons />
|
|
37
49
|
<LanguageSelect />
|
|
38
50
|
<ThemeSelect />
|
|
39
51
|
</div>
|
|
40
52
|
{
|
|
41
53
|
hasSidebar && (
|
|
42
|
-
<div class="
|
|
54
|
+
<div class="flex items-center gap-2 md:hidden print:hidden">
|
|
43
55
|
<MobileMenuToggle />
|
|
44
56
|
</div>
|
|
45
57
|
)
|
|
@@ -19,15 +19,23 @@ const {
|
|
|
19
19
|
} = Astro.props
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
<span
|
|
22
|
+
<span
|
|
23
|
+
class:list={[
|
|
24
|
+
'not-content',
|
|
25
|
+
'inline-flex items-center justify-center align-middle',
|
|
26
|
+
]}
|
|
27
|
+
>
|
|
23
28
|
<a
|
|
24
29
|
class:list={[
|
|
25
|
-
'
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
'
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
'not-content',
|
|
31
|
+
'group me-2 mt-2 mb-2 inline-flex items-center justify-between gap-2 rounded-xl border border-solid border-transparent px-6 py-3 font-medium no-underline transition active:scale-97',
|
|
32
|
+
variant === 'primary'
|
|
33
|
+
? 'bg-black text-white shadow-sm hover:bg-gray-800 hover:shadow-md dark:bg-gray-100 dark:text-gray-900 dark:hover:bg-gray-300'
|
|
34
|
+
: undefined,
|
|
35
|
+
variant === 'secondary'
|
|
36
|
+
? 'border-(--sl-color-gray-5) bg-white text-gray-700 shadow-sm hover:bg-gray-50 hover:shadow-md dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700'
|
|
37
|
+
: undefined,
|
|
38
|
+
variant === 'minimal' ? 'text-gray-700 dark:text-gray-200' : undefined,
|
|
31
39
|
className,
|
|
32
40
|
]}
|
|
33
41
|
{...attrs}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Icon } from '@astrojs/starlight/components'
|
|
3
3
|
import type { StarlightIcon } from '@astrojs/starlight/types'
|
|
4
|
+
import ArrowRightIcon from '../icons/lucide-arrow-right.svg'
|
|
5
|
+
import ArrowLeftIcon from '../icons/lucide-arrow-left.svg'
|
|
4
6
|
|
|
5
7
|
interface Props {
|
|
6
8
|
icon: StarlightIcon
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
const { icon } = Astro.props
|
|
10
|
-
|
|
11
|
-
let className = ''
|
|
12
|
-
|
|
13
|
-
if (icon === 'right-arrow') {
|
|
14
|
-
className = 'nova-link-button-icon-right'
|
|
15
|
-
} else if (icon === 'left-arrow') {
|
|
16
|
-
className = 'nova-link-button-icon-left'
|
|
17
|
-
}
|
|
18
12
|
---
|
|
19
13
|
|
|
20
|
-
{
|
|
14
|
+
{
|
|
15
|
+
icon === 'right-arrow' ? (
|
|
16
|
+
<ArrowRightIcon class="block size-5 transition group-hover:translate-x-1" />
|
|
17
|
+
) : icon === 'left-arrow' ? (
|
|
18
|
+
<ArrowLeftIcon class="block size-5 transition group-hover:-translate-x-1" />
|
|
19
|
+
) : (
|
|
20
|
+
<Icon name={icon} size="1.25rem" />
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
import ArrowRightIcon from '../icons/lucide-arrow-right.svg'
|
|
3
4
|
|
|
4
5
|
interface Props extends Omit<HTMLAttributes<'a'>, 'title'> {
|
|
5
6
|
title: string
|
|
@@ -9,10 +10,23 @@ interface Props extends Omit<HTMLAttributes<'a'>, 'title'> {
|
|
|
9
10
|
const { title, description, class: className, ...attributes } = Astro.props
|
|
10
11
|
---
|
|
11
12
|
|
|
12
|
-
<div
|
|
13
|
-
|
|
13
|
+
<div
|
|
14
|
+
class:list={[
|
|
15
|
+
'not-content',
|
|
16
|
+
'group relative flex flex-col gap-2 rounded-xl border border-solid border-(--sl-color-gray-5) bg-white px-5 py-4 text-gray-700 shadow-sm transition hover:bg-gray-50 hover:shadow-md active:scale-99 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700',
|
|
17
|
+
className,
|
|
18
|
+
]}
|
|
19
|
+
>
|
|
20
|
+
<a
|
|
21
|
+
class:list={[
|
|
22
|
+
'inline-flex items-center justify-between text-lg font-semibold text-gray-700 no-underline dark:text-gray-200',
|
|
23
|
+
/* a11y fix for https://github.com/withastro/starlight/issues/487 */
|
|
24
|
+
"before:absolute before:inset-0 before:content-['']",
|
|
25
|
+
]}
|
|
26
|
+
{...attributes}
|
|
27
|
+
>
|
|
14
28
|
<span set:html={title} />
|
|
15
|
-
<
|
|
29
|
+
<ArrowRightIcon class="ml-2 size-5 transition group-hover:translate-x-1" />
|
|
16
30
|
</a>
|
|
17
31
|
{description && <span set:html={description} />}
|
|
18
32
|
</div>
|
|
@@ -4,7 +4,7 @@ import SocialIcons from 'virtual:starlight/components/SocialIcons'
|
|
|
4
4
|
import ThemeSelect from 'virtual:starlight/components/ThemeSelect'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
<div class="
|
|
7
|
+
<div class="flex items-center justify-end gap-2 py-4 print:hidden">
|
|
8
8
|
<SocialIcons />
|
|
9
9
|
<LanguageSelect />
|
|
10
10
|
<ThemeSelect />
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MenuIcon from '../icons/lucide-menu.svg'
|
|
3
|
+
import XIcon from '../icons/lucide-x.svg'
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
<nova-mobile-menu-toggle
|
|
2
|
-
class="
|
|
7
|
+
class="flex size-8 rounded-md p-2 text-(--sl-color-text) transition hover:bg-gray-400/30 focus-visible:outline-offset-1 active:scale-90 print:hidden"
|
|
3
8
|
aria-label={Astro.locals.t('menuButton.accessibleLabel')}
|
|
4
9
|
aria-controls="starlight__sidebar"
|
|
5
10
|
>
|
|
6
|
-
<div
|
|
11
|
+
<div
|
|
12
|
+
class="transition-transform [body[data-mobile-menu-expanded]_&]:rotate-90"
|
|
13
|
+
>
|
|
14
|
+
<MenuIcon class="block [body[data-mobile-menu-expanded]_&]:hidden" />
|
|
15
|
+
<XIcon class="hidden [body[data-mobile-menu-expanded]_&]:block" />
|
|
16
|
+
</div>
|
|
7
17
|
</nova-mobile-menu-toggle>
|
|
8
18
|
|
|
9
19
|
<script>
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
const { hasSidebar } = Astro.locals.starlightRoute
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<div class="
|
|
6
|
-
<header
|
|
5
|
+
<div class="flex min-h-screen flex-col">
|
|
6
|
+
<header
|
|
7
|
+
class="fixed inset-0 z-(--sl-z-index-navbar) box-border h-(--sl-nav-height) w-full border-0 border-b border-solid border-(--sl-color-hairline) bg-(--sl-color-bg-nav) px-(--sl-nav-pad-x) py-(--sl-nav-pad-y) backdrop-blur"
|
|
8
|
+
>
|
|
7
9
|
<slot name="header" />
|
|
8
10
|
</header>
|
|
9
11
|
{
|
|
@@ -15,9 +17,21 @@ const { hasSidebar } = Astro.locals.starlightRoute
|
|
|
15
17
|
>
|
|
16
18
|
<div
|
|
17
19
|
id="starlight__sidebar"
|
|
18
|
-
class:list={[
|
|
20
|
+
class:list={[
|
|
21
|
+
'nova-scroll-container',
|
|
22
|
+
|
|
23
|
+
'invisible md:visible [body[data-mobile-menu-expanded]_&]:max-md:visible',
|
|
24
|
+
|
|
25
|
+
'fixed top-(--sl-nav-height) bottom-0 left-0 z-(--sl-z-index-menu) overflow-y-auto border-0 border-solid border-(--sl-color-hairline) bg-(--sl-color-black) max-md:w-full md:w-(--sl-sidebar-width) md:border-r',
|
|
26
|
+
]}
|
|
19
27
|
>
|
|
20
|
-
<div
|
|
28
|
+
<div
|
|
29
|
+
class:list={[
|
|
30
|
+
// The class name `sidebar-content` is used here: https://github.com/withastro/starlight/blob/5387d33b9644900afd61651b8287503698cdb065/packages/starlight/user-components/Badge.astro#L77
|
|
31
|
+
'sidebar-content',
|
|
32
|
+
'flex h-full min-h-max flex-col px-(--sl-sidebar-pad-x) py-4',
|
|
33
|
+
]}
|
|
34
|
+
>
|
|
21
35
|
<slot name="sidebar" />
|
|
22
36
|
</div>
|
|
23
37
|
</div>
|
|
@@ -29,23 +43,6 @@ const { hasSidebar } = Astro.locals.starlightRoute
|
|
|
29
43
|
|
|
30
44
|
<style>
|
|
31
45
|
@layer nova {
|
|
32
|
-
.sidebar-pane {
|
|
33
|
-
position: fixed;
|
|
34
|
-
z-index: var(--sl-z-index-menu);
|
|
35
|
-
inset-block: var(--sl-nav-height) 0;
|
|
36
|
-
inset-inline-start: 0;
|
|
37
|
-
background-color: var(--sl-color-black);
|
|
38
|
-
overflow-y: auto;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.sidebar-content {
|
|
42
|
-
height: 100%;
|
|
43
|
-
min-height: max-content;
|
|
44
|
-
padding: 1rem var(--sl-sidebar-pad-x) 1rem;
|
|
45
|
-
flex-direction: column;
|
|
46
|
-
gap: 1rem;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
46
|
.main-frame {
|
|
50
47
|
padding-top: calc(var(--sl-nav-height) + var(--sl-mobile-toc-height));
|
|
51
48
|
padding-inline-start: var(--sl-content-inline-start);
|
|
@@ -6,7 +6,10 @@ const { prev, next } = pagination
|
|
|
6
6
|
const isRtl = dir === 'rtl'
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
<div
|
|
9
|
+
<div
|
|
10
|
+
class="flex min-w-full flex-row items-stretch justify-between gap-2 px-1 pt-0 pb-6 print:hidden"
|
|
11
|
+
dir={dir}
|
|
12
|
+
>
|
|
10
13
|
{
|
|
11
14
|
prev && (
|
|
12
15
|
<PaginationLink
|
|
@@ -17,7 +20,7 @@ const isRtl = dir === 'rtl'
|
|
|
17
20
|
/>
|
|
18
21
|
)
|
|
19
22
|
}
|
|
20
|
-
<div class="
|
|
23
|
+
<div class="flex-1"></div>
|
|
21
24
|
{
|
|
22
25
|
next && (
|
|
23
26
|
<PaginationLink
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
+
import ChevronRightIcon from '../icons/lucide-chevron-right.svg'
|
|
3
|
+
import ChevronLeftIcon from '../icons/lucide-chevron-left.svg'
|
|
4
|
+
|
|
2
5
|
interface Props {
|
|
3
6
|
label: string
|
|
4
7
|
href: string
|
|
@@ -9,13 +12,19 @@ interface Props {
|
|
|
9
12
|
const { label, href, rel, side } = Astro.props
|
|
10
13
|
---
|
|
11
14
|
|
|
12
|
-
<a
|
|
15
|
+
<a
|
|
16
|
+
href={href}
|
|
17
|
+
rel={rel}
|
|
18
|
+
data-side={side}
|
|
19
|
+
class="group m-0 flex items-center justify-end gap-2 rounded-xl p-2 font-medium text-(--sl-color-gray-2) no-underline transition hover:text-(--sl-color-white) md:text-lg [[rel='next']]:flex-row [[rel='prev']]:flex-row-reverse"
|
|
20
|
+
>
|
|
13
21
|
<span>{label}</span>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
side === 'right' ? (
|
|
25
|
+
<ChevronRightIcon class="block min-h-5 min-w-5 transition group-hover:translate-x-1" />
|
|
26
|
+
) : (
|
|
27
|
+
<ChevronLeftIcon class="block min-h-5 min-w-5 transition group-hover:-translate-x-1" />
|
|
28
|
+
)
|
|
29
|
+
}
|
|
21
30
|
</a>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import project from 'virtual:starlight/project-context'
|
|
3
|
+
import SearchIcon from '../icons/lucide-search.svg'
|
|
3
4
|
|
|
4
5
|
const pagefindTranslations = {
|
|
5
6
|
placeholder: Astro.locals.t('search.label'),
|
|
@@ -19,13 +20,13 @@ if (project.trailingSlash === 'never')
|
|
|
19
20
|
|
|
20
21
|
<site-search class={Astro.props.class} {...dataAttributes}>
|
|
21
22
|
<button
|
|
22
|
-
class="
|
|
23
|
+
class="flex size-8 rounded-md p-2 text-(--sl-color-text) transition hover:bg-gray-400/30 focus-visible:outline-offset-1 active:scale-90 md:h-9 md:w-full md:max-w-88 md:rounded-md md:border md:border-solid md:border-(--sl-color-gray-5) md:p-2 md:text-(--sl-color-text) md:transition-colors md:hover:bg-gray-400/10"
|
|
23
24
|
data-open-modal
|
|
24
25
|
disabled
|
|
25
26
|
aria-label={Astro.locals.t('search.label')}
|
|
26
27
|
aria-keyshortcuts="Control+K"
|
|
27
28
|
>
|
|
28
|
-
<
|
|
29
|
+
<SearchIcon class="size-4" />
|
|
29
30
|
<span class="sl-hidden md:sl-block" aria-hidden="true"
|
|
30
31
|
>{Astro.locals.t('search.label')}</span
|
|
31
32
|
>
|
|
@@ -2,4 +2,8 @@
|
|
|
2
2
|
import Default from '@astrojs/starlight/components/SiteTitle.astro'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
<span
|
|
5
|
+
<span
|
|
6
|
+
class="-m-1.5 rounded-md p-1.5 **:text-lg **:font-semibold **:text-(--sl-color-text) focus-visible:outline-offset-0"
|
|
7
|
+
>
|
|
8
|
+
<Default />
|
|
9
|
+
</span>
|
|
@@ -17,7 +17,11 @@ if (!Array.isArray(links)) {
|
|
|
17
17
|
links.length > 0 && (
|
|
18
18
|
<>
|
|
19
19
|
{links.map(({ label, href, icon }) => (
|
|
20
|
-
<a
|
|
20
|
+
<a
|
|
21
|
+
href={href}
|
|
22
|
+
rel="me"
|
|
23
|
+
class="flex size-8 rounded-md p-2 text-(--sl-color-text) transition hover:bg-gray-400/30 focus-visible:outline-offset-1 active:scale-90"
|
|
24
|
+
>
|
|
21
25
|
<span class="sr-only">{label}</span>
|
|
22
26
|
<Icon name={icon} size="1rem" color="currentColor" />
|
|
23
27
|
</a>
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Toggle } from 'astro-theme-toggle/components'
|
|
3
|
+
import MoonIcon from '../icons/tabler-moon-filled.svg'
|
|
4
|
+
import SunIcon from '../icons/tabler-sun-high-filled.svg'
|
|
3
5
|
---
|
|
4
6
|
|
|
5
|
-
<div class="
|
|
6
|
-
<Toggle
|
|
7
|
+
<div class="size-8 overflow-visible">
|
|
8
|
+
<Toggle
|
|
9
|
+
class="flex size-8 rounded-md p-2 text-(--sl-color-text) transition hover:bg-gray-400/30 focus-visible:outline-offset-1 active:scale-90"
|
|
10
|
+
>
|
|
7
11
|
<Fragment slot="icon-light">
|
|
8
|
-
<
|
|
12
|
+
<SunIcon class="size-4" />
|
|
9
13
|
</Fragment>
|
|
10
14
|
<Fragment slot="icon-dark">
|
|
11
|
-
<
|
|
15
|
+
<MoonIcon class="size-4" />
|
|
12
16
|
</Fragment>
|
|
13
17
|
</Toggle>
|
|
14
18
|
</div>
|
package/src/constants.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 19l-7-7l7-7m7 7H5"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14m-7-7l7 7l-7 7"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 18l-6-6l6-6"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18l6-6l-6-6"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 5h16M4 12h16M4 19h16"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m21 21l-4.34-4.34"/><circle cx="11" cy="11" r="8"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Lucide by Lucide Contributors - https://github.com/lucide-icons/lucide/blob/main/LICENSE --><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 6L6 18M6 6l12 12"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Tabler Icons by Paweł Kuna - https://github.com/tabler/tabler-icons/blob/master/LICENSE --><path fill="currentColor" d="M12 1.992a10 10 0 1 0 9.236 13.838c.341-.82-.476-1.644-1.298-1.31a6.5 6.5 0 0 1-6.864-10.787l.077-.08c.551-.63.113-1.653-.758-1.653h-.266l-.068-.006z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><!-- Icon from Tabler Icons by Paweł Kuna - https://github.com/tabler/tabler-icons/blob/master/LICENSE --><path fill="currentColor" d="M12 19a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1m-4.95-2.05a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 1 1-1.414-1.414l1.414-1.414a1 1 0 0 1 1.414 0m11.314 0l1.414 1.414a1 1 0 0 1-1.414 1.414l-1.414-1.414a1 1 0 0 1 1.414-1.414m-5.049-9.836a5 5 0 1 1-2.532 9.674a5 5 0 0 1 2.532-9.674M4 11a1 1 0 0 1 0 2H2a1 1 0 0 1 0-2zm18 0a1 1 0 0 1 0 2h-2a1 1 0 0 1 0-2zM5.636 4.222L7.05 5.636A1 1 0 0 1 5.636 7.05L4.222 5.636a1 1 0 0 1 1.414-1.414m14.142 0a1 1 0 0 1 0 1.414L18.364 7.05a1 1 0 0 1-1.414-1.414l1.414-1.414a1 1 0 0 1 1.414 0M12 1a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0V2a1 1 0 0 1 1-1"/></svg>
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
StarlightConfig,
|
|
2
3
|
StarlightPlugin,
|
|
3
4
|
StarlightUserConfig,
|
|
4
5
|
} from '@astrojs/starlight/types'
|
|
6
|
+
import type { AstroConfig } from 'astro'
|
|
5
7
|
import remarkCustomHeaderId from 'remark-custom-header-id'
|
|
6
8
|
|
|
7
9
|
import { createShikiConfig } from './shiki-config'
|
|
@@ -25,7 +27,7 @@ const components = {
|
|
|
25
27
|
'starlight-theme-nova/components/MobileTableOfContents.astro',
|
|
26
28
|
MobileMenuFooter: 'starlight-theme-nova/components/MobileMenuFooter.astro',
|
|
27
29
|
LanguageSelect: 'starlight-theme-nova/components/LanguageSelect.astro',
|
|
28
|
-
} as const
|
|
30
|
+
} as const satisfies Partial<StarlightConfig['components']>
|
|
29
31
|
|
|
30
32
|
export type { ThemeNovaOptions }
|
|
31
33
|
|
|
@@ -35,13 +37,29 @@ export default function starlightThemeNova(
|
|
|
35
37
|
return {
|
|
36
38
|
name: 'starlight-theme-nova',
|
|
37
39
|
hooks: {
|
|
38
|
-
setup({ config, updateConfig, addIntegration, astroConfig }) {
|
|
40
|
+
setup: async ({ config, updateConfig, addIntegration, astroConfig }) => {
|
|
41
|
+
let useTailwind: boolean
|
|
42
|
+
|
|
43
|
+
if (options.stylingSystem === 'css') {
|
|
44
|
+
useTailwind = false
|
|
45
|
+
} else if (options.stylingSystem === 'tailwind') {
|
|
46
|
+
useTailwind = true
|
|
47
|
+
} else {
|
|
48
|
+
const hasTailwindcss = await checkHasTailwindcss(
|
|
49
|
+
astroConfig.vite?.plugins,
|
|
50
|
+
)
|
|
51
|
+
useTailwind = hasTailwindcss
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
const newConfig = {
|
|
40
55
|
customCss: [
|
|
41
56
|
...(config.customCss || []),
|
|
42
57
|
// Including nova styles *after* any user CSS, so that @layer nova
|
|
43
58
|
// can have a higher precedence.
|
|
44
59
|
'starlight-theme-nova/styles.css',
|
|
60
|
+
useTailwind
|
|
61
|
+
? 'starlight-theme-nova/tailwind.css'
|
|
62
|
+
: 'starlight-theme-nova/tailwind.gen.css',
|
|
45
63
|
],
|
|
46
64
|
components: {
|
|
47
65
|
// Including any user components *after* our own.
|
|
@@ -78,3 +96,26 @@ export default function starlightThemeNova(
|
|
|
78
96
|
},
|
|
79
97
|
}
|
|
80
98
|
}
|
|
99
|
+
|
|
100
|
+
type ViteUserConfig = AstroConfig['vite']
|
|
101
|
+
type VitePlugin = NonNullable<ViteUserConfig['plugins']>[number]
|
|
102
|
+
|
|
103
|
+
async function checkHasTailwindcss(
|
|
104
|
+
plugin: VitePlugin | Promise<VitePlugin>,
|
|
105
|
+
): Promise<boolean> {
|
|
106
|
+
const awaited = await plugin
|
|
107
|
+
|
|
108
|
+
if (!awaited) {
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
if (Array.isArray(awaited)) {
|
|
112
|
+
for (const p of awaited) {
|
|
113
|
+
if (await checkHasTailwindcss(p)) {
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return false
|
|
118
|
+
}
|
|
119
|
+
let name = awaited.name || ''
|
|
120
|
+
return name.includes('tailwind')
|
|
121
|
+
}
|