@rxova/astro-ui 0.0.0 → 0.2.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -2
  3. package/package.json +65 -6
  4. package/src/components/BackLink.astro +24 -0
  5. package/src/components/CodeRecipes.astro +67 -0
  6. package/src/components/CtaBand.astro +121 -0
  7. package/src/components/DataTable.astro +114 -0
  8. package/src/components/DocAccordion.astro +15 -0
  9. package/src/components/DocAccordionItem.astro +83 -0
  10. package/src/components/Header.astro +148 -0
  11. package/src/components/Icon.astro +29 -0
  12. package/src/components/ModeTabs.astro +124 -0
  13. package/src/components/PageHeader.astro +63 -0
  14. package/src/components/ProjectSwitcher.astro +95 -0
  15. package/src/components/ProofStats.astro +207 -0
  16. package/src/components/QuickStart.astro +156 -0
  17. package/src/components/ScreenshotGrid.astro +164 -0
  18. package/src/components/Section.astro +103 -0
  19. package/src/components/ShowMore.astro +82 -0
  20. package/src/components/SiteFooter.astro +149 -0
  21. package/src/components/SiteShell.astro +155 -0
  22. package/src/components/SizeTable.astro +118 -0
  23. package/src/components/ThemeScript.astro +31 -0
  24. package/src/components/ThemeToggle.astro +163 -0
  25. package/src/components/ValueGrid.astro +116 -0
  26. package/src/components/VisuallyHidden.astro +23 -0
  27. package/src/components/icons/Collapse.astro +11 -0
  28. package/src/components/icons/Expand.astro +11 -0
  29. package/src/components/icons/Next.astro +11 -0
  30. package/src/components/icons/Pause.astro +11 -0
  31. package/src/components/icons/Play.astro +11 -0
  32. package/src/components/icons/Prev.astro +11 -0
  33. package/src/components/icons/Replay.astro +11 -0
  34. package/src/env.d.ts +15 -0
  35. package/src/lib/entries.ts +72 -0
  36. package/src/lib/icons.ts +15 -0
  37. package/src/scripts/show-more.ts +46 -0
  38. package/src/starlight/Footer.astro +16 -0
  39. package/src/starlight/SiteTitle.astro +34 -0
  40. package/src/starlight/SocialIcons.astro +18 -0
  41. package/src/starlight/ThemeSelect.astro +42 -0
  42. package/src/starlight/index.ts +103 -0
  43. package/src/styles/chrome.css +8 -0
  44. package/src/styles/document.css +72 -0
  45. package/src/styles/footer.css +124 -0
  46. package/src/styles/landing.css +55 -0
  47. package/src/styles/mermaid.css +75 -0
  48. package/src/styles/starlight.css +162 -0
@@ -0,0 +1,155 @@
1
+ ---
2
+ /**
3
+ * Artifact document for rxova.org's non-Starlight pages: metadata and assets only, no header,
4
+ * footer, analytics or theme bootstrap. rxova-website supplies the public shell at deploy time.
5
+ */
6
+ import '@rxova/brand/fonts.css'
7
+ import '../styles/document.css'
8
+
9
+ import { canonicalUrl, siteUrl } from '@rxova/brand'
10
+
11
+ interface Props {
12
+ title: string
13
+ description: string
14
+ /** Canonical path, e.g. `/blog/why-rxova-has-a-blog`. Normalised below. */
15
+ path: string
16
+ ogType?: 'website' | 'article'
17
+ /** Absolute URL of the social card, chosen by the caller; defaults to the umbrella card. */
18
+ image?: string
19
+ /** Advertises an RSS feed for this surface, as `rel="alternate"`. */
20
+ feed?: { href: string; title: string }
21
+ /** JSON-LD for this page, emitted verbatim as `application/ld+json`. */
22
+ jsonLd?: unknown
23
+ }
24
+
25
+ const { title, description, path, ogType = 'website', image, feed, jsonLd } = Astro.props
26
+
27
+ // Normalised here so no caller can declare a canonical URL without the trailing slash (a 301).
28
+ const canonical = canonicalUrl(path)
29
+
30
+ const ogImage = image ?? siteUrl('/og/rxova.png')
31
+
32
+ /** Serialise JSON-LD for an inline `<script>`; `<` is escaped so a `</script>` cannot close it. */
33
+ const serialiseJsonLd = (value: unknown): string => JSON.stringify(value).replace(/</g, '\\u003c')
34
+ ---
35
+
36
+ <!doctype html>
37
+ <html lang="en">
38
+ <head>
39
+ <meta charset="utf-8" />
40
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
41
+ <link rel="canonical" href={canonical} />
42
+ <title>{title}</title>
43
+ <meta name="description" content={description} />
44
+ <meta property="og:title" content={title} />
45
+ <meta property="og:description" content={description} />
46
+ <meta property="og:type" content={ogType} />
47
+ <meta property="og:url" content={canonical} />
48
+ <meta property="og:image" content={ogImage} />
49
+ <meta name="twitter:card" content="summary_large_image" />
50
+ {feed && (
51
+ <link rel="alternate" type="application/rss+xml" title={feed.title} href={feed.href} />
52
+ )}
53
+ {jsonLd && (
54
+ <script type="application/ld+json" is:inline set:html={serialiseJsonLd(jsonLd)}></script>
55
+ )}
56
+ </head>
57
+ <body>
58
+ <main>
59
+ <slot />
60
+ </main>
61
+
62
+ <style>
63
+ main {
64
+ max-width: var(--rx-max-wide);
65
+ margin: 0 auto;
66
+ padding: clamp(2rem, 6vh, 3.5rem) 1.5rem 4rem;
67
+ }
68
+ </style>
69
+
70
+ <!-- Prose styling for rendered markdown. Global because <Content /> markup carries no Astro
71
+ scoping attributes. -->
72
+ <style is:global>
73
+ .prose {
74
+ color: var(--rx-muted);
75
+ line-height: 1.7;
76
+ }
77
+ .prose > * + * {
78
+ margin-top: 1.1rem;
79
+ }
80
+ .prose h2 {
81
+ color: var(--rx-fg);
82
+ font-size: 1.25rem;
83
+ font-weight: 640;
84
+ letter-spacing: -0.01em;
85
+ margin-top: 2.5rem;
86
+ }
87
+ .prose h3 {
88
+ color: var(--rx-fg);
89
+ font-size: 1.05rem;
90
+ font-weight: 620;
91
+ margin-top: 2rem;
92
+ }
93
+ .prose a {
94
+ color: var(--rx-fg);
95
+ text-decoration: underline;
96
+ text-underline-offset: 2px;
97
+ }
98
+ .prose strong {
99
+ color: var(--rx-fg);
100
+ font-weight: 620;
101
+ }
102
+ .prose ul,
103
+ .prose ol {
104
+ margin-left: 1.2rem;
105
+ }
106
+ .prose li + li {
107
+ margin-top: 0.35rem;
108
+ }
109
+ .prose code {
110
+ font-family: var(--rx-font-mono);
111
+ font-size: 0.88em;
112
+ background: var(--rx-tag-bg);
113
+ padding: 0.05rem 0.35rem;
114
+ border-radius: 4px;
115
+ }
116
+ .prose pre {
117
+ background: var(--rx-card);
118
+ border: 1px solid var(--rx-rule);
119
+ border-radius: 10px;
120
+ padding: 1rem 1.1rem;
121
+ /* Long lines scroll inside the block; the page itself never does. */
122
+ overflow-x: auto;
123
+ }
124
+ .prose pre code {
125
+ background: none;
126
+ padding: 0;
127
+ }
128
+ .prose blockquote {
129
+ border-left: 2px solid var(--rx-rule);
130
+ padding-left: 1rem;
131
+ color: var(--rx-faint);
132
+ }
133
+ .prose img {
134
+ max-width: 100%;
135
+ height: auto;
136
+ border-radius: 10px;
137
+ }
138
+ .prose table {
139
+ width: 100%;
140
+ border-collapse: collapse;
141
+ font-size: 0.95rem;
142
+ }
143
+ .prose th,
144
+ .prose td {
145
+ border-bottom: 1px solid var(--rx-rule);
146
+ padding: 0.5rem 0.6rem;
147
+ text-align: left;
148
+ }
149
+ .prose th {
150
+ color: var(--rx-fg);
151
+ font-weight: 620;
152
+ }
153
+ </style>
154
+ </body>
155
+ </html>
@@ -0,0 +1,118 @@
1
+ ---
2
+ /**
3
+ * Per-package bundle budgets as a real table: right-aligned tabular figures are the shape that
4
+ * supports comparing against whatever the reader ships today.
5
+ */
6
+ export interface SizeRow {
7
+ pkg: string
8
+ entry: string
9
+ limitKb: number
10
+ }
11
+
12
+ interface Props {
13
+ rows: readonly SizeRow[]
14
+ /** The column heading: "brotli", "gzip". */
15
+ compression: string
16
+ caption: string
17
+ }
18
+
19
+ const { rows, compression, caption } = Astro.props
20
+ ---
21
+
22
+ {/* Focusable and labelled: the box scrolls sideways on a narrow viewport, and a scrollable region needs a tab stop. */}
23
+ <div class="rx-sizes" tabindex="0" role="region" aria-label="Bundle size budgets">
24
+ <table class="rx-sizes__table">
25
+ <caption class="rx-sizes__caption">{caption}</caption>
26
+ <thead>
27
+ <tr>
28
+ <th scope="col">Package</th>
29
+ <th scope="col">You import</th>
30
+ <th scope="col" class="rx-sizes__num">
31
+ {compression}
32
+ </th>
33
+ </tr>
34
+ </thead>
35
+ <tbody>
36
+ {rows.map((row) => (
37
+ <tr>
38
+ <th scope="row" class="rx-sizes__pkg">
39
+ {row.pkg}
40
+ </th>
41
+ <td>
42
+ <code>{row.entry}</code>
43
+ </td>
44
+ <td class="rx-sizes__num">≤ {row.limitKb} kB</td>
45
+ </tr>
46
+ ))}
47
+ </tbody>
48
+ </table>
49
+ </div>
50
+
51
+ <style>
52
+ .rx-sizes {
53
+ overflow-x: auto;
54
+ border: 1px solid var(--rx-rule);
55
+ border-radius: var(--rx-radius);
56
+ }
57
+
58
+ .rx-sizes__table {
59
+ width: 100%;
60
+ border-collapse: collapse;
61
+ font-size: 0.9rem;
62
+ }
63
+
64
+ .rx-sizes__caption {
65
+ padding: 1rem 1.25rem;
66
+ /* --rx-muted, not --rx-faint: faint on the card is ~3.4:1 and fails AA here. */
67
+ color: var(--rx-muted);
68
+ font-size: 0.82rem;
69
+ line-height: 1.5;
70
+ text-align: start;
71
+ caption-side: bottom;
72
+ border-top: 1px solid var(--rx-rule);
73
+ }
74
+
75
+ .rx-sizes__table th,
76
+ .rx-sizes__table td {
77
+ padding: 0.85rem 1.25rem;
78
+ text-align: start;
79
+ border-bottom: 1px solid var(--rx-rule);
80
+ }
81
+
82
+ .rx-sizes__table thead th {
83
+ background: var(--rx-card);
84
+ color: var(--rx-muted);
85
+ font-size: 0.75rem;
86
+ font-weight: 700;
87
+ letter-spacing: 0.06em;
88
+ text-transform: uppercase;
89
+ white-space: nowrap;
90
+ }
91
+
92
+ .rx-sizes__table tbody tr:last-child th,
93
+ .rx-sizes__table tbody tr:last-child td {
94
+ border-bottom: 0;
95
+ }
96
+
97
+ .rx-sizes__pkg {
98
+ color: var(--rx-fg);
99
+ font-family: var(--rx-font-mono);
100
+ font-size: 0.84rem;
101
+ font-weight: 500;
102
+ white-space: nowrap;
103
+ }
104
+
105
+ .rx-sizes__table code {
106
+ color: var(--rx-muted);
107
+ font-family: var(--rx-font-mono);
108
+ font-size: 0.84rem;
109
+ white-space: nowrap;
110
+ }
111
+
112
+ .rx-sizes__num {
113
+ text-align: end;
114
+ color: var(--rx-fg);
115
+ font-variant-numeric: tabular-nums;
116
+ white-space: nowrap;
117
+ }
118
+ </style>
@@ -0,0 +1,31 @@
1
+ ---
2
+ /**
3
+ * The pre-paint theme script for non-Starlight surfaces; goes in `<head>`. It reads Starlight's
4
+ * `starlight-theme` key so the choice carries across the origin; no saved choice => CSS default.
5
+ */
6
+ ---
7
+
8
+ <script is:inline>
9
+ ;(function () {
10
+ function stored() {
11
+ try {
12
+ const t = localStorage.getItem('starlight-theme')
13
+ return t === 'light' || t === 'dark' ? t : null
14
+ } catch {
15
+ /* localStorage may be unavailable */
16
+ return null
17
+ }
18
+ }
19
+ function sync() {
20
+ const t = stored()
21
+ if (t) document.documentElement.setAttribute('data-theme', t)
22
+ else document.documentElement.removeAttribute('data-theme')
23
+ }
24
+ sync()
25
+ // Back from a docs site restores this page from the bfcache without rerunning the script;
26
+ // `pageshow` is the only notification, so re-sync the theme there.
27
+ window.addEventListener('pageshow', function (e) {
28
+ if (e.persisted) sync()
29
+ })
30
+ })()
31
+ </script>
@@ -0,0 +1,163 @@
1
+ ---
2
+ /**
3
+ * The light/dark toggle for non-Starlight surfaces. Pairs with ThemeScript.astro in <head>, which
4
+ * avoids the flash; this only handles clicks and keeps the icon honest.
5
+ */
6
+
7
+ interface Props {
8
+ /** Pin the button to the viewport's top-right corner; `false` when it sits in a header. */
9
+ floating?: boolean
10
+ }
11
+
12
+ const { floating = true } = Astro.props
13
+ ---
14
+
15
+ <button
16
+ id="theme-toggle"
17
+ class:list={['theme-toggle', { 'theme-toggle--floating': floating }]}
18
+ type="button"
19
+ aria-label="Toggle theme"
20
+ >
21
+ <span class="icon" aria-hidden="true">
22
+ <svg
23
+ xmlns="http://www.w3.org/2000/svg"
24
+ viewBox="0 0 24 24"
25
+ width="24"
26
+ height="24"
27
+ fill="none"
28
+ stroke="currentColor"
29
+ stroke-width="2"
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ >
33
+ <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
34
+ </svg>
35
+ </span>
36
+ </button>
37
+
38
+ <style>
39
+ /* Quiet by default: no border, no fill, the same muted ink as the nav links beside it. */
40
+ .theme-toggle {
41
+ flex: none;
42
+ width: 2rem;
43
+ height: 2rem;
44
+ display: grid;
45
+ place-items: center;
46
+ border: 1px solid transparent;
47
+ border-radius: 8px;
48
+ background: none;
49
+ color: var(--rx-muted);
50
+ cursor: pointer;
51
+ transition:
52
+ color 0.15s ease,
53
+ border-color 0.15s ease,
54
+ background-color 0.2s ease;
55
+ }
56
+
57
+ /* Floating over arbitrary content, it keeps the border and fill so it still reads as a button. */
58
+ .theme-toggle--floating {
59
+ position: fixed;
60
+ top: 1rem;
61
+ right: 1rem;
62
+ /* Above SiteShell's sticky header (z-index 10), so the fixed button stays reachable. */
63
+ z-index: 20;
64
+ width: 2.25rem;
65
+ height: 2.25rem;
66
+ border-color: var(--rx-rule);
67
+ background: var(--rx-card);
68
+ color: var(--rx-fg);
69
+ }
70
+
71
+ .theme-toggle .icon {
72
+ display: grid;
73
+ place-items: center;
74
+ }
75
+
76
+ /* `:global` because the script swaps the icon via innerHTML, which carries no Astro scoping
77
+ attributes. */
78
+ .theme-toggle :global(svg) {
79
+ width: 1.05rem;
80
+ height: 1.05rem;
81
+ display: block;
82
+ stroke-width: 1.6;
83
+ }
84
+
85
+ .theme-toggle:hover {
86
+ color: var(--rx-fg);
87
+ }
88
+
89
+ .theme-toggle--floating:hover {
90
+ border-color: var(--rx-faint);
91
+ }
92
+
93
+ .theme-toggle:focus-visible {
94
+ outline: 2px solid var(--rx-fg);
95
+ outline-offset: 2px;
96
+ }
97
+ </style>
98
+
99
+ <script is:inline>
100
+ ;(function () {
101
+ const root = document.documentElement
102
+ const btn = document.getElementById('theme-toggle')
103
+ const glyph = btn.querySelector('.icon')
104
+ const media = window.matchMedia('(prefers-color-scheme: dark)')
105
+
106
+ // Lucide icons (ISC licensed).
107
+ const ICON_MOON =
108
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>'
109
+ const ICON_SUN =
110
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>'
111
+
112
+ function current() {
113
+ return root.getAttribute('data-theme') || (media.matches ? 'dark' : 'light')
114
+ }
115
+ function stored() {
116
+ try {
117
+ const t = localStorage.getItem('starlight-theme')
118
+ return t === 'light' || t === 'dark' ? t : null
119
+ } catch {
120
+ /* localStorage may be unavailable */
121
+ return null
122
+ }
123
+ }
124
+ // Re-read the saved choice and reflect it in the DOM. Same job as the
125
+ // pre-paint script in <head>, minus the write.
126
+ function sync() {
127
+ const t = stored()
128
+ if (t) root.setAttribute('data-theme', t)
129
+ else root.removeAttribute('data-theme')
130
+ render()
131
+ }
132
+ function render() {
133
+ const dark = current() === 'dark'
134
+ // Show the icon of the theme you'd switch TO.
135
+ glyph.innerHTML = dark ? ICON_SUN : ICON_MOON
136
+ btn.setAttribute('aria-label', dark ? 'Switch to light theme' : 'Switch to dark theme')
137
+ }
138
+ function apply(t) {
139
+ root.setAttribute('data-theme', t)
140
+ try {
141
+ // Starlight's key — see the pre-paint script in <head>.
142
+ localStorage.setItem('starlight-theme', t)
143
+ } catch {
144
+ /* localStorage may be unavailable */
145
+ }
146
+ render()
147
+ }
148
+
149
+ btn.addEventListener('click', function () {
150
+ apply(current() === 'dark' ? 'light' : 'dark')
151
+ })
152
+ // Track the OS preference while the user hasn't overridden it.
153
+ media.addEventListener('change', function () {
154
+ if (!root.getAttribute('data-theme')) render()
155
+ })
156
+ // Back from a docs site restores this page from the bfcache without rerunning any script;
157
+ // `pageshow` is the only notification, so re-sync the theme there.
158
+ window.addEventListener('pageshow', function (e) {
159
+ if (e.persisted) sync()
160
+ })
161
+ render()
162
+ })()
163
+ </script>
@@ -0,0 +1,116 @@
1
+ ---
2
+ /**
3
+ * A grid of claims in the landing's language: a gradient hairline over each, a faint-ink Lucide
4
+ * icon beside the title, the body hanging under it. `icon` is a `lucide-static` name, inlined at build time.
5
+ */
6
+ import { lucideGlyph } from '../lib/icons.ts'
7
+
8
+ export interface ValueItem {
9
+ title: string
10
+ /** Set as HTML, so it may carry inline `<code>`. */
11
+ body: string
12
+ icon: string
13
+ }
14
+
15
+ interface Props {
16
+ items: readonly ValueItem[]
17
+ }
18
+
19
+ const { items } = Astro.props
20
+ ---
21
+
22
+ <ul class="rx-vg">
23
+ {items.map((item) => (
24
+ <li class="rx-vg__item">
25
+ <svg
26
+ class="rx-vg__icon"
27
+ viewBox="0 0 24 24"
28
+ fill="none"
29
+ stroke="currentColor"
30
+ stroke-width="1.5"
31
+ stroke-linecap="round"
32
+ stroke-linejoin="round"
33
+ aria-hidden="true"
34
+ set:html={lucideGlyph(item.icon)}
35
+ />
36
+ <h3 class="rx-vg__title">{item.title}</h3>
37
+ <p class="rx-vg__body" set:html={item.body} />
38
+ </li>
39
+ ))}
40
+ </ul>
41
+
42
+ <style>
43
+ .rx-vg {
44
+ display: grid;
45
+ gap: 2rem 2.5rem;
46
+ margin: 0;
47
+ padding: 0;
48
+ list-style: none;
49
+ grid-template-columns: 1fr;
50
+ }
51
+
52
+ /* Explicit counts: auto-fit lands on four at the wide measure and leaves a half-empty last row. */
53
+ @media (min-width: 38rem) {
54
+ .rx-vg {
55
+ grid-template-columns: repeat(2, 1fr);
56
+ }
57
+ }
58
+
59
+ @media (min-width: 60rem) {
60
+ .rx-vg {
61
+ grid-template-columns: repeat(3, 1fr);
62
+ }
63
+ }
64
+
65
+ /* Icon beside the title, body under the title; 2px of the gradient over each binds them into one set. */
66
+ .rx-vg__item {
67
+ display: grid;
68
+ grid-template-columns: auto minmax(0, 1fr);
69
+ column-gap: 0.7rem;
70
+ row-gap: 0.4rem;
71
+ align-content: start;
72
+ padding-top: 1rem;
73
+ border-top: 2px solid transparent;
74
+ border-image: var(--rx-gradient) 1;
75
+ border-image-width: 2px 0 0 0;
76
+ }
77
+
78
+ .rx-vg__icon {
79
+ grid-column: 1;
80
+ grid-row: 1;
81
+ width: 1.375rem;
82
+ height: 1.375rem;
83
+ align-self: center;
84
+ color: var(--rx-faint);
85
+ }
86
+
87
+ .rx-vg__title {
88
+ grid-column: 2;
89
+ grid-row: 1;
90
+ margin: 0;
91
+ color: var(--rx-fg);
92
+ font-size: 1.05rem;
93
+ font-weight: 620;
94
+ line-height: 1.3;
95
+ letter-spacing: -0.015em;
96
+ text-wrap: balance;
97
+ }
98
+
99
+ .rx-vg__body {
100
+ grid-column: 2;
101
+ grid-row: 2;
102
+ margin: 0;
103
+ color: var(--rx-muted);
104
+ font-size: 0.95rem;
105
+ line-height: 1.55;
106
+ text-wrap: pretty;
107
+ }
108
+
109
+ .rx-vg__body :global(code) {
110
+ padding: 0.1em 0.35em;
111
+ background: var(--rx-tag-bg);
112
+ border-radius: var(--rx-radius-sm);
113
+ font-family: var(--rx-font-mono);
114
+ font-size: 0.86em;
115
+ }
116
+ </style>
@@ -0,0 +1,23 @@
1
+ ---
2
+ /** Text only screen readers get; unlike `display: none`, it stays in the accessibility tree. */
3
+ import type { HTMLAttributes } from 'astro/types'
4
+
5
+ type Props = HTMLAttributes<'span'>
6
+
7
+ const { class: className, ...rest } = Astro.props
8
+ ---
9
+
10
+ <span class:list={['visually-hidden', className]} {...rest}>
11
+ <slot />
12
+ </span>
13
+
14
+ <style>
15
+ .visually-hidden {
16
+ position: absolute;
17
+ width: 1px;
18
+ height: 1px;
19
+ overflow: hidden;
20
+ clip-path: inset(50%);
21
+ white-space: nowrap;
22
+ }
23
+ </style>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** Four corners pointing in. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M6 2.75V6H2.75M13.25 6H10V2.75M10 13.25V10h3.25M2.75 10H6v3.25"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** Four corners pointing out. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M2.75 6V2.75H6M10 2.75h3.25V6M13.25 10v3.25H10M6 13.25H2.75V10"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** A right chevron. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M6 3.5 10.5 8 6 12.5"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** Two bars. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M5.25 3.5v9M10.75 3.5v9"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** A solid triangle. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props} solid>
10
+ <path d="M5 3.2v9.6L12.6 8z"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** A left chevron. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M10 3.5 5.5 8l4.5 4.5"></path>
11
+ </Icon>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Icon from '../Icon.astro'
4
+
5
+ /** An arrow turning back to its start. */
6
+ type Props = Omit<ComponentProps<typeof Icon>, 'solid'>
7
+ ---
8
+
9
+ <Icon {...Astro.props}>
10
+ <path d="M3.2 8a4.8 4.8 0 1 0 1.4-3.4M4.2 2.4v2.8H7"></path>
11
+ </Icon>