@jant/core 0.3.21 → 0.3.23

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 (99) hide show
  1. package/dist/app.js +23 -4
  2. package/dist/index.js +11 -4
  3. package/dist/lib/feed.js +112 -0
  4. package/dist/lib/navigation.js +9 -9
  5. package/dist/lib/render.js +48 -0
  6. package/dist/lib/theme-components.js +18 -18
  7. package/dist/lib/view.js +228 -0
  8. package/dist/routes/api/timeline.js +22 -18
  9. package/dist/routes/feed/rss.js +34 -78
  10. package/dist/routes/feed/sitemap.js +11 -26
  11. package/dist/routes/pages/archive.js +18 -195
  12. package/dist/routes/pages/collection.js +16 -70
  13. package/dist/routes/pages/home.js +25 -47
  14. package/dist/routes/pages/page.js +15 -27
  15. package/dist/routes/pages/post.js +25 -79
  16. package/dist/routes/pages/search.js +20 -130
  17. package/dist/theme/components/MediaGallery.js +10 -10
  18. package/dist/theme/components/index.js +0 -2
  19. package/dist/theme/index.js +10 -13
  20. package/dist/theme/layouts/index.js +0 -1
  21. package/dist/themes/minimal/MinimalSiteLayout.js +83 -0
  22. package/dist/themes/minimal/index.js +65 -0
  23. package/dist/themes/minimal/pages/ArchivePage.js +156 -0
  24. package/dist/themes/minimal/pages/CollectionPage.js +65 -0
  25. package/dist/themes/minimal/pages/HomePage.js +25 -0
  26. package/dist/themes/minimal/pages/PostPage.js +47 -0
  27. package/dist/themes/minimal/pages/SearchPage.js +121 -0
  28. package/dist/themes/minimal/pages/SinglePage.js +22 -0
  29. package/dist/themes/minimal/timeline/ArticleCard.js +36 -0
  30. package/dist/themes/minimal/timeline/ImageCard.js +67 -0
  31. package/dist/themes/minimal/timeline/LinkCard.js +47 -0
  32. package/dist/themes/minimal/timeline/NoteCard.js +34 -0
  33. package/dist/{theme/components → themes/minimal}/timeline/QuoteCard.js +9 -12
  34. package/dist/themes/minimal/timeline/ThreadPreview.js +46 -0
  35. package/dist/themes/minimal/timeline/TimelineFeed.js +48 -0
  36. package/dist/themes/minimal/timeline/TimelineItem.js +44 -0
  37. package/package.json +2 -1
  38. package/src/app.tsx +27 -4
  39. package/src/i18n/locales/en.po +53 -53
  40. package/src/i18n/locales/zh-Hans.po +53 -53
  41. package/src/i18n/locales/zh-Hant.po +53 -53
  42. package/src/index.ts +54 -6
  43. package/src/lib/__tests__/theme-components.test.ts +33 -14
  44. package/src/lib/__tests__/view.test.ts +377 -0
  45. package/src/lib/feed.ts +148 -0
  46. package/src/lib/navigation.ts +11 -11
  47. package/src/lib/render.tsx +67 -0
  48. package/src/lib/theme-components.ts +27 -35
  49. package/src/lib/view.ts +318 -0
  50. package/src/routes/api/__tests__/timeline.test.ts +3 -3
  51. package/src/routes/api/timeline.tsx +34 -27
  52. package/src/routes/feed/rss.ts +47 -94
  53. package/src/routes/feed/sitemap.ts +8 -30
  54. package/src/routes/pages/archive.tsx +24 -209
  55. package/src/routes/pages/collection.tsx +19 -75
  56. package/src/routes/pages/home.tsx +42 -76
  57. package/src/routes/pages/page.tsx +17 -28
  58. package/src/routes/pages/post.tsx +28 -86
  59. package/src/routes/pages/search.tsx +29 -151
  60. package/src/services/search.ts +2 -8
  61. package/src/styles/components.css +0 -54
  62. package/src/theme/components/MediaGallery.tsx +12 -12
  63. package/src/theme/components/index.ts +0 -12
  64. package/src/theme/index.ts +11 -13
  65. package/src/theme/layouts/index.ts +1 -1
  66. package/src/themes/minimal/MinimalSiteLayout.tsx +100 -0
  67. package/src/themes/minimal/index.ts +83 -0
  68. package/src/themes/minimal/pages/ArchivePage.tsx +157 -0
  69. package/src/themes/minimal/pages/CollectionPage.tsx +60 -0
  70. package/src/themes/minimal/pages/HomePage.tsx +41 -0
  71. package/src/themes/minimal/pages/PostPage.tsx +43 -0
  72. package/src/themes/minimal/pages/SearchPage.tsx +122 -0
  73. package/src/themes/minimal/pages/SinglePage.tsx +23 -0
  74. package/src/themes/minimal/timeline/ArticleCard.tsx +37 -0
  75. package/src/themes/minimal/timeline/ImageCard.tsx +63 -0
  76. package/src/themes/minimal/timeline/LinkCard.tsx +48 -0
  77. package/src/themes/minimal/timeline/NoteCard.tsx +35 -0
  78. package/src/{theme/components → themes/minimal}/timeline/QuoteCard.tsx +11 -17
  79. package/src/themes/minimal/timeline/ThreadPreview.tsx +47 -0
  80. package/src/{theme/components → themes/minimal}/timeline/TimelineFeed.tsx +20 -15
  81. package/src/themes/minimal/timeline/TimelineItem.tsx +75 -0
  82. package/src/types.ts +262 -38
  83. package/dist/theme/components/timeline/ArticleCard.js +0 -50
  84. package/dist/theme/components/timeline/ImageCard.js +0 -86
  85. package/dist/theme/components/timeline/LinkCard.js +0 -62
  86. package/dist/theme/components/timeline/NoteCard.js +0 -37
  87. package/dist/theme/components/timeline/ThreadPreview.js +0 -52
  88. package/dist/theme/components/timeline/TimelineFeed.js +0 -43
  89. package/dist/theme/components/timeline/TimelineItem.js +0 -25
  90. package/dist/theme/components/timeline/index.js +0 -8
  91. package/dist/theme/layouts/SiteLayout.js +0 -160
  92. package/src/theme/components/timeline/ArticleCard.tsx +0 -57
  93. package/src/theme/components/timeline/ImageCard.tsx +0 -80
  94. package/src/theme/components/timeline/LinkCard.tsx +0 -66
  95. package/src/theme/components/timeline/NoteCard.tsx +0 -41
  96. package/src/theme/components/timeline/ThreadPreview.tsx +0 -49
  97. package/src/theme/components/timeline/TimelineItem.tsx +0 -39
  98. package/src/theme/components/timeline/index.ts +0 -8
  99. package/src/theme/layouts/SiteLayout.tsx +0 -184
@@ -1,184 +0,0 @@
1
- /**
2
- * Site Layout
3
- *
4
- * Two-column layout for public pages with sidebar navigation.
5
- * On mobile, uses a slide-out drawer menu.
6
- */
7
-
8
- import type { FC, PropsWithChildren } from "hono/jsx";
9
- import type { NavigationLink } from "../../types.js";
10
-
11
- export interface SiteLayoutProps {
12
- siteName: string;
13
- navigationLinks: NavigationLink[];
14
- currentPath: string;
15
- }
16
-
17
- /**
18
- * Determine if a navigation link is active based on the current path.
19
- *
20
- * @param linkUrl - The link's URL
21
- * @param currentPath - The current page path
22
- * @returns Whether the link should be shown as active
23
- */
24
- function isLinkActive(linkUrl: string, currentPath: string): boolean {
25
- // External links are never active
26
- if (linkUrl.startsWith("http://") || linkUrl.startsWith("https://")) {
27
- return false;
28
- }
29
-
30
- // Exact match for home
31
- if (linkUrl === "/") {
32
- return currentPath === "/";
33
- }
34
-
35
- // Prefix match for other internal links
36
- return currentPath === linkUrl || currentPath.startsWith(linkUrl + "/");
37
- }
38
-
39
- /**
40
- * Check if a URL is external
41
- */
42
- function isExternalUrl(url: string): boolean {
43
- return url.startsWith("http://") || url.startsWith("https://");
44
- }
45
-
46
- /**
47
- * Render navigation links with dot indicator for active state.
48
- */
49
- function NavLinks({
50
- navigationLinks,
51
- currentPath,
52
- }: {
53
- navigationLinks: NavigationLink[];
54
- currentPath: string;
55
- }) {
56
- return (
57
- <>
58
- {navigationLinks.map((link) => {
59
- const active = isLinkActive(link.url, currentPath);
60
- const external = isExternalUrl(link.url);
61
- return (
62
- <a
63
- key={link.id}
64
- href={link.url}
65
- class={`text-sm flex items-center gap-2 py-0.5 ${
66
- active
67
- ? "text-primary font-medium"
68
- : "text-muted-foreground hover:text-foreground"
69
- }`}
70
- {...(external
71
- ? { target: "_blank", rel: "noopener noreferrer" }
72
- : {})}
73
- >
74
- <span
75
- class={`size-1.5 rounded-full shrink-0 ${active ? "bg-primary" : "bg-transparent"}`}
76
- />
77
- {link.label}
78
- {external && <span class="ml-1 text-xs opacity-50">↗</span>}
79
- </a>
80
- );
81
- })}
82
- </>
83
- );
84
- }
85
-
86
- export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
87
- siteName,
88
- navigationLinks,
89
- currentPath,
90
- children,
91
- }) => {
92
- return (
93
- <div
94
- class="container py-8 md:flex md:gap-12"
95
- data-signals={JSON.stringify({ _drawerOpen: false })}
96
- >
97
- {/* Mobile header with hamburger */}
98
- <div class="flex items-center justify-between mb-6 md:hidden">
99
- <a href="/" class="text-xl font-semibold">
100
- {siteName}
101
- </a>
102
- <button
103
- data-on:click="$_drawerOpen = true"
104
- class="p-2 -mr-2 text-muted-foreground hover:text-foreground"
105
- aria-label="Open menu"
106
- >
107
- <svg
108
- class="size-5"
109
- fill="none"
110
- viewBox="0 0 24 24"
111
- stroke-width="1.5"
112
- stroke="currentColor"
113
- >
114
- <path
115
- stroke-linecap="round"
116
- stroke-linejoin="round"
117
- d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
118
- />
119
- </svg>
120
- </button>
121
- </div>
122
-
123
- {/* Mobile drawer backdrop */}
124
- <div
125
- class="fixed inset-0 bg-black/50 z-40 opacity-0 pointer-events-none transition-opacity duration-300 ease-in-out md:hidden"
126
- data-class="{'opacity-100 pointer-events-auto': $_drawerOpen, 'opacity-0 pointer-events-none': !$_drawerOpen}"
127
- data-on:click="$_drawerOpen = false"
128
- />
129
-
130
- {/* Mobile drawer panel */}
131
- <aside
132
- class="fixed inset-y-0 left-0 w-64 bg-background z-50 p-6 overflow-y-auto shadow-lg -translate-x-full transition-transform duration-300 ease-in-out md:hidden"
133
- data-class="{'translate-x-0': $_drawerOpen, '-translate-x-full': !$_drawerOpen}"
134
- >
135
- <div class="flex items-center justify-between mb-8">
136
- <a href="/" class="text-xl font-semibold">
137
- {siteName}
138
- </a>
139
- <button
140
- data-on:click="$_drawerOpen = false"
141
- class="p-2 -mr-2 text-muted-foreground hover:text-foreground"
142
- aria-label="Close menu"
143
- >
144
- <svg
145
- class="size-5"
146
- fill="none"
147
- viewBox="0 0 24 24"
148
- stroke-width="1.5"
149
- stroke="currentColor"
150
- >
151
- <path
152
- stroke-linecap="round"
153
- stroke-linejoin="round"
154
- d="M6 18L18 6M6 6l12 12"
155
- />
156
- </svg>
157
- </button>
158
- </div>
159
- <nav class="flex flex-col gap-0.5">
160
- <NavLinks
161
- navigationLinks={navigationLinks}
162
- currentPath={currentPath}
163
- />
164
- </nav>
165
- </aside>
166
-
167
- {/* Desktop sidebar */}
168
- <aside class="hidden md:block md:w-48 md:shrink-0 md:sticky md:top-8 md:self-start">
169
- <a href="/" class="text-xl font-semibold block mb-20">
170
- {siteName}
171
- </a>
172
- <nav class="flex flex-col gap-0.5">
173
- <NavLinks
174
- navigationLinks={navigationLinks}
175
- currentPath={currentPath}
176
- />
177
- </nav>
178
- </aside>
179
-
180
- {/* Main content */}
181
- <main class="flex-1 min-w-0">{children}</main>
182
- </div>
183
- );
184
- };