astro-theme-popular 0.14.0 → 0.14.2

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/index.mjs CHANGED
@@ -27,8 +27,10 @@ import Slugger from 'github-slugger';
27
27
  survive a subpath install (parity with Hugo's render hooks passing paths
28
28
  through relURL). Everything the templates write is handled by src/lib/url.ts
29
29
  instead; MDX component props (<Photo src="/images/x.png">) are JSX, not HAST,
30
- so the components prefix those themselves. And a hover "#" anchor on every
31
- h2-h6, so each section has a copyable URL (Hugo's render-heading.html).
30
+ so the components prefix those themselves. A hover "#" anchor on every
31
+ h2-h6, so each section has a copyable URL (Hugo's render-heading.html). And
32
+ a <div class="g-table-scroll"> around every table, so a wide table scrolls
33
+ sideways on a phone instead of stretching the page (Hugo's render-table.html).
32
34
 
33
35
  Registered on the active markdown processor rather than through
34
36
  `markdown.rehypePlugins`: Astro 7's default processor is Sätteri, which does
@@ -73,6 +75,20 @@ const anchorNode = (id) => ({
73
75
  children: [], // the "#" is CSS generated content; see base.css
74
76
  });
75
77
 
78
+ /* Wide tables: every markdown <table> is wrapped in <div class="g-table-scroll">
79
+ (base.css: overflow-x: auto) so a table with more columns than a phone is
80
+ wide scrolls inside the page instead of stretching it. The wrapper scrolls,
81
+ not the table: `display: block; overflow-x: auto` on the table itself would
82
+ drop its table semantics for screen readers. Parity with Hugo's
83
+ render-table.html. A table an earlier hast plugin already wrapped is left
84
+ alone; a wrapper hand-written around a table in markdown or MDX is raw
85
+ HTML or JSX rather than a hast div, so it is not detected and the table
86
+ gets a second, harmless wrapper inside it. */
87
+ const TABLE_WRAPPER = 'g-table-scroll';
88
+ const tableWrapper = () => ({ type: 'element', tagName: 'div', properties: { className: [TABLE_WRAPPER] }, children: [] });
89
+ const isTableWrapper = (node) =>
90
+ node?.type === 'element' && node.tagName === 'div' && [].concat(node.properties?.className ?? []).includes(TABLE_WRAPPER);
91
+
76
92
  /* Heading text the way Astro's own heading-id plugins read it: text nodes,
77
93
  plus MDX `{frontmatter.x}` expressions resolved against the frontmatter
78
94
  (mirrors collectHastText in @astrojs/markdown-satteri, which is not a
@@ -125,6 +141,12 @@ function satteriMarkdownHooks(prefix) {
125
141
  if (href !== props.href) ctx.setProperty(node, 'href', href);
126
142
  },
127
143
  },
144
+ {
145
+ filter: ['table'],
146
+ visit(node, ctx) {
147
+ if (!isTableWrapper(ctx.parent(node))) ctx.wrapNode(node, tableWrapper());
148
+ },
149
+ },
128
150
  {
129
151
  filter: HEADINGS,
130
152
  visit(node, ctx) {
@@ -169,6 +191,11 @@ function rehypeMarkdownHooks(prefix) {
169
191
  if (node.tagName !== 'h1' && props.id) (node.children ??= []).push(anchorNode(props.id));
170
192
  }
171
193
  }
194
+ if (node.children && !isTableWrapper(node)) {
195
+ node.children = node.children.map((child) =>
196
+ child.type === 'element' && child.tagName === 'table' ? { ...tableWrapper(), children: [child] } : child,
197
+ );
198
+ }
172
199
  (node.children || []).forEach(walk);
173
200
  };
174
201
  walk(tree);
@@ -186,7 +213,7 @@ function registerMarkdownHooks(config, logger) {
186
213
  } else {
187
214
  logger.warn(
188
215
  `markdown.processor "${processor?.name ?? 'unknown'}" takes neither hastPlugins nor rehypePlugins: ` +
189
- 'markdown images will not get loading="lazy"' +
216
+ 'markdown images will not get loading="lazy", headings no "#" anchor, tables no scroll wrapper' +
190
217
  (prefix ? ', and site-absolute links in content will not carry the base' : ''),
191
218
  );
192
219
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-theme-popular",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Popular: a warm, community-first Astro theme for meetups, clubs and fan communities. Ships as an Astro integration.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/lib/ical.ts CHANGED
@@ -57,10 +57,10 @@ export function buildIcs(
57
57
  const L: string[] = [];
58
58
  L.push(fold('BEGIN:VCALENDAR'));
59
59
  L.push(fold('VERSION:2.0'));
60
- L.push(fold(`PRODID:-//${opts.siteTitle}//Popular theme//EN`));
60
+ L.push(fold(`PRODID:-//${icsEscape(opts.siteTitle)}//Popular theme//EN`));
61
61
  L.push(fold('CALSCALE:GREGORIAN'));
62
62
  L.push(fold('METHOD:PUBLISH'));
63
- L.push(fold(`X-WR-CALNAME:${opts.siteTitle} events`));
63
+ L.push(fold(`X-WR-CALNAME:${icsEscape(opts.siteTitle)} events`));
64
64
  /* Subscription refresh hints (RFC 7986 + the Apple/Outlook legacy twin).
65
65
  Google Calendar ignores both and polls on its own schedule. */
66
66
  L.push(fold('REFRESH-INTERVAL;VALUE=DURATION:PT12H'));
@@ -113,6 +113,25 @@ pre code { font-size: inherit; background: none; padding: 0; border-radius: 0; }
113
113
  !important beats the inline background-color that Chroma (Hugo) and
114
114
  Shiki (Astro) emit, and unhighlighted languages get the same canvas. */
115
115
  .g-prose pre { overflow-x: auto; padding: 1rem 1.2rem; border-radius: var(--radius-lg); background: var(--surface-code-block) !important; color: var(--ink-100); }
116
+ /* Markdown tables. Browser defaults draw no borders and no padding, so a
117
+ cell holding several sentences runs into the next one. Every cell gets a
118
+ thin border and the header row a wash. Text aligns start and top unless the
119
+ column asked for an alignment in markdown (`:---:`): Goldmark and Sätteri
120
+ emit that as an inline style, which beats this default on its own, and the
121
+ unified/rehype pipeline as an align attribute, which would lose to it, so
122
+ the three [align] rules restate it as author CSS (left included: start
123
+ is right on an RTL site, and `:---` asked for left). Each table is wrapped
124
+ in .g-table-scroll by the markdown hook (Astro) and render-table.html
125
+ (Hugo): the wrapper scrolls sideways when a table is wider than a phone,
126
+ so the table itself keeps its semantics (display: block; overflow-x: auto
127
+ on the <table> would drop them for screen readers). */
128
+ .g-table-scroll { overflow-x: auto; }
129
+ .g-prose table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); line-height: var(--leading-normal); }
130
+ .g-prose th, .g-prose td { border: var(--border-width) solid var(--border-default); padding: 0.55rem 0.75rem; text-align: start; vertical-align: top; }
131
+ .g-prose th { background: var(--surface-wash-soft); color: var(--text-strong); font-weight: var(--weight-semibold); }
132
+ .g-prose :is(th, td)[align="left"] { text-align: left; }
133
+ .g-prose :is(th, td)[align="center"] { text-align: center; }
134
+ .g-prose :is(th, td)[align="right"] { text-align: right; }
116
135
 
117
136
  /* Skip link for a11y */
118
137
  .g-skip { position: absolute; left: -999px; top: 0; background: var(--color-primary); color: #fff; padding: 0.6rem 1rem; border-radius: var(--radius-md); z-index: 100; }