@astrojs/starlight 0.0.15 → 0.0.17

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/404.astro CHANGED
@@ -32,7 +32,7 @@ const { lang = 'en', dir = 'ltr', locale } = config.defaultLocale || {};
32
32
  <body>
33
33
  <ThemeProvider />
34
34
  <SkipLink {locale} />
35
- <PageFrame {locale}>
35
+ <PageFrame {locale} hasSidebar={false}>
36
36
  <Header slot="header" {locale} />
37
37
  <main>
38
38
  <MarkdownContent>
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @astrojs/starlight
2
2
 
3
+ ## 0.0.17
4
+
5
+ ### Patch Changes
6
+
7
+ - [#107](https://github.com/withastro/starlight/pull/107) [`2f2d3ee`](https://github.com/withastro/starlight/commit/2f2d3eed1e7ed48d75205cfc3169719da7fdae1a) Thanks [@delucis](https://github.com/delucis)! - Small CSS size optimisation
8
+
9
+ - [#105](https://github.com/withastro/starlight/pull/105) [`55fec5d`](https://github.com/withastro/starlight/commit/55fec5d7e15da0e7365cee196d091bf5d15129c9) Thanks [@delucis](https://github.com/delucis)! - Add `<Card>` and `<CardGrid>` components for landing pages and other uses
10
+
11
+ ## 0.0.16
12
+
13
+ ### Patch Changes
14
+
15
+ - [#103](https://github.com/withastro/starlight/pull/103) [`ccb919d`](https://github.com/withastro/starlight/commit/ccb919d6580955e3428430a704f4a33fbc55a78d) Thanks [@delucis](https://github.com/delucis)! - Support adding a hero section to pages
16
+
17
+ - [#101](https://github.com/withastro/starlight/pull/101) [`6a2c0df`](https://github.com/withastro/starlight/commit/6a2c0df4d5586b70b46c854061df67b028e73630) Thanks [@TheOtterlord](https://github.com/TheOtterlord)! - Add better error messages for starlight config
18
+
3
19
  ## 0.0.15
4
20
 
5
21
  ### Patch Changes
@@ -0,0 +1,51 @@
1
+ ---
2
+ import Icon from './Icon.astro';
3
+ import type { Icons } from './Icons';
4
+
5
+ interface Props {
6
+ variant: 'primary' | 'secondary' | 'minimal';
7
+ link: string;
8
+ icon?:
9
+ | undefined
10
+ | { type: 'icon'; name: keyof typeof Icons }
11
+ | { type: 'raw'; html: string };
12
+ }
13
+
14
+ const { link, variant, icon } = Astro.props;
15
+ ---
16
+
17
+ <a class:list={['flex action', variant]} href={link}>
18
+ <slot />
19
+ {icon?.type === 'icon' && <Icon name={icon.name} size="1.5rem" />}
20
+ {icon?.type === 'raw' && <Fragment set:html={icon.html} />}
21
+ </a>
22
+
23
+ <style>
24
+ .action {
25
+ gap: 0.5em;
26
+ align-items: center;
27
+ border-radius: 999rem;
28
+ padding: 0.5rem 1.125rem;
29
+ color: var(--sl-color-white);
30
+ line-height: 1.1875;
31
+ text-decoration: none;
32
+ font-size: var(--sl-text-sm);
33
+ }
34
+ .action.primary {
35
+ background: var(--sl-color-text-accent);
36
+ color: var(--sl-color-black);
37
+ }
38
+ .action.secondary {
39
+ border: 1px solid;
40
+ }
41
+ .action.minimal {
42
+ padding-inline: 0;
43
+ }
44
+
45
+ @media (min-width: 50rem) {
46
+ .action {
47
+ font-size: var(--sl-text-base);
48
+ padding: 1rem 1.25rem;
49
+ }
50
+ }
51
+ </style>
@@ -9,7 +9,7 @@ interface Props {
9
9
  const t = useTranslations(Astro.props.locale);
10
10
  ---
11
11
 
12
- <p>
12
+ <p class="flex">
13
13
  <Icon
14
14
  name={'warning'}
15
15
  size="1.5em"
@@ -25,7 +25,6 @@ const t = useTranslations(Astro.props.locale);
25
25
  color: var(--sl-color-orange-high);
26
26
  width: max-content;
27
27
  max-width: 100%;
28
- display: flex;
29
28
  align-items: center;
30
29
  gap: 0.75em;
31
30
  font-size: var(--sl-text-body-sm);
@@ -12,7 +12,7 @@ interface Props {
12
12
  const { locale } = Astro.props;
13
13
  ---
14
14
 
15
- <div class="header">
15
+ <div class="header flex">
16
16
  <SiteTitle {locale} />
17
17
  <Search {locale} />
18
18
  <div class="hidden md:flex right-group">
@@ -24,7 +24,6 @@ const { locale } = Astro.props;
24
24
 
25
25
  <style>
26
26
  .header {
27
- display: flex;
28
27
  gap: var(--sl-nav-gap);
29
28
  justify-content: space-between;
30
29
  align-items: center;
@@ -0,0 +1,133 @@
1
+ ---
2
+ import type { CollectionEntry } from 'astro:content';
3
+ import { Image } from 'astro:assets';
4
+ import CallToAction from './CallToAction.astro';
5
+
6
+ interface Props {
7
+ fallbackTitle: string;
8
+ hero: NonNullable<CollectionEntry<'docs'>['data']['hero']>;
9
+ }
10
+
11
+ const {
12
+ title = Astro.props.fallbackTitle,
13
+ tagline,
14
+ image,
15
+ actions,
16
+ } = Astro.props.hero;
17
+ ---
18
+
19
+ <div class="hero">
20
+ {
21
+ image?.file ? (
22
+ <Image
23
+ src={image.file}
24
+ loading="eager"
25
+ width={400}
26
+ height={400}
27
+ alt={image.alt}
28
+ />
29
+ ) : (
30
+ image?.html && <div class="hero-html flex" set:html={image.html} />
31
+ )
32
+ }
33
+ <div class="flex stack">
34
+ <div class="flex copy">
35
+ <h1 id="starlight__overview" set:html={title} />
36
+ {tagline && <div class="tagline" set:html={tagline} />}
37
+ </div>
38
+ {
39
+ actions.length > 0 && (
40
+ <div class="flex actions">
41
+ {actions.map(({ text, ...attrs }) => (
42
+ <CallToAction {...attrs} set:html={text} />
43
+ ))}
44
+ </div>
45
+ )
46
+ }
47
+ </div>
48
+ </div>
49
+
50
+ <style>
51
+ .hero {
52
+ display: grid;
53
+ align-items: center;
54
+ gap: 1rem;
55
+ padding-bottom: 1rem;
56
+ }
57
+
58
+ .hero > img,
59
+ .hero > .hero-html {
60
+ object-fit: contain;
61
+ width: min(70%, 20rem);
62
+ height: auto;
63
+ margin-inline: auto;
64
+ }
65
+
66
+ .stack {
67
+ flex-direction: column;
68
+ gap: clamp(1.5rem, calc(1.5rem + 1vw), 2rem);
69
+ text-align: center;
70
+ }
71
+
72
+ .copy {
73
+ flex-direction: column;
74
+ gap: 1rem;
75
+ align-items: center;
76
+ }
77
+
78
+ .copy > * {
79
+ max-width: 50ch;
80
+ }
81
+
82
+ h1 {
83
+ font-size: clamp(
84
+ var(--sl-text-3xl),
85
+ calc(0.25rem + 5vw),
86
+ var(--sl-text-6xl)
87
+ );
88
+ line-height: var(--sl-line-height-headings);
89
+ font-weight: 600;
90
+ color: var(--sl-color-white);
91
+ }
92
+
93
+ .tagline {
94
+ font-size: clamp(
95
+ var(--sl-text-base),
96
+ calc(0.0625rem + 2vw),
97
+ var(--sl-text-xl)
98
+ );
99
+ color: var(--sl-color-gray-2);
100
+ }
101
+
102
+ .actions {
103
+ gap: 1rem 2rem;
104
+ flex-wrap: wrap;
105
+ justify-content: center;
106
+ }
107
+
108
+ @media (min-width: 50rem) {
109
+ .hero {
110
+ grid-template-columns: 7fr 4fr;
111
+ gap: 3%;
112
+ padding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);
113
+ }
114
+
115
+ .hero > img,
116
+ .hero > .hero-html {
117
+ order: 2;
118
+ width: min(100%, 25rem);
119
+ }
120
+
121
+ .stack {
122
+ text-align: start;
123
+ }
124
+
125
+ .copy {
126
+ align-items: flex-start;
127
+ }
128
+
129
+ .actions {
130
+ justify-content: flex-start;
131
+ }
132
+ }
133
+ </style>
@@ -9,7 +9,7 @@ interface Props {
9
9
  class?: string;
10
10
  }
11
11
 
12
- const { name, label, size = '1em', color = '' } = Astro.props;
12
+ const { name, label, size = '1em', color } = Astro.props;
13
13
  const a11yAttrs = label
14
14
  ? ({ 'aria-label': label } as const)
15
15
  : ({ 'aria-hidden': 'true' } as const);
@@ -22,13 +22,12 @@ const a11yAttrs = label
22
22
  height="16"
23
23
  viewBox="0 0 24 24"
24
24
  fill="currentColor"
25
- style={`--sl-icon-color: ${color}; --sl-icon-size: ${size};`}
26
25
  set:html={Icons[name]}
27
26
  />
28
27
 
29
- <style>
28
+ <style define:vars={{ 'sl-icon-color': color, 'sl-icon-size': size }}>
30
29
  svg {
31
- color: var(--sl-icon-color, inherit);
30
+ color: var(--sl-icon-color);
32
31
  font-size: var(--sl-icon-size, 1em);
33
32
  width: 1em;
34
33
  height: 1em;
@@ -14,6 +14,11 @@ export const Icons = {
14
14
  '<path fill-rule="evenodd" clip-rule="evenodd" d="M8.51562 3C7.99605 3 7.57486 3.42119 7.57486 3.94076V5.09057H2.94076C2.42119 5.09057 2 5.51176 2 6.03133C2 6.5509 2.42119 6.97209 2.94076 6.97209H10.3025C10.1154 8.43628 9.49493 9.81581 8.51605 10.9298C7.89546 10.2235 7.41119 9.40161 7.09425 8.50519C6.92107 8.01534 6.38356 7.75864 5.89371 7.93183C5.40386 8.10501 5.14715 8.64252 5.32034 9.13237C5.71804 10.2572 6.32594 11.2885 7.10503 12.1745C5.88484 13.0016 4.43607 13.4529 2.94076 13.4529C2.42119 13.4529 2 13.8741 2 14.3936C2 14.9132 2.42119 15.3344 2.94076 15.3344C4.96251 15.3344 6.91641 14.6763 8.51606 13.4787C8.58325 13.529 8.65118 13.5784 8.71984 13.627C9.88827 14.4533 11.2259 14.995 12.6263 15.2183L11.8634 16.7441C11.8576 16.7552 11.8519 16.7665 11.8465 16.7779L10.4616 19.5478C10.2292 20.0125 10.4176 20.5776 10.8823 20.8099C11.347 21.0423 11.9121 20.8539 12.1445 20.3892L13.2782 18.1218H19.0839L20.2176 20.3892C20.45 20.8539 21.015 21.0423 21.4798 20.8099C21.9445 20.5776 22.1328 20.0125 21.9005 19.5478L20.5162 16.7792C20.5104 16.7669 20.5043 16.7548 20.498 16.7428L17.0225 9.79176C16.8631 9.47304 16.5374 9.27172 16.181 9.27172C15.8247 9.27172 15.4989 9.47304 15.3396 9.79176L13.52 13.4309C12.236 13.3317 10.9971 12.8998 9.92708 12.1745C11.2086 10.7172 12.0005 8.89713 12.1961 6.97209H14.0905C14.61 6.97209 15.0312 6.5509 15.0312 6.03133C15.0312 5.51176 14.61 5.09057 14.0905 5.09057H9.45638V3.94076C9.45638 3.42119 9.03519 3 8.51562 3ZM14.9419 14.7944C14.9357 14.8074 14.9293 14.8203 14.9226 14.833L14.2189 16.2403H18.1431L16.181 12.3161L14.9419 14.7944Z"></path>',
15
15
  pencil:
16
16
  '<path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/>',
17
+ pen: '<path d="M21 12a1 1 0 0 0-1 1v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h6a1 1 0 1 0 0-2H5a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-6a1 1 0 0 0-1-1Zm-15 .76V17a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .71-.29l6.92-6.93L21.71 8a1 1 0 0 0 0-1.42l-4.24-4.29a1 1 0 0 0-1.42 0l-2.82 2.83-6.94 6.93a1 1 0 0 0-.29.71Zm10.76-8.35 2.83 2.83-1.42 1.42-2.83-2.83 1.42-1.42ZM8 13.17l5.93-5.93 2.83 2.83L10.83 16H8v-2.83Z"/>',
18
+ document:
19
+ '<path d="M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3.06a1.3 1.3 0 0 0-.06-.27v-.09c-.05-.1-.11-.2-.19-.28l-6-6a1.07 1.07 0 0 0-.28-.19h-.09a.88.88 0 0 0-.33-.11H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V8.94Zm-6-3.53L16.59 8H15a1 1 0 0 1-1-1V5.41ZM18 19a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z"/>',
20
+ external:
21
+ '<path d="M19.33 10.18a1 1 0 0 1-.77 0 1 1 0 0 1-.62-.93l.01-1.83-8.2 8.2a1 1 0 0 1-1.41-1.42l8.2-8.2H14.7a1 1 0 0 1 0-2h4.25a1 1 0 0 1 1 1v4.25a1 1 0 0 1-.62.93Z"/><path d="M11 4a1 1 0 1 1 0 2H7a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-4a1 1 0 1 1 2 0v4a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h4Z"/>',
17
22
  moon: '<path d="M21.64 13C21.4957 12.8807 21.3207 12.8043 21.1351 12.7796C20.9494 12.7548 20.7606 12.7827 20.59 12.86C19.5326 13.3439 18.3829 13.593 17.22 13.59C15.0689 13.5874 13.006 12.7345 11.4812 11.2171C9.95632 9.69979 9.09321 7.64114 9.08001 5.49003C9.08457 4.81586 9.16848 4.14458 9.33001 3.49003C9.36429 3.31557 9.35143 3.13512 9.29277 2.96728C9.2341 2.79944 9.13175 2.65028 8.99626 2.53516C8.86076 2.42004 8.69702 2.34313 8.52191 2.31234C8.3468 2.28156 8.16665 2.29802 8.00001 2.36003C6.43234 3.06494 5.06958 4.15679 4.03977 5.53301C3.00996 6.90924 2.34689 8.52465 2.11286 10.2275C1.87883 11.9304 2.08152 13.6648 2.70188 15.2678C3.32225 16.8708 4.33993 18.2898 5.65931 19.3915C6.9787 20.4932 8.55649 21.2414 10.2445 21.5658C11.9324 21.8903 13.6752 21.7803 15.309 21.2463C16.9428 20.7122 18.414 19.7716 19.5844 18.5128C20.7548 17.254 21.5861 15.7183 22 14.05C22.0504 13.859 22.0431 13.6574 21.9791 13.4705C21.915 13.2836 21.797 13.1199 21.64 13ZM12.14 19.69C10.4618 19.6782 8.82821 19.1479 7.46301 18.1718C6.0978 17.1956 5.06768 15.8214 4.5137 14.2372C3.95971 12.6529 3.90895 10.9362 4.36835 9.32203C4.82776 7.70785 5.77487 6.27513 7.08001 5.22003V5.49003C7.08266 8.17851 8.15183 10.7561 10.0529 12.6572C11.9539 14.5582 14.5315 15.6274 17.22 15.63C17.9259 15.6326 18.63 15.5589 19.32 15.41C18.6299 16.7155 17.5965 17.8079 16.3312 18.5692C15.0659 19.3305 13.6167 19.7319 12.14 19.73V19.69Z"></path>',
18
23
  sun: '<path d="M5 12C5 11.7348 4.89464 11.4804 4.70711 11.2929C4.51957 11.1054 4.26522 11 4 11H3C2.73478 11 2.48043 11.1054 2.29289 11.2929C2.10536 11.4804 2 11.7348 2 12C2 12.2652 2.10536 12.5196 2.29289 12.7071C2.48043 12.8946 2.73478 13 3 13H4C4.26522 13 4.51957 12.8946 4.70711 12.7071C4.89464 12.5196 5 12.2652 5 12ZM5.64 17L4.93 17.71C4.74375 17.8974 4.63921 18.1508 4.63921 18.415C4.63921 18.6792 4.74375 18.9326 4.93 19.12C5.11736 19.3063 5.37081 19.4108 5.635 19.4108C5.89919 19.4108 6.15264 19.3063 6.34 19.12L7.05 18.41C7.21383 18.2187 7.29943 17.9726 7.28971 17.7209C7.27999 17.4693 7.17566 17.2305 6.99756 17.0524C6.81947 16.8743 6.58073 16.77 6.32905 16.7603C6.07738 16.7506 5.8313 16.8362 5.64 17ZM12 5C12.2652 5 12.5196 4.89464 12.7071 4.70711C12.8946 4.51957 13 4.26522 13 4V3C13 2.73478 12.8946 2.48043 12.7071 2.29289C12.5196 2.10536 12.2652 2 12 2C11.7348 2 11.4804 2.10536 11.2929 2.29289C11.1054 2.48043 11 2.73478 11 3V4C11 4.26522 11.1054 4.51957 11.2929 4.70711C11.4804 4.89464 11.7348 5 12 5ZM17.66 7.34C17.9223 7.3389 18.1737 7.23474 18.36 7.05L19.07 6.34C19.1747 6.25035 19.2597 6.14004 19.3197 6.01597C19.3797 5.89191 19.4135 5.75677 19.4188 5.61905C19.4241 5.48133 19.4009 5.344 19.3506 5.21568C19.3004 5.08735 19.2241 4.9708 19.1266 4.87335C19.0292 4.77589 18.9126 4.69964 18.7843 4.64936C18.656 4.59909 18.5187 4.57588 18.3809 4.5812C18.2432 4.58652 18.1081 4.62025 17.984 4.68027C17.86 4.7403 17.7496 4.82532 17.66 4.93L17 5.64C16.8137 5.82736 16.7092 6.08081 16.7092 6.345C16.7092 6.60919 16.8137 6.86264 17 7.05C17.1763 7.22536 17.4116 7.32875 17.66 7.34ZM5.66 7.05C5.84626 7.23474 6.09766 7.3389 6.36 7.34C6.49161 7.34076 6.62207 7.31554 6.74391 7.26577C6.86574 7.21601 6.97656 7.14268 7.07 7.05C7.25625 6.86264 7.36079 6.60919 7.36079 6.345C7.36079 6.08081 7.25625 5.82736 7.07 5.64L6.36 4.93C6.26742 4.8361 6.15725 4.76136 6.03578 4.71005C5.91432 4.65873 5.78393 4.63184 5.65207 4.63091C5.52021 4.62998 5.38946 4.65503 5.26728 4.70463C5.14511 4.75424 5.0339 4.82742 4.94 4.92C4.8461 5.01258 4.77136 5.12275 4.72005 5.24422C4.66873 5.36568 4.64184 5.49607 4.64091 5.62793C4.63903 5.89423 4.74302 6.15037 4.93 6.34L5.66 7.05ZM21 11H20C19.7348 11 19.4804 11.1054 19.2929 11.2929C19.1054 11.4804 19 11.7348 19 12C19 12.2652 19.1054 12.5196 19.2929 12.7071C19.4804 12.8946 19.7348 13 20 13H21C21.2652 13 21.5196 12.8946 21.7071 12.7071C21.8946 12.5196 22 12.2652 22 12C22 11.7348 21.8946 11.4804 21.7071 11.2929C21.5196 11.1054 21.2652 11 21 11ZM18.36 17C18.17 16.8943 17.9508 16.8534 17.7355 16.8835C17.5202 16.9136 17.3205 17.0131 17.1668 17.1668C17.0131 17.3205 16.9136 17.5202 16.8835 17.7355C16.8534 17.9508 16.8943 18.17 17 18.36L17.71 19.07C17.8974 19.2563 18.1508 19.3608 18.415 19.3608C18.6792 19.3608 18.9326 19.2563 19.12 19.07C19.3063 18.8826 19.4108 18.6292 19.4108 18.365C19.4108 18.1008 19.3063 17.8474 19.12 17.66L18.36 17ZM12 6.5C10.9122 6.5 9.84883 6.82257 8.94436 7.42692C8.03989 8.03126 7.33494 8.89025 6.91866 9.89524C6.50238 10.9002 6.39346 12.0061 6.60568 13.073C6.8179 14.1399 7.34172 15.1199 8.11091 15.8891C8.8801 16.6583 9.86011 17.1821 10.927 17.3943C11.9939 17.6065 13.0998 17.4976 14.1048 17.0813C15.1098 16.6651 15.9687 15.9601 16.5731 15.0556C17.1774 14.1512 17.5 13.0878 17.5 12C17.4974 10.5421 16.917 9.14471 15.8862 8.11383C14.8553 7.08295 13.4579 6.50264 12 6.5ZM12 15.5C11.3078 15.5 10.6311 15.2947 10.0555 14.9101C9.47993 14.5256 9.03133 13.9789 8.76642 13.3394C8.50151 12.6999 8.4322 11.9961 8.56725 11.3172C8.7023 10.6383 9.03564 10.0146 9.52513 9.52513C10.0146 9.03564 10.6383 8.7023 11.3172 8.56725C11.9961 8.4322 12.6999 8.50151 13.3394 8.76642C13.9789 9.03133 14.5256 9.47993 14.9101 10.0555C15.2947 10.6311 15.5 11.3078 15.5 12C15.5 12.9283 15.1313 13.8185 14.4749 14.4749C13.8185 15.1313 12.9283 15.5 12 15.5ZM12 19C11.7348 19 11.4804 19.1054 11.2929 19.2929C11.1054 19.4804 11 19.7348 11 20V21C11 21.2652 11.1054 21.5196 11.2929 21.7071C11.4804 21.8946 11.7348 22 12 22C12.2652 22 12.5196 21.8946 12.7071 21.7071C12.8946 21.5196 13 21.2652 13 21V20C13 19.7348 12.8946 19.4804 12.7071 19.2929C12.5196 19.1054 12.2652 19 12 19Z"></path>',
19
24
  laptop:
@@ -38,6 +43,9 @@ export const Icons = {
38
43
  '<path d="M18.71 7.20998C18.617 7.11625 18.5064 7.04186 18.3846 6.99109C18.2627 6.94032 18.132 6.91418 18 6.91418C17.868 6.91418 17.7373 6.94032 17.6154 6.99109C17.4936 7.04186 17.383 7.11625 17.29 7.20998L9.84001 14.67L6.71001 11.53C6.61349 11.4367 6.49955 11.3634 6.37469 11.3142C6.24984 11.265 6.11651 11.2409 5.98233 11.2432C5.84815 11.2455 5.71574 11.2743 5.59266 11.3278C5.46959 11.3812 5.35825 11.4585 5.26501 11.555C5.17177 11.6515 5.09846 11.7654 5.04925 11.8903C5.00005 12.0152 4.97592 12.1485 4.97824 12.2827C4.98056 12.4168 5.00929 12.5493 5.06278 12.6723C5.11628 12.7954 5.19349 12.9067 5.29001 13L9.13001 16.84C9.22297 16.9337 9.33358 17.0081 9.45543 17.0589C9.57729 17.1096 9.708 17.1358 9.84001 17.1358C9.97202 17.1358 10.1027 17.1096 10.2246 17.0589C10.3464 17.0081 10.457 16.9337 10.55 16.84L18.71 8.67998C18.8115 8.58634 18.8925 8.47269 18.9479 8.34619C19.0033 8.21969 19.0319 8.08308 19.0319 7.94498C19.0319 7.80688 19.0033 7.67028 18.9479 7.54378C18.8925 7.41728 18.8115 7.30363 18.71 7.20998Z"></path>',
39
44
  rocket:
40
45
  '<path fill-rule="evenodd" clip-rule="evenodd" d="M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z"></path><path d="M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z"></path>',
46
+ star: '<path d="M22 9.67a1 1 0 0 0-.86-.67l-5.69-.83L12.9 3a1 1 0 0 0-1.8 0L8.55 8.16 2.86 9a1 1 0 0 0-.81.68 1 1 0 0 0 .25 1l4.13 4-1 5.68a1 1 0 0 0 1.45 1.07L12 18.76l5.1 2.68c.14.08.3.12.46.12a1 1 0 0 0 .99-1.19l-1-5.68 4.13-4A1 1 0 0 0 22 9.67Zm-6.15 4a1 1 0 0 0-.29.89l.72 4.19-3.76-2a1 1 0 0 0-.94 0l-3.76 2 .72-4.19a1 1 0 0 0-.29-.89l-3-3 4.21-.61a1 1 0 0 0 .76-.55L12 5.7l1.88 3.82a1 1 0 0 0 .76.55l4.21.61-3 2.99Z"/>',
47
+ puzzle:
48
+ '<path d="M17 22H5a3 3 0 0 1-3-3V9a3 3 0 0 1 3-3h1a4 4 0 0 1 7.3-2.18c.448.64.692 1.4.7 2.18h3a1 1 0 0 1 1 1v3a4 4 0 0 1 2.18 7.3A3.86 3.86 0 0 1 18 18v3a1 1 0 0 1-1 1ZM5 8a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h11v-3.18a1 1 0 0 1 1.33-.95 1.77 1.77 0 0 0 1.74-.23 2 2 0 0 0 .93-1.37 2 2 0 0 0-.48-1.59 1.89 1.89 0 0 0-2.17-.55 1 1 0 0 1-1.33-.95V8h-3.2a1 1 0 0 1-1-1.33 1.77 1.77 0 0 0-.23-1.74 1.939 1.939 0 0 0-3-.43A2 2 0 0 0 8 6c.002.23.046.456.13.67A1 1 0 0 1 7.18 8H5Z"/>',
41
49
  'list-format':
42
50
  '<path d="M3.71 16.29C3.6149 16.199 3.50276 16.1276 3.38 16.08C3.13654 15.98 2.86346 15.98 2.62 16.08C2.49725 16.1276 2.38511 16.199 2.29 16.29C2.19896 16.3851 2.1276 16.4972 2.08 16.62C2.00342 16.8021 1.9825 17.0028 2.01988 17.1968C2.05725 17.3908 2.15125 17.5694 2.29 17.71C2.3872 17.7983 2.49882 17.8694 2.62 17.92C2.7397 17.9729 2.86913 18.0002 3 18.0002C3.13087 18.0002 3.2603 17.9729 3.38 17.92C3.50119 17.8694 3.6128 17.7983 3.71 17.71C3.84876 17.5694 3.94276 17.3908 3.98013 17.1968C4.01751 17.0028 3.99658 16.8021 3.92 16.62C3.87241 16.4972 3.80104 16.3851 3.71 16.29ZM7 8H21C21.2652 8 21.5196 7.89464 21.7071 7.70711C21.8946 7.51957 22 7.26522 22 7C22 6.73478 21.8946 6.48043 21.7071 6.29289C21.5196 6.10536 21.2652 6 21 6H7C6.73479 6 6.48043 6.10536 6.2929 6.29289C6.10536 6.48043 6 6.73478 6 7C6 7.26522 6.10536 7.51957 6.2929 7.70711C6.48043 7.89464 6.73479 8 7 8ZM3.71 11.29C3.56938 11.1512 3.39081 11.0572 3.19682 11.0199C3.00283 10.9825 2.80211 11.0034 2.62 11.08C2.49882 11.1306 2.3872 11.2017 2.29 11.29C2.19896 11.3851 2.1276 11.4972 2.08 11.62C2.0271 11.7397 1.99977 11.8691 1.99977 12C1.99977 12.1309 2.0271 12.2603 2.08 12.38C2.13065 12.5012 2.20167 12.6128 2.29 12.71C2.3872 12.7983 2.49882 12.8694 2.62 12.92C2.7397 12.9729 2.86913 13.0002 3 13.0002C3.13087 13.0002 3.2603 12.9729 3.38 12.92C3.50119 12.8694 3.6128 12.7983 3.71 12.71C3.79833 12.6128 3.86936 12.5012 3.92 12.38C3.97291 12.2603 4.00024 12.1309 4.00024 12C4.00024 11.8691 3.97291 11.7397 3.92 11.62C3.87241 11.4972 3.80104 11.3851 3.71 11.29ZM21 11H7C6.73479 11 6.48043 11.1054 6.2929 11.2929C6.10536 11.4804 6 11.7348 6 12C6 12.2652 6.10536 12.5196 6.2929 12.7071C6.48043 12.8946 6.73479 13 7 13H21C21.2652 13 21.5196 12.8946 21.7071 12.7071C21.8946 12.5196 22 12.2652 22 12C22 11.7348 21.8946 11.4804 21.7071 11.2929C21.5196 11.1054 21.2652 11 21 11ZM3.71 6.29C3.6149 6.19896 3.50276 6.12759 3.38 6.08C3.19789 6.00342 2.99718 5.9825 2.80319 6.01987C2.6092 6.05725 2.43063 6.15124 2.29 6.29C2.20167 6.3872 2.13065 6.49882 2.08 6.62C2.0271 6.7397 1.99977 6.86913 1.99977 7C1.99977 7.13087 2.0271 7.2603 2.08 7.38C2.13065 7.50119 2.20167 7.6128 2.29 7.71C2.3872 7.79833 2.49882 7.86936 2.62 7.92C2.80211 7.99658 3.00283 8.0175 3.19682 7.98013C3.39081 7.94275 3.56938 7.84876 3.71 7.71C3.79833 7.6128 3.86936 7.50119 3.92 7.38C3.97291 7.2603 4.00024 7.13087 4.00024 7C4.00024 6.86913 3.97291 6.7397 3.92 6.62C3.86936 6.49882 3.79833 6.3872 3.71 6.29ZM21 16H7C6.73479 16 6.48043 16.1054 6.2929 16.2929C6.10536 16.4804 6 16.7348 6 17C6 17.2652 6.10536 17.5196 6.2929 17.7071C6.48043 17.8946 6.73479 18 7 18H21C21.2652 18 21.5196 17.8946 21.7071 17.7071C21.8946 17.5196 22 17.2652 22 17C22 16.7348 21.8946 16.4804 21.7071 16.2929C21.5196 16.1054 21.2652 16 21 16Z"></path>',
43
51
  github:
@@ -14,7 +14,7 @@ const t = useTranslations(Astro.props.locale);
14
14
  aria-expanded="false"
15
15
  aria-label={t('menuButton.accessibleLabel')}
16
16
  aria-controls="starlight__sidebar"
17
- class="md:hidden"
17
+ class="flex md:hidden"
18
18
  >
19
19
  <Icon name="bars" />
20
20
  </button>
@@ -64,7 +64,6 @@ const t = useTranslations(Astro.props.locale);
64
64
  z-index: var(--sl-z-index-navbar);
65
65
  border: 0;
66
66
  border-radius: 50%;
67
- display: flex;
68
67
  width: var(--sl-menu-button-size);
69
68
  height: var(--sl-menu-button-size);
70
69
  padding: 0.5rem;
@@ -15,7 +15,7 @@ const isRtl = dir === 'rtl';
15
15
  const t = useTranslations(locale);
16
16
  ---
17
17
 
18
- <div class="pagination-links" dir={dir}>
18
+ <div class="pagination-links flex" dir={dir}>
19
19
  {
20
20
  prev && (
21
21
  <a href={prev.href} rel="prev">
@@ -44,7 +44,6 @@ const t = useTranslations(locale);
44
44
 
45
45
  <style>
46
46
  .pagination-links {
47
- display: flex;
48
47
  flex-wrap: wrap;
49
48
  gap: 1rem;
50
49
  }
@@ -25,7 +25,7 @@ const t = useTranslations(Astro.props.locale);
25
25
  </button>
26
26
 
27
27
  <dialog style="padding:0" aria-label={t('search.label')}>
28
- <div class="dialog-frame">
28
+ <div class="dialog-frame flex">
29
29
  {
30
30
  /* TODO: Make the layout of this button flexible to accommodate different word lengths. Currently hard-coded for English: “Cancel” */
31
31
  }
@@ -170,7 +170,6 @@ const t = useTranslations(Astro.props.locale);
170
170
  }
171
171
 
172
172
  .dialog-frame {
173
- display: flex;
174
173
  flex-direction: column;
175
174
  gap: 1rem;
176
175
  padding: 1.5rem;
@@ -179,7 +178,6 @@ const t = useTranslations(Astro.props.locale);
179
178
  button[data-close-modal] {
180
179
  position: absolute;
181
180
  z-index: 1;
182
- display: flex;
183
181
  align-items: center;
184
182
  align-self: flex-end;
185
183
  height: calc(64px * var(--pagefind-ui-scale));
@@ -213,10 +211,6 @@ const t = useTranslations(Astro.props.locale);
213
211
  min-height: 15rem;
214
212
  max-height: calc(100% - 8rem);
215
213
  }
216
-
217
- button[data-close-modal] {
218
- display: none;
219
- }
220
214
  }
221
215
  </style>
222
216
 
@@ -12,11 +12,13 @@ const t = useTranslations(Astro.props.locale);
12
12
 
13
13
  <style>
14
14
  a {
15
+ clip: rect(0, 0, 0, 0);
15
16
  position: fixed;
16
17
  top: 0.75rem;
17
18
  inset-inline-start: 0.75rem;
18
19
  }
19
20
  a:focus {
21
+ clip: unset;
20
22
  z-index: var(--sl-z-index-skiplink);
21
23
  display: block;
22
24
  padding: 0.5rem 1rem;
package/components.ts CHANGED
@@ -1,2 +1,4 @@
1
+ export { default as Card } from './user-components/Card.astro';
2
+ export { default as CardGrid } from './user-components/CardGrid.astro';
1
3
  export { default as Tabs } from './user-components/Tabs.astro';
2
4
  export { default as TabItem } from './user-components/TabItem.astro';
package/index.astro CHANGED
@@ -24,6 +24,7 @@ import SkipLink from './components/SkipLink.astro';
24
24
  import ThemeProvider from './components/ThemeProvider.astro';
25
25
  import PageFrame from './layout/PageFrame.astro';
26
26
  import TwoColumnContent from './layout/TwoColumnContent.astro';
27
+ import Hero from './components/Hero.astro';
27
28
 
28
29
  // Remark component CSS (needs to override `MarkdownContent.astro`)
29
30
  import './style/asides.css';
@@ -48,9 +49,10 @@ const tocConfig = !hasSidebar
48
49
  ? entry.data.tableOfContents
49
50
  : config.tableOfContents;
50
51
  const hasToC = Boolean(tocConfig);
52
+ const hasHero = Boolean(entry.data.hero);
51
53
  ---
52
54
 
53
- <html lang={lang} dir={dir} data-has-toc={hasToC} data-has-sidebar={hasSidebar}>
55
+ <html lang={lang} dir={dir} data-has-toc={hasToC} data-has-sidebar={hasSidebar} data-has-hero={hasHero}>
54
56
  <head>
55
57
  <HeadSEO data={entry.data} lang={lang} />
56
58
  <style>
@@ -88,19 +90,27 @@ const hasToC = Boolean(tocConfig);
88
90
  <TwoColumnContent {hasToC}>
89
91
  <RightSidebar slot="right-sidebar" {headings} {locale} {tocConfig} />
90
92
  <main data-pagefind-body lang={entryMeta.lang} dir={entryMeta.dir}>
91
- <ContentPanel>
92
- <h1
93
- id="starlight__overview"
94
- style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
95
- >
96
- {entry.data.title}
97
- </h1>
98
- {isFallback && <FallbackContentNotice {locale} />}
99
- </ContentPanel>
100
- <ContentPanel>
101
- <MarkdownContent><Content /></MarkdownContent>
102
- <Footer {...{ entry, dir, lang, locale, sidebar }} />
103
- </ContentPanel>
93
+ {/* TODO: Revisit how this logic flows. */}
94
+ {entry.data.hero ? (
95
+ <ContentPanel>
96
+ <Hero hero={entry.data.hero} fallbackTitle={entry.data.title} />
97
+ <MarkdownContent><Content /></MarkdownContent>
98
+ </ContentPanel>
99
+ ) : (
100
+ <ContentPanel>
101
+ <h1
102
+ id="starlight__overview"
103
+ style="font-size: var(--sl-text-h1); line-height: var(--sl-line-height-headings); font-weight: 600; color: var(--sl-color-white); margin-top: 1rem;"
104
+ >
105
+ {entry.data.title}
106
+ </h1>
107
+ {isFallback && <FallbackContentNotice {locale} />}
108
+ </ContentPanel>
109
+ <ContentPanel>
110
+ <MarkdownContent><Content /></MarkdownContent>
111
+ <Footer {...{ entry, dir, lang, locale, sidebar }} />
112
+ </ContentPanel>
113
+ )}
104
114
  </main>
105
115
  </TwoColumnContent>
106
116
  </PageFrame>
package/index.ts CHANGED
@@ -15,11 +15,21 @@ import {
15
15
  StarlightConfig,
16
16
  StarlightConfigSchema,
17
17
  } from './utils/user-config';
18
+ import { errorMap } from './utils/error-map';
18
19
 
19
20
  export default function StarlightIntegration(
20
21
  opts: StarlightUserConfig
21
22
  ): AstroIntegration[] {
22
- const userConfig = StarlightConfigSchema.parse(opts);
23
+ const parsedConfig = StarlightConfigSchema.safeParse(opts, { errorMap });
24
+
25
+ if (!parsedConfig.success) {
26
+ throw new Error(
27
+ 'Invalid config passed to starlight integration\n' +
28
+ parsedConfig.error.issues.map((i) => i.message).join('\n')
29
+ );
30
+ }
31
+
32
+ const userConfig = parsedConfig.data;
23
33
 
24
34
  const Starlight: AstroIntegration = {
25
35
  name: '@astrojs/starlight',
@@ -45,7 +55,7 @@ export default function StarlightIntegration(
45
55
  ? {}
46
56
  : { theme: 'css-variables' },
47
57
  },
48
- experimental: { assets: true },
58
+ experimental: { assets: true, inlineStylesheets: 'auto' },
49
59
  };
50
60
  updateConfig(newConfig);
51
61
  },
@@ -11,7 +11,7 @@ const { hasSidebar, locale } = Astro.props;
11
11
  const t = useTranslations(locale);
12
12
  ---
13
13
 
14
- <div class="page">
14
+ <div class="page flex">
15
15
  <header class="header"><slot name="header" /></header>
16
16
  {
17
17
  hasSidebar && (
@@ -30,7 +30,6 @@ const t = useTranslations(locale);
30
30
 
31
31
  <style>
32
32
  .page {
33
- display: flex;
34
33
  flex-direction: column;
35
34
  min-height: 100vh;
36
35
  }
@@ -4,7 +4,7 @@ interface Props {
4
4
  }
5
5
  ---
6
6
 
7
- <div class="container">
7
+ <div class="lg:flex">
8
8
  {
9
9
  Astro.props.hasToC && (
10
10
  <aside class="right-sidebar-container">
@@ -19,10 +19,6 @@ interface Props {
19
19
 
20
20
  <style>
21
21
  @media (min-width: 72rem) {
22
- .container {
23
- display: flex;
24
- }
25
-
26
22
  .right-sidebar-container {
27
23
  order: 2;
28
24
  position: relative;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrojs/starlight",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "Build beautiful, high-performance documentation websites with Astro",
5
5
  "keywords": [
6
6
  "docs",
package/schema.ts CHANGED
@@ -1,38 +1,117 @@
1
1
  import { z } from 'astro/zod';
2
2
  import { HeadConfigSchema } from './schemas/head';
3
3
  import { TableOfContentsSchema } from './schemas/tableOfContents';
4
+ import { Icons } from './components/Icons';
4
5
  export { i18nSchema } from './schemas/i18n';
5
6
 
7
+ type IconName = keyof typeof Icons;
8
+ const iconNames = Object.keys(Icons) as [IconName, ...IconName[]];
9
+
10
+ type ImageFunction = () => z.ZodObject<{
11
+ src: z.ZodString;
12
+ width: z.ZodNumber;
13
+ height: z.ZodNumber;
14
+ format: z.ZodUnion<
15
+ [
16
+ z.ZodLiteral<'png'>,
17
+ z.ZodLiteral<'jpg'>,
18
+ z.ZodLiteral<'jpeg'>,
19
+ z.ZodLiteral<'tiff'>,
20
+ z.ZodLiteral<'webp'>,
21
+ z.ZodLiteral<'gif'>,
22
+ z.ZodLiteral<'svg'>
23
+ ]
24
+ >;
25
+ }>;
26
+
6
27
  export function docsSchema() {
7
- return z.object({
8
- /** The title of the current page. Required. */
9
- title: z.string(),
10
-
11
- /**
12
- * A short description of the current page’s content. Optional, but recommended.
13
- * A good description is 150–160 characters long and outlines the key content
14
- * of the page in a clear and engaging way.
15
- */
16
- description: z.string().optional(),
17
-
18
- /**
19
- * Custom URL where a reader can edit this page.
20
- * Overrides the `editLink.baseUrl` global config if set.
21
- *
22
- * Can also be set to `false` to disable showing an edit link on this page.
23
- */
24
- editUrl: z.union([z.string().url(), z.boolean()]).optional().default(true),
25
-
26
- /** Set custom `<head>` tags just for this page. */
27
- head: HeadConfigSchema(),
28
-
29
- /** Override global table of contents configuration for this page. */
30
- tableOfContents: TableOfContentsSchema().optional(),
31
-
32
- /**
33
- * Set the layout style for this page.
34
- * Can be `'doc'` (the default) or `'splash'` for a wider layout without any sidebars.
35
- */
36
- template: z.enum(['doc', 'splash']).default('doc'),
37
- });
28
+ return ({ image }: { image: ImageFunction }) =>
29
+ z.object({
30
+ /** The title of the current page. Required. */
31
+ title: z.string(),
32
+
33
+ /**
34
+ * A short description of the current page’s content. Optional, but recommended.
35
+ * A good description is 150–160 characters long and outlines the key content
36
+ * of the page in a clear and engaging way.
37
+ */
38
+ description: z.string().optional(),
39
+
40
+ /**
41
+ * Custom URL where a reader can edit this page.
42
+ * Overrides the `editLink.baseUrl` global config if set.
43
+ *
44
+ * Can also be set to `false` to disable showing an edit link on this page.
45
+ */
46
+ editUrl: z
47
+ .union([z.string().url(), z.boolean()])
48
+ .optional()
49
+ .default(true),
50
+
51
+ /** Set custom `<head>` tags just for this page. */
52
+ head: HeadConfigSchema(),
53
+
54
+ /** Override global table of contents configuration for this page. */
55
+ tableOfContents: TableOfContentsSchema().optional(),
56
+
57
+ /**
58
+ * Set the layout style for this page.
59
+ * Can be `'doc'` (the default) or `'splash'` for a wider layout without any sidebars.
60
+ */
61
+ template: z.enum(['doc', 'splash']).default('doc'),
62
+
63
+ /** Display a hero section on this page. */
64
+ hero: z
65
+ .object({
66
+ /**
67
+ * The large title text to show. If not provided, will default to the top-level `title`.
68
+ * Can include HTML.
69
+ */
70
+ title: z.string().optional(),
71
+ /**
72
+ * A short bit of text about your project.
73
+ * Will be displayed in a smaller size below the title.
74
+ */
75
+ tagline: z.string().optional(),
76
+ /** The image to use in the hero. You can provide either a relative `file` path or raw `html`. */
77
+ image: z
78
+ .object({
79
+ /** Alt text for screenreaders and other assistive technologies describing your hero image. */
80
+ alt: z.string().default(''),
81
+ /** Relative path to an image file in your repo, e.g. `../../assets/hero.png`. */
82
+ file: image().optional(),
83
+ /** Raw HTML string instead of an image file. Useful for inline SVGs or more complex hero content. */
84
+ html: z.string().optional(),
85
+ })
86
+ .optional(),
87
+ /** An array of call-to-action links displayed at the bottom of the hero. */
88
+ actions: z
89
+ .object({
90
+ /** Text label displayed in the link. */
91
+ text: z.string(),
92
+ /** Value for the link’s `href` attribute, e.g. `/page` or `https://mysite.com`. */
93
+ link: z.string(),
94
+ /** Button style to use. One of `primary`, `secondary`, or `minimal` (the default). */
95
+ variant: z
96
+ .enum(['primary', 'secondary', 'minimal'])
97
+ .default('minimal'),
98
+ /**
99
+ * An optional icon to display alongside the link text.
100
+ * Can be an inline `<svg>` or the name of one of Starlight’s built-in icons.
101
+ */
102
+ icon: z
103
+ .union([z.enum(iconNames), z.string().startsWith('<svg')])
104
+ .transform((icon) => {
105
+ const parsedIcon = z.enum(iconNames).safeParse(icon);
106
+ return parsedIcon.success
107
+ ? ({ type: 'icon', name: parsedIcon.data } as const)
108
+ : ({ type: 'raw', html: icon } as const);
109
+ })
110
+ .optional(),
111
+ })
112
+ .array()
113
+ .default([]),
114
+ })
115
+ .optional(),
116
+ });
38
117
  }
package/style/props.css CHANGED
@@ -17,7 +17,7 @@
17
17
  --sl-hue-green: 101;
18
18
  --sl-color-green-low: hsl(var(--sl-hue-green), 39%, 22%);
19
19
  --sl-color-green: hsl(var(--sl-hue-green), 82%, 63%);
20
- --sl-color-green-high: hsl(var(--sl-hue-green), 82%, 87%);
20
+ --sl-color-green-high: hsl(var(--sl-hue-green), 82%, 80%);
21
21
  --sl-hue-blue: 234;
22
22
  --sl-color-blue-low: hsl(var(--sl-hue-blue), 54%, 20%);
23
23
  --sl-color-blue: hsl(var(--sl-hue-blue), 100%, 60%);
@@ -58,28 +58,6 @@
58
58
  0px 16px 6px hsla(0, 0%, 0%, 0.1), 0px 9px 5px hsla(223, 13%, 10%, 0.33),
59
59
  0px 4px 4px hsla(0, 0%, 0%, 0.75), 0px 4px 2px hsla(0, 0%, 0%, 0.25);
60
60
 
61
- /* Gradients (unchanged across dark & light modes) */
62
- --sl-gradient-blue-purple: linear-gradient(
63
- to bottom,
64
- hsl(234, 100%, 59.8%) 0%,
65
- hsl(281, 82.1%, 62.7%) 100%
66
- );
67
- --sl-gradient-red-pink: linear-gradient(
68
- to bottom,
69
- hsl(0, 67.9%, 52.4%) 0%,
70
- hsl(295, 100%, 62.7%) 100%
71
- );
72
- --sl-gradient-orange-yellow: linear-gradient(
73
- to bottom,
74
- hsl(54, 93.5%, 57.6%) 0%,
75
- hsl(14, 100%, 66.5%) 100%
76
- );
77
- --sl-gradient-blue-green: linear-gradient(
78
- to bottom,
79
- hsl(165, 86.6%, 62%) 0%,
80
- hsl(227, 58.4%, 44.3%) 100%
81
- );
82
-
83
61
  /* Text size and line height */
84
62
  --sl-text-xs: 0.8125rem; /* 13px */
85
63
  --sl-text-sm: 0.875rem; /* 14px */
@@ -90,6 +68,7 @@
90
68
  --sl-text-3xl: 1.8125rem; /* 29px */
91
69
  --sl-text-4xl: 2.1875rem; /* 35px */
92
70
  --sl-text-5xl: 2.625rem; /* 42px */
71
+ --sl-text-6xl: 4rem; /* 64px */
93
72
 
94
73
  --sl-text-body: var(--sl-text-base);
95
74
  --sl-text-body-sm: var(--sl-text-xs);
@@ -150,7 +129,7 @@
150
129
  --sl-color-orange: hsl(var(--sl-hue-orange), 90%, 60%);
151
130
  --sl-color-orange-low: hsl(var(--sl-hue-orange), 90%, 88%);
152
131
  --sl-color-green-high: hsl(var(--sl-hue-green), 80%, 22%);
153
- --sl-color-green: hsl(var(--sl-hue-green), 90%, 60%);
132
+ --sl-color-green: hsl(var(--sl-hue-green), 90%, 46%);
154
133
  --sl-color-green-low: hsl(var(--sl-hue-green), 85%, 90%);
155
134
  --sl-color-blue-high: hsl(var(--sl-hue-blue), 80%, 30%);
156
135
  --sl-color-blue: hsl(var(--sl-hue-blue), 90%, 60%);
@@ -0,0 +1,69 @@
1
+ ---
2
+ import Icon from '../components/Icon.astro';
3
+ import type { Icons } from '../components/Icons';
4
+
5
+ interface Props {
6
+ icon?: keyof typeof Icons;
7
+ title: string;
8
+ }
9
+
10
+ const { icon, title } = Astro.props;
11
+ ---
12
+
13
+ <article class="card flex">
14
+ <p class="title flex">
15
+ {icon && <Icon name={icon} class="icon" size="1.333em" />}
16
+ <span set:html={title} />
17
+ </p>
18
+ <div class="body"><slot /></div>
19
+ </article>
20
+
21
+ <style>
22
+ .card {
23
+ --sl-card-border: var(--sl-color-purple);
24
+ --sl-card-bg: var(--sl-color-purple-low);
25
+ border: 1px solid var(--sl-color-gray-5);
26
+ background-color: var(--sl-color-black);
27
+ padding: clamp(1rem, calc(0.125rem + 3vw), 2.5rem);
28
+ flex-direction: column;
29
+ gap: clamp(0.5rem, calc(0.125rem + 1vw), 1rem);
30
+ }
31
+ .card:nth-child(4n + 1) {
32
+ --sl-card-border: var(--sl-color-orange);
33
+ --sl-card-bg: var(--sl-color-orange-low);
34
+ }
35
+ .card:nth-child(4n + 3) {
36
+ --sl-card-border: var(--sl-color-green);
37
+ --sl-card-bg: var(--sl-color-green-low);
38
+ }
39
+ .card:nth-child(4n + 4) {
40
+ --sl-card-border: var(--sl-color-red);
41
+ --sl-card-bg: var(--sl-color-red-low);
42
+ }
43
+ .card:nth-child(4n + 5) {
44
+ --sl-card-border: var(--sl-color-blue);
45
+ --sl-card-bg: var(--sl-color-blue-low);
46
+ }
47
+ .title {
48
+ font-weight: 600;
49
+ font-size: var(--sl-text-h4);
50
+ color: var(--sl-color-white);
51
+ line-height: var(--sl-line-height-headings);
52
+ gap: 1rem;
53
+ align-items: center;
54
+ }
55
+ .card .icon {
56
+ border: 1px solid var(--sl-card-border);
57
+ background-color: var(--sl-card-bg);
58
+ padding: 0.2em;
59
+ border-radius: 0.25rem;
60
+ }
61
+ .card .body {
62
+ margin: 0;
63
+ font-size: clamp(
64
+ var(--sl-text-sm),
65
+ calc(0.5rem + 1vw),
66
+ var(--sl-text-body)
67
+ );
68
+ }
69
+ </style>
@@ -0,0 +1,35 @@
1
+ ---
2
+ interface Props {
3
+ stagger?: boolean;
4
+ }
5
+
6
+ const { stagger = false } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={['card-grid', { stagger }]}><slot /></div>
10
+
11
+ <style>
12
+ .card-grid {
13
+ display: grid;
14
+ gap: 1rem;
15
+ }
16
+
17
+ .card-grid > :global(*) {
18
+ margin-top: 0 !important;
19
+ }
20
+
21
+ @media (min-width: 50rem) {
22
+ .card-grid {
23
+ grid-template-columns: 1fr 1fr;
24
+ gap: 1.5rem;
25
+ }
26
+ .stagger {
27
+ --stagger-height: 5rem;
28
+ padding-bottom: var(--stagger-height);
29
+ }
30
+
31
+ .stagger > :global(*):nth-child(2n) {
32
+ transform: translateY(var(--stagger-height));
33
+ }
34
+ }
35
+ </style>
@@ -0,0 +1,104 @@
1
+ /**
2
+ * This is a modified version of Astro's error map.
3
+ * source: https://github.com/withastro/astro/blob/main/packages/astro/src/content/error-map.ts
4
+ */
5
+
6
+ import type { z } from 'astro:content';
7
+
8
+ type TypeOrLiteralErrByPathEntry = {
9
+ code: 'invalid_type' | 'invalid_literal';
10
+ received: unknown;
11
+ expected: unknown[];
12
+ };
13
+
14
+ export const errorMap: z.ZodErrorMap = (baseError, ctx) => {
15
+ const baseErrorPath = flattenErrorPath(baseError.path);
16
+ if (baseError.code === 'invalid_union') {
17
+ // Optimization: Combine type and literal errors for keys that are common across ALL union types
18
+ // Ex. a union between `{ key: z.literal('tutorial') }` and `{ key: z.literal('blog') }` will
19
+ // raise a single error when `key` does not match:
20
+ // > Did not match union.
21
+ // > key: Expected `'tutorial' | 'blog'`, received 'foo'
22
+ let typeOrLiteralErrByPath: Map<string, TypeOrLiteralErrByPathEntry> = new Map();
23
+ for (const unionError of baseError.unionErrors.map((e) => e.errors).flat()) {
24
+ if (unionError.code === 'invalid_type' || unionError.code === 'invalid_literal') {
25
+ const flattenedErrorPath = flattenErrorPath(unionError.path);
26
+ if (typeOrLiteralErrByPath.has(flattenedErrorPath)) {
27
+ typeOrLiteralErrByPath.get(flattenedErrorPath)!.expected.push(unionError.expected);
28
+ } else {
29
+ typeOrLiteralErrByPath.set(flattenedErrorPath, {
30
+ code: unionError.code,
31
+ received: (unionError as any).received,
32
+ expected: [unionError.expected],
33
+ });
34
+ }
35
+ }
36
+ }
37
+ let messages: string[] = [
38
+ prefix(
39
+ baseErrorPath,
40
+ typeOrLiteralErrByPath.size ? 'Did not match union:' : 'Did not match union.'
41
+ ),
42
+ ];
43
+ return {
44
+ message: messages
45
+ .concat(
46
+ [...typeOrLiteralErrByPath.entries()]
47
+ // If type or literal error isn't common to ALL union types,
48
+ // filter it out. Can lead to confusing noise.
49
+ .filter(([, error]) => error.expected.length === baseError.unionErrors.length)
50
+ .map(([key, error]) =>
51
+ key === baseErrorPath
52
+ ? // Avoid printing the key again if it's a base error
53
+ `> ${getTypeOrLiteralMsg(error)}`
54
+ : `> ${prefix(key, getTypeOrLiteralMsg(error))}`
55
+ )
56
+ )
57
+ .join('\n'),
58
+ };
59
+ }
60
+ if (baseError.code === 'invalid_literal' || baseError.code === 'invalid_type') {
61
+ return {
62
+ message: prefix(
63
+ baseErrorPath,
64
+ getTypeOrLiteralMsg({
65
+ code: baseError.code,
66
+ received: (baseError as any).received,
67
+ expected: [baseError.expected],
68
+ })
69
+ ),
70
+ };
71
+ } else if (baseError.message) {
72
+ return { message: prefix(baseErrorPath, baseError.message) };
73
+ } else {
74
+ return { message: prefix(baseErrorPath, ctx.defaultError) };
75
+ }
76
+ };
77
+
78
+ const getTypeOrLiteralMsg = (error: TypeOrLiteralErrByPathEntry): string => {
79
+ if (error.received === 'undefined') return 'Required';
80
+ const expectedDeduped = new Set(error.expected);
81
+ switch (error.code) {
82
+ case 'invalid_type':
83
+ return `Expected type \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
84
+ error.received
85
+ )}`;
86
+ case 'invalid_literal':
87
+ return `Expected \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
88
+ error.received
89
+ )}`;
90
+ }
91
+ };
92
+
93
+ const prefix = (key: string, msg: string) => (key.length ? `**${key}**: ${msg}` : msg);
94
+
95
+ const unionExpectedVals = (expectedVals: Set<unknown>) =>
96
+ [...expectedVals]
97
+ .map((expectedVal, idx) => {
98
+ if (idx === 0) return JSON.stringify(expectedVal);
99
+ const sep = ' | ';
100
+ return `${sep}${JSON.stringify(expectedVal)}`;
101
+ })
102
+ .join('');
103
+
104
+ const flattenErrorPath = (errorPath: (string | number)[]) => errorPath.join('.');