veslx 0.1.27 → 0.1.29

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.
Files changed (50) hide show
  1. package/bin/lib/build.ts +2 -1
  2. package/bin/lib/export.ts +214 -0
  3. package/bin/lib/serve.ts +2 -1
  4. package/dist/client/components/front-matter.js +46 -1
  5. package/dist/client/components/front-matter.js.map +1 -1
  6. package/dist/client/components/header.js +2 -24
  7. package/dist/client/components/header.js.map +1 -1
  8. package/dist/client/components/mdx-components.js +2 -0
  9. package/dist/client/components/mdx-components.js.map +1 -1
  10. package/dist/client/components/post-list-item.js +43 -0
  11. package/dist/client/components/post-list-item.js.map +1 -0
  12. package/dist/client/components/post-list.js +54 -79
  13. package/dist/client/components/post-list.js.map +1 -1
  14. package/dist/client/hooks/use-mdx-content.js +64 -4
  15. package/dist/client/hooks/use-mdx-content.js.map +1 -1
  16. package/dist/client/lib/content-classification.js +1 -22
  17. package/dist/client/lib/content-classification.js.map +1 -1
  18. package/dist/client/pages/content-router.js +2 -10
  19. package/dist/client/pages/content-router.js.map +1 -1
  20. package/dist/client/pages/home.js +20 -23
  21. package/dist/client/pages/home.js.map +1 -1
  22. package/dist/client/pages/index-post.js +34 -0
  23. package/dist/client/pages/index-post.js.map +1 -0
  24. package/dist/client/pages/post.js +1 -3
  25. package/dist/client/pages/post.js.map +1 -1
  26. package/dist/client/pages/slides.js +4 -3
  27. package/dist/client/pages/slides.js.map +1 -1
  28. package/package.json +1 -1
  29. package/plugin/src/plugin.ts +127 -30
  30. package/plugin/src/types.ts +34 -4
  31. package/src/components/front-matter.tsx +60 -3
  32. package/src/components/header.tsx +2 -20
  33. package/src/components/mdx-components.tsx +3 -1
  34. package/src/components/post-list-item.tsx +54 -0
  35. package/src/components/post-list.tsx +74 -116
  36. package/src/components/welcome.tsx +2 -2
  37. package/src/hooks/use-mdx-content.ts +96 -7
  38. package/src/index.css +17 -0
  39. package/src/lib/content-classification.ts +0 -24
  40. package/src/pages/content-router.tsx +6 -17
  41. package/src/pages/home.tsx +26 -58
  42. package/src/pages/index-post.tsx +59 -0
  43. package/src/pages/post.tsx +1 -3
  44. package/src/pages/slides.tsx +5 -3
  45. package/src/vite-env.d.ts +11 -1
  46. package/vite.config.ts +4 -3
  47. package/dist/client/components/running-bar.js +0 -15
  48. package/dist/client/components/running-bar.js.map +0 -1
  49. package/src/components/content-tabs.tsx +0 -64
  50. package/src/components/running-bar.tsx +0 -21
@@ -2,7 +2,6 @@ import { useParams } from "react-router-dom";
2
2
  import { findSlides, isSimulationRunning, useDirectory } from "../../plugin/src/client";
3
3
  import Loading from "@/components/loading";
4
4
  import { FileEntry } from "plugin/src/lib";
5
- import { RunningBar } from "@/components/running-bar";
6
5
  import { Header } from "@/components/header";
7
6
  import { useMDXContent } from "@/hooks/use-mdx-content";
8
7
  import { mdxComponents } from "@/components/mdx-components";
@@ -41,7 +40,6 @@ export function Post() {
41
40
  return (
42
41
  <div className="flex min-h-screen flex-col bg-background noise-overlay">
43
42
  <title>{frontmatter?.title}</title>
44
- <RunningBar />
45
43
  <Header />
46
44
  <main className="flex-1 w-full overflow-x-clip">
47
45
  {isRunning && (
@@ -56,7 +54,7 @@ export function Post() {
56
54
 
57
55
  {Content && (
58
56
  <FrontmatterProvider frontmatter={frontmatter}>
59
- <article className="my-12 mx-auto px-[var(--page-padding)] prose dark:prose-invert prose-headings:tracking-tight prose-p:leading-relaxed prose-a:text-primary prose-a:no-underline hover:prose-a:underline max-w-[var(--content-width)] animate-fade-in">
57
+ <article className="mt-12 mb-64 mx-auto px-[var(--page-padding)] max-w-[var(--content-width)] animate-fade-in">
60
58
  <Content components={mdxComponents} />
61
59
  </article>
62
60
  </FrontmatterProvider>
@@ -2,11 +2,12 @@ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { FULLSCREEN_DATA_ATTR } from "@/lib/constants";
3
3
  import { useParams, useSearchParams } from "react-router-dom"
4
4
  import Loading from "@/components/loading";
5
- import { RunningBar } from "@/components/running-bar";
6
5
  import { Header } from "@/components/header";
7
6
  import { useMDXSlides } from "@/hooks/use-mdx-content";
8
7
  import { slidesMdxComponents } from "@/components/slides-renderer";
9
8
  import { FrontmatterProvider } from "@/lib/frontmatter-context";
9
+ import veslxConfig from "virtual:veslx-config";
10
+ import { cn } from "@/lib/utils";
10
11
 
11
12
 
12
13
  export function SlidesPage() {
@@ -121,10 +122,11 @@ export function SlidesPage() {
121
122
  );
122
123
  }
123
124
 
125
+ const scrollSnap = veslxConfig.slides.scrollSnap;
126
+
124
127
  return (
125
- <main className="slides-container">
128
+ <main className={cn("slides-container", scrollSnap && "slides-scroll-snap")}>
126
129
  <title>{frontmatter?.title}</title>
127
- <RunningBar />
128
130
  <Header
129
131
  slideControls={{
130
132
  current: currentSlide,
package/src/vite-env.d.ts CHANGED
@@ -9,6 +9,16 @@ declare module 'virtual:veslx-config' {
9
9
  github: string;
10
10
  defaultView: ContentView;
11
11
  }
12
- const config: SiteConfig;
12
+
13
+ interface SlidesConfig {
14
+ scrollSnap: boolean;
15
+ }
16
+
17
+ interface Config {
18
+ site: SiteConfig;
19
+ slides: SlidesConfig;
20
+ }
21
+
22
+ const config: Config;
13
23
  export default config;
14
24
  }
package/vite.config.ts CHANGED
@@ -80,11 +80,11 @@ export default defineConfig(({ command }) => {
80
80
  reactResolverPlugin(),
81
81
  tailwindcss(),
82
82
  // MDX for slides - splits at --- into <Slide> components
83
- // Matches: SLIDES.mdx, slides.mdx, *.slides.mdx
83
+ // Matches: SLIDES.mdx, SLIDES.md, slides.mdx, slides.md, *.slides.mdx, *.slides.md
84
84
  {
85
85
  enforce: 'pre',
86
86
  ...mdx({
87
- include: /SLIDES\.mdx$|slides\.mdx$/i,
87
+ include: /SLIDES\.mdx?$|slides\.mdx?$/i,
88
88
  remarkPlugins: [
89
89
  ...commonRemarkPlugins,
90
90
  remarkSlides, // Transform --- into <Slide> wrappers
@@ -97,7 +97,8 @@ export default defineConfig(({ command }) => {
97
97
  {
98
98
  enforce: 'pre',
99
99
  ...mdx({
100
- exclude: /SLIDES\.mdx$|slides\.mdx$/i,
100
+ include: /\.mdx?$/,
101
+ exclude: /SLIDES\.mdx?$|slides\.mdx?$/i,
101
102
  remarkPlugins: commonRemarkPlugins,
102
103
  rehypePlugins: [rehypeKatex],
103
104
  providerImportSource: '@mdx-js/react',
@@ -1,15 +0,0 @@
1
- import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
- import { isSimulationRunning } from "../plugin/src/client.js";
3
- function RunningBar() {
4
- const isRunning = isSimulationRunning();
5
- return /* @__PURE__ */ jsx(Fragment, { children: isRunning && // this should stay red not another color
6
- /* @__PURE__ */ jsx("div", { className: "running-bar sticky top-0 z-50 px-[var(--page-padding)] py-2 bg-red-500 text-primary-foreground font-mono text-xs text-center tracking-wide", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-3", children: [
7
- /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-pulse" }),
8
- /* @__PURE__ */ jsx("span", { className: "uppercase tracking-widest", children: "simulation running" }),
9
- /* @__PURE__ */ jsx("span", { className: "text-primary-foreground/60", children: "Page will auto-refresh on completion" })
10
- ] }) }) });
11
- }
12
- export {
13
- RunningBar
14
- };
15
- //# sourceMappingURL=running-bar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"running-bar.js","sources":["../../../src/components/running-bar.tsx"],"sourcesContent":["import { isSimulationRunning } from \"../../plugin/src/client\";\n\n\nexport function RunningBar() {\n const isRunning = isSimulationRunning();\n\n return (\n <>\n {isRunning && (\n // this should stay red not another color\n <div className=\"running-bar sticky top-0 z-50 px-[var(--page-padding)] py-2 bg-red-500 text-primary-foreground font-mono text-xs text-center tracking-wide\">\n <span className=\"inline-flex items-center gap-3\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-current animate-pulse\" />\n <span className=\"uppercase tracking-widest\">simulation running</span>\n <span className=\"text-primary-foreground/60\">Page will auto-refresh on completion</span>\n </span>\n </div>\n )}\n </>\n )\n}"],"names":[],"mappings":";;AAGO,SAAS,aAAa;AAC3B,QAAM,YAAY,oBAAA;AAElB,SACE,oBAAA,UAAA,EACG,UAAA;AAAA,sBAEE,OAAA,EAAI,WAAU,8IACb,UAAA,qBAAC,QAAA,EAAK,WAAU,kCACd,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,WAAU,oDAAA,CAAoD;AAAA,IACpE,oBAAC,QAAA,EAAK,WAAU,6BAA4B,UAAA,sBAAkB;AAAA,IAC9D,oBAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,uCAAA,CAAoC;AAAA,EAAA,EAAA,CACnF,GACF,GAEJ;AAEJ;"}
@@ -1,64 +0,0 @@
1
- import { Link } from "react-router-dom";
2
- import { cn } from "@/lib/utils";
3
- import type { ContentView } from "@/lib/content-classification";
4
-
5
- interface ContentTabsProps {
6
- value: ContentView;
7
- counts: { posts: number; docs: number; all: number };
8
- }
9
-
10
- const views: { key: ContentView; label: string; path: string }[] = [
11
- { key: "posts", label: "Posts", path: "/posts" },
12
- { key: "docs", label: "Docs", path: "/docs" },
13
- // { key: "all", label: "All", path: "/all" },
14
- ];
15
-
16
- export function ContentTabs({ value, counts }: ContentTabsProps) {
17
- const hasOnlyPosts = counts.posts > 0 && counts.docs === 0;
18
- const hasOnlyDocs = counts.docs > 0 && counts.posts === 0;
19
-
20
- if (hasOnlyPosts || hasOnlyDocs) {
21
- return null;
22
- }
23
-
24
- const isDisabled = (key: ContentView) => {
25
- if (key === "posts") return counts.posts === 0;
26
- if (key === "docs") return counts.docs === 0;
27
- return false;
28
- };
29
-
30
- return (
31
- <nav className="flex items-center gap-3 font-mono font-medium text-xs text-muted-foreground">
32
- {views.map((view) => {
33
- const disabled = isDisabled(view.key);
34
-
35
- if (disabled) {
36
- return (
37
- <span
38
- key={view.key}
39
- className="opacity-30 cursor-not-allowed"
40
- >
41
- {view.label}
42
- </span>
43
- );
44
- }
45
-
46
- return (
47
- <Link
48
- key={view.key}
49
- to={view.path}
50
- className={cn(
51
- "transition-colors duration-150",
52
- "hover:text-foreground hover:underline hover:underline-offset-4 hover:decoration-primary/60",
53
- value === view.key
54
- ? "text-foreground underline-offset-4 decoration-primary/60"
55
- : ""
56
- )}
57
- >
58
- {view.label}
59
- </Link>
60
- );
61
- })}
62
- </nav>
63
- );
64
- }
@@ -1,21 +0,0 @@
1
- import { isSimulationRunning } from "../../plugin/src/client";
2
-
3
-
4
- export function RunningBar() {
5
- const isRunning = isSimulationRunning();
6
-
7
- return (
8
- <>
9
- {isRunning && (
10
- // this should stay red not another color
11
- <div className="running-bar sticky top-0 z-50 px-[var(--page-padding)] py-2 bg-red-500 text-primary-foreground font-mono text-xs text-center tracking-wide">
12
- <span className="inline-flex items-center gap-3">
13
- <span className="h-1.5 w-1.5 rounded-full bg-current animate-pulse" />
14
- <span className="uppercase tracking-widest">simulation running</span>
15
- <span className="text-primary-foreground/60">Page will auto-refresh on completion</span>
16
- </span>
17
- </div>
18
- )}
19
- </>
20
- )
21
- }