@astronox/core 0.2.3 → 0.3.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.
- package/README.md +16 -1
- package/package.json +18 -4
- package/src/admin/authController.ts +166 -0
- package/src/admin/cache.ts +44 -17
- package/src/admin/index.ts +3 -0
- package/src/admin/preparedDestination.ts +114 -0
- package/src/admin/resourceClient.ts +107 -0
- package/src/ads/adsense/index.ts +1 -0
- package/src/ads/adsense.ts +112 -0
- package/src/ads/contracts.ts +11 -0
- package/src/ads/index.ts +2 -0
- package/src/ads/slot.ts +16 -0
- package/src/auth/contracts.ts +1 -4
- package/src/auth/firebase/client.ts +19 -6
- package/src/auth/firebase/index.ts +1 -0
- package/src/client/formSubmission.ts +6 -1
- package/src/client/preferences.ts +8 -4
- package/src/components/actions/Button/Button.astro +30 -42
- package/src/components/actions/Button/Button.css +1 -1
- package/src/components/actions/CardAction/CardAction.css +8 -13
- package/src/components/actions/IdentityProviderAction/IdentityProviderAction.astro +6 -8
- package/src/components/actions/MediaTrigger/MediaTrigger.astro +1 -1
- package/src/components/actions/ScrollToTop/ScrollToTop.astro +2 -1
- package/src/components/actions/ScrollToTop/ScrollToTop.css +2 -6
- package/src/components/actions/ThemeToggle/ThemeToggle.astro +59 -0
- package/src/components/actions/ThemeToggle/ThemeToggle.css +83 -0
- package/src/components/actions/ThemeToggle/themeToggleController.ts +110 -0
- package/src/components/content/CardFooter/CardFooter.css +2 -4
- package/src/components/content/CardHeader/CardHeader.astro +1 -4
- package/src/components/content/CardLink/CardLink.astro +3 -15
- package/src/components/content/CardLink/CardLink.css +4 -15
- package/src/components/content/CodeBlock/CodeBlock.astro +7 -6
- package/src/components/content/CodeBlock/CodeBlock.css +2 -5
- package/src/components/content/CodeBlock/codeBlockController.ts +1 -2
- package/src/components/content/MarkdownContent/MarkdownContent.astro +1 -3
- package/src/components/content/MarkdownContent/MarkdownContent.css +7 -2
- package/src/components/content/MarkdownContent/MarkdownInline.astro +11 -3
- package/src/components/content/MarkdownContent/MarkdownNode.astro +28 -33
- package/src/components/content/MarkdownContent/MarkdownSymbol.astro +30 -19
- package/src/components/content/MarkdownContent/contracts.ts +15 -15
- package/src/components/content/MarkdownContent/markdownContentRenderer.ts +27 -83
- package/src/components/feedback/PreferenceBootstrap/PreferenceBootstrap.astro +19 -22
- package/src/components/feedback/Spinner/Spinner.astro +1 -2
- package/src/components/feedback/ThemeBootstrap/ThemeBootstrap.astro +31 -0
- package/src/components/feedback/Tooltip/tooltipController.ts +1 -4
- package/src/components/forms/ChoiceGroup/ChoiceGroup.css +2 -5
- package/src/components/forms/DateTimeInput/DateTimeInput.astro +2 -1
- package/src/components/forms/PreparedFormBootstrap/PreparedFormBootstrap.astro +10 -8
- package/src/components/forms/PreparedFormBootstrap/parsePreparedFormState.ts +48 -0
- package/src/components/forms/Textarea/Textarea.astro +2 -2
- package/src/components/icons/BurnIcon.astro +2 -1
- package/src/components/icons/CircleSymbolIcon.css +3 -3
- package/src/components/icons/FieldIcon.astro +10 -4
- package/src/components/icons/GrassIcon.astro +3 -2
- package/src/components/icons/SlowIcon.astro +1 -2
- package/src/components/icons/StunIcon.astro +2 -1
- package/src/components/icons/WaterIcon.astro +3 -2
- package/src/components/index.ts +4 -0
- package/src/components/media/CanvasFrame/CanvasFrame.astro +1 -2
- package/src/components/media/CanvasFrame/canvasFrameController.ts +1 -4
- package/src/components/media/EmbedFrame/EmbedFrame.astro +5 -12
- package/src/components/media/EmbedFrame/embedFrameController.ts +4 -4
- package/src/components/monetization/AdSlot/AdSlot.astro +33 -0
- package/src/components/monetization/AdSlot/AdSlot.css +53 -0
- package/src/components/navigation/DesktopNavigation.css +5 -3
- package/src/components/navigation/Footer/Footer.css +3 -9
- package/src/components/navigation/Header.astro +20 -2
- package/src/components/navigation/MobileNavigation.astro +107 -43
- package/src/components/navigation/MobileNavigation.css +102 -26
- package/src/components/navigation/NavigationBrand.css +1 -1
- package/src/components/navigation/NavigationControl.css +16 -2
- package/src/components/navigation/NavigationItemContent.astro +6 -1
- package/src/components/navigation/mobileNavigationController.ts +0 -16
- package/src/components/navigation/navigationTypes.ts +6 -1
- package/src/components/seo/SeoHead.astro +1 -6
- package/src/composition/SurfaceGroup/SurfaceGroup.css +4 -14
- package/src/config/environment.ts +52 -0
- package/src/config/index.ts +3 -0
- package/src/config/integrations.ts +9 -0
- package/src/config/siteConfig.ts +5 -0
- package/src/config/storage.ts +16 -0
- package/src/content/admin.ts +354 -0
- package/src/content/cache.ts +177 -0
- package/src/content/catalog.ts +72 -0
- package/src/content/contracts.ts +77 -0
- package/src/content/drafts.ts +49 -0
- package/src/content/index.ts +7 -0
- package/src/content/markdown.ts +146 -0
- package/src/content/snapshot.ts +139 -0
- package/src/data/firestore/client/contracts.ts +10 -2
- package/src/data/index.ts +1 -0
- package/src/data/memoizedLoader.ts +13 -0
- package/src/display/contracts.ts +2 -5
- package/src/i18n/config.ts +2 -8
- package/src/i18n/coreMessages.ts +2 -9
- package/src/i18n/preference.ts +2 -6
- package/src/layouts/BaseLayout.astro +5 -0
- package/src/patterns/Combobox/Combobox.astro +9 -12
- package/src/patterns/Combobox/comboboxController.ts +14 -8
- package/src/patterns/Fullscreen/FullscreenControl.astro +5 -1
- package/src/patterns/Fullscreen/fullscreenController.ts +1 -3
- package/src/patterns/MapViewport/MapViewport.css +3 -3
- package/src/patterns/MapViewport/geometry.ts +1 -4
- package/src/patterns/Modal/Modal.css +1 -4
- package/src/patterns/Modal/ModalOpen.astro +5 -1
- package/src/patterns/Table/Table.astro +10 -10
- package/src/patterns/Table/TableBody.astro +1 -4
- package/src/patterns/Table/TableBody.css +2 -4
- package/src/patterns/Table/TablePagination.astro +23 -30
- package/src/patterns/Table/TableSkeleton.astro +1 -5
- package/src/patterns/Table/tableClientController.ts +2 -2
- package/src/patterns/Table/tableFilterController.ts +1 -3
- package/src/patterns/Table/tableHeaderOverflowController.ts +1 -4
- package/src/patterns/Table/tableProgressiveController.ts +62 -60
- package/src/patterns/Table/tableScrollController.ts +3 -2
- package/src/primitives/text/TextBlock/TextBlock.astro +1 -3
- package/src/publication/contracts.ts +11 -0
- package/src/publication/http.ts +31 -0
- package/src/publication/index.ts +2 -0
- package/src/routing/localized.ts +9 -12
- package/src/seo/localizedMeta.ts +2 -6
- package/src/styles/interaction.css +7 -7
- package/src/styles/style.css +12 -20
- package/src/styles/tokens.css +55 -15
- package/src/theme/contracts.ts +3 -6
- package/src/theme/index.ts +1 -0
- package/src/theme/storage.ts +1 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { ColorTheme } from '../../../theme/contracts';
|
|
2
|
+
import { defaultThemeStorageKey } from '../../../theme/storage';
|
|
3
|
+
|
|
4
|
+
const initializedToggles = new WeakSet<HTMLElement>();
|
|
5
|
+
const systemThemeQuery = '(prefers-color-scheme: dark)';
|
|
6
|
+
let globalListenersInitialized = false;
|
|
7
|
+
|
|
8
|
+
function isColorTheme(value: string | null): value is ColorTheme {
|
|
9
|
+
return value === 'light' || value === 'dark';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getStorageKey(): string {
|
|
13
|
+
return (
|
|
14
|
+
document.documentElement.dataset.themeStorageKey ?? defaultThemeStorageKey
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function readStoredTheme(): ColorTheme | null {
|
|
19
|
+
try {
|
|
20
|
+
const value = window.localStorage.getItem(getStorageKey());
|
|
21
|
+
return isColorTheme(value) ? value : null;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getSystemTheme(): ColorTheme {
|
|
28
|
+
return window.matchMedia(systemThemeQuery).matches ? 'dark' : 'light';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getCurrentTheme(): ColorTheme {
|
|
32
|
+
const value = document.documentElement.dataset.theme ?? null;
|
|
33
|
+
return isColorTheme(value) ? value : (readStoredTheme() ?? getSystemTheme());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function updateToggle(toggle: HTMLElement, theme: ColorTheme): void {
|
|
37
|
+
const label =
|
|
38
|
+
theme === 'light'
|
|
39
|
+
? toggle.dataset.themeToggleDarkLabel
|
|
40
|
+
: toggle.dataset.themeToggleLightLabel;
|
|
41
|
+
|
|
42
|
+
if (label) {
|
|
43
|
+
toggle.setAttribute('aria-label', label);
|
|
44
|
+
toggle.setAttribute('title', label);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function updateToggles(theme: ColorTheme): void {
|
|
49
|
+
for (const toggle of document.querySelectorAll<HTMLElement>(
|
|
50
|
+
'[data-theme-toggle]',
|
|
51
|
+
)) {
|
|
52
|
+
updateToggle(toggle, theme);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function applyTheme(theme: ColorTheme, persist: boolean): void {
|
|
57
|
+
document.documentElement.dataset.theme = theme;
|
|
58
|
+
|
|
59
|
+
if (persist) {
|
|
60
|
+
try {
|
|
61
|
+
window.localStorage.setItem(getStorageKey(), theme);
|
|
62
|
+
} catch {
|
|
63
|
+
// The selected theme remains active for the current document.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
updateToggles(theme);
|
|
68
|
+
document.dispatchEvent(
|
|
69
|
+
new CustomEvent('astronox:theme-change', { detail: { theme } }),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function initializeGlobalListeners(): void {
|
|
74
|
+
if (globalListenersInitialized) return;
|
|
75
|
+
globalListenersInitialized = true;
|
|
76
|
+
|
|
77
|
+
const media = window.matchMedia(systemThemeQuery);
|
|
78
|
+
media.addEventListener('change', (event) => {
|
|
79
|
+
if (readStoredTheme() === null) {
|
|
80
|
+
applyTheme(event.matches ? 'dark' : 'light', false);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
window.addEventListener('storage', (event) => {
|
|
85
|
+
if (event.key !== getStorageKey()) return;
|
|
86
|
+
|
|
87
|
+
const theme = isColorTheme(event.newValue)
|
|
88
|
+
? event.newValue
|
|
89
|
+
: getSystemTheme();
|
|
90
|
+
applyTheme(theme, false);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function initThemeToggle(toggle: HTMLElement): () => void {
|
|
95
|
+
if (initializedToggles.has(toggle)) return () => {};
|
|
96
|
+
initializedToggles.add(toggle);
|
|
97
|
+
initializeGlobalListeners();
|
|
98
|
+
updateToggle(toggle, getCurrentTheme());
|
|
99
|
+
|
|
100
|
+
const handleClick = (): void => {
|
|
101
|
+
applyTheme(getCurrentTheme() === 'light' ? 'dark' : 'light', true);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
toggle.addEventListener('click', handleClick);
|
|
105
|
+
|
|
106
|
+
return () => {
|
|
107
|
+
toggle.removeEventListener('click', handleClick);
|
|
108
|
+
initializedToggles.delete(toggle);
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -42,16 +42,14 @@
|
|
|
42
42
|
var(--card-footer-size);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
.card-footer[data-has-leading-action][data-has-action]
|
|
46
|
-
.card-footer__layout {
|
|
45
|
+
.card-footer[data-has-leading-action][data-has-action] .card-footer__layout {
|
|
47
46
|
grid-template-columns:
|
|
48
47
|
var(--card-footer-size)
|
|
49
48
|
minmax(0, 1fr)
|
|
50
49
|
var(--card-footer-size);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
.card-footer[data-has-leading-action][data-has-media]
|
|
54
|
-
.card-footer__layout {
|
|
52
|
+
.card-footer[data-has-leading-action][data-has-media] .card-footer__layout {
|
|
55
53
|
grid-template-columns:
|
|
56
54
|
var(--card-footer-size)
|
|
57
55
|
var(--card-footer-size)
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
import type { HTMLAttributes } from 'astro/types';
|
|
3
3
|
import type { Tone } from '../../../theme/contracts';
|
|
4
4
|
import type { DisplayMedia, TextWeight } from '../../../display/contracts';
|
|
5
|
-
import type {
|
|
6
|
-
AstroComponent,
|
|
7
|
-
HeadingLevel,
|
|
8
|
-
} from '../../widgetTypes';
|
|
5
|
+
import type { AstroComponent, HeadingLevel } from '../../widgetTypes';
|
|
9
6
|
import Inline from '../../../composition/Inline/Inline.astro';
|
|
10
7
|
import Media from '../../../primitives/media/Media/Media.astro';
|
|
11
8
|
|
|
@@ -90,11 +90,7 @@ const resolvedTone = tone ?? dataTone;
|
|
|
90
90
|
{Icon ? (
|
|
91
91
|
<Icon class="card-link__icon" data-tone={iconTone} />
|
|
92
92
|
) : media ? (
|
|
93
|
-
<Media
|
|
94
|
-
media={media}
|
|
95
|
-
fit="contain"
|
|
96
|
-
size="intrinsic"
|
|
97
|
-
/>
|
|
93
|
+
<Media media={media} fit="contain" size="intrinsic" />
|
|
98
94
|
) : null}
|
|
99
95
|
</span>
|
|
100
96
|
) : null
|
|
@@ -104,11 +100,7 @@ const resolvedTone = tone ?? dataTone;
|
|
|
104
100
|
{
|
|
105
101
|
hasContentMedia && media ? (
|
|
106
102
|
<span class="card-link__content-media" aria-hidden="true">
|
|
107
|
-
<Media
|
|
108
|
-
media={media}
|
|
109
|
-
fit="contain"
|
|
110
|
-
size="intrinsic"
|
|
111
|
-
/>
|
|
103
|
+
<Media media={media} fit="contain" size="intrinsic" />
|
|
112
104
|
</span>
|
|
113
105
|
) : null
|
|
114
106
|
}
|
|
@@ -134,11 +126,7 @@ const resolvedTone = tone ?? dataTone;
|
|
|
134
126
|
{Icon ? (
|
|
135
127
|
<Icon class="card-link__icon" data-tone={iconTone} />
|
|
136
128
|
) : media ? (
|
|
137
|
-
<Media
|
|
138
|
-
media={media}
|
|
139
|
-
fit="contain"
|
|
140
|
-
size="intrinsic"
|
|
141
|
-
/>
|
|
129
|
+
<Media media={media} fit="contain" size="intrinsic" />
|
|
142
130
|
) : null}
|
|
143
131
|
</span>
|
|
144
132
|
) : null
|
|
@@ -154,26 +154,17 @@
|
|
|
154
154
|
);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
.card-link:is(
|
|
158
|
-
[data-media-size='compact'],
|
|
159
|
-
[data-media-size='small']
|
|
160
|
-
)
|
|
157
|
+
.card-link:is([data-media-size='compact'], [data-media-size='small'])
|
|
161
158
|
.card-link__layout {
|
|
162
159
|
--card-link-artwork-max-size: var(--card-link-resolved-media-size);
|
|
163
160
|
}
|
|
164
161
|
|
|
165
|
-
.card-link:is(
|
|
166
|
-
[data-media-size='compact'],
|
|
167
|
-
[data-media-size='small']
|
|
168
|
-
)
|
|
162
|
+
.card-link:is([data-media-size='compact'], [data-media-size='small'])
|
|
169
163
|
.card-link__content {
|
|
170
164
|
--card-link-content-media-size: var(--card-link-resolved-media-size);
|
|
171
165
|
}
|
|
172
166
|
|
|
173
|
-
.card-link:is(
|
|
174
|
-
[data-media-size='compact'],
|
|
175
|
-
[data-media-size='small']
|
|
176
|
-
)
|
|
167
|
+
.card-link:is([data-media-size='compact'], [data-media-size='small'])
|
|
177
168
|
:is(.card-link__media, .card-link__content-media)
|
|
178
169
|
[data-widget='media'] {
|
|
179
170
|
--media-object-inline-size: 100%;
|
|
@@ -203,9 +194,7 @@
|
|
|
203
194
|
}
|
|
204
195
|
|
|
205
196
|
.card-link[data-density='relaxed'] .card-link__layout {
|
|
206
|
-
--card-link-size: calc(
|
|
207
|
-
var(--nox-navigation-block-size) + var(--nox-space-5)
|
|
208
|
-
);
|
|
197
|
+
--card-link-size: calc(var(--nox-navigation-block-size) + var(--nox-space-5));
|
|
209
198
|
}
|
|
210
199
|
|
|
211
200
|
.card-link[data-density='relaxed'] .card-link__content {
|
|
@@ -3,10 +3,7 @@ import type { HTMLAttributes } from 'astro/types';
|
|
|
3
3
|
import Button from '../../actions/Button/Button.astro';
|
|
4
4
|
import CopyIcon from '../../icons/CopyIcon.astro';
|
|
5
5
|
import type { Tone } from '../../../theme/contracts';
|
|
6
|
-
import type {
|
|
7
|
-
CodeBlockCopy,
|
|
8
|
-
CodeBlockPresentation,
|
|
9
|
-
} from './contracts';
|
|
6
|
+
import type { CodeBlockCopy, CodeBlockPresentation } from './contracts';
|
|
10
7
|
|
|
11
8
|
type Props = HTMLAttributes<'pre'> & {
|
|
12
9
|
copy?: CodeBlockCopy;
|
|
@@ -42,7 +39,9 @@ const resolvedTone = tone ?? dataTone;
|
|
|
42
39
|
data-code-block-content
|
|
43
40
|
data-code-block-presentation={presentation}
|
|
44
41
|
data-wrap={wrap ? true : undefined}
|
|
45
|
-
>
|
|
42
|
+
>
|
|
43
|
+
{text}
|
|
44
|
+
</pre>
|
|
46
45
|
<Button
|
|
47
46
|
class="code-block__copy"
|
|
48
47
|
type="button"
|
|
@@ -75,7 +74,9 @@ const resolvedTone = tone ?? dataTone;
|
|
|
75
74
|
data-code-block-presentation={presentation}
|
|
76
75
|
data-tone={resolvedTone}
|
|
77
76
|
data-wrap={wrap ? true : undefined}
|
|
78
|
-
>
|
|
77
|
+
>
|
|
78
|
+
{text}
|
|
79
|
+
</pre>
|
|
79
80
|
)
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
--code-block-light-line-height: 1.125rem;
|
|
19
19
|
--code-block-copy-size: calc(
|
|
20
20
|
var(--code-block-light-line-height) + var(--nox-space-3) +
|
|
21
|
-
var(--nox-space-3) + var(--nox-border-width) +
|
|
22
|
-
var(--nox-border-width)
|
|
21
|
+
var(--nox-space-3) + var(--nox-border-width) + var(--nox-border-width)
|
|
23
22
|
);
|
|
24
23
|
|
|
25
24
|
position: relative;
|
|
@@ -30,9 +29,7 @@
|
|
|
30
29
|
.code-block-shell .code-block {
|
|
31
30
|
box-sizing: border-box;
|
|
32
31
|
inline-size: 100%;
|
|
33
|
-
padding-inline-end: calc(
|
|
34
|
-
var(--code-block-copy-size) + var(--nox-space-3)
|
|
35
|
-
);
|
|
32
|
+
padding-inline-end: calc(var(--code-block-copy-size) + var(--nox-space-3));
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
.code-block[data-code-block-presentation='light'] {
|
|
@@ -17,8 +17,7 @@ export function initCodeBlock(root: HTMLElement): () => void {
|
|
|
17
17
|
root.setAttribute(initializedAttribute, 'true');
|
|
18
18
|
const copyLabel = copyButton.dataset.copyLabel ?? '';
|
|
19
19
|
const copiedLabel = copyButton.dataset.copiedLabel ?? copyLabel;
|
|
20
|
-
const unavailableLabel =
|
|
21
|
-
copyButton.dataset.copyUnavailableLabel ?? copyLabel;
|
|
20
|
+
const unavailableLabel = copyButton.dataset.copyUnavailableLabel ?? copyLabel;
|
|
22
21
|
let feedbackTimeout: number | undefined;
|
|
23
22
|
|
|
24
23
|
const setButtonLabel = (label: string): void => {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
-
import type {
|
|
4
|
-
CodeBlockCopy,
|
|
5
|
-
} from '../CodeBlock/contracts';
|
|
3
|
+
import type { CodeBlockCopy } from '../CodeBlock/contracts';
|
|
6
4
|
import MarkdownNode from './MarkdownNode.astro';
|
|
7
5
|
import type { MarkdownDocument } from './contracts';
|
|
8
6
|
|
|
@@ -163,8 +163,7 @@
|
|
|
163
163
|
gap: 0;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
.markdown-content__list-item[data-markdown-resource]
|
|
167
|
-
.markdown-content__list {
|
|
166
|
+
.markdown-content__list-item[data-markdown-resource] .markdown-content__list {
|
|
168
167
|
padding-inline-start: 0;
|
|
169
168
|
list-style: none;
|
|
170
169
|
}
|
|
@@ -268,6 +267,12 @@
|
|
|
268
267
|
block-size: 1em;
|
|
269
268
|
}
|
|
270
269
|
|
|
270
|
+
.markdown-content__symbol-media {
|
|
271
|
+
block-size: 1.5em;
|
|
272
|
+
inline-size: 1.5em;
|
|
273
|
+
object-fit: contain;
|
|
274
|
+
}
|
|
275
|
+
|
|
271
276
|
.markdown-content__symbol[data-markdown-symbol^='terrain-']
|
|
272
277
|
.markdown-content__symbol-icon {
|
|
273
278
|
inline-size: 1.25em;
|
|
@@ -20,10 +20,16 @@ const { node }: Props = Astro.props;
|
|
|
20
20
|
<MarkdownSymbol node={node} />
|
|
21
21
|
) : node.type === 'strong' ? (
|
|
22
22
|
<strong class="markdown-content__strong">
|
|
23
|
-
{node.children.map((child) =>
|
|
23
|
+
{node.children.map((child) => (
|
|
24
|
+
<Astro.self node={child} />
|
|
25
|
+
))}
|
|
24
26
|
</strong>
|
|
25
27
|
) : node.type === 'emphasis' ? (
|
|
26
|
-
<em>
|
|
28
|
+
<em>
|
|
29
|
+
{node.children.map((child) => (
|
|
30
|
+
<Astro.self node={child} />
|
|
31
|
+
))}
|
|
32
|
+
</em>
|
|
27
33
|
) : node.type === 'code' ? (
|
|
28
34
|
<code class="markdown-content__inline-code">{node.value}</code>
|
|
29
35
|
) : node.type === 'link' ? (
|
|
@@ -36,7 +42,9 @@ const { node }: Props = Astro.props;
|
|
|
36
42
|
rel={node.external ? 'noopener noreferrer' : undefined}
|
|
37
43
|
target={node.external ? '_blank' : undefined}
|
|
38
44
|
>
|
|
39
|
-
{node.children.map((child) =>
|
|
45
|
+
{node.children.map((child) => (
|
|
46
|
+
<Astro.self node={child} />
|
|
47
|
+
))}
|
|
40
48
|
</a>
|
|
41
49
|
) : (
|
|
42
50
|
<br />
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import CodeBlock from '../CodeBlock/CodeBlock.astro';
|
|
3
|
-
import type {
|
|
4
|
-
CodeBlockCopy,
|
|
5
|
-
} from '../CodeBlock/contracts';
|
|
3
|
+
import type { CodeBlockCopy } from '../CodeBlock/contracts';
|
|
6
4
|
import Media from '../../../primitives/media/Media/Media.astro';
|
|
7
5
|
import Separator from '../../../primitives/layout/Separator/Separator.astro';
|
|
8
6
|
import type { Tone } from '../../../theme/contracts';
|
|
@@ -26,14 +24,14 @@ function toHeadingTag(
|
|
|
26
24
|
return `h${level}` as 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
const defaultListMarker = {
|
|
27
|
+
const defaultListMarker: MarkdownListMarker = {
|
|
30
28
|
symbol: 'bullet',
|
|
31
29
|
tone: 'neutral',
|
|
32
|
-
}
|
|
33
|
-
const nestedListMarker = {
|
|
30
|
+
};
|
|
31
|
+
const nestedListMarker: MarkdownListMarker = {
|
|
34
32
|
symbol: 'arrow-right',
|
|
35
33
|
tone: 'neutral',
|
|
36
|
-
}
|
|
34
|
+
};
|
|
37
35
|
|
|
38
36
|
const codeBlockTones = new Set<Tone>([
|
|
39
37
|
'neutral',
|
|
@@ -77,10 +75,7 @@ const listItems =
|
|
|
77
75
|
|
|
78
76
|
{
|
|
79
77
|
node.type === 'section' ? (
|
|
80
|
-
<section
|
|
81
|
-
class="markdown-content__section"
|
|
82
|
-
aria-labelledby={node.id}
|
|
83
|
-
>
|
|
78
|
+
<section class="markdown-content__section" aria-labelledby={node.id}>
|
|
84
79
|
<HeadingTag
|
|
85
80
|
class="markdown-content__section-title"
|
|
86
81
|
data-markdown-heading-level={node.level}
|
|
@@ -89,16 +84,16 @@ const listItems =
|
|
|
89
84
|
{node.title}
|
|
90
85
|
</HeadingTag>
|
|
91
86
|
<div class="markdown-content__section-body">
|
|
92
|
-
{
|
|
93
|
-
node
|
|
94
|
-
|
|
95
|
-
))
|
|
96
|
-
}
|
|
87
|
+
{node.blocks.map((block) => (
|
|
88
|
+
<Astro.self node={block} codeBlockCopy={codeBlockCopy} />
|
|
89
|
+
))}
|
|
97
90
|
</div>
|
|
98
91
|
</section>
|
|
99
92
|
) : node.type === 'paragraph' ? (
|
|
100
93
|
<p class="markdown-content__paragraph">
|
|
101
|
-
{node.children.map((child) =>
|
|
94
|
+
{node.children.map((child) => (
|
|
95
|
+
<MarkdownInline node={child} />
|
|
96
|
+
))}
|
|
102
97
|
</p>
|
|
103
98
|
) : node.type === 'heading' ? (
|
|
104
99
|
<HeadingTag
|
|
@@ -106,17 +101,23 @@ const listItems =
|
|
|
106
101
|
data-markdown-heading-level={node.level}
|
|
107
102
|
id={node.id}
|
|
108
103
|
>
|
|
109
|
-
{node.children.map((child) =>
|
|
104
|
+
{node.children.map((child) => (
|
|
105
|
+
<MarkdownInline node={child} />
|
|
106
|
+
))}
|
|
110
107
|
</HeadingTag>
|
|
111
108
|
) : node.type === 'change' ? (
|
|
112
109
|
<div class="markdown-content__change">
|
|
113
110
|
<span class="markdown-content__change-label">
|
|
114
|
-
{node.label.map((child) =>
|
|
111
|
+
{node.label.map((child) => (
|
|
112
|
+
<MarkdownInline node={child} />
|
|
113
|
+
))}
|
|
115
114
|
<span>:</span>
|
|
116
115
|
</span>
|
|
117
116
|
{node.presentation === 'statement' ? (
|
|
118
117
|
<span class="markdown-content__change-values">
|
|
119
|
-
{node.value.map((child) =>
|
|
118
|
+
{node.value.map((child) => (
|
|
119
|
+
<MarkdownInline node={child} />
|
|
120
|
+
))}
|
|
120
121
|
</span>
|
|
121
122
|
) : (
|
|
122
123
|
<span class="markdown-content__change-values" lang={node.valueLang}>
|
|
@@ -187,9 +188,7 @@ const listItems =
|
|
|
187
188
|
media={item.resource.media}
|
|
188
189
|
size="fill"
|
|
189
190
|
upscale={
|
|
190
|
-
item.resource.mediaScale === 'compact'
|
|
191
|
-
? 'prevent'
|
|
192
|
-
: undefined
|
|
191
|
+
item.resource.mediaScale === 'compact' ? 'prevent' : undefined
|
|
193
192
|
}
|
|
194
193
|
/>
|
|
195
194
|
) : null}
|
|
@@ -242,11 +241,9 @@ const listItems =
|
|
|
242
241
|
)}
|
|
243
242
|
</div>
|
|
244
243
|
) : null}
|
|
245
|
-
{
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
))
|
|
249
|
-
}
|
|
244
|
+
{item.children.map((block) => (
|
|
245
|
+
<Astro.self node={block} codeBlockCopy={codeBlockCopy} />
|
|
246
|
+
))}
|
|
250
247
|
</div>
|
|
251
248
|
</li>
|
|
252
249
|
))}
|
|
@@ -256,11 +253,9 @@ const listItems =
|
|
|
256
253
|
class="markdown-content__quote"
|
|
257
254
|
data-tone={node.tone ?? 'neutral'}
|
|
258
255
|
>
|
|
259
|
-
{
|
|
260
|
-
node
|
|
261
|
-
|
|
262
|
-
))
|
|
263
|
-
}
|
|
256
|
+
{node.children.map((block) => (
|
|
257
|
+
<Astro.self node={block} codeBlockCopy={codeBlockCopy} />
|
|
258
|
+
))}
|
|
264
259
|
</blockquote>
|
|
265
260
|
) : node.type === 'separator' ? (
|
|
266
261
|
<Separator bleed emphasis={node.emphasis} />
|
|
@@ -5,29 +5,24 @@ import ArrowRightIcon from '../../icons/ArrowRightIcon.astro';
|
|
|
5
5
|
import ArrowUpIcon from '../../icons/ArrowUpIcon.astro';
|
|
6
6
|
import BulletIcon from '../../icons/BulletIcon.astro';
|
|
7
7
|
import EqualIcon from '../../icons/EqualIcon.astro';
|
|
8
|
-
import
|
|
9
|
-
import GrassIcon from '../../icons/GrassIcon.astro';
|
|
10
|
-
import MountainIcon from '../../icons/MountainIcon.astro';
|
|
11
|
-
import WaterIcon from '../../icons/WaterIcon.astro';
|
|
12
|
-
import type { MarkdownSymbol } from './contracts';
|
|
8
|
+
import type { MarkdownBuiltinSymbolName, MarkdownSymbol } from './contracts';
|
|
13
9
|
|
|
14
10
|
type Props = {
|
|
15
11
|
node: MarkdownSymbol;
|
|
16
12
|
};
|
|
17
13
|
|
|
18
14
|
const { node }: Props = Astro.props;
|
|
19
|
-
const
|
|
15
|
+
const icons = {
|
|
20
16
|
adjustment: ArrowUpDownIcon,
|
|
21
17
|
'arrow-right': ArrowRightIcon,
|
|
22
18
|
bullet: BulletIcon,
|
|
23
19
|
decrease: ArrowDownIcon,
|
|
24
20
|
increase: ArrowUpIcon,
|
|
25
21
|
neutral: EqualIcon,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}[node.name];
|
|
22
|
+
} satisfies Record<MarkdownBuiltinSymbolName, typeof ArrowUpDownIcon>;
|
|
23
|
+
const Icon = node.media ? null : icons[node.name as MarkdownBuiltinSymbolName];
|
|
24
|
+
if (!node.media && !Icon)
|
|
25
|
+
throw new Error(`Unknown Markdown symbol: ${node.name}`);
|
|
31
26
|
---
|
|
32
27
|
|
|
33
28
|
<span
|
|
@@ -36,12 +31,28 @@ const Icon = {
|
|
|
36
31
|
data-tone={node.tone}
|
|
37
32
|
lang={node.lang}
|
|
38
33
|
>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
{
|
|
35
|
+
node.media ? (
|
|
36
|
+
<img
|
|
37
|
+
class="markdown-content__symbol-media"
|
|
38
|
+
src={node.media.src}
|
|
39
|
+
alt={node.media.alt}
|
|
40
|
+
width={node.media.width}
|
|
41
|
+
height={node.media.height}
|
|
42
|
+
loading={node.media.loading ?? 'lazy'}
|
|
43
|
+
decoding={node.media.decoding ?? 'async'}
|
|
44
|
+
/>
|
|
45
|
+
) : Icon ? (
|
|
46
|
+
<Icon class="markdown-content__symbol-icon" />
|
|
47
|
+
) : null
|
|
48
|
+
}
|
|
49
|
+
{
|
|
50
|
+
node.label ? (
|
|
51
|
+
<span class="markdown-content__symbol-label">{node.label}</span>
|
|
52
|
+
) : node.accessibleLabel ? (
|
|
53
|
+
<span class="markdown-content__visually-hidden">
|
|
54
|
+
{node.accessibleLabel}
|
|
55
|
+
</span>
|
|
56
|
+
) : null
|
|
57
|
+
}
|
|
47
58
|
</span>
|
|
@@ -7,27 +7,27 @@ export type MarkdownText = {
|
|
|
7
7
|
value: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export type
|
|
11
|
-
| '
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| 'decrease'
|
|
15
|
-
| 'increase'
|
|
16
|
-
| 'neutral'
|
|
17
|
-
| 'terrain-field'
|
|
18
|
-
| 'terrain-grass'
|
|
19
|
-
| 'terrain-mountain'
|
|
20
|
-
| 'terrain-water';
|
|
21
|
-
|
|
22
|
-
export type MarkdownSymbol = {
|
|
10
|
+
export type MarkdownBuiltinSymbolName =
|
|
11
|
+
'adjustment' | 'arrow-right' | 'bullet' | 'decrease' | 'increase' | 'neutral';
|
|
12
|
+
|
|
13
|
+
type MarkdownSymbolBase = {
|
|
23
14
|
type: 'symbol';
|
|
24
15
|
accessibleLabel?: string;
|
|
25
16
|
lang?: string;
|
|
26
17
|
label?: string;
|
|
27
|
-
name: MarkdownSymbolName;
|
|
28
18
|
tone?: Tone;
|
|
29
19
|
};
|
|
30
20
|
|
|
21
|
+
export type MarkdownSymbol =
|
|
22
|
+
| (MarkdownSymbolBase & {
|
|
23
|
+
media?: never;
|
|
24
|
+
name: MarkdownBuiltinSymbolName;
|
|
25
|
+
})
|
|
26
|
+
| (MarkdownSymbolBase & {
|
|
27
|
+
media: DisplayMedia;
|
|
28
|
+
name: string;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
31
|
export type MarkdownStrong = {
|
|
32
32
|
type: 'strong';
|
|
33
33
|
children: readonly MarkdownInline[];
|
|
@@ -91,7 +91,7 @@ export type MarkdownListMarker = {
|
|
|
91
91
|
lang?: string;
|
|
92
92
|
label?: string;
|
|
93
93
|
symbol: Extract<
|
|
94
|
-
|
|
94
|
+
MarkdownBuiltinSymbolName,
|
|
95
95
|
| 'adjustment'
|
|
96
96
|
| 'arrow-right'
|
|
97
97
|
| 'bullet'
|