@jant/core 0.6.11 → 0.6.13

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 (139) hide show
  1. package/bin/commands/import-site.js +47 -30
  2. package/bin/commands/migrate-text-attachments.js +1 -3
  3. package/bin/commands/site/export.js +1 -3
  4. package/bin/commands/telegram/register-webhooks.js +9 -3
  5. package/bin/lib/site-snapshot.js +1 -5
  6. package/dist/app-CWJFPjuR.js +6 -0
  7. package/dist/{app-CpmficmQ.js → app-HnzmsaqU.js} +721 -473
  8. package/dist/client/.vite/manifest.json +3 -3
  9. package/dist/client/_assets/{client-Dd9U383b.js → client-3_OaxhTs.js} +1 -1
  10. package/dist/client/_assets/client-DCrcHVJl.css +2 -0
  11. package/dist/client/_assets/{client-auth-DkpSdIDz.js → client-auth-TsYq90xm.js} +625 -561
  12. package/dist/{export-Ba7NJImL.js → export-Dfbq9aot.js} +12 -15
  13. package/dist/{github-sync-Cb4_6_i7.js → github-sync--PSoE-Ne.js} +1 -1
  14. package/dist/{github-sync-BD4w2m8-.js → github-sync-BGTLx8Mf.js} +2 -2
  15. package/dist/index.js +3 -3
  16. package/dist/node.js +4 -4
  17. package/package.json +1 -1
  18. package/src/__tests__/export-service.test.ts +1 -2
  19. package/src/__tests__/helpers/app.ts +3 -0
  20. package/src/__tests__/helpers/export-fixtures.ts +0 -1
  21. package/src/__tests__/import-site-command.test.ts +76 -2
  22. package/src/__tests__/vite-dev-plugins.test.ts +34 -0
  23. package/src/client/__tests__/compose-launch.test.ts +50 -1
  24. package/src/client/__tests__/compose-shortcuts.test.ts +74 -18
  25. package/src/client/__tests__/site-header-nav.test.ts +36 -2
  26. package/src/client/components/__tests__/compose-title-from-heading.test.ts +57 -0
  27. package/src/client/components/__tests__/jant-command-palette.test.ts +63 -0
  28. package/src/client/components/__tests__/jant-compose-dialog.test.ts +33 -0
  29. package/src/client/components/__tests__/jant-compose-editor-rehost-notice.test.ts +20 -1
  30. package/src/client/components/__tests__/jant-compose-editor.test.ts +94 -2
  31. package/src/client/components/__tests__/jant-nav-manager.test.ts +181 -20
  32. package/src/client/components/__tests__/jant-settings-avatar.test.ts +6 -0
  33. package/src/client/components/__tests__/jant-settings-general.test.ts +72 -0
  34. package/src/client/components/compose-title-from-heading.ts +66 -0
  35. package/src/client/components/compose-types.ts +8 -0
  36. package/src/client/components/inline-image-issues.ts +17 -0
  37. package/src/client/components/jant-command-palette.ts +67 -2
  38. package/src/client/components/jant-compose-dialog.ts +10 -2
  39. package/src/client/components/jant-compose-editor.ts +78 -1
  40. package/src/client/components/jant-compose-fullscreen.ts +2 -0
  41. package/src/client/components/jant-nav-manager.ts +382 -152
  42. package/src/client/components/jant-settings-general.ts +56 -0
  43. package/src/client/components/nav-manager-types.ts +14 -10
  44. package/src/client/components/settings-types.ts +30 -0
  45. package/src/client/compose-launch.ts +30 -0
  46. package/src/client/compose-shortcuts.ts +46 -3
  47. package/src/client/site-header-nav.d.ts +1 -0
  48. package/src/client/site-header-nav.js +105 -47
  49. package/src/client/tiptap/__tests__/block-insertion.test.ts +35 -0
  50. package/src/client/tiptap/__tests__/image-input-rules.test.ts +117 -0
  51. package/src/client/tiptap/__tests__/rehost-images.test.ts +66 -13
  52. package/src/client/tiptap/create-editor.ts +7 -0
  53. package/src/client/tiptap/extensions.ts +7 -2
  54. package/src/client/tiptap/image-input-rules.ts +48 -0
  55. package/src/client/tiptap/image-node.ts +189 -7
  56. package/src/client/tiptap/rehost-images.ts +5 -1
  57. package/src/client-auth.ts +0 -1
  58. package/src/i18n/__tests__/fallback.test.ts +24 -0
  59. package/src/i18n/locales/public/en.po +20 -4
  60. package/src/i18n/locales/public/en.ts +1 -1
  61. package/src/i18n/locales/public/zh-Hans.po +22 -6
  62. package/src/i18n/locales/public/zh-Hans.ts +1 -1
  63. package/src/i18n/locales/public/zh-Hant.po +22 -6
  64. package/src/i18n/locales/public/zh-Hant.ts +1 -1
  65. package/src/i18n/locales/settings/en.po +77 -20
  66. package/src/i18n/locales/settings/en.ts +1 -1
  67. package/src/i18n/locales/settings/zh-Hans.po +85 -28
  68. package/src/i18n/locales/settings/zh-Hans.ts +1 -1
  69. package/src/i18n/locales/settings/zh-Hant.po +79 -22
  70. package/src/i18n/locales/settings/zh-Hant.ts +1 -1
  71. package/src/lib/__tests__/feed.test.ts +96 -10
  72. package/src/lib/__tests__/navigation.test.ts +4 -37
  73. package/src/lib/__tests__/resolve-config.test.ts +6 -1
  74. package/src/lib/__tests__/view.test.ts +6 -30
  75. package/src/lib/feed.ts +63 -3
  76. package/src/lib/github-sync-site-config.ts +0 -2
  77. package/src/lib/hugo-markdown.ts +1 -1
  78. package/src/lib/navigation.ts +5 -22
  79. package/src/lib/post-display.ts +14 -8
  80. package/src/lib/resolve-config.ts +9 -2
  81. package/src/lib/site-header-fragment.tsx +37 -0
  82. package/src/lib/view.ts +2 -7
  83. package/src/node/__tests__/cli-site-snapshot.test.ts +45 -45
  84. package/src/preset.css +60 -18
  85. package/src/routes/api/__tests__/nav-items.test.ts +26 -0
  86. package/src/routes/api/export.ts +0 -2
  87. package/src/routes/api/internal/__tests__/uploads.test.ts +9 -13
  88. package/src/routes/api/internal/sites.ts +5 -5
  89. package/src/routes/api/nav-items.ts +25 -4
  90. package/src/routes/dash/settings.tsx +48 -3
  91. package/src/routes/feed/__tests__/feed.test.ts +42 -0
  92. package/src/routes/feed/__tests__/sitemap.test.ts +2 -13
  93. package/src/routes/feed/feed.ts +1 -0
  94. package/src/routes/feed/sitemap.ts +2 -6
  95. package/src/routes/pages/__tests__/draft-about-edit.test.ts +65 -0
  96. package/src/routes/pages/archive.tsx +1 -0
  97. package/src/routes/pages/collection.tsx +1 -0
  98. package/src/routes/pages/featured.tsx +0 -4
  99. package/src/routes/pages/home.tsx +4 -51
  100. package/src/routes/pages/latest.tsx +2 -51
  101. package/src/routes/pages/page.tsx +44 -12
  102. package/src/services/__tests__/about-page.test.ts +116 -0
  103. package/src/services/__tests__/github-app-installations.test.ts +10 -10
  104. package/src/services/__tests__/navigation.test.ts +231 -1
  105. package/src/services/__tests__/post-timeline.test.ts +175 -2
  106. package/src/services/__tests__/post.test.ts +33 -0
  107. package/src/services/__tests__/settings.test.ts +5 -20
  108. package/src/services/about-page.ts +143 -0
  109. package/src/services/export-theme/assets/client-site.js +10 -10
  110. package/src/services/export-theme/layouts/_default/rss.xml +7 -16
  111. package/src/services/export-theme/layouts/index.html +26 -39
  112. package/src/services/export-theme/layouts/partials/feed-post-content.xml +25 -1
  113. package/src/services/export-theme/styles/main.css +46 -14
  114. package/src/services/export.ts +5 -10
  115. package/src/services/github-app-installations.ts +1 -3
  116. package/src/services/index.ts +27 -17
  117. package/src/services/navigation.ts +186 -1
  118. package/src/services/post.ts +103 -63
  119. package/src/services/settings.ts +0 -10
  120. package/src/services/site-admin.ts +0 -2
  121. package/src/services/upload-session.ts +4 -18
  122. package/src/styles/components.css +20 -0
  123. package/src/styles/tokens.css +28 -10
  124. package/src/styles/ui.css +349 -13
  125. package/src/types/bindings.ts +0 -1
  126. package/src/types/config.ts +3 -7
  127. package/src/types/views.ts +13 -0
  128. package/src/ui/compose/ComposeDialog.tsx +28 -0
  129. package/src/ui/dash/appearance/NavigationContent.tsx +58 -1
  130. package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +19 -0
  131. package/src/ui/dash/settings/AccountMenuContent.tsx +2 -2
  132. package/src/ui/dash/settings/GeneralContent.tsx +44 -0
  133. package/src/ui/dash/settings/SettingsRootContent.tsx +3 -3
  134. package/src/ui/dash/settings/__tests__/GeneralContent.test.tsx +8 -0
  135. package/src/ui/feed/__tests__/timeline-cards.test.ts +162 -1
  136. package/src/ui/layouts/SiteLayout.tsx +249 -216
  137. package/dist/app-DqKkZenB.js +0 -6
  138. package/dist/client/_assets/client-BhHHVvSY.css +0 -2
  139. package/src/client/nav-manager-bridge.ts +0 -54
@@ -112,26 +112,35 @@ function HeaderLink({
112
112
  );
113
113
  }
114
114
 
115
- export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
115
+ export interface SiteHeaderProps {
116
+ siteName: string;
117
+ links: NavItemView[];
118
+ currentPath: string;
119
+ sitePathPrefix?: string;
120
+ siteAvatarUrl?: string;
121
+ showHeaderAvatar?: boolean;
122
+ }
123
+
124
+ function linkCollapseTier(idx: number): string {
125
+ if (idx < 2) return "";
126
+ if (idx === 2) return "site-header-link-collapse-sm";
127
+ if (idx === 3) return "site-header-link-collapse-md";
128
+ return "site-header-link-collapse-lg";
129
+ }
130
+
131
+ function moreLinkRevealTier(idx: number): string {
132
+ if (idx === 2) return "site-header-more-link-show-sm";
133
+ if (idx === 3) return "site-header-more-link-show-md";
134
+ return "site-header-more-link-show-lg";
135
+ }
136
+
137
+ export const SiteHeader: FC<SiteHeaderProps> = ({
116
138
  siteName,
117
139
  links,
118
140
  currentPath,
119
141
  sitePathPrefix = "",
120
- isAuthenticated,
121
- collections,
122
142
  siteAvatarUrl,
123
143
  showHeaderAvatar,
124
- siteDescriptionHtml,
125
- siteFooterHtml,
126
- showHomeBranding = false,
127
- sidebar,
128
- uploadMaxFileSize,
129
- showComposeDialog = true,
130
- showHeader = true,
131
- composeOpenShortcutDiscovered = false,
132
- slashCommandDiscovered = false,
133
- composeCollectionId,
134
- children,
135
144
  }) => {
136
145
  const { i18n } = useLingui();
137
146
  const linksWithLabels = links.map((link) => ({
@@ -154,46 +163,25 @@ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
154
163
  comment: "@context: Hamburger menu button label",
155
164
  }),
156
165
  );
157
- const moreLabel = i18n._(NAV_MORE_LABEL);
158
- const newPostLabel = i18n._(
166
+ const closeMenuLabel = i18n._(
159
167
  msg({
160
- message: "New post",
161
- comment:
162
- "@context: Mobile floating action button label to open the compose dialog",
168
+ message: "Close menu",
169
+ comment: "@context: Close drawer button label",
163
170
  }),
164
171
  );
172
+ const moreLabel = i18n._(NAV_MORE_LABEL);
165
173
 
166
- // Split custom links by placement
174
+ // Split custom links by placement.
167
175
  const headerLinks = linksWithLabels.filter(
168
176
  (l) => l.placement === "header" || !l.placement,
169
177
  );
170
178
  const moreLinks = linksWithLabels.filter((l) => l.placement === "more");
171
- // Responsive collapse tiers — first two links always stay inline; the
172
- // remaining links collapse into the "More" popover in stages so wider
173
- // windows (tablets, narrow laptops) can show 3 or 4 links before falling
174
- // back to the minimum of 2.
175
- //
176
- // idx 2 → collapse-sm (hidden ≤580px, shown in popover)
177
- // idx 3 → collapse-md (hidden ≤780px)
178
- // idx ≥ 4 → collapse-lg (hidden ≤960px)
179
- function linkCollapseTier(idx: number): string {
180
- if (idx < 2) return "";
181
- if (idx === 2) return "site-header-link-collapse-sm";
182
- if (idx === 3) return "site-header-link-collapse-md";
183
- return "site-header-link-collapse-lg";
184
- }
185
- function moreLinkRevealTier(idx: number): string {
186
- if (idx === 2) return "site-header-more-link-show-sm";
187
- if (idx === 3) return "site-header-more-link-show-md";
188
- return "site-header-more-link-show-lg";
189
- }
190
179
  const hasResponsiveOverflow = headerLinks.length > 2;
191
180
  const hasSupplementalMoreLinks = moreLinks.length > 0;
192
181
  const showMoreMenu = hasResponsiveOverflow || hasSupplementalMoreLinks;
182
+
193
183
  // Decide the widest breakpoint at which the "More" button must appear
194
- // when there are no supplemental links. With 3 total links only idx 2 ever
195
- // collapses (≤780); with 4 links idx 3 starts collapsing at ≤920; with 5+
196
- // idx 4 starts collapsing at ≤1100.
184
+ // when there are no supplemental links.
197
185
  let responsiveTierClass = "";
198
186
  if (hasResponsiveOverflow && !hasSupplementalMoreLinks) {
199
187
  if (headerLinks.length >= 5) {
@@ -213,127 +201,87 @@ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
213
201
  ]
214
202
  .filter(Boolean)
215
203
  .join(" ");
216
-
217
204
  const isHomePage =
218
205
  currentPath === toPublicPath("/", sitePathPrefix) ||
219
206
  currentPath === toPublicPath("/featured", sitePathPrefix) ||
220
207
  currentPath === toPublicPath("/latest", sitePathPrefix);
221
- const showMobileComposeFab = Boolean(
222
- (isHomePage || composeCollectionId) && isAuthenticated && showComposeDialog,
223
- );
224
- const mobileComposeFabClick = composeCollectionId
225
- ? `document.getElementById('compose-dialog')?.querySelector('jant-compose-dialog')?.openNew(${JSON.stringify(
226
- { collectionId: composeCollectionId },
227
- )})`
228
- : "document.getElementById('compose-dialog')?.querySelector('jant-compose-dialog')?.openNew()";
229
- const contentClass = [
230
- "site-content",
231
- isHomePage ? "site-content-home" : "",
232
- showMobileComposeFab ? "site-content-mobile-compose-enabled" : "",
233
- ]
234
- .filter(Boolean)
235
- .join(" ");
236
208
 
237
209
  return (
238
- <div class="site-page">
239
- {showHeader && (
240
- <header class="site-header">
241
- <div class="site-header-inner">
242
- <div
243
- class={`site-header-top site-header-top-bordered${isHomePage ? " site-header-top-home" : ""}`}
244
- >
245
- <a href={toPublicPath("/", sitePathPrefix)} class="site-logo">
246
- {showHeaderAvatar && siteAvatarUrl && (
247
- <img src={siteAvatarUrl} class="site-logo-avatar" alt="" />
248
- )}
249
- {siteName}
250
- </a>
251
- <nav class="site-header-nav" aria-label="Primary">
252
- {headerLinks.map((link, idx) => (
253
- <HeaderLink
254
- key={link.id}
255
- link={link}
256
- label={link.displayLabel}
257
- className={[
258
- idx < 2
259
- ? "site-header-link-primary"
260
- : "site-header-link-overflow",
261
- linkCollapseTier(idx),
262
- ]
263
- .filter(Boolean)
264
- .join(" ")}
265
- />
266
- ))}
267
- {showMoreMenu && (
268
- <div class={moreMenuClass}>
269
- <button
270
- type="button"
271
- class="site-header-more-btn"
272
- id="site-nav-more-trigger"
273
- aria-haspopup="menu"
274
- aria-expanded="false"
275
- >
276
- {moreLabel}
277
- <svg
278
- xmlns="http://www.w3.org/2000/svg"
279
- width="12"
280
- height="12"
281
- viewBox="0 0 24 24"
282
- fill="none"
283
- stroke="currentColor"
284
- stroke-width="2.5"
285
- stroke-linecap="round"
286
- stroke-linejoin="round"
287
- aria-hidden="true"
288
- >
289
- <path d="m6 9 6 6 6-6" />
290
- </svg>
291
- </button>
292
- <div
293
- id="site-nav-more-popover"
294
- class="site-header-more-popover"
295
- data-popover
296
- data-align="start"
210
+ <>
211
+ <header class="site-header" data-site-header-fragment="header">
212
+ <div class="site-header-inner">
213
+ <div
214
+ class={`site-header-top site-header-top-bordered${isHomePage ? " site-header-top-home" : ""}`}
215
+ >
216
+ <a href={toPublicPath("/", sitePathPrefix)} class="site-logo">
217
+ {showHeaderAvatar && siteAvatarUrl && (
218
+ <img src={siteAvatarUrl} class="site-logo-avatar" alt="" />
219
+ )}
220
+ {siteName}
221
+ </a>
222
+ <nav class="site-header-nav" aria-label="Primary">
223
+ {headerLinks.map((link, idx) => (
224
+ <HeaderLink
225
+ key={link.id}
226
+ link={link}
227
+ label={link.displayLabel}
228
+ className={[
229
+ idx < 2
230
+ ? "site-header-link-primary"
231
+ : "site-header-link-overflow",
232
+ linkCollapseTier(idx),
233
+ ]
234
+ .filter(Boolean)
235
+ .join(" ")}
236
+ />
237
+ ))}
238
+ {showMoreMenu && (
239
+ <div class={moreMenuClass}>
240
+ <button
241
+ type="button"
242
+ class="site-header-more-btn"
243
+ id="site-nav-more-trigger"
244
+ aria-haspopup="menu"
245
+ aria-expanded="false"
246
+ >
247
+ {moreLabel}
248
+ <svg
249
+ xmlns="http://www.w3.org/2000/svg"
250
+ width="12"
251
+ height="12"
252
+ viewBox="0 0 24 24"
253
+ fill="none"
254
+ stroke="currentColor"
255
+ stroke-width="2.5"
256
+ stroke-linecap="round"
257
+ stroke-linejoin="round"
297
258
  aria-hidden="true"
298
259
  >
299
- {headerLinks.slice(2).map((link, i) => {
300
- const idx = i + 2;
301
- const classes = [
302
- "site-header-more-link",
303
- "site-header-more-link-responsive",
304
- moreLinkRevealTier(idx),
305
- link.isActive ? "site-header-more-link-active" : "",
306
- ]
307
- .filter(Boolean)
308
- .join(" ");
309
- return (
310
- <a
311
- key={link.id}
312
- href={link.url}
313
- class={classes}
314
- {...(link.isExternal
315
- ? {
316
- target: "_blank",
317
- rel: "noopener noreferrer",
318
- }
319
- : {})}
320
- {...(link.freshAt
321
- ? { "data-fresh-at": link.freshAt }
322
- : {})}
323
- >
324
- {link.displayLabel}
325
- {link.isExternal && <ExternalLinkIcon />}
326
- </a>
327
- );
328
- })}
329
- {hasResponsiveOverflow && hasSupplementalMoreLinks && (
330
- <div class="site-header-more-divider site-header-more-divider-responsive" />
331
- )}
332
- {moreLinks.map((link) => (
260
+ <path d="m6 9 6 6 6-6" />
261
+ </svg>
262
+ </button>
263
+ <div
264
+ id="site-nav-more-popover"
265
+ class="site-header-more-popover"
266
+ data-popover
267
+ data-align="start"
268
+ aria-hidden="true"
269
+ >
270
+ {headerLinks.slice(2).map((link, i) => {
271
+ const idx = i + 2;
272
+ const classes = [
273
+ "site-header-more-link",
274
+ "site-header-more-link-responsive",
275
+ moreLinkRevealTier(idx),
276
+ link.isActive ? "site-header-more-link-active" : "",
277
+ ]
278
+ .filter(Boolean)
279
+ .join(" ");
280
+ return (
333
281
  <a
334
282
  key={link.id}
335
283
  href={link.url}
336
- class={`site-header-more-link site-header-more-link-supplemental ${link.isActive ? "site-header-more-link-active" : ""}`}
284
+ class={classes}
337
285
  {...(link.isExternal
338
286
  ? {
339
287
  target: "_blank",
@@ -347,75 +295,99 @@ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
347
295
  {link.displayLabel}
348
296
  {link.isExternal && <ExternalLinkIcon />}
349
297
  </a>
350
- ))}
351
- </div>
298
+ );
299
+ })}
300
+ {hasResponsiveOverflow && hasSupplementalMoreLinks && (
301
+ <div class="site-header-more-divider site-header-more-divider-responsive" />
302
+ )}
303
+ {moreLinks.map((link) => (
304
+ <a
305
+ key={link.id}
306
+ href={link.url}
307
+ class={`site-header-more-link site-header-more-link-supplemental ${link.isActive ? "site-header-more-link-active" : ""}`}
308
+ {...(link.isExternal
309
+ ? {
310
+ target: "_blank",
311
+ rel: "noopener noreferrer",
312
+ }
313
+ : {})}
314
+ {...(link.freshAt
315
+ ? { "data-fresh-at": link.freshAt }
316
+ : {})}
317
+ >
318
+ {link.displayLabel}
319
+ {link.isExternal && <ExternalLinkIcon />}
320
+ </a>
321
+ ))}
352
322
  </div>
353
- )}
354
- </nav>
323
+ </div>
324
+ )}
325
+ </nav>
355
326
 
356
- {/* Search */}
357
- <div class="site-header-search-slot">
358
- <form
359
- class="site-header-search-form"
360
- action={searchHref}
361
- method="get"
362
- >
363
- <SearchIcon class="site-header-search-icon" />
364
- <input
365
- type="search"
366
- name="q"
367
- class="site-header-search-input"
368
- placeholder={searchLabel}
369
- aria-label={searchLabel}
370
- enterkeyhint="search"
371
- />
372
- </form>
373
- <a
374
- href={searchHref}
375
- class="site-header-search-link"
327
+ <div class="site-header-search-slot">
328
+ <form
329
+ class="site-header-search-form"
330
+ action={searchHref}
331
+ method="get"
332
+ >
333
+ <SearchIcon class="site-header-search-icon" />
334
+ <input
335
+ type="search"
336
+ name="q"
337
+ class="site-header-search-input"
338
+ placeholder={searchLabel}
376
339
  aria-label={searchLabel}
377
- title={searchLabel}
378
- >
379
- <SearchIcon class="site-header-search-link-icon" />
380
- </a>
381
- </div>
340
+ enterkeyhint="search"
341
+ />
342
+ </form>
343
+ <a
344
+ href={searchHref}
345
+ class="site-header-search-link"
346
+ aria-label={searchLabel}
347
+ title={searchLabel}
348
+ >
349
+ <SearchIcon class="site-header-search-link-icon" />
350
+ </a>
351
+ </div>
382
352
 
383
- <div class="site-header-right">
384
- {/* Mobile hamburger */}
385
- <button
386
- type="button"
387
- class="site-header-hamburger"
388
- aria-controls="site-nav-drawer"
389
- aria-expanded="false"
390
- aria-label={menuLabel}
353
+ <div class="site-header-right">
354
+ <button
355
+ type="button"
356
+ class="site-header-hamburger"
357
+ aria-controls="site-nav-drawer"
358
+ aria-expanded="false"
359
+ aria-label={menuLabel}
360
+ >
361
+ <svg
362
+ xmlns="http://www.w3.org/2000/svg"
363
+ width="20"
364
+ height="20"
365
+ viewBox="0 0 24 24"
366
+ fill="none"
367
+ stroke="currentColor"
368
+ stroke-width="2"
369
+ stroke-linecap="round"
370
+ stroke-linejoin="round"
391
371
  >
392
- <svg
393
- xmlns="http://www.w3.org/2000/svg"
394
- width="20"
395
- height="20"
396
- viewBox="0 0 24 24"
397
- fill="none"
398
- stroke="currentColor"
399
- stroke-width="2"
400
- stroke-linecap="round"
401
- stroke-linejoin="round"
402
- >
403
- <line x1="4" x2="20" y1="12" y2="12" />
404
- <line x1="4" x2="20" y1="6" y2="6" />
405
- <line x1="4" x2="20" y1="18" y2="18" />
406
- </svg>
407
- </button>
408
- </div>
372
+ <line x1="4" x2="20" y1="12" y2="12" />
373
+ <line x1="4" x2="20" y1="6" y2="6" />
374
+ <line x1="4" x2="20" y1="18" y2="18" />
375
+ </svg>
376
+ </button>
409
377
  </div>
410
378
  </div>
411
- </header>
412
- )}
379
+ </div>
380
+ </header>
413
381
 
414
- {/* Mobile navigation drawer */}
415
- <div class="site-nav-drawer-backdrop" aria-hidden="true" />
382
+ <div
383
+ class="site-nav-drawer-backdrop"
384
+ data-site-header-fragment="drawer-backdrop"
385
+ aria-hidden="true"
386
+ />
416
387
  <div
417
388
  id="site-nav-drawer"
418
389
  class="site-nav-drawer"
390
+ data-site-header-fragment="drawer"
419
391
  role="dialog"
420
392
  aria-modal="true"
421
393
  aria-label={menuLabel}
@@ -439,12 +411,7 @@ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
439
411
  <button
440
412
  type="button"
441
413
  class="site-nav-drawer-close"
442
- aria-label={i18n._(
443
- msg({
444
- message: "Close menu",
445
- comment: "@context: Close drawer button label",
446
- }),
447
- )}
414
+ aria-label={closeMenuLabel}
448
415
  >
449
416
  <svg
450
417
  xmlns="http://www.w3.org/2000/svg"
@@ -499,6 +466,72 @@ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
499
466
  )}
500
467
  </nav>
501
468
  </div>
469
+ </>
470
+ );
471
+ };
472
+
473
+ export const SiteLayout: FC<PropsWithChildren<SiteLayoutProps>> = ({
474
+ siteName,
475
+ links,
476
+ currentPath,
477
+ sitePathPrefix = "",
478
+ isAuthenticated,
479
+ collections,
480
+ siteAvatarUrl,
481
+ showHeaderAvatar,
482
+ siteDescriptionHtml,
483
+ siteFooterHtml,
484
+ showHomeBranding = false,
485
+ sidebar,
486
+ uploadMaxFileSize,
487
+ showComposeDialog = true,
488
+ showHeader = true,
489
+ composeOpenShortcutDiscovered = false,
490
+ slashCommandDiscovered = false,
491
+ composeCollectionId,
492
+ children,
493
+ }) => {
494
+ const { i18n } = useLingui();
495
+ const newPostLabel = i18n._(
496
+ msg({
497
+ message: "New post",
498
+ comment:
499
+ "@context: Mobile floating action button label to open the compose dialog",
500
+ }),
501
+ );
502
+
503
+ const isHomePage =
504
+ currentPath === toPublicPath("/", sitePathPrefix) ||
505
+ currentPath === toPublicPath("/featured", sitePathPrefix) ||
506
+ currentPath === toPublicPath("/latest", sitePathPrefix);
507
+ const showMobileComposeFab = Boolean(
508
+ (isHomePage || composeCollectionId) && isAuthenticated && showComposeDialog,
509
+ );
510
+ const mobileComposeFabClick = composeCollectionId
511
+ ? `document.getElementById('compose-dialog')?.querySelector('jant-compose-dialog')?.openNew(${JSON.stringify(
512
+ { collectionId: composeCollectionId },
513
+ )})`
514
+ : "document.getElementById('compose-dialog')?.querySelector('jant-compose-dialog')?.openNew()";
515
+ const contentClass = [
516
+ "site-content",
517
+ isHomePage ? "site-content-home" : "",
518
+ showMobileComposeFab ? "site-content-mobile-compose-enabled" : "",
519
+ ]
520
+ .filter(Boolean)
521
+ .join(" ");
522
+
523
+ return (
524
+ <div class="site-page">
525
+ {showHeader && (
526
+ <SiteHeader
527
+ siteName={siteName}
528
+ links={links}
529
+ currentPath={currentPath}
530
+ sitePathPrefix={sitePathPrefix}
531
+ siteAvatarUrl={siteAvatarUrl}
532
+ showHeaderAvatar={showHeaderAvatar}
533
+ />
534
+ )}
502
535
 
503
536
  <main class="site-main">
504
537
  {sidebar ? (
@@ -1,6 +0,0 @@
1
- import "./url-BMYO-Zlt.js";
2
- import { t as createApp } from "./app-CpmficmQ.js";
3
- import "./export-Ba7NJImL.js";
4
- import "./env-OHRKGcMj.js";
5
- import "./github-sync-Cb4_6_i7.js";
6
- export { createApp };