@san-siva/blogkit-md 0.3.22 → 0.3.24

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/dist/index.d.mts CHANGED
@@ -1,13 +1,19 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React, { ReactNode } from 'react';
2
3
  import { WithContext, Thing } from 'schema-dts';
3
- import React from 'react';
4
+
5
+ type BlogPageProperties = {
6
+ children: ReactNode;
7
+ };
8
+ declare const BlogPage: ({ children }: BlogPageProperties) => react_jsx_runtime.JSX.Element;
4
9
 
5
10
  type BlogPostProperties = {
6
11
  filePath: string;
7
12
  jsonLd?: WithContext<Thing>;
8
13
  increasedWidthMode?: boolean;
14
+ isTocEnabled?: boolean;
9
15
  };
10
- declare const BlogPost: ({ filePath, jsonLd, increasedWidthMode, }: BlogPostProperties) => Promise<react_jsx_runtime.JSX.Element>;
16
+ declare const BlogPost: ({ filePath, jsonLd, increasedWidthMode, isTocEnabled, }: BlogPostProperties) => Promise<react_jsx_runtime.JSX.Element>;
11
17
 
12
18
  type RenderedMarkdown = {
13
19
  sections: React.ReactNode[];
@@ -27,4 +33,4 @@ type MarkdownFileResult = {
27
33
  };
28
34
  declare const readMarkdownFile: (filePath: string | undefined) => Promise<MarkdownFileResult>;
29
35
 
30
- export { BlogPost, MarkdownSections, readMarkdownFile };
36
+ export { BlogPage, BlogPost, MarkdownSections, readMarkdownFile };
package/dist/index.js CHANGED
@@ -1,5 +1,43 @@
1
+ // src/components/BlogPage.tsx
2
+ import { Blog, CheckList } from "@san-siva/blogkit";
3
+ import { useSyncExternalStore } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var STORAGE_KEY = "blogkit-md:increased-width-mode";
6
+ var increasedWidthMode = typeof localStorage === "undefined" ? false : localStorage.getItem(STORAGE_KEY) === "true";
7
+ var listeners = /* @__PURE__ */ new Set();
8
+ var subscribe = (listener) => {
9
+ listeners.add(listener);
10
+ return () => listeners.delete(listener);
11
+ };
12
+ var getSnapshot = () => increasedWidthMode;
13
+ var setIncreasedWidthMode = (value) => {
14
+ increasedWidthMode = value;
15
+ localStorage.setItem(STORAGE_KEY, String(value));
16
+ for (const listener of listeners) listener();
17
+ };
18
+ var BlogPage = ({ children }) => {
19
+ const checked = useSyncExternalStore(subscribe, getSnapshot, () => false);
20
+ return /* @__PURE__ */ jsxs(Blog, { increasedWidthMode: checked, children: [
21
+ /* @__PURE__ */ jsx(
22
+ CheckList,
23
+ {
24
+ items: [
25
+ {
26
+ id: "increased-width-mode",
27
+ isChecked: checked,
28
+ onClick: () => setIncreasedWidthMode(!checked),
29
+ children: /* @__PURE__ */ jsx("p", { children: "Increased width mode" })
30
+ }
31
+ ]
32
+ }
33
+ ),
34
+ children
35
+ ] });
36
+ };
37
+ var BlogPage_default = BlogPage;
38
+
1
39
  // src/components/BlogPost.tsx
2
- import { Blog, BlogHeader, Callout as Callout2 } from "@san-siva/blogkit";
40
+ import { Blog as Blog2, BlogHeader, Callout as Callout2 } from "@san-siva/blogkit";
3
41
  import { readFile } from "fs/promises";
4
42
  import path from "path";
5
43
 
@@ -63,7 +101,7 @@ var parseMarkdown = (content) => {
63
101
  import {
64
102
  BlogSection,
65
103
  Callout,
66
- CheckList,
104
+ CheckList as CheckList2,
67
105
  CodeBlock,
68
106
  Mermaid,
69
107
  Table
@@ -132,7 +170,7 @@ var groupSections = (nodes) => {
132
170
 
133
171
  // src/utils/renderPhrasingContent.tsx
134
172
  import styles from "@san-siva/stylekit/styles/index.module.scss";
135
- import { jsx } from "react/jsx-runtime";
173
+ import { jsx as jsx2 } from "react/jsx-runtime";
136
174
  function escapeHtml(text) {
137
175
  return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
138
176
  }
@@ -172,7 +210,7 @@ function toHtmlString(nodes) {
172
210
  }
173
211
  function renderPhrasingContent(nodes) {
174
212
  if (nodes.some((node) => node.type === "html")) {
175
- return /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: toHtmlString(nodes) } });
213
+ return /* @__PURE__ */ jsx2("span", { dangerouslySetInnerHTML: { __html: toHtmlString(nodes) } });
176
214
  }
177
215
  return nodes.map((node, index) => {
178
216
  var _a;
@@ -181,22 +219,22 @@ function renderPhrasingContent(nodes) {
181
219
  return node.value;
182
220
  }
183
221
  case "strong": {
184
- return /* @__PURE__ */ jsx("strong", { children: renderPhrasingContent(node.children) }, index);
222
+ return /* @__PURE__ */ jsx2("strong", { children: renderPhrasingContent(node.children) }, index);
185
223
  }
186
224
  case "emphasis": {
187
- return /* @__PURE__ */ jsx("em", { children: renderPhrasingContent(node.children) }, index);
225
+ return /* @__PURE__ */ jsx2("em", { children: renderPhrasingContent(node.children) }, index);
188
226
  }
189
227
  case "inlineCode": {
190
- return /* @__PURE__ */ jsx("code", { children: node.value }, index);
228
+ return /* @__PURE__ */ jsx2("code", { children: node.value }, index);
191
229
  }
192
230
  case "link": {
193
- return /* @__PURE__ */ jsx("a", { href: node.url, className: styles["a--highlighted"], children: renderPhrasingContent(node.children) }, index);
231
+ return /* @__PURE__ */ jsx2("a", { href: node.url, className: styles["a--highlighted"], children: renderPhrasingContent(node.children) }, index);
194
232
  }
195
233
  case "break": {
196
- return /* @__PURE__ */ jsx("br", {}, index);
234
+ return /* @__PURE__ */ jsx2("br", {}, index);
197
235
  }
198
236
  case "image": {
199
- return /* @__PURE__ */ jsx(
237
+ return /* @__PURE__ */ jsx2(
200
238
  "img",
201
239
  {
202
240
  src: node.url,
@@ -215,7 +253,7 @@ function renderPhrasingContent(nodes) {
215
253
 
216
254
  // src/utils/renderMarkdown.tsx
217
255
  import styles2 from "@san-siva/stylekit/styles/index.module.scss";
218
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
256
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
219
257
  function renderNode({
220
258
  node,
221
259
  key,
@@ -228,17 +266,17 @@ function renderNode({
228
266
  switch (node.type) {
229
267
  case "paragraph": {
230
268
  if (inList) {
231
- return /* @__PURE__ */ jsx2("p", { children: renderPhrasingContent(node.children) }, key);
269
+ return /* @__PURE__ */ jsx3("p", { children: renderPhrasingContent(node.children) }, key);
232
270
  }
233
271
  const isFollowedByParagraph = (nextNode == null ? void 0 : nextNode.type) === "paragraph";
234
272
  const isLastInCallout = !nextNode && inCallout;
235
273
  const marginClass = isFollowedByParagraph ? styles2["margin-bottom--1"] : isLastInCallout ? void 0 : styles2["margin-bottom--2"];
236
- return /* @__PURE__ */ jsx2("p", { className: marginClass, children: renderPhrasingContent(node.children) }, key);
274
+ return /* @__PURE__ */ jsx3("p", { className: marginClass, children: renderPhrasingContent(node.children) }, key);
237
275
  }
238
276
  case "code": {
239
277
  if (node.lang === "mermaid") {
240
278
  const mermaidId = counters.mermaid++;
241
- return /* @__PURE__ */ jsx2(
279
+ return /* @__PURE__ */ jsx3(
242
280
  Mermaid,
243
281
  {
244
282
  id: `mermaid-${mermaidId}`,
@@ -249,7 +287,7 @@ function renderNode({
249
287
  key
250
288
  );
251
289
  }
252
- return /* @__PURE__ */ jsx2(
290
+ return /* @__PURE__ */ jsx3(
253
291
  CodeBlock,
254
292
  {
255
293
  language: (_a = node.lang) != null ? _a : "text",
@@ -261,10 +299,10 @@ function renderNode({
261
299
  );
262
300
  }
263
301
  case "heading": {
264
- return /* @__PURE__ */ jsx2("p", { className: styles2["margin-bottom--2"], children: /* @__PURE__ */ jsx2("strong", { children: renderPhrasingContent(node.children) }) }, key);
302
+ return /* @__PURE__ */ jsx3("p", { className: styles2["margin-bottom--2"], children: /* @__PURE__ */ jsx3("strong", { children: renderPhrasingContent(node.children) }) }, key);
265
303
  }
266
304
  case "thematicBreak": {
267
- return /* @__PURE__ */ jsx2("hr", { className: styles2["margin-bottom--2"] }, key);
305
+ return /* @__PURE__ */ jsx3("hr", { className: styles2["margin-bottom--2"] }, key);
268
306
  }
269
307
  case "table": {
270
308
  const [headerRow, ...bodyRows] = node.children;
@@ -272,9 +310,9 @@ function renderNode({
272
310
  (cell) => renderPhrasingContent(cell.children)
273
311
  );
274
312
  const rows = bodyRows.map(
275
- (row) => row.children.map((cell, index) => /* @__PURE__ */ jsx2("p", { children: renderPhrasingContent(cell.children) }, index))
313
+ (row) => row.children.map((cell, index) => /* @__PURE__ */ jsx3("p", { children: renderPhrasingContent(cell.children) }, index))
276
314
  );
277
- return /* @__PURE__ */ jsx2(
315
+ return /* @__PURE__ */ jsx3(
278
316
  Table,
279
317
  {
280
318
  headers,
@@ -303,7 +341,7 @@ function renderNode({
303
341
  }
304
342
  }
305
343
  }
306
- return /* @__PURE__ */ jsx2(Callout, { type: calloutType, hasMarginUp: true, hasMarginDown: true, children: /* @__PURE__ */ jsx2("div", { children: strippedChildren.map(
344
+ return /* @__PURE__ */ jsx3(Callout, { type: calloutType, hasMarginUp: true, hasMarginDown: true, children: /* @__PURE__ */ jsx3("div", { children: strippedChildren.map(
307
345
  (child, index) => renderNode({
308
346
  node: child,
309
347
  key: index,
@@ -320,17 +358,17 @@ function renderNode({
320
358
  if (isTaskList) {
321
359
  const items = node.children.map((item, index) => {
322
360
  const para = item.children.find((c) => c.type === "paragraph");
323
- const children = (para == null ? void 0 : para.type) === "paragraph" ? /* @__PURE__ */ jsx2("p", { children: renderPhrasingContent(para.children) }) : /* @__PURE__ */ jsx2("p", {});
361
+ const children = (para == null ? void 0 : para.type) === "paragraph" ? /* @__PURE__ */ jsx3("p", { children: renderPhrasingContent(para.children) }) : /* @__PURE__ */ jsx3("p", {});
324
362
  return {
325
363
  id: String(index),
326
364
  isChecked: item.checked === true,
327
365
  children
328
366
  };
329
367
  });
330
- return /* @__PURE__ */ jsx2(CheckList, { items, hasMarginUp: true, hasMarginDown: true }, key);
368
+ return /* @__PURE__ */ jsx3(CheckList2, { items, hasMarginUp: true, hasMarginDown: true }, key);
331
369
  }
332
370
  const Tag = node.ordered ? "ol" : "ul";
333
- return /* @__PURE__ */ jsx2(Tag, { className: styles2["margin-bottom--2"], children: node.children.map((item, index) => /* @__PURE__ */ jsx2("li", { children: item.children.map(
371
+ return /* @__PURE__ */ jsx3(Tag, { className: styles2["margin-bottom--2"], children: node.children.map((item, index) => /* @__PURE__ */ jsx3("li", { children: item.children.map(
334
372
  (child, index2) => renderNode({
335
373
  node: child,
336
374
  key: index2,
@@ -350,8 +388,8 @@ function renderNodes(nodes, counters) {
350
388
  );
351
389
  }
352
390
  function renderSection(section, counters, key = -1) {
353
- const title = section.titleNodes.length > 0 ? /* @__PURE__ */ jsx2("p", { children: renderPhrasingContent(section.titleNodes) }) : "";
354
- return /* @__PURE__ */ jsxs(BlogSection, { title, children: [
391
+ const title = section.titleNodes.length > 0 ? /* @__PURE__ */ jsx3("p", { children: renderPhrasingContent(section.titleNodes) }) : "";
392
+ return /* @__PURE__ */ jsxs2(BlogSection, { title, children: [
355
393
  renderNodes(section.nodes, counters),
356
394
  section.subsections.map(
357
395
  (subsection, index) => renderSection(subsection, counters, index)
@@ -369,28 +407,29 @@ var renderMarkdownAst = (ast) => {
369
407
  };
370
408
  var MarkdownSections = ({
371
409
  rendered
372
- }) => /* @__PURE__ */ jsx2(Fragment, { children: rendered.sections });
410
+ }) => /* @__PURE__ */ jsx3(Fragment, { children: rendered.sections });
373
411
 
374
412
  // src/components/BlogPost.tsx
375
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
413
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
376
414
  var BlogPost = async ({
377
415
  filePath,
378
416
  jsonLd,
379
- increasedWidthMode
417
+ increasedWidthMode: increasedWidthMode2,
418
+ isTocEnabled
380
419
  }) => {
381
420
  const absolutePath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath);
382
421
  let content;
383
422
  try {
384
423
  content = await readFile(absolutePath, "utf8");
385
424
  } catch (e) {
386
- return /* @__PURE__ */ jsx3(Blog, { increasedWidthMode, children: /* @__PURE__ */ jsx3(Callout2, { type: "warning", children: /* @__PURE__ */ jsxs2("p", { children: [
425
+ return /* @__PURE__ */ jsx4(Blog2, { increasedWidthMode: increasedWidthMode2, isTocEnabled, children: /* @__PURE__ */ jsx4(Callout2, { type: "warning", children: /* @__PURE__ */ jsxs3("p", { children: [
387
426
  'Could not read file: "',
388
427
  filePath,
389
428
  '". Make sure the path is correct and the file exists.'
390
429
  ] }) }) });
391
430
  }
392
431
  if (!content.trim()) {
393
- return /* @__PURE__ */ jsx3(Blog, { increasedWidthMode, children: /* @__PURE__ */ jsxs2(Callout2, { type: "warning", children: [
432
+ return /* @__PURE__ */ jsx4(Blog2, { increasedWidthMode: increasedWidthMode2, isTocEnabled, children: /* @__PURE__ */ jsxs3(Callout2, { type: "warning", children: [
394
433
  'File "',
395
434
  filePath,
396
435
  '" is empty.'
@@ -398,9 +437,9 @@ var BlogPost = async ({
398
437
  }
399
438
  const { ast, title, description: desc } = parseMarkdown(content);
400
439
  const rendered = renderMarkdownAst(ast);
401
- return /* @__PURE__ */ jsxs2(Blog, { jsonLd, increasedWidthMode, children: [
402
- title && /* @__PURE__ */ jsx3(BlogHeader, { title: [title], desc: desc ? [desc] : [] }),
403
- /* @__PURE__ */ jsx3(MarkdownSections, { rendered })
440
+ return /* @__PURE__ */ jsxs3(Blog2, { jsonLd, increasedWidthMode: increasedWidthMode2, isTocEnabled, children: [
441
+ title && /* @__PURE__ */ jsx4(BlogHeader, { title: [title], desc: desc ? [desc] : [] }),
442
+ /* @__PURE__ */ jsx4(MarkdownSections, { rendered })
404
443
  ] });
405
444
  };
406
445
  var BlogPost_default = BlogPost;
@@ -430,6 +469,7 @@ var readMarkdownFile = async (filePath) => {
430
469
  return { success: true, rendered, title, description };
431
470
  };
432
471
  export {
472
+ BlogPage_default as BlogPage,
433
473
  BlogPost_default as BlogPost,
434
474
  MarkdownSections,
435
475
  readMarkdownFile
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@san-siva/blogkit-md",
3
- "version": "0.3.22",
3
+ "version": "0.3.24",
4
4
  "description": "Converts markdown files into JSX blog posts for Blogkit",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -21,7 +21,7 @@
21
21
  "fix": "eslint . --config eslint.config.ts --fix"
22
22
  },
23
23
  "dependencies": {
24
- "@san-siva/blogkit": "^1.1.43",
24
+ "@san-siva/blogkit": "^1.1.44",
25
25
  "@san-siva/stylekit": "^1.0.14",
26
26
  "next": "^16.0.10",
27
27
  "react": "^19.0.0",
package/src/client.ts ADDED
@@ -0,0 +1 @@
1
+ export { default as BlogPage } from './components/BlogPage';
@@ -0,0 +1,53 @@
1
+ 'use client';
2
+
3
+ import { Blog, CheckList } from '@san-siva/blogkit';
4
+ import { useSyncExternalStore } from 'react';
5
+ import type { ReactNode } from 'react';
6
+
7
+ const STORAGE_KEY = 'blogkit-md:increased-width-mode';
8
+
9
+ let increasedWidthMode =
10
+ typeof localStorage === 'undefined'
11
+ ? false
12
+ : localStorage.getItem(STORAGE_KEY) === 'true';
13
+
14
+ const listeners = new Set<() => void>();
15
+
16
+ const subscribe = (listener: () => void) => {
17
+ listeners.add(listener);
18
+ return () => listeners.delete(listener);
19
+ };
20
+
21
+ const getSnapshot = () => increasedWidthMode;
22
+
23
+ const setIncreasedWidthMode = (value: boolean) => {
24
+ increasedWidthMode = value;
25
+ localStorage.setItem(STORAGE_KEY, String(value));
26
+ for (const listener of listeners) listener();
27
+ };
28
+
29
+ type BlogPageProperties = {
30
+ children: ReactNode;
31
+ };
32
+
33
+ const BlogPage = ({ children }: BlogPageProperties) => {
34
+ const checked = useSyncExternalStore(subscribe, getSnapshot, () => false);
35
+
36
+ return (
37
+ <Blog increasedWidthMode={checked}>
38
+ <CheckList
39
+ items={[
40
+ {
41
+ id: 'increased-width-mode',
42
+ isChecked: checked,
43
+ onClick: () => setIncreasedWidthMode(!checked),
44
+ children: <p>Increased width mode</p>,
45
+ },
46
+ ]}
47
+ />
48
+ {children}
49
+ </Blog>
50
+ );
51
+ };
52
+
53
+ export default BlogPage;
@@ -10,12 +10,14 @@ type BlogPostProperties = {
10
10
  filePath: string;
11
11
  jsonLd?: WithContext<Thing>;
12
12
  increasedWidthMode?: boolean;
13
+ isTocEnabled?: boolean;
13
14
  };
14
15
 
15
16
  const BlogPost = async ({
16
17
  filePath,
17
18
  jsonLd,
18
19
  increasedWidthMode,
20
+ isTocEnabled,
19
21
  }: BlogPostProperties) => {
20
22
  const absolutePath = path.isAbsolute(filePath)
21
23
  ? filePath
@@ -26,7 +28,7 @@ const BlogPost = async ({
26
28
  content = await readFile(absolutePath, 'utf8');
27
29
  } catch {
28
30
  return (
29
- <Blog increasedWidthMode={increasedWidthMode}>
31
+ <Blog increasedWidthMode={increasedWidthMode} isTocEnabled={isTocEnabled}>
30
32
  <Callout type="warning">
31
33
  <p>
32
34
  Could not read file: &quot;{filePath}&quot;. Make sure the path is
@@ -39,7 +41,7 @@ const BlogPost = async ({
39
41
 
40
42
  if (!content.trim()) {
41
43
  return (
42
- <Blog increasedWidthMode={increasedWidthMode}>
44
+ <Blog increasedWidthMode={increasedWidthMode} isTocEnabled={isTocEnabled}>
43
45
  <Callout type="warning">File &quot;{filePath}&quot; is empty.</Callout>
44
46
  </Blog>
45
47
  );
@@ -50,7 +52,7 @@ const BlogPost = async ({
50
52
  const rendered = renderMarkdownAst(ast);
51
53
 
52
54
  return (
53
- <Blog jsonLd={jsonLd} increasedWidthMode={increasedWidthMode}>
55
+ <Blog jsonLd={jsonLd} increasedWidthMode={increasedWidthMode} isTocEnabled={isTocEnabled}>
54
56
  {title && <BlogHeader title={[title]} desc={desc ? [desc] : []} />}
55
57
  <MarkdownSections rendered={rendered} />
56
58
  </Blog>
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as BlogPage } from './components/BlogPage';
1
2
  export { default as BlogPost } from './components/BlogPost';
2
3
  export { readMarkdownFile } from './hooks/readMarkdownFile';
3
4
  export { MarkdownSections } from './utils/renderMarkdown';