@janga/norna 0.7.8 → 0.7.10
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 +1 -1
- package/docs/README.md +18 -11
- package/docs/configuration.md +9 -54
- package/docs/content.md +6 -7
- package/docs/design/norna-diagram-design.md +158 -0
- package/docs/getting-started.md +18 -16
- package/docs/routes.md +7 -6
- package/docs/site-structure.md +4 -2
- package/docs/sitewide-content.md +74 -0
- package/docs/theme.md +61 -128
- package/docs/typography.md +45 -33
- package/examples/001-dog-shelter-single-page/README.md +9 -0
- package/examples/001-dog-shelter-single-page/site/config.mjs +27 -0
- package/examples/001-dog-shelter-single-page/site/content.md +38 -0
- package/examples/001-dog-shelter-single-page/site/images/what-we-do/dog-house.svg +25 -0
- package/examples/001-dog-shelter-single-page/site/images/you-can-help/heart.svg +13 -0
- package/examples/001-dog-shelter-single-page/site/public/favicon.svg +10 -0
- package/examples/001-dog-shelter-single-page/site/public/robots.txt +2 -0
- package/examples/001-dog-shelter-single-page/site/sitewide-content.md +6 -0
- package/examples/001-dog-shelter-single-page/site/theme.md +25 -0
- package/examples/002-dog-shelter-multi-page/README.md +9 -0
- package/examples/002-dog-shelter-multi-page/site/config.mjs +27 -0
- package/examples/002-dog-shelter-multi-page/site/content.md +12 -0
- package/examples/002-dog-shelter-multi-page/site/public/favicon.svg +10 -0
- package/examples/002-dog-shelter-multi-page/site/public/robots.txt +2 -0
- package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rex.svg +19 -0
- package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/images/dogs/rover.svg +19 -0
- package/examples/002-dog-shelter-multi-page/site/routes/010-dogs/route-content.md +30 -0
- package/examples/002-dog-shelter-multi-page/site/routes/020-adopt/route-content.md +12 -0
- package/examples/002-dog-shelter-multi-page/site/sitewide-content.md +6 -0
- package/examples/002-dog-shelter-multi-page/site/theme.md +25 -0
- package/examples/dog-gallery/.astro/collections/site.schema.json +776 -0
- package/examples/dog-gallery/.astro/collections/theme.schema.json +672 -0
- package/examples/dog-gallery/.astro/content-assets.mjs +4 -0
- package/examples/dog-gallery/.astro/content-modules.mjs +1 -0
- package/examples/dog-gallery/.astro/content.d.ts +175 -0
- package/examples/dog-gallery/.astro/data-store.json +1 -0
- package/examples/dog-gallery/.astro/dev-local.json +8 -0
- package/examples/dog-gallery/.astro/dev.json +13 -0
- package/examples/dog-gallery/.astro/dev.log +95 -0
- package/examples/dog-gallery/.astro/settings.json +5 -0
- package/examples/dog-gallery/.astro/types.d.ts +2 -0
- package/examples/dog-gallery/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +1 -0
- package/examples/dog-gallery/dist/_astro/SitePage.DicGh_5N.css +1 -0
- package/examples/dog-gallery/dist/dog-care/index.html +15 -0
- package/examples/dog-gallery/dist/dog-shelter-logo.svg +14 -0
- package/examples/dog-gallery/dist/favicon.svg +7 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-1536.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/black-puppy-meadow-7255e3d9-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/black-dogs/photo-of-a-black-dog-5cf614d2-960.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-3939.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/brown-dog-50ef114e-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-2400.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/brown-dogs/dog-accompanies-master-7ef804d5-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-1600.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/golden-retriever-f797fd88-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-1920.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-2576.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/golden-dogs/toller-puppy-a2a8fbc0-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-1277.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-cute-dog-077a0689-768.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1080.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1440.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-1536.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-480.webp +0 -0
- package/examples/dog-gallery/dist/images/generated/white-dogs/white-puppy-garden-d3ab2ca0-768.webp +0 -0
- package/examples/dog-gallery/dist/index.html +45 -0
- package/examples/dog-gallery/dist/robots.txt +2 -0
- package/examples/dog-gallery/node_modules/.vite/deps/_metadata.json +7 -7
- package/examples/dog-gallery/site/.norna/generated-images.json +8 -8
- package/examples/dog-gallery/site/config.mjs +0 -20
- package/examples/dog-gallery/site/content.md +4 -5
- package/examples/dog-gallery/site/public/logo.svg +14 -0
- package/examples/dog-gallery/site/sitewide-content.md +16 -0
- package/examples/dog-gallery/site/theme.md +13 -24
- package/examples/presentation/README.md +15 -0
- package/examples/presentation/site/.norna/generated-images.json +66 -0
- package/examples/presentation/site/config.mjs +29 -0
- package/examples/presentation/site/content.md +67 -0
- package/examples/presentation/site/public/robots.txt +2 -0
- package/examples/presentation/site/routes/010-presets/route-content.md +63 -0
- package/examples/presentation/site/routes/010-presets/theme.md +4 -0
- package/examples/presentation/site/routes/020-media/images/cards/card-carousel.svg +11 -0
- package/examples/presentation/site/routes/020-media/images/cards/card-stack.svg +9 -0
- package/examples/presentation/site/routes/020-media/images/cards/card-surfaces.svg +8 -0
- package/examples/presentation/site/routes/020-media/images/carousel/carousel-one.svg +8 -0
- package/examples/presentation/site/routes/020-media/images/carousel/carousel-three.svg +13 -0
- package/examples/presentation/site/routes/020-media/images/carousel/carousel-two.svg +8 -0
- package/examples/presentation/site/routes/020-media/images/stack/stack-one.svg +8 -0
- package/examples/presentation/site/routes/020-media/images/stack/stack-two.svg +9 -0
- package/examples/presentation/site/routes/020-media/route-content.md +77 -0
- package/examples/presentation/site/routes/020-media/theme.md +4 -0
- package/examples/presentation/site/routes/030-surfaces/route-content.md +44 -0
- package/examples/presentation/site/routes/030-surfaces/theme.md +7 -0
- package/examples/presentation/site/sitewide-content.md +6 -0
- package/examples/presentation/site/theme.md +43 -0
- package/examples/typography-presets/.astro/collections/routeTheme.schema.json +746 -0
- package/examples/typography-presets/.astro/collections/site.schema.json +59 -0
- package/examples/typography-presets/.astro/collections/sitewide.schema.json +114 -0
- package/examples/typography-presets/.astro/collections/theme.schema.json +770 -0
- package/examples/typography-presets/.astro/content-assets.mjs +4 -0
- package/examples/typography-presets/.astro/content-modules.mjs +1 -0
- package/examples/typography-presets/.astro/content.d.ts +183 -0
- package/examples/typography-presets/.astro/data-store.json +1 -0
- package/examples/typography-presets/.astro/dev-local.json +8 -0
- package/examples/typography-presets/.astro/dev.json +15 -0
- package/examples/typography-presets/.astro/dev.log +45 -0
- package/examples/typography-presets/.astro/settings.json +5 -0
- package/examples/typography-presets/.astro/types.d.ts +2 -0
- package/examples/typography-presets/node_modules/.vite/deps/_metadata.json +80 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro-D_GIpJIE.js +434 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro-D_GIpJIE.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_aria-query.js +6390 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_aria-query.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_axobject-query.js +2702 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_axobject-query.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_html-escaper.js +65 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_n_html-escaper.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +455 -0
- package/examples/typography-presets/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/audit-DM9Hkl5B.js +1534 -0
- package/examples/typography-presets/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/embla-carousel.js +1389 -0
- package/examples/typography-presets/node_modules/.vite/deps/embla-carousel.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/highlight-DnZ1ULOL.js +48 -0
- package/examples/typography-presets/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/icons-RyebKi45.js +42 -0
- package/examples/typography-presets/node_modules/.vite/deps/icons-RyebKi45.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/package.json +3 -0
- package/examples/typography-presets/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +4 -0
- package/examples/typography-presets/node_modules/.vite/deps/settings-DaU-gNnK.js +190 -0
- package/examples/typography-presets/node_modules/.vite/deps/settings-DaU-gNnK.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/toolbar-63PA619H.js +458 -0
- package/examples/typography-presets/node_modules/.vite/deps/toolbar-63PA619H.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/ui-library--bkcNSYz.js +1016 -0
- package/examples/typography-presets/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/window-jPkpKVcy.js +32 -0
- package/examples/typography-presets/node_modules/.vite/deps/window-jPkpKVcy.js.map +1 -0
- package/examples/typography-presets/node_modules/.vite/deps/xray-BXCHpEJP.js +111 -0
- package/examples/typography-presets/node_modules/.vite/deps/xray-BXCHpEJP.js.map +1 -0
- package/examples/typography-presets/site/.norna/generated-images.json +290 -0
- package/examples/typography-presets/site/config.mjs +29 -0
- package/examples/typography-presets/site/content.md +16 -0
- package/examples/typography-presets/site/public/robots.txt +2 -0
- package/examples/typography-presets/site/routes/010-quiet-gallery/images/quiet-gallery/puppy-portrait.jpg +0 -0
- package/examples/typography-presets/site/routes/010-quiet-gallery/images/quiet-gallery/shepherd-portrait.jpg +0 -0
- package/examples/typography-presets/site/routes/010-quiet-gallery/images/quiet-gallery/white-puppy.jpg +0 -0
- package/examples/typography-presets/site/routes/010-quiet-gallery/route-content.md +34 -0
- package/examples/typography-presets/site/routes/010-quiet-gallery/theme.md +4 -0
- package/examples/typography-presets/site/routes/020-compact-gallery/images/compact-gallery/black-schnauzer.jpg +0 -0
- package/examples/typography-presets/site/routes/020-compact-gallery/images/compact-gallery/retriever-portrait.jpg +0 -0
- package/examples/typography-presets/site/routes/020-compact-gallery/images/compact-gallery/schnauzer-portrait.jpg +0 -0
- package/examples/typography-presets/site/routes/020-compact-gallery/route-content.md +33 -0
- package/examples/typography-presets/site/routes/020-compact-gallery/theme.md +4 -0
- package/examples/typography-presets/site/routes/030-text-forward/images/text-forward/boxer-portrait.jpg +0 -0
- package/examples/typography-presets/site/routes/030-text-forward/images/text-forward/grass-puppy.jpg +0 -0
- package/examples/typography-presets/site/routes/030-text-forward/images/text-forward/grey-street-dog.jpg +0 -0
- package/examples/typography-presets/site/routes/030-text-forward/route-content.md +34 -0
- package/examples/typography-presets/site/routes/030-text-forward/theme.md +4 -0
- package/examples/typography-presets/site/routes/040-statement/images/statement/black-pedigree.jpg +0 -0
- package/examples/typography-presets/site/routes/040-statement/images/statement/sheepdog-grass.jpg +0 -0
- package/examples/typography-presets/site/routes/040-statement/images/statement/sheepdog-wide.jpg +0 -0
- package/examples/typography-presets/site/routes/040-statement/route-content.md +34 -0
- package/examples/typography-presets/site/routes/040-statement/theme.md +4 -0
- package/examples/typography-presets/site/sitewide-content.md +14 -0
- package/examples/typography-presets/site/theme.md +43 -0
- package/fixtures/basic/site/config.mjs +0 -13
- package/fixtures/basic/site/sitewide-content.md +12 -0
- package/fixtures/basic/site/theme.md +2 -2
- package/fixtures/content-model-v2/site/content.md +2 -5
- package/fixtures/content-model-v2/site/theme.md +1 -3
- package/package.json +3 -2
- package/scripts/check-config.mjs +22 -1
- package/scripts/lib/frontmatter-yaml.mjs +28 -0
- package/scripts/lib/logo-assets.mjs +35 -0
- package/scripts/lib/norna-markdown-blocks.mjs +166 -0
- package/scripts/lib/presentation.mjs +104 -46
- package/scripts/lib/project-config.mjs +67 -105
- package/scripts/lib/site-content.mjs +26 -42
- package/scripts/lib/site-paths.mjs +2 -0
- package/scripts/lib/sitewide-config.mjs +34 -0
- package/scripts/lib/theme-config.mjs +72 -6
- package/scripts/lib/typography.mjs +20 -26
- package/scripts/show-typography.mjs +40 -147
- package/scripts/sync-content-sections.mjs +19 -14
- package/scripts/test-content-check.mjs +76 -14
- package/scripts/test-content-model-v2.mjs +154 -0
- package/scripts/test-engine-commands.mjs +3 -1
- package/scripts/test-package-check.mjs +78 -19
- package/scripts/test-temporary-visibility.mjs +19 -2
- package/src/components/CardList.astro +5 -2
- package/src/components/GalleryGrid.astro +37 -16
- package/src/components/SiteBanners.astro +100 -0
- package/src/components/SiteNavigation.astro +48 -31
- package/src/components/SitePage.astro +55 -13
- package/src/components/SiteSection.astro +194 -36
- package/src/content.config.ts +78 -48
- package/src/layouts/BaseLayout.astro +64 -14
- package/src/lib/routeThemes.ts +61 -0
- package/src/lib/sectionContent.ts +236 -44
- package/src/lib/sitePublicAssets.ts +1 -0
- package/src/styles/global.css +282 -93
- package/starters/basic/.github/workflows/deploy.yml +1 -1
- package/starters/basic/README.md +7 -6
- package/starters/basic/site/config.mjs +0 -13
- package/starters/basic/site/content.md +1 -1
- package/starters/basic/site/sitewide-content.md +14 -0
- package/starters/basic/site/theme.md +13 -24
- package/starters/project/.github/workflows/deploy.yml +1 -1
- package/starters/project/README.md +10 -8
- package/starters/project/site/config.mjs +0 -13
- package/starters/project/site/sitewide-content.md +14 -0
- package/starters/project/site/theme.md +3 -11
|
@@ -1,71 +1,129 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defaultTypography,
|
|
3
3
|
resolveTypographyConfig,
|
|
4
|
-
resolveTypographyOverride,
|
|
5
4
|
} from './typography.mjs';
|
|
6
5
|
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export const presentationPaletteNames = ['dark', 'light', 'paper'];
|
|
7
|
+
|
|
8
|
+
const presentationPalettes = Object.freeze({
|
|
9
|
+
dark: {
|
|
10
|
+
colorScheme: 'dark',
|
|
11
|
+
page: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
12
|
+
surfaces: {
|
|
13
|
+
base: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
14
|
+
soft: { backgroundColor: '#171717', textColor: '#f2eee6' },
|
|
15
|
+
emphasis: { backgroundColor: '#252525', textColor: '#f2eee6' },
|
|
16
|
+
},
|
|
17
|
+
frame: { backgroundColor: '#000000', textColor: '#f2eee6' },
|
|
18
|
+
css: {
|
|
19
|
+
surface: '#101010',
|
|
20
|
+
muted: '#aaa49a',
|
|
21
|
+
soft: '#302f2c',
|
|
22
|
+
accent: '#d8d2c8',
|
|
23
|
+
border: 'rgb(255 255 255 / 14%)',
|
|
24
|
+
navBackground: 'rgb(0 0 0 / 90%)',
|
|
25
|
+
navSeparator: 'rgb(255 255 255 / 28%)',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
light: {
|
|
29
|
+
colorScheme: 'light',
|
|
30
|
+
page: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
31
|
+
surfaces: {
|
|
32
|
+
base: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
33
|
+
soft: { backgroundColor: '#f1f4f2', textColor: '#17201d' },
|
|
34
|
+
emphasis: { backgroundColor: '#dde7e1', textColor: '#17201d' },
|
|
35
|
+
},
|
|
36
|
+
frame: { backgroundColor: '#ffffff', textColor: '#17201d' },
|
|
37
|
+
css: {
|
|
38
|
+
surface: '#f7f8f7',
|
|
39
|
+
muted: '#5e655f',
|
|
40
|
+
soft: '#d9dfda',
|
|
41
|
+
accent: '#38645a',
|
|
42
|
+
border: 'rgb(0 0 0 / 14%)',
|
|
43
|
+
navBackground: 'rgb(255 255 255 / 92%)',
|
|
44
|
+
navSeparator: 'rgb(0 0 0 / 20%)',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
paper: {
|
|
48
|
+
colorScheme: 'light',
|
|
49
|
+
page: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
50
|
+
surfaces: {
|
|
51
|
+
base: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
52
|
+
soft: { backgroundColor: '#ebe5d9', textColor: '#272522' },
|
|
53
|
+
emphasis: { backgroundColor: '#ded4c5', textColor: '#272522' },
|
|
54
|
+
},
|
|
55
|
+
frame: { backgroundColor: '#f8f5ee', textColor: '#272522' },
|
|
56
|
+
css: {
|
|
57
|
+
surface: '#f0ebe1',
|
|
58
|
+
muted: '#746e63',
|
|
59
|
+
soft: '#d8d0c4',
|
|
60
|
+
accent: '#685a43',
|
|
61
|
+
border: 'rgb(39 37 34 / 18%)',
|
|
62
|
+
navBackground: 'rgb(248 245 238 / 92%)',
|
|
63
|
+
navSeparator: 'rgb(39 37 34 / 24%)',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
10
66
|
});
|
|
11
67
|
|
|
12
68
|
const normalizePresentation = (presentation) => presentation ?? {};
|
|
13
69
|
|
|
70
|
+
export const getPresentationPalette = (paletteName = 'dark') => {
|
|
71
|
+
const palette = presentationPalettes[paletteName];
|
|
72
|
+
if (!palette) {
|
|
73
|
+
throw new Error(`Unknown presentation palette: ${paletteName}. Use one of: ${presentationPaletteNames.join(', ')}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return palette;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const getPresentationCssVariables = (presentation) => {
|
|
80
|
+
const { palette } = presentation;
|
|
81
|
+
return {
|
|
82
|
+
'--color-page': palette.page.backgroundColor,
|
|
83
|
+
'--color-text': palette.page.textColor,
|
|
84
|
+
'--color-surface': palette.css.surface,
|
|
85
|
+
'--color-muted': palette.css.muted,
|
|
86
|
+
'--color-soft': palette.css.soft,
|
|
87
|
+
'--color-accent': palette.css.accent,
|
|
88
|
+
'--color-border': palette.css.border,
|
|
89
|
+
'--color-nav-background': palette.css.navBackground,
|
|
90
|
+
'--color-nav-separator': palette.css.navSeparator,
|
|
91
|
+
'--color-scheme': palette.colorScheme,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
14
95
|
export const resolveThemePresentation = (theme) => {
|
|
15
96
|
const normalizedTheme = theme ?? {};
|
|
16
97
|
const normalizedThemePresentation = normalizePresentation(normalizedTheme.presentation);
|
|
98
|
+
const paletteName = normalizedThemePresentation.palette ?? 'dark';
|
|
99
|
+
const palette = getPresentationPalette(paletteName);
|
|
17
100
|
|
|
18
101
|
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
102
|
+
paletteName,
|
|
103
|
+
palette,
|
|
104
|
+
sectionSurfaces: {
|
|
105
|
+
mode: normalizedThemePresentation.sectionSurfaces?.mode ?? 'none',
|
|
106
|
+
sequence: normalizedThemePresentation.sectionSurfaces?.sequence ?? ['base', 'soft', 'emphasis'],
|
|
107
|
+
},
|
|
22
108
|
typography: resolveTypographyConfig(normalizedTheme.typography ?? defaultTypography),
|
|
23
109
|
};
|
|
24
110
|
};
|
|
25
111
|
|
|
26
|
-
export const resolvePagePresentation = (theme
|
|
112
|
+
export const resolvePagePresentation = (theme) => {
|
|
27
113
|
const resolvedThemePresentation = resolveThemePresentation(theme);
|
|
28
|
-
const normalizedPagePresentation = normalizePresentation(pagePresentation);
|
|
29
114
|
|
|
30
|
-
return
|
|
31
|
-
backgroundColor: normalizedPagePresentation.backgroundColor ?? resolvedThemePresentation.backgroundColor,
|
|
32
|
-
textColor: normalizedPagePresentation.textColor ?? resolvedThemePresentation.textColor,
|
|
33
|
-
inlineStyles: resolvedThemePresentation.inlineStyles,
|
|
34
|
-
typography: resolveTypographyOverride(
|
|
35
|
-
resolvedThemePresentation.typography,
|
|
36
|
-
normalizedPagePresentation.typography,
|
|
37
|
-
),
|
|
38
|
-
};
|
|
115
|
+
return resolvedThemePresentation;
|
|
39
116
|
};
|
|
40
117
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const resolveColorSource = ({ colors, themeFrameColors, pagePresentation }) => {
|
|
47
|
-
if (!colors || colors === 'theme') {
|
|
48
|
-
return themeFrameColors;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (colors === 'presentation') {
|
|
52
|
-
return getColorsFromPresentation(pagePresentation);
|
|
53
|
-
}
|
|
118
|
+
export const resolveSectionSurface = (pagePresentation, sectionIndex) => {
|
|
119
|
+
const surfaceName = pagePresentation.sectionSurfaces.mode === 'cycle'
|
|
120
|
+
? pagePresentation.sectionSurfaces.sequence[sectionIndex % pagePresentation.sectionSurfaces.sequence.length]
|
|
121
|
+
: 'base';
|
|
54
122
|
|
|
55
|
-
return
|
|
123
|
+
return {
|
|
124
|
+
name: surfaceName,
|
|
125
|
+
...pagePresentation.palette.surfaces[surfaceName],
|
|
126
|
+
};
|
|
56
127
|
};
|
|
57
128
|
|
|
58
|
-
export const resolveFrameColors = ({ theme
|
|
59
|
-
const resolvedThemePresentation = resolveThemePresentation(theme);
|
|
60
|
-
const themeFrameColors = resolveColorSource({
|
|
61
|
-
colors: theme?.frame?.colors ?? 'presentation',
|
|
62
|
-
themeFrameColors: getColorsFromPresentation(resolvedThemePresentation),
|
|
63
|
-
pagePresentation: resolvedThemePresentation,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return resolveColorSource({
|
|
67
|
-
colors: pageFrame?.colors ?? 'theme',
|
|
68
|
-
themeFrameColors,
|
|
69
|
-
pagePresentation,
|
|
70
|
-
});
|
|
71
|
-
};
|
|
129
|
+
export const resolveFrameColors = ({ theme }) => resolveThemePresentation(theme).palette.frame;
|
|
@@ -37,20 +37,6 @@ const readString = (object, key, path, sourceLabel = siteConfigLabel) => {
|
|
|
37
37
|
return value.trim();
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
const readOptionalString = (object, key, path, sourceLabel = siteConfigLabel) => {
|
|
41
|
-
const value = object[key];
|
|
42
|
-
|
|
43
|
-
if (value === undefined || value === null || value === '') {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (typeof value !== 'string' || value.trim() === '') {
|
|
48
|
-
throw new Error(`${path}.${key} must be a non-empty string when set in ${sourceLabel}.`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return value.trim();
|
|
52
|
-
};
|
|
53
|
-
|
|
54
40
|
const readFontFamily = (object, key, path, fallback, sourceLabel = siteConfigLabel) => {
|
|
55
41
|
const value = object[key] ?? fallback;
|
|
56
42
|
|
|
@@ -242,58 +228,19 @@ const readLocale = (rawLocale) => {
|
|
|
242
228
|
lang: lang.trim(),
|
|
243
229
|
labels: Object.freeze({
|
|
244
230
|
closeMenu: readString({ closeMenu: labels.closeMenu ?? 'Close menu' }, 'closeMenu', 'locale.labels'),
|
|
231
|
+
dismissBanner: readString({ dismissBanner: labels.dismissBanner ?? 'Dismiss notice' }, 'dismissBanner', 'locale.labels'),
|
|
245
232
|
skipToContent: readString({ skipToContent: labels.skipToContent ?? 'Skip to content' }, 'skipToContent', 'locale.labels'),
|
|
246
233
|
sectionNavigation: readString({ sectionNavigation: labels.sectionNavigation ?? 'Sections' }, 'sectionNavigation', 'locale.labels'),
|
|
247
234
|
gallery: readString({ gallery: labels.gallery ?? 'Images' }, 'gallery', 'locale.labels'),
|
|
235
|
+
note: readString({ note: labels.note ?? 'Note' }, 'note', 'locale.labels'),
|
|
248
236
|
menu: readString({ menu: labels.menu ?? 'Menu' }, 'menu', 'locale.labels'),
|
|
249
237
|
pageNavigation: readString({ pageNavigation: labels.pageNavigation ?? 'On this page' }, 'pageNavigation', 'locale.labels'),
|
|
250
238
|
siteNavigation: readString({ siteNavigation: labels.siteNavigation ?? 'Pages' }, 'siteNavigation', 'locale.labels'),
|
|
239
|
+
siteBanners: readString({ siteBanners: labels.siteBanners ?? 'Site notices' }, 'siteBanners', 'locale.labels'),
|
|
251
240
|
}),
|
|
252
241
|
});
|
|
253
242
|
};
|
|
254
243
|
|
|
255
|
-
const readDateTimeFormat = (object, path) => {
|
|
256
|
-
const dateTimeFormat = assertObject(object, path);
|
|
257
|
-
const locale = readString(dateTimeFormat, 'locale', path);
|
|
258
|
-
const timeZone = readString(dateTimeFormat, 'timeZone', path);
|
|
259
|
-
const dateStyle = readString(dateTimeFormat, 'dateStyle', path);
|
|
260
|
-
const timeStyle = readString(dateTimeFormat, 'timeStyle', path);
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
new Intl.DateTimeFormat(locale, {
|
|
264
|
-
dateStyle,
|
|
265
|
-
timeStyle,
|
|
266
|
-
timeZone,
|
|
267
|
-
});
|
|
268
|
-
} catch (error) {
|
|
269
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
270
|
-
throw new Error(`${path} must be a valid Intl.DateTimeFormat configuration in ${siteConfigLabel}: ${message}`);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return Object.freeze({
|
|
274
|
-
dateStyle,
|
|
275
|
-
locale,
|
|
276
|
-
timeStyle,
|
|
277
|
-
timeZone,
|
|
278
|
-
});
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const readBuildInfo = (footer) => {
|
|
282
|
-
const value = footer.buildInfo;
|
|
283
|
-
|
|
284
|
-
if (value === undefined || value === null || value === false) {
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const buildInfo = assertObject(value, 'footer.buildInfo');
|
|
289
|
-
|
|
290
|
-
return Object.freeze({
|
|
291
|
-
enabled: readBoolean(buildInfo, 'enabled', 'footer.buildInfo', true),
|
|
292
|
-
text: readString(buildInfo, 'text', 'footer.buildInfo'),
|
|
293
|
-
dateTimeFormat: readDateTimeFormat(buildInfo.dateTimeFormat, 'footer.buildInfo.dateTimeFormat'),
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
|
-
|
|
297
244
|
const rawConfig = assertObject(siteConfig, 'default export');
|
|
298
245
|
const misplacedThemeKeys = ['layout', 'gallery', 'typography'].filter((key) => key in rawConfig);
|
|
299
246
|
if (misplacedThemeKeys.length > 0) {
|
|
@@ -302,13 +249,8 @@ if (misplacedThemeKeys.length > 0) {
|
|
|
302
249
|
|
|
303
250
|
const rawTheme = assertObject(themeConfig, 'theme frontmatter', siteThemeLabel);
|
|
304
251
|
const rawSite = assertObject(rawConfig.site, 'site');
|
|
305
|
-
const rawLayout = assertObject(rawTheme.layout ?? {}, 'layout', siteThemeLabel);
|
|
306
|
-
const rawLayoutSpacing = assertObject(rawLayout.spacing ?? {}, 'layout.spacing', siteThemeLabel);
|
|
307
|
-
const rawGallery = assertObject(rawTheme.gallery ?? {}, 'gallery', siteThemeLabel);
|
|
308
|
-
const rawTypography = assertObject(rawTheme.typography ?? {}, 'typography', siteThemeLabel);
|
|
309
252
|
const rawNavigation = assertObject(rawConfig.navigation ?? {}, 'navigation');
|
|
310
253
|
const rawLocale = rawConfig.locale ?? {};
|
|
311
|
-
const rawFooter = assertObject(rawConfig.footer ?? {}, 'footer');
|
|
312
254
|
const rawGithub = assertObject(rawConfig.github, 'github');
|
|
313
255
|
const rawDeploy = assertObject(rawConfig.deploy ?? {}, 'deploy');
|
|
314
256
|
const rawDeployWatch = assertObject(rawDeploy.watch ?? {}, 'deploy.watch');
|
|
@@ -317,9 +259,9 @@ const defaultFontFamily = "Arial, 'Helvetica Neue', Helvetica, sans-serif";
|
|
|
317
259
|
const layoutDensityNames = ['compact', 'normal', 'airy'];
|
|
318
260
|
const layoutDensityProfiles = Object.freeze({
|
|
319
261
|
compact: Object.freeze({
|
|
320
|
-
|
|
321
|
-
desktop: '
|
|
322
|
-
mobile: '
|
|
262
|
+
blockGap: Object.freeze({
|
|
263
|
+
desktop: '1.25em',
|
|
264
|
+
mobile: '1.1em',
|
|
323
265
|
}),
|
|
324
266
|
finalSectionBottom: Object.freeze({
|
|
325
267
|
desktop: 'clamp(1.2rem, 2.4vw, 2.25rem)',
|
|
@@ -329,6 +271,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
329
271
|
desktop: 'clamp(1rem, 2vw, 1.75rem)',
|
|
330
272
|
mobile: '1rem',
|
|
331
273
|
}),
|
|
274
|
+
headingToBlock: Object.freeze({
|
|
275
|
+
desktop: '0.65em',
|
|
276
|
+
mobile: '0.6em',
|
|
277
|
+
}),
|
|
332
278
|
imageGap: Object.freeze({
|
|
333
279
|
desktop: 'clamp(1rem, 2vw, 1.5rem)',
|
|
334
280
|
mobile: '1.25rem',
|
|
@@ -339,9 +285,9 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
339
285
|
}),
|
|
340
286
|
}),
|
|
341
287
|
normal: Object.freeze({
|
|
342
|
-
|
|
343
|
-
desktop: '1.
|
|
344
|
-
mobile: '
|
|
288
|
+
blockGap: Object.freeze({
|
|
289
|
+
desktop: '1.5em',
|
|
290
|
+
mobile: '1.25em',
|
|
345
291
|
}),
|
|
346
292
|
finalSectionBottom: Object.freeze({
|
|
347
293
|
desktop: 'clamp(1.4rem, 3vw, 2.75rem)',
|
|
@@ -351,6 +297,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
351
297
|
desktop: 'clamp(1.25rem, 3vw, 2.5rem)',
|
|
352
298
|
mobile: '1.25rem',
|
|
353
299
|
}),
|
|
300
|
+
headingToBlock: Object.freeze({
|
|
301
|
+
desktop: '0.75em',
|
|
302
|
+
mobile: '0.7em',
|
|
303
|
+
}),
|
|
354
304
|
imageGap: Object.freeze({
|
|
355
305
|
desktop: 'clamp(1.25rem, 2.8vw, 2rem)',
|
|
356
306
|
mobile: '1.5rem',
|
|
@@ -361,9 +311,9 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
361
311
|
}),
|
|
362
312
|
}),
|
|
363
313
|
airy: Object.freeze({
|
|
364
|
-
|
|
365
|
-
desktop: '1.
|
|
366
|
-
mobile: '1.
|
|
314
|
+
blockGap: Object.freeze({
|
|
315
|
+
desktop: '1.75em',
|
|
316
|
+
mobile: '1.5em',
|
|
367
317
|
}),
|
|
368
318
|
finalSectionBottom: Object.freeze({
|
|
369
319
|
desktop: 'clamp(2.25rem, 5vw, 4.5rem)',
|
|
@@ -373,6 +323,10 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
373
323
|
desktop: 'clamp(2rem, 5vw, 4rem)',
|
|
374
324
|
mobile: '1.5rem',
|
|
375
325
|
}),
|
|
326
|
+
headingToBlock: Object.freeze({
|
|
327
|
+
desktop: '0.9em',
|
|
328
|
+
mobile: '0.8em',
|
|
329
|
+
}),
|
|
376
330
|
imageGap: Object.freeze({
|
|
377
331
|
desktop: 'clamp(1.5rem, 3.5vw, 2.75rem)',
|
|
378
332
|
mobile: '2rem',
|
|
@@ -383,51 +337,59 @@ const layoutDensityProfiles = Object.freeze({
|
|
|
383
337
|
}),
|
|
384
338
|
}),
|
|
385
339
|
});
|
|
386
|
-
const
|
|
387
|
-
const
|
|
340
|
+
export const resolveThemeVisualConfig = (theme, sourceLabel = siteThemeLabel) => {
|
|
341
|
+
const rawThemeConfig = assertObject(theme ?? {}, 'theme frontmatter', sourceLabel);
|
|
342
|
+
const rawLayoutConfig = assertObject(rawThemeConfig.layout ?? {}, 'layout', sourceLabel);
|
|
343
|
+
const rawLayoutSpacingConfig = assertObject(rawLayoutConfig.spacing ?? {}, 'layout.spacing', sourceLabel);
|
|
344
|
+
const rawGalleryConfig = assertObject(rawThemeConfig.gallery ?? {}, 'gallery', sourceLabel);
|
|
345
|
+
const rawTypographyConfig = assertObject(rawThemeConfig.typography ?? {}, 'typography', sourceLabel);
|
|
346
|
+
const resolvedLayoutDensity = readEnum(rawLayoutConfig, 'density', 'layout', layoutDensityNames, 'normal', sourceLabel);
|
|
347
|
+
const resolvedLayoutSpacingDefaults = layoutDensityProfiles[resolvedLayoutDensity];
|
|
348
|
+
|
|
349
|
+
return Object.freeze({
|
|
350
|
+
layout: Object.freeze({
|
|
351
|
+
density: resolvedLayoutDensity,
|
|
352
|
+
gutter: readResponsiveCssLength(rawLayoutConfig, 'gutter', 'layout', Object.freeze({
|
|
353
|
+
desktop: 'clamp(1.25rem, 4vw, 3rem)',
|
|
354
|
+
mobile: '1rem',
|
|
355
|
+
}), sourceLabel),
|
|
356
|
+
pageWidth: readCssLength(rawLayoutConfig, 'pageWidth', 'layout', '1180px', sourceLabel),
|
|
357
|
+
spacing: Object.freeze({
|
|
358
|
+
blockGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'blockGap', 'layout.spacing', resolvedLayoutSpacingDefaults.blockGap, sourceLabel),
|
|
359
|
+
finalSectionBottom: readResponsiveCssLength(rawLayoutSpacingConfig, 'finalSectionBottom', 'layout.spacing', resolvedLayoutSpacingDefaults.finalSectionBottom, sourceLabel),
|
|
360
|
+
firstSectionTop: readResponsiveCssLength(rawLayoutSpacingConfig, 'firstSectionTop', 'layout.spacing', resolvedLayoutSpacingDefaults.firstSectionTop, sourceLabel),
|
|
361
|
+
headingToBlock: readResponsiveCssLength(rawLayoutSpacingConfig, 'headingToBlock', 'layout.spacing', resolvedLayoutSpacingDefaults.headingToBlock, sourceLabel),
|
|
362
|
+
imageGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'imageGap', 'layout.spacing', resolvedLayoutSpacingDefaults.imageGap, sourceLabel),
|
|
363
|
+
sectionGap: readResponsiveCssLength(rawLayoutSpacingConfig, 'sectionGap', 'layout.spacing', resolvedLayoutSpacingDefaults.sectionGap, sourceLabel),
|
|
364
|
+
}),
|
|
365
|
+
}),
|
|
366
|
+
gallery: Object.freeze({
|
|
367
|
+
maxAvailableHeightPercent: readResponsivePercent(rawGalleryConfig, 'maxAvailableHeightPercent', 'gallery', Object.freeze({
|
|
368
|
+
desktop: 74,
|
|
369
|
+
mobile: 68,
|
|
370
|
+
}), sourceLabel),
|
|
371
|
+
maxAvailableWidthPercent: readResponsivePercent(rawGalleryConfig, 'maxAvailableWidthPercent', 'gallery', Object.freeze({
|
|
372
|
+
desktop: 100,
|
|
373
|
+
mobile: 100,
|
|
374
|
+
}), sourceLabel),
|
|
375
|
+
width: readCssLength(rawGalleryConfig, 'width', 'gallery', '900px', sourceLabel),
|
|
376
|
+
}),
|
|
377
|
+
typography: Object.freeze({
|
|
378
|
+
fontFamily: readFontFamily(rawTypographyConfig, 'fontFamily', 'typography', defaultFontFamily, sourceLabel),
|
|
379
|
+
}),
|
|
380
|
+
});
|
|
381
|
+
};
|
|
388
382
|
|
|
389
383
|
export const projectConfig = Object.freeze({
|
|
390
384
|
site: Object.freeze({
|
|
391
385
|
basePath: readBasePath(rawSite, 'basePath', 'site'),
|
|
392
386
|
url: readUrl(rawSite, 'url', 'site'),
|
|
393
387
|
}),
|
|
394
|
-
|
|
395
|
-
density: layoutDensity,
|
|
396
|
-
gutter: readResponsiveCssLength(rawLayout, 'gutter', 'layout', Object.freeze({
|
|
397
|
-
desktop: 'clamp(1.25rem, 4vw, 3rem)',
|
|
398
|
-
mobile: '1rem',
|
|
399
|
-
}), siteThemeLabel),
|
|
400
|
-
pageWidth: readCssLength(rawLayout, 'pageWidth', 'layout', '1180px', siteThemeLabel),
|
|
401
|
-
spacing: Object.freeze({
|
|
402
|
-
bodyToImages: readResponsiveCssLength(rawLayoutSpacing, 'bodyToImages', 'layout.spacing', layoutSpacingDefaults.bodyToImages, siteThemeLabel),
|
|
403
|
-
finalSectionBottom: readResponsiveCssLength(rawLayoutSpacing, 'finalSectionBottom', 'layout.spacing', layoutSpacingDefaults.finalSectionBottom, siteThemeLabel),
|
|
404
|
-
firstSectionTop: readResponsiveCssLength(rawLayoutSpacing, 'firstSectionTop', 'layout.spacing', layoutSpacingDefaults.firstSectionTop, siteThemeLabel),
|
|
405
|
-
imageGap: readResponsiveCssLength(rawLayoutSpacing, 'imageGap', 'layout.spacing', layoutSpacingDefaults.imageGap, siteThemeLabel),
|
|
406
|
-
sectionGap: readResponsiveCssLength(rawLayoutSpacing, 'sectionGap', 'layout.spacing', layoutSpacingDefaults.sectionGap, siteThemeLabel),
|
|
407
|
-
}),
|
|
408
|
-
}),
|
|
409
|
-
gallery: Object.freeze({
|
|
410
|
-
maxAvailableHeightPercent: readResponsivePercent(rawGallery, 'maxAvailableHeightPercent', 'gallery', Object.freeze({
|
|
411
|
-
desktop: 74,
|
|
412
|
-
mobile: 68,
|
|
413
|
-
}), siteThemeLabel),
|
|
414
|
-
maxAvailableWidthPercent: readResponsivePercent(rawGallery, 'maxAvailableWidthPercent', 'gallery', Object.freeze({
|
|
415
|
-
desktop: 100,
|
|
416
|
-
mobile: 100,
|
|
417
|
-
}), siteThemeLabel),
|
|
418
|
-
width: readCssLength(rawGallery, 'width', 'gallery', '900px', siteThemeLabel),
|
|
419
|
-
}),
|
|
420
|
-
typography: Object.freeze({
|
|
421
|
-
fontFamily: readFontFamily(rawTypography, 'fontFamily', 'typography', defaultFontFamily, siteThemeLabel),
|
|
422
|
-
}),
|
|
388
|
+
...resolveThemeVisualConfig(rawTheme, siteThemeLabel),
|
|
423
389
|
navigation: Object.freeze({
|
|
424
390
|
smoothScroll: readSmoothScroll(rawNavigation),
|
|
425
391
|
}),
|
|
426
392
|
locale: readLocale(rawLocale),
|
|
427
|
-
footer: Object.freeze({
|
|
428
|
-
buildInfo: readBuildInfo(rawFooter),
|
|
429
|
-
copyrightMessage: readOptionalString(rawFooter, 'copyrightMessage', 'footer'),
|
|
430
|
-
}),
|
|
431
393
|
github: Object.freeze({
|
|
432
394
|
repo: readString(rawGithub, 'repo', 'github'),
|
|
433
395
|
branch: readString(rawGithub, 'branch', 'github'),
|
|
@@ -18,21 +18,20 @@ export const supportedImageExtensions = new Set([...rasterImageExtensions, ...st
|
|
|
18
18
|
|
|
19
19
|
const h2Regex = /^##\s+.*$/gm;
|
|
20
20
|
const explicitHeadingIdRegex = /\s*\{#([a-z0-9-]+)\}\s*$/;
|
|
21
|
-
const
|
|
21
|
+
const deprecatedInlineStyleReferenceRegex = /\[[^\]\n]+\]\{\.([a-z][a-z0-9-]*)\}/g;
|
|
22
22
|
const frontmatterDelimiterRegex = /^---\s*$/;
|
|
23
|
-
const knownContentTopLevelFrontmatterKeys = new Set(['title', 'description', 'navigation', '
|
|
24
|
-
const knownThemeTopLevelFrontmatterKeys = new Set(['navigation', 'layout', 'gallery', 'typography', 'presentation'
|
|
23
|
+
const knownContentTopLevelFrontmatterKeys = new Set(['title', 'description', 'navigation', 'sections']);
|
|
24
|
+
const knownThemeTopLevelFrontmatterKeys = new Set(['navigation', 'layout', 'gallery', 'typography', 'presentation']);
|
|
25
|
+
const knownRouteThemeTopLevelFrontmatterKeys = new Set(['navigation', 'layout', 'gallery', 'typography', 'presentation']);
|
|
26
|
+
const knownSitewideTopLevelFrontmatterKeys = new Set(['navigation', 'banners', 'footer']);
|
|
25
27
|
const knownNestedFrontmatterKeys = new Set([
|
|
26
28
|
'align',
|
|
27
29
|
'alt',
|
|
28
|
-
'backgroundColor',
|
|
29
30
|
'body',
|
|
30
|
-
'
|
|
31
|
+
'blockGap',
|
|
31
32
|
'brand',
|
|
32
33
|
'caption',
|
|
33
34
|
'carousel',
|
|
34
|
-
'color',
|
|
35
|
-
'colors',
|
|
36
35
|
'density',
|
|
37
36
|
'desktop',
|
|
38
37
|
'fontFamily',
|
|
@@ -40,6 +39,7 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
40
39
|
'finalSectionBottom',
|
|
41
40
|
'gallery',
|
|
42
41
|
'gutter',
|
|
42
|
+
'headingToBlock',
|
|
43
43
|
'h1',
|
|
44
44
|
'h2',
|
|
45
45
|
'h3',
|
|
@@ -50,8 +50,8 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
50
50
|
'include',
|
|
51
51
|
'image',
|
|
52
52
|
'imageGap',
|
|
53
|
-
'inlineStyles',
|
|
54
53
|
'label',
|
|
54
|
+
'logo',
|
|
55
55
|
'lineHeight',
|
|
56
56
|
'maxAvailableHeightPercent',
|
|
57
57
|
'maxAvailableWidthPercent',
|
|
@@ -60,15 +60,18 @@ const knownNestedFrontmatterKeys = new Set([
|
|
|
60
60
|
'overrides',
|
|
61
61
|
'paragraphSpacing',
|
|
62
62
|
'pageWidth',
|
|
63
|
+
'palette',
|
|
63
64
|
'preset',
|
|
64
65
|
'presentation',
|
|
65
66
|
'rhythm',
|
|
67
|
+
'sequence',
|
|
66
68
|
'sections',
|
|
67
69
|
'sectionGap',
|
|
70
|
+
'sectionSurfaces',
|
|
68
71
|
'size',
|
|
69
72
|
'spacingAfter',
|
|
70
73
|
'spacingBefore',
|
|
71
|
-
'
|
|
74
|
+
'surface',
|
|
72
75
|
'theme',
|
|
73
76
|
'typography',
|
|
74
77
|
'until',
|
|
@@ -273,6 +276,18 @@ export const validateThemeFrontmatterStructure = (frontmatter, addIssue) =>
|
|
|
273
276
|
fileKind: 'theme',
|
|
274
277
|
});
|
|
275
278
|
|
|
279
|
+
export const validateRouteThemeFrontmatterStructure = (frontmatter, addIssue) =>
|
|
280
|
+
validateFrontmatterStructure(frontmatter, addIssue, {
|
|
281
|
+
knownTopLevelFrontmatterKeys: knownRouteThemeTopLevelFrontmatterKeys,
|
|
282
|
+
fileKind: 'route theme',
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
export const validateSitewideFrontmatterStructure = (frontmatter, addIssue) =>
|
|
286
|
+
validateFrontmatterStructure(frontmatter, addIssue, {
|
|
287
|
+
knownTopLevelFrontmatterKeys: knownSitewideTopLevelFrontmatterKeys,
|
|
288
|
+
fileKind: 'sitewide content',
|
|
289
|
+
});
|
|
290
|
+
|
|
276
291
|
export const readThemeFile = async (sitePath) => readSiteFile(sitePath, siteThemeLabel);
|
|
277
292
|
|
|
278
293
|
export const getFrontmatterSections = (frontmatter) => {
|
|
@@ -298,42 +313,11 @@ export const getFrontmatterSections = (frontmatter) => {
|
|
|
298
313
|
return sections;
|
|
299
314
|
};
|
|
300
315
|
|
|
301
|
-
export const
|
|
302
|
-
const names = new Set();
|
|
303
|
-
const lines = frontmatter.split(/\r?\n/);
|
|
304
|
-
let inlineStylesIndent = null;
|
|
305
|
-
|
|
306
|
-
for (const line of lines) {
|
|
307
|
-
const inlineStylesMatch = line.match(/^(\s*)inlineStyles:\s*$/);
|
|
308
|
-
|
|
309
|
-
if (inlineStylesMatch) {
|
|
310
|
-
inlineStylesIndent = inlineStylesMatch[1].length;
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (inlineStylesIndent === null) continue;
|
|
315
|
-
if (!line.trim() || line.trim().startsWith('#')) continue;
|
|
316
|
-
|
|
317
|
-
const indent = line.match(/^\s*/)?.[0].length ?? 0;
|
|
318
|
-
if (indent <= inlineStylesIndent) {
|
|
319
|
-
inlineStylesIndent = null;
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const nameMatch = line.match(new RegExp(`^\\s{${inlineStylesIndent + 2}}([a-z][a-z0-9-]*):\\s*$`));
|
|
324
|
-
if (nameMatch) {
|
|
325
|
-
names.add(nameMatch[1]);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return names;
|
|
330
|
-
};
|
|
316
|
+
export const getHeadingId = (heading) => heading.match(explicitHeadingIdRegex)?.[1];
|
|
331
317
|
|
|
332
|
-
export const
|
|
318
|
+
export const getDeprecatedInlineStyleReferences = (body) => Array.from(body.matchAll(deprecatedInlineStyleReferenceRegex))
|
|
333
319
|
.map((match) => match[1]);
|
|
334
320
|
|
|
335
|
-
export const getHeadingId = (heading) => heading.match(explicitHeadingIdRegex)?.[1];
|
|
336
|
-
|
|
337
321
|
export const getBodySections = (body) => {
|
|
338
322
|
const matches = Array.from(body.matchAll(h2Regex));
|
|
339
323
|
const prelude = matches.length > 0 ? body.slice(0, matches[0].index) : body;
|
|
@@ -117,6 +117,7 @@ export const siteDir = resolvedSitePaths.siteDir;
|
|
|
117
117
|
export const siteConfigPath = path.join(siteDir, 'config.mjs');
|
|
118
118
|
export const siteThemePath = path.join(siteDir, 'theme.md');
|
|
119
119
|
export const siteContentPath = path.join(siteDir, 'content.md');
|
|
120
|
+
export const sitewideContentPath = path.join(siteDir, 'sitewide-content.md');
|
|
120
121
|
export const siteImagesDir = path.join(siteDir, 'images');
|
|
121
122
|
export const siteRoutesDir = path.join(siteDir, 'routes');
|
|
122
123
|
export const sitePublicDir = path.join(siteDir, 'public');
|
|
@@ -135,6 +136,7 @@ export const siteDirLabel = getPathLabel(siteDir);
|
|
|
135
136
|
export const siteConfigLabel = getPathLabel(siteConfigPath);
|
|
136
137
|
export const siteThemeLabel = getPathLabel(siteThemePath);
|
|
137
138
|
export const siteContentLabel = getPathLabel(siteContentPath);
|
|
139
|
+
export const sitewideContentLabel = getPathLabel(sitewideContentPath);
|
|
138
140
|
export const siteImagesLabel = getPathLabel(siteImagesDir);
|
|
139
141
|
export const siteRoutesLabel = getPathLabel(siteRoutesDir);
|
|
140
142
|
export const sitePublicLabel = getPathLabel(sitePublicDir);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { parseYamlMapping } from './frontmatter-yaml.mjs';
|
|
3
|
+
import {
|
|
4
|
+
sitewideContentLabel,
|
|
5
|
+
sitewideContentPath,
|
|
6
|
+
} from './site-paths.mjs';
|
|
7
|
+
import {
|
|
8
|
+
splitSiteFile,
|
|
9
|
+
validateFrontmatterIndentation,
|
|
10
|
+
validateSitewideFrontmatterStructure,
|
|
11
|
+
} from './site-content.mjs';
|
|
12
|
+
|
|
13
|
+
export const readSitewideConfig = async () => {
|
|
14
|
+
const source = await readFile(sitewideContentPath, 'utf8').catch((error) => {
|
|
15
|
+
if (error?.code === 'ENOENT') return null;
|
|
16
|
+
throw error;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
if (!source) return {};
|
|
20
|
+
|
|
21
|
+
const { frontmatter, frontmatterBody } = splitSiteFile(source, sitewideContentLabel);
|
|
22
|
+
const issues = [];
|
|
23
|
+
validateFrontmatterIndentation(frontmatter, (issue) => issues.push(issue));
|
|
24
|
+
validateSitewideFrontmatterStructure(frontmatter, (issue) => issues.push(issue));
|
|
25
|
+
|
|
26
|
+
if (issues.length > 0) {
|
|
27
|
+
throw new Error([
|
|
28
|
+
`${sitewideContentLabel} has invalid frontmatter.`,
|
|
29
|
+
...issues.map((issue) => `- ${issue.message}`),
|
|
30
|
+
].join('\n'));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return parseYamlMapping(frontmatterBody);
|
|
34
|
+
};
|