@lad-sapienza/scms-core 0.1.0 → 0.1.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 CHANGED
@@ -50,7 +50,7 @@ export default defineConfig({
50
50
  });
51
51
  ```
52
52
 
53
- `scms()` bundles content-asset serving, the Gallery virtual module, Expressive Code, MDX, React, and sitemap integrations into one call, and self-registers the Vite config the components need — `dedupe`/`optimizeDeps` for React and `@tanstack/react-table` (avoids duplicate-module "Invalid hook call" errors) and `ssr.noExternal` for `maplibre-gl` (so the `Map` component's MapLibre v6 worker import resolves in the SSR pass). No extra Vite config required in the consumer.
53
+ `scms()` bundles content-asset serving, the Gallery virtual module, Expressive Code, MDX, React, and sitemap integrations into one call, and self-registers the Vite config the components need — `dedupe`/`optimizeDeps` for React and `@tanstack/react-table` (avoids duplicate-module "Invalid hook call" errors) and `ssr.noExternal` for `maplibre-gl` (so the `Map` component's MapLibre v6 worker import resolves in the SSR pass). It also links MapLibre's stylesheet from every page so `Map` controls and popups are styled however the MDX is rendered; pass `scms({ mapCss: false })` to opt out. No extra Vite config required in the consumer.
54
54
 
55
55
  Import components from the package root in any `.mdx` file:
56
56
 
@@ -177,6 +177,32 @@ add `popupTemplate`/`fitToContent`/`visible` (properties the style spec
177
177
  itself has no room for). See `MapProps` in [`types.ts`](./types.ts) for the
178
178
  exact shape.
179
179
 
180
+ ## Styles (MapLibre CSS)
181
+
182
+ `Map.tsx` imports `maplibre-gl/dist/maplibre-gl.css` itself, so you do not need
183
+ to import it yourself: it styles the layer control, zoom/compass buttons,
184
+ attribution and popups. Without it the map still renders, but those controls
185
+ and popups appear unstyled.
186
+
187
+ That import is not always linked from the page in production builds (`astro
188
+ dev` is unaffected). It is missed when `<Map>` is imported from an MDX
189
+ content-collection entry whose `render()`ed `Content` is passed as a prop to
190
+ another component (e.g. `<ArticlePage Content={Content} />`): Astro emits the
191
+ CSS file but no page links it. This happens with every client directive
192
+ (`client:load` and `client:only="react"` alike).
193
+
194
+ `scms()` works around this by linking the stylesheet from every page. If you
195
+ are on a version that predates that fix, or you set `scms({ mapCss: false })`
196
+ (e.g. because the site has no maps, or to avoid the stylesheet on pages
197
+ without one), import it once in your layout instead:
198
+
199
+ ```astro
200
+ ---
201
+ // src/layouts/BaseLayout.astro
202
+ import 'maplibre-gl/dist/maplibre-gl.css';
203
+ ---
204
+ ```
205
+
180
206
  ## Props
181
207
 
182
208
  ### `Map`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lad-sapienza/scms-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Framework components and Astro integrations for s:CMS — DataTb, Gallery, Map, ZoteroGeoViewer, Record.",
5
5
  "type": "module",
6
6
  "license": "BSD-0-Clause",
package/scms.ts CHANGED
@@ -36,6 +36,13 @@ export interface ScmsOptions {
36
36
  pagesDir?: string;
37
37
  /** Path to shared galleries, relative to the project root. Defaults to 'src/galleries'. */
38
38
  galleriesDir?: string;
39
+ /**
40
+ * Link MapLibre's stylesheet (`maplibre-gl/dist/maplibre-gl.css`, ~83 KB /
41
+ * ~11 KB gzipped) from every page — see `scmsMapCssIntegration`. Defaults to
42
+ * `true`. Set `false` for sites that never render `<Map>`, or that import the
43
+ * stylesheet themselves.
44
+ */
45
+ mapCss?: boolean;
39
46
  }
40
47
 
41
48
  /** react, react-dom, and any library that calls hooks internally (@tanstack/react-table) — see file doc comment. */
@@ -85,9 +92,12 @@ function scmsViteConfigIntegration(): AstroIntegration {
85
92
  // `maplibre-gl/dist/...?worker&url` import (see that file). Vite's
86
93
  // worker plugin can only resolve that specifier when maplibre-gl
87
94
  // is bundled for SSR rather than externalised to a raw Node
88
- // `import` — required for consumers that render <Map> with
89
- // `client:load`/`client:visible` (server pass) rather than
90
- // `client:only`. MapLibre's own Astro guidance calls for this.
95
+ // `import`. MapLibre's own Astro guidance calls for this.
96
+ //
97
+ // This is about the worker only. It has no bearing on whether the
98
+ // stylesheet reaches the page — that is a separate problem, with
99
+ // the same symptom under every client directive (`client:load`
100
+ // and `client:only` alike); see `scmsMapCssIntegration`.
91
101
  noExternal: ['maplibre-gl'],
92
102
  },
93
103
  },
@@ -109,8 +119,40 @@ function scmsThemeInitIntegration(): AstroIntegration {
109
119
  };
110
120
  }
111
121
 
122
+ /**
123
+ * Links MapLibre's stylesheet from every page.
124
+ *
125
+ * `Map.tsx` imports `maplibre-gl/dist/maplibre-gl.css` itself, which is enough
126
+ * when `<Map>` is imported straight into a page or layout. It is NOT enough
127
+ * for a `<Map>` imported from an MDX content-collection entry whose
128
+ * `render()`ed `Content` is handed down as a prop to another component (e.g.
129
+ * `<ArticlePage Content={Content} />`, which then renders `<Content />` inside
130
+ * a layout): Astro still emits the stylesheet but never links it from the
131
+ * page's HTML, so the layer control, zoom buttons and popups render unstyled
132
+ * in production builds. `astro dev` is unaffected (Vite injects CSS at
133
+ * runtime), which is why it only shows up after `astro build`. Reproduced on
134
+ * Astro 7.2.4 with `client:load` and `client:only="react"`.
135
+ *
136
+ * Importing the stylesheet from `page-ssr` puts it in every page's own module
137
+ * graph, so it is linked regardless of how the MDX is rendered. Costs: one
138
+ * cached, render-blocking ~11 KB (gzipped) request on pages that have no map —
139
+ * hence the `mapCss` opt-out — and, for a `<Map client:only>` imported
140
+ * directly into a page, a second identical-content file (Astro emits the
141
+ * island's copy separately), which is redundant but harmless.
142
+ */
143
+ function scmsMapCssIntegration(): AstroIntegration {
144
+ return {
145
+ name: 'scms-map-css',
146
+ hooks: {
147
+ 'astro:config:setup': ({ injectScript }) => {
148
+ injectScript('page-ssr', "import 'maplibre-gl/dist/maplibre-gl.css';");
149
+ },
150
+ },
151
+ };
152
+ }
153
+
112
154
  export function scms(options: ScmsOptions = {}): AstroIntegration[] {
113
- const { contentDir, pagesDir, galleriesDir } = options;
155
+ const { contentDir, pagesDir, galleriesDir, mapCss = true } = options;
114
156
 
115
157
  return [
116
158
  contentAssetsIntegration({ contentDir }),
@@ -125,5 +167,6 @@ export function scms(options: ScmsOptions = {}): AstroIntegration[] {
125
167
  sitemap(),
126
168
  scmsViteConfigIntegration(),
127
169
  scmsThemeInitIntegration(),
170
+ ...(mapCss ? [scmsMapCssIntegration()] : []),
128
171
  ];
129
172
  }