@astronox/core 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/CardAction/CardAction.astro +7 -0
- package/src/components/actions/CardAction/CardAction.css +31 -10
- 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 +3 -3
- package/src/components/actions/ThemeToggle/themeToggleController.ts +7 -4
- 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/Tooltip/tooltipController.ts +1 -4
- package/src/components/forms/ChoiceGroup/ChoiceGroup.css +1 -4
- 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/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 +2 -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 +1 -2
- package/src/components/navigation/Footer/Footer.css +3 -9
- package/src/components/navigation/MobileNavigation.astro +10 -2
- package/src/components/navigation/MobileNavigation.css +8 -22
- package/src/components/navigation/navigationTypes.ts +1 -4
- package/src/components/seo/SeoHead.astro +21 -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 +7 -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 +1 -5
- package/src/i18n/config.ts +2 -8
- package/src/i18n/coreMessages.ts +2 -9
- package/src/i18n/preference.ts +2 -6
- 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/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 +14 -7
- package/src/styles/style.css +11 -20
- package/src/theme/contracts.ts +1 -6
|
@@ -8,12 +8,7 @@ const initializedAttribute = 'data-table-progressive-initialized';
|
|
|
8
8
|
|
|
9
9
|
type PaginationState = 'idle' | 'loading' | 'error' | 'complete';
|
|
10
10
|
type TableLoadingState =
|
|
11
|
-
| '
|
|
12
|
-
| 'ready'
|
|
13
|
-
| 'refreshing'
|
|
14
|
-
| 'appending'
|
|
15
|
-
| 'empty'
|
|
16
|
-
| 'error';
|
|
11
|
+
'pending' | 'ready' | 'refreshing' | 'appending' | 'empty' | 'error';
|
|
17
12
|
type SortDirection = 'ascending' | 'descending';
|
|
18
13
|
type SortType = 'number' | 'text';
|
|
19
14
|
type SortValue = string | number | null;
|
|
@@ -74,13 +69,16 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
74
69
|
if (!rowsRoot || !skeletonTemplate) {
|
|
75
70
|
return () => undefined;
|
|
76
71
|
}
|
|
72
|
+
const activeRowsRoot = rowsRoot;
|
|
73
|
+
const activeSkeletonTemplate = skeletonTemplate;
|
|
77
74
|
|
|
78
75
|
if (!manifest) {
|
|
79
76
|
if (root.dataset.tablePreparation !== 'controlled') {
|
|
80
|
-
revealServerRows(root,
|
|
77
|
+
revealServerRows(root, activeRowsRoot);
|
|
81
78
|
}
|
|
82
79
|
return () => undefined;
|
|
83
80
|
}
|
|
81
|
+
const activeManifest = manifest;
|
|
84
82
|
|
|
85
83
|
const pagination = root.querySelector<HTMLElement>('[data-table-pagination]');
|
|
86
84
|
const sentinel = pagination?.querySelector<HTMLElement>(
|
|
@@ -92,22 +90,25 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
92
90
|
if (!pagination || !sentinel || !status) {
|
|
93
91
|
return () => undefined;
|
|
94
92
|
}
|
|
93
|
+
const activePagination = pagination;
|
|
94
|
+
const activeSentinel = sentinel;
|
|
95
|
+
const activeStatus = status;
|
|
95
96
|
|
|
96
|
-
const fallbackLink =
|
|
97
|
+
const fallbackLink = activePagination.querySelector<HTMLAnchorElement>(
|
|
97
98
|
'[data-table-pagination-link]',
|
|
98
99
|
);
|
|
99
100
|
if (!('IntersectionObserver' in window)) {
|
|
100
101
|
if (root.dataset.tablePreparation !== 'controlled') {
|
|
101
|
-
revealServerRows(root,
|
|
102
|
+
revealServerRows(root, activeRowsRoot);
|
|
102
103
|
}
|
|
103
|
-
showFallback(
|
|
104
|
+
showFallback(activePagination, fallbackLink);
|
|
104
105
|
return () => undefined;
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
root.setAttribute(initializedAttribute, 'true');
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
activePagination.hidden = false;
|
|
110
|
+
activePagination.setAttribute('data-table-progressive-enhanced', 'true');
|
|
111
|
+
activePagination.removeAttribute('data-surface');
|
|
111
112
|
|
|
112
113
|
const locale = document.documentElement.lang || undefined;
|
|
113
114
|
const normalize = (value: string): string =>
|
|
@@ -115,24 +116,22 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
115
116
|
.normalize('NFD')
|
|
116
117
|
.replace(/\p{Diacritic}/gu, '')
|
|
117
118
|
.toLocaleLowerCase(locale);
|
|
118
|
-
const entries =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
119
|
+
const entries = activeManifest.entries.map((entry, index): IndexedEntry => ({
|
|
120
|
+
...entry,
|
|
121
|
+
index,
|
|
122
|
+
exclusions: new Set(),
|
|
123
|
+
normalizedSearch: (entry.filters?.search ?? []).map(normalize),
|
|
124
|
+
sortValues: entry.sortValues ?? {},
|
|
125
|
+
}));
|
|
127
126
|
const entriesByKey = new Map(entries.map((entry) => [entry.key, entry]));
|
|
128
127
|
const rowsByKey = new Map<string, HTMLElement>();
|
|
129
128
|
const loadedSources = new Set<string>();
|
|
130
129
|
const batchSize = Math.max(
|
|
131
130
|
1,
|
|
132
|
-
Math.floor(
|
|
131
|
+
Math.floor(activeManifest.batchSize ?? tableProgressiveBatchSize),
|
|
133
132
|
);
|
|
134
133
|
const initialOffset = Math.min(
|
|
135
|
-
Math.max(0, Math.floor(
|
|
134
|
+
Math.max(0, Math.floor(activeManifest.initialOffset ?? 0)),
|
|
136
135
|
entries.length,
|
|
137
136
|
);
|
|
138
137
|
const empty = root.querySelector<HTMLElement>('[data-table-filter-empty]');
|
|
@@ -148,12 +147,12 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
148
147
|
let results = entries;
|
|
149
148
|
let cursor = 0;
|
|
150
149
|
let request: AbortController | null = null;
|
|
151
|
-
let skeletonRows = getSkeletonRows(
|
|
150
|
+
let skeletonRows = getSkeletonRows(activeRowsRoot);
|
|
152
151
|
let disposed = false;
|
|
153
152
|
let generation = 0;
|
|
154
153
|
let prepared = false;
|
|
155
154
|
|
|
156
|
-
registerRows(getRows(
|
|
155
|
+
registerRows(getRows(activeRowsRoot));
|
|
157
156
|
|
|
158
157
|
const observer = new IntersectionObserver(
|
|
159
158
|
(observedEntries) => {
|
|
@@ -179,16 +178,16 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
179
178
|
function addSkeleton(count: number): void {
|
|
180
179
|
removeSkeleton();
|
|
181
180
|
const candidates = Array.from(
|
|
182
|
-
|
|
181
|
+
activeSkeletonTemplate.content.querySelectorAll<HTMLElement>(
|
|
183
182
|
'[data-table-skeleton-row]',
|
|
184
183
|
),
|
|
185
184
|
).slice(0, count);
|
|
186
185
|
skeletonRows = candidates.map((row) => document.importNode(row, true));
|
|
187
|
-
insertBeforeEmpty(
|
|
186
|
+
insertBeforeEmpty(activeRowsRoot, empty, skeletonRows);
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
function detachRenderedRows(): HTMLElement[] {
|
|
191
|
-
const rendered = getRows(
|
|
190
|
+
const rendered = getRows(activeRowsRoot);
|
|
192
191
|
rendered.forEach((row) => row.remove());
|
|
193
192
|
return rendered;
|
|
194
193
|
}
|
|
@@ -196,7 +195,7 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
196
195
|
function appendRows(rows: readonly HTMLElement[]): void {
|
|
197
196
|
if (rows.length === 0) return;
|
|
198
197
|
for (const row of rows) row.hidden = false;
|
|
199
|
-
insertBeforeEmpty(
|
|
198
|
+
insertBeforeEmpty(activeRowsRoot, empty, rows);
|
|
200
199
|
root.dispatchEvent(
|
|
201
200
|
new CustomEvent<TableRowsAppendedDetail>('table:rows-appended', {
|
|
202
201
|
bubbles: true,
|
|
@@ -212,9 +211,13 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
212
211
|
function updatePagination(): void {
|
|
213
212
|
observer.disconnect();
|
|
214
213
|
const complete = cursor >= results.length;
|
|
215
|
-
|
|
216
|
-
setPaginationState(
|
|
217
|
-
|
|
214
|
+
activePagination.hidden = complete;
|
|
215
|
+
setPaginationState(
|
|
216
|
+
activePagination,
|
|
217
|
+
activeStatus,
|
|
218
|
+
complete ? 'complete' : 'idle',
|
|
219
|
+
);
|
|
220
|
+
if (!complete) observer.observe(activeSentinel);
|
|
218
221
|
}
|
|
219
222
|
|
|
220
223
|
function updateTableState(state: TableLoadingState): void {
|
|
@@ -300,18 +303,19 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
300
303
|
if (missing.length > 0) {
|
|
301
304
|
const activeRequest = new AbortController();
|
|
302
305
|
request = activeRequest;
|
|
303
|
-
setPaginationState(
|
|
306
|
+
setPaginationState(activePagination, activeStatus, 'loading');
|
|
304
307
|
updateTableState(loadingState);
|
|
305
308
|
addSkeleton(target.length);
|
|
306
309
|
|
|
307
310
|
try {
|
|
308
311
|
await loadSources(missing, activeRequest.signal);
|
|
309
312
|
} catch (error) {
|
|
310
|
-
if (error instanceof DOMException && error.name === 'AbortError')
|
|
313
|
+
if (error instanceof DOMException && error.name === 'AbortError')
|
|
314
|
+
return;
|
|
311
315
|
removeSkeleton();
|
|
312
|
-
setPaginationState(
|
|
316
|
+
setPaginationState(activePagination, activeStatus, 'error');
|
|
313
317
|
updateTableState('error');
|
|
314
|
-
showFallback(
|
|
318
|
+
showFallback(activePagination, fallbackLink);
|
|
315
319
|
observer.disconnect();
|
|
316
320
|
return;
|
|
317
321
|
} finally {
|
|
@@ -325,9 +329,9 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
325
329
|
const rows = target.map((entry) => rowsByKey.get(entry.key));
|
|
326
330
|
if (rows.some((row) => !row)) {
|
|
327
331
|
removeSkeleton();
|
|
328
|
-
setPaginationState(
|
|
332
|
+
setPaginationState(activePagination, activeStatus, 'error');
|
|
329
333
|
updateTableState('error');
|
|
330
|
-
showFallback(
|
|
334
|
+
showFallback(activePagination, fallbackLink);
|
|
331
335
|
observer.disconnect();
|
|
332
336
|
return;
|
|
333
337
|
}
|
|
@@ -343,17 +347,18 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
343
347
|
missingEntries: readonly IndexedEntry[],
|
|
344
348
|
signal: AbortSignal,
|
|
345
349
|
): Promise<void> {
|
|
350
|
+
const sources = activeManifest.sources;
|
|
346
351
|
const sourceIds = new Set(
|
|
347
352
|
missingEntries.map((entry) => entry.source).filter(isString),
|
|
348
353
|
);
|
|
349
|
-
if (sourceIds.size === 0 || !
|
|
354
|
+
if (sourceIds.size === 0 || !sources) {
|
|
350
355
|
throw new Error('Missing progressive table row source');
|
|
351
356
|
}
|
|
352
357
|
|
|
353
358
|
await Promise.all(
|
|
354
359
|
[...sourceIds].map(async (sourceId) => {
|
|
355
360
|
if (loadedSources.has(sourceId)) return;
|
|
356
|
-
const href =
|
|
361
|
+
const href = sources[sourceId];
|
|
357
362
|
if (!href) throw new Error(`Missing table source: ${sourceId}`);
|
|
358
363
|
|
|
359
364
|
const url = new URL(href, window.location.href);
|
|
@@ -379,12 +384,13 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
379
384
|
documentNode.querySelectorAll<HTMLElement>('[data-table-key]'),
|
|
380
385
|
).find((table) => table.dataset.tableKey === tableKey)
|
|
381
386
|
: null;
|
|
382
|
-
const sourceRowsRoot =
|
|
383
|
-
'[data-table-rows]'
|
|
384
|
-
);
|
|
387
|
+
const sourceRowsRoot =
|
|
388
|
+
sourceTable?.querySelector<HTMLElement>('[data-table-rows]');
|
|
385
389
|
const sourceRows = sourceRowsRoot ? getRows(sourceRowsRoot) : [];
|
|
386
390
|
if (sourceRows.length === 0) {
|
|
387
|
-
throw new Error(
|
|
391
|
+
throw new Error(
|
|
392
|
+
`Missing progressive table: ${tableKey ?? 'unknown'}`,
|
|
393
|
+
);
|
|
388
394
|
}
|
|
389
395
|
|
|
390
396
|
registerRows(sourceRows.map((row) => document.importNode(row, true)));
|
|
@@ -430,12 +436,14 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
430
436
|
request?.abort();
|
|
431
437
|
observer.disconnect();
|
|
432
438
|
removeSkeleton();
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
if (!
|
|
437
|
-
|
|
438
|
-
|
|
439
|
+
activePagination.hidden = !fallbackLink;
|
|
440
|
+
activePagination.removeAttribute('data-table-progressive-enhanced');
|
|
441
|
+
activePagination.removeAttribute('data-table-progressive-state');
|
|
442
|
+
if (!activePagination.hidden) {
|
|
443
|
+
activePagination.setAttribute('data-surface', '');
|
|
444
|
+
}
|
|
445
|
+
activeStatus.hidden = true;
|
|
446
|
+
activeStatus.textContent = '';
|
|
439
447
|
root.removeAttribute('aria-busy');
|
|
440
448
|
root.removeAttribute('data-table-loading-state');
|
|
441
449
|
root.removeAttribute(initializedAttribute);
|
|
@@ -533,9 +541,7 @@ function getProgressiveContext(
|
|
|
533
541
|
): ProgressiveContext | undefined {
|
|
534
542
|
const existing = contexts.get(root);
|
|
535
543
|
if (existing) return existing;
|
|
536
|
-
if (
|
|
537
|
-
!root.querySelector(':scope > [data-table-progressive-manifest]')
|
|
538
|
-
) {
|
|
544
|
+
if (!root.querySelector(':scope > [data-table-progressive-manifest]')) {
|
|
539
545
|
return undefined;
|
|
540
546
|
}
|
|
541
547
|
initTableProgressive(root);
|
|
@@ -574,17 +580,13 @@ function getRows(root: ParentNode): HTMLElement[] {
|
|
|
574
580
|
|
|
575
581
|
function getSkeletonRows(root: ParentNode): HTMLElement[] {
|
|
576
582
|
return Array.from(
|
|
577
|
-
root.querySelectorAll<HTMLElement>(
|
|
578
|
-
':scope > [data-table-skeleton-row]',
|
|
579
|
-
),
|
|
583
|
+
root.querySelectorAll<HTMLElement>(':scope > [data-table-skeleton-row]'),
|
|
580
584
|
);
|
|
581
585
|
}
|
|
582
586
|
|
|
583
587
|
function revealServerRows(root: HTMLElement, rowsRoot: HTMLElement): void {
|
|
584
588
|
getSkeletonRows(rowsRoot).forEach((row) => row.remove());
|
|
585
|
-
root.dataset.tableLoadingState = getRows(rowsRoot).some(
|
|
586
|
-
(row) => !row.hidden,
|
|
587
|
-
)
|
|
589
|
+
root.dataset.tableLoadingState = getRows(rowsRoot).some((row) => !row.hidden)
|
|
588
590
|
? 'ready'
|
|
589
591
|
: 'empty';
|
|
590
592
|
root.removeAttribute('aria-busy');
|
|
@@ -25,8 +25,9 @@ export function initTableScroll(root: HTMLElement): () => void {
|
|
|
25
25
|
|
|
26
26
|
root.setAttribute(initializedAttribute, 'true');
|
|
27
27
|
|
|
28
|
-
const bodyColumnGrid =
|
|
29
|
-
|
|
28
|
+
const bodyColumnGrid = bodyScrollport.querySelector<HTMLElement>(
|
|
29
|
+
bodyColumnGridSelector,
|
|
30
|
+
);
|
|
30
31
|
const hasStableColumns = root.dataset.tableLayout === 'index';
|
|
31
32
|
let isActive = true;
|
|
32
33
|
let layoutFrame: number | null = null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SnapshotReader<TSnapshot> {
|
|
2
|
+
read(): Promise<TSnapshot>;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type SnapshotParser<TSnapshot> = (value: unknown) => TSnapshot;
|
|
6
|
+
|
|
7
|
+
export type HttpSnapshotReaderOptions<TSnapshot> = {
|
|
8
|
+
parse: SnapshotParser<TSnapshot>;
|
|
9
|
+
timeoutMs: number;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { HttpSnapshotReaderOptions, SnapshotReader } from './contracts';
|
|
2
|
+
|
|
3
|
+
export class HttpSnapshotReader<
|
|
4
|
+
TSnapshot,
|
|
5
|
+
> implements SnapshotReader<TSnapshot> {
|
|
6
|
+
readonly #parse: HttpSnapshotReaderOptions<TSnapshot>['parse'];
|
|
7
|
+
readonly #timeoutMs: number;
|
|
8
|
+
readonly #url: string;
|
|
9
|
+
|
|
10
|
+
constructor({ parse, timeoutMs, url }: HttpSnapshotReaderOptions<TSnapshot>) {
|
|
11
|
+
this.#parse = parse;
|
|
12
|
+
this.#timeoutMs = timeoutMs;
|
|
13
|
+
this.#url = url;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async read(): Promise<TSnapshot> {
|
|
17
|
+
const response = await fetch(this.#url, {
|
|
18
|
+
cache: 'no-store',
|
|
19
|
+
headers: { Accept: 'application/json' },
|
|
20
|
+
signal: AbortSignal.timeout(this.#timeoutMs),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Snapshot source returned ${response.status}: ${this.#url}`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return this.#parse(await response.json());
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/routing/localized.ts
CHANGED
|
@@ -12,9 +12,7 @@ export type LocalizedRouter<TLocale extends string> = {
|
|
|
12
12
|
normalizePath(path: string): string;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export function createLocalizedRouter<
|
|
16
|
-
TDefinition extends LocaleDefinition,
|
|
17
|
-
>({
|
|
15
|
+
export function createLocalizedRouter<TDefinition extends LocaleDefinition>({
|
|
18
16
|
localeConfig,
|
|
19
17
|
localizedRoots = ['/'],
|
|
20
18
|
technicalRoots = [],
|
|
@@ -39,9 +37,10 @@ export function createLocalizedRouter<
|
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
const prefix = `/${localeConfig.getDefinition(locale).urlCode}`;
|
|
42
|
-
const localizedPath =
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const localizedPath =
|
|
41
|
+
normalizedPath === '/'
|
|
42
|
+
? prefix
|
|
43
|
+
: normalizePathname(`${prefix}${normalizedPath}`);
|
|
45
44
|
return `${localizedPath}${suffix}`;
|
|
46
45
|
};
|
|
47
46
|
|
|
@@ -76,9 +75,7 @@ export function createLocalizedRouter<
|
|
|
76
75
|
const normalizedPath = normalizePathname(unprefixedPath);
|
|
77
76
|
|
|
78
77
|
if (
|
|
79
|
-
normalizedTechnicalRoots.some((root) =>
|
|
80
|
-
matchesRoot(normalizedPath, root),
|
|
81
|
-
)
|
|
78
|
+
normalizedTechnicalRoots.some((root) => matchesRoot(normalizedPath, root))
|
|
82
79
|
) {
|
|
83
80
|
return 'technical';
|
|
84
81
|
}
|
|
@@ -114,9 +111,9 @@ export type LocalizedRouteParams = {
|
|
|
114
111
|
locale: string;
|
|
115
112
|
};
|
|
116
113
|
|
|
117
|
-
export function createLocalizedRoutePaths<
|
|
118
|
-
TDefinition
|
|
119
|
-
|
|
114
|
+
export function createLocalizedRoutePaths<TDefinition extends LocaleDefinition>(
|
|
115
|
+
localeConfig: LocaleConfig<TDefinition>,
|
|
116
|
+
): readonly {
|
|
120
117
|
params: LocalizedRouteParams;
|
|
121
118
|
props: { locale: TDefinition['id'] };
|
|
122
119
|
}[] {
|
package/src/seo/localizedMeta.ts
CHANGED
|
@@ -14,9 +14,7 @@ export type LocalizedMetaInput = Omit<
|
|
|
14
14
|
canonical: string;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export function createLocalizedPageMeta<
|
|
18
|
-
TDefinition extends LocaleDefinition,
|
|
19
|
-
>({
|
|
17
|
+
export function createLocalizedPageMeta<TDefinition extends LocaleDefinition>({
|
|
20
18
|
input,
|
|
21
19
|
locale,
|
|
22
20
|
localeConfig,
|
|
@@ -30,9 +28,7 @@ export function createLocalizedPageMeta<
|
|
|
30
28
|
socialImageAlt?: string;
|
|
31
29
|
}): PageMeta {
|
|
32
30
|
const definition = localeConfig.getDefinition(locale);
|
|
33
|
-
const { path } = router.stripLocalePrefix(
|
|
34
|
-
normalizePathname(input.canonical),
|
|
35
|
-
);
|
|
31
|
+
const { path } = router.stripLocalePrefix(normalizePathname(input.canonical));
|
|
36
32
|
const alternates = localeConfig.definitions.map((alternateLocale) => ({
|
|
37
33
|
lang: alternateLocale.languageTag,
|
|
38
34
|
href: router.localizePath(path, alternateLocale.id),
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
[data-theme-switching='true'],
|
|
2
|
+
[data-theme-switching='true'] *,
|
|
3
|
+
[data-theme-switching='true'] *::before,
|
|
4
|
+
[data-theme-switching='true'] *::after {
|
|
5
|
+
transition: none !important;
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
[data-interaction-accent] {
|
|
2
9
|
--nox-interaction-accent-hover-background: color-mix(
|
|
3
10
|
in srgb,
|
|
@@ -31,13 +38,13 @@
|
|
|
31
38
|
|
|
32
39
|
@media (hover: none) and (pointer: coarse) {
|
|
33
40
|
:where(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
a[href],
|
|
42
|
+
button,
|
|
43
|
+
summary,
|
|
44
|
+
[role='button'],
|
|
45
|
+
[role='link'],
|
|
46
|
+
[tabindex]:not(input, select, textarea)
|
|
47
|
+
):focus-visible {
|
|
41
48
|
--nox-focus-ring: transparent;
|
|
42
49
|
--nox-tone-focus-ring: transparent;
|
|
43
50
|
|
package/src/styles/style.css
CHANGED
|
@@ -18,12 +18,9 @@
|
|
|
18
18
|
layer(components);
|
|
19
19
|
@import '../components/actions/Button/Button.css' layer(components);
|
|
20
20
|
@import '../components/actions/ThemeToggle/ThemeToggle.css' layer(components);
|
|
21
|
-
@import '../components/actions/CardAction/CardAction.css'
|
|
22
|
-
|
|
23
|
-
@import '../components/actions/
|
|
24
|
-
layer(components);
|
|
25
|
-
@import '../components/actions/MediaTrigger/MediaTrigger.css'
|
|
26
|
-
layer(components);
|
|
21
|
+
@import '../components/actions/CardAction/CardAction.css' layer(components);
|
|
22
|
+
@import '../components/actions/ScrollToTop/ScrollToTop.css' layer(components);
|
|
23
|
+
@import '../components/actions/MediaTrigger/MediaTrigger.css' layer(components);
|
|
27
24
|
@import '../components/content/CodeBlock/CodeBlock.css' layer(components);
|
|
28
25
|
@import '../components/content/CardBody/CardBody.css' layer(components);
|
|
29
26
|
@import '../components/content/CardFooter/CardFooter.css' layer(components);
|
|
@@ -33,15 +30,11 @@
|
|
|
33
30
|
layer(components);
|
|
34
31
|
@import '../components/content/MarkdownContent/MarkdownContent.css'
|
|
35
32
|
layer(components);
|
|
36
|
-
@import '../components/data-display/BadgeList/BadgeList.css'
|
|
37
|
-
|
|
38
|
-
@import '../components/data-display/
|
|
39
|
-
layer(components);
|
|
40
|
-
@import '../components/data-display/MetricTile/MetricTile.css'
|
|
41
|
-
layer(components);
|
|
33
|
+
@import '../components/data-display/BadgeList/BadgeList.css' layer(components);
|
|
34
|
+
@import '../components/data-display/IconList/IconList.css' layer(components);
|
|
35
|
+
@import '../components/data-display/MetricTile/MetricTile.css' layer(components);
|
|
42
36
|
@import '../components/data-display/Tag/Tag.css' layer(components);
|
|
43
|
-
@import '../components/data-display/TextPair/TextPair.css'
|
|
44
|
-
layer(components);
|
|
37
|
+
@import '../components/data-display/TextPair/TextPair.css' layer(components);
|
|
45
38
|
@import '../components/forms/Checkbox/Checkbox.css' layer(components);
|
|
46
39
|
@import '../components/forms/ChoiceGroup/ChoiceGroup.css' layer(components);
|
|
47
40
|
@import '../components/forms/FieldLabel/FieldLabel.css' layer(components);
|
|
@@ -53,13 +46,11 @@
|
|
|
53
46
|
@import '../components/feedback/Spinner/Spinner.css' layer(components);
|
|
54
47
|
@import '../components/icons/CurrencyIcon.css' layer(components);
|
|
55
48
|
@import '../components/icons/CircleSymbolIcon.css' layer(components);
|
|
56
|
-
@import '../components/media/CanvasFrame/CanvasFrame.css'
|
|
57
|
-
|
|
58
|
-
@import '../components/media/EmbedFrame/EmbedFrame.css'
|
|
59
|
-
layer(components);
|
|
49
|
+
@import '../components/media/CanvasFrame/CanvasFrame.css' layer(components);
|
|
50
|
+
@import '../components/media/EmbedFrame/EmbedFrame.css' layer(components);
|
|
60
51
|
@import '../components/media/MediaFrame/MediaFrame.css' layer(components);
|
|
61
|
-
@import '../components/
|
|
62
|
-
|
|
52
|
+
@import '../components/monetization/AdSlot/AdSlot.css' layer(components);
|
|
53
|
+
@import '../components/navigation/Breadcrumbs/Breadcrumbs.css' layer(components);
|
|
63
54
|
@import '../components/navigation/Header.css' layer(components);
|
|
64
55
|
@import '../components/navigation/Footer/Footer.css' layer(components);
|
|
65
56
|
@import '../components/navigation/NavigationBrand.css' layer(components);
|