@berlysia/vertical-writing-slide-system 0.0.30 → 0.0.31

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@berlysia/vertical-writing-slide-system",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "vertical-slides": "./cli.js"
@@ -1,7 +1,8 @@
1
1
  import { existsSync } from "fs";
2
- import { mkdir, readdir, stat, cp, writeFile, mkdtemp, rm } from "fs/promises";
2
+ import { mkdir, readdir, stat, cp, writeFile, mkdtemp, rm, readFile, } from "fs/promises";
3
3
  import { join, resolve } from "path";
4
4
  import { build } from "vite";
5
+ import matter from "gray-matter";
5
6
  const defaultSlidesDir = resolve(import.meta.dirname, "..", "slides");
6
7
  const pagesDir = "pages";
7
8
  // Ensure pages directory exists
@@ -22,9 +23,49 @@ async function buildSlide(slideName) {
22
23
  await cp(tmpDir, slideOutputDir, { recursive: true });
23
24
  await rm(tmpDir, { recursive: true });
24
25
  }
25
- async function createIndexPage(slideNames) {
26
- const slides = slideNames
27
- .map((name) => ` <li><a href="${name}/">${name}</a></li>`)
26
+ /**
27
+ * スライドコレクションからメタデータを取得
28
+ */
29
+ async function getSlideMetadata(slidesDir, slideName) {
30
+ const mdxPath = join(slidesDir, slideName, "index.mdx");
31
+ const mdPath = join(slidesDir, slideName, "index.md");
32
+ let filePath;
33
+ if (existsSync(mdxPath)) {
34
+ filePath = mdxPath;
35
+ }
36
+ else if (existsSync(mdPath)) {
37
+ filePath = mdPath;
38
+ }
39
+ if (!filePath) {
40
+ return { title: slideName };
41
+ }
42
+ try {
43
+ const content = await readFile(filePath, "utf-8");
44
+ const parsed = matter(content);
45
+ return {
46
+ title: slideName,
47
+ ...parsed.data,
48
+ };
49
+ }
50
+ catch (error) {
51
+ console.warn(`Failed to parse frontmatter for ${slideName}: ${error}`);
52
+ return { title: slideName };
53
+ }
54
+ }
55
+ async function createIndexPage(slideNames, slidesDir) {
56
+ // 各スライドのメタデータを取得
57
+ const slideMetadataList = await Promise.all(slideNames.map(async (name) => ({
58
+ name,
59
+ metadata: await getSlideMetadata(slidesDir, name),
60
+ })));
61
+ const slides = slideMetadataList
62
+ .map(({ name, metadata }) => {
63
+ const displayTitle = metadata.title || name;
64
+ const description = metadata.description
65
+ ? ` - ${metadata.description}`
66
+ : "";
67
+ return ` <li><a href="${name}/">${displayTitle}</a>${description}</li>`;
68
+ })
28
69
  .join("\n");
29
70
  const html = `<!DOCTYPE html>
30
71
  <html>
@@ -56,7 +97,7 @@ export async function buildPages(options = {}) {
56
97
  for (const slide of slides) {
57
98
  await buildSlide(slide);
58
99
  }
59
- await createIndexPage(slides);
100
+ await createIndexPage(slides, resolvedSlidesDir);
60
101
  }
61
102
  // CLI entry point
62
103
  if (import.meta.url === `file://${process.argv[1]}`) {
package/src/App.tsx CHANGED
@@ -114,20 +114,10 @@ function App() {
114
114
  gotoNextSlide(false);
115
115
  }
116
116
  };
117
- const handleWheel = (event: WheelEvent) => {
118
- if (event.deltaY > 0) {
119
- gotoNextSlide();
120
- } else if (event.deltaY < 0) {
121
- gotoNextSlide(false);
122
- }
123
- };
124
117
  const controller = new AbortController();
125
118
  window.addEventListener("keydown", handleKeydown, {
126
119
  signal: controller.signal,
127
120
  });
128
- window.addEventListener("wheel", handleWheel, {
129
- signal: controller.signal,
130
- });
131
121
  return () => {
132
122
  controller.abort();
133
123
  };