@open-slide/core 1.8.0 → 1.10.0

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 (36) hide show
  1. package/dist/{build-CCZDC8eF.js → build-ZM7IfDO-.js} +1 -1
  2. package/dist/cli/bin.js +3 -3
  3. package/dist/{config-C7sZtiY2.js → config-BAZeaz2P.js} +248 -232
  4. package/dist/{config-D1bANimZ.d.ts → config-mwmC1XI1.d.ts} +6 -1
  5. package/dist/{dev-kLS_4CAI.js → dev-BQkNTG_t.js} +1 -1
  6. package/dist/format-BvBmqbNW.js +1581 -0
  7. package/dist/index.d.ts +24 -4
  8. package/dist/index.js +120 -10
  9. package/dist/locale/index.d.ts +1 -1
  10. package/dist/locale/index.js +1 -1135
  11. package/dist/{preview-DUkOjOx8.js → preview-D8hUtbRA.js} +1 -1
  12. package/dist/{types-Bvk1pM70.d.ts → types-D_q_ylIe.d.ts} +19 -0
  13. package/dist/vite/index.d.ts +2 -2
  14. package/dist/vite/index.js +1 -1
  15. package/package.json +2 -1
  16. package/skills/slide-authoring/SKILL.md +42 -0
  17. package/src/app/components/language-toggle.tsx +39 -0
  18. package/src/app/components/player.tsx +30 -11
  19. package/src/app/components/pptx-progress-toast.tsx +32 -0
  20. package/src/app/components/sidebar/sidebar-footer.tsx +51 -0
  21. package/src/app/components/sidebar/sidebar.tsx +8 -1
  22. package/src/app/components/slide-transition-layer.tsx +36 -4
  23. package/src/app/components/thumbnail-rail.tsx +77 -15
  24. package/src/app/lib/design-presets.ts +1 -1
  25. package/src/app/lib/export-pptx.ts +284 -0
  26. package/src/app/lib/locale-store.ts +67 -0
  27. package/src/app/lib/step-context.tsx +169 -0
  28. package/src/app/lib/use-locale.ts +4 -16
  29. package/src/app/routes/slide.tsx +70 -0
  30. package/src/app/virtual.d.ts +1 -0
  31. package/src/locale/en.ts +21 -0
  32. package/src/locale/ja.ts +22 -0
  33. package/src/locale/types.ts +21 -0
  34. package/src/locale/zh-cn.ts +20 -0
  35. package/src/locale/zh-tw.ts +20 -0
  36. package/dist/en-hyGpmL1O.js +0 -375
@@ -5,12 +5,14 @@ import {
5
5
  ChevronLeft,
6
6
  Download,
7
7
  FileCode2,
8
+ FileImage,
8
9
  FileText,
9
10
  Link2,
10
11
  Loader2,
11
12
  Maximize,
12
13
  MonitorSpeaker,
13
14
  Play,
15
+ Presentation,
14
16
  } from 'lucide-react';
15
17
  import { type RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
16
18
  import { Link, useParams, useSearchParams } from 'react-router-dom';
@@ -33,6 +35,7 @@ import {
33
35
  DropdownMenu,
34
36
  DropdownMenuContent,
35
37
  DropdownMenuItem,
38
+ DropdownMenuSeparator,
36
39
  DropdownMenuTrigger,
37
40
  } from '@/components/ui/dropdown-menu';
38
41
  import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
@@ -47,11 +50,13 @@ import { cn } from '@/lib/utils';
47
50
  import { NotesDrawer } from '../components/notes-drawer';
48
51
  import { PdfProgressToast } from '../components/pdf-progress-toast';
49
52
  import { openPresenterWindow, Player } from '../components/player';
53
+ import { PptxProgressToast } from '../components/pptx-progress-toast';
50
54
  import { SlideCanvas } from '../components/slide-canvas';
51
55
  import { SlideTransitionLayer } from '../components/slide-transition-layer';
52
56
  import { type ThumbnailActions, ThumbnailRail } from '../components/thumbnail-rail';
53
57
  import { exportSlideAsHtml } from '../lib/export-html';
54
58
  import { exportSlideAsPdf, isSafari } from '../lib/export-pdf';
59
+ import { exportSlideAsImagePptx } from '../lib/export-pptx';
55
60
  import { remapNotesSessionCacheAfterReorder } from '../lib/inspector/use-notes';
56
61
  import type { SlideModule } from '../lib/sdk';
57
62
  import { usePrefersReducedMotion } from '../lib/use-prefers-reduced-motion';
@@ -500,6 +505,69 @@ export function Slide() {
500
505
  <FileText />
501
506
  {t.slide.exportAsPdf}
502
507
  </DropdownMenuItem>
508
+ <DropdownMenuSeparator />
509
+ <DropdownMenuItem
510
+ disabled={exporting}
511
+ onSelect={async () => {
512
+ if (!slide || exporting) return;
513
+ setExporting(true);
514
+ const toastId = `pptx-export-${slideId}`;
515
+ toast.custom(
516
+ () => (
517
+ <PptxProgressToast
518
+ progress={{
519
+ phase: 'processing',
520
+ current: 0,
521
+ total: pages.length,
522
+ percent: 0,
523
+ }}
524
+ />
525
+ ),
526
+ { id: toastId, duration: Infinity },
527
+ );
528
+ try {
529
+ await exportSlideAsImagePptx(slide, slideId, (p) => {
530
+ toast.custom(() => <PptxProgressToast progress={p} />, {
531
+ id: toastId,
532
+ duration: Infinity,
533
+ });
534
+ });
535
+ } catch (err) {
536
+ console.error('[open-slide] image pptx export failed', err);
537
+ toast.error(t.slide.imagePptxExportFailed, {
538
+ id: toastId,
539
+ duration: 4000,
540
+ });
541
+ } finally {
542
+ setExporting(false);
543
+ toast.dismiss(toastId);
544
+ }
545
+ }}
546
+ >
547
+ <FileImage />
548
+ {t.slide.exportAsImagePptx}
549
+ </DropdownMenuItem>
550
+ <TooltipProvider delayDuration={200}>
551
+ <Tooltip>
552
+ <TooltipTrigger asChild>
553
+ <div
554
+ aria-disabled
555
+ className="relative flex cursor-help items-center justify-between gap-2 rounded-[5px] px-2 py-1.5 text-[12.5px] opacity-45 select-none [&_svg]:size-3.5 [&_svg]:shrink-0 [&_svg]:opacity-80"
556
+ >
557
+ <span className="flex items-center gap-2">
558
+ <Presentation />
559
+ {t.slide.exportAsPptx}
560
+ </span>
561
+ <span className="rounded-[3px] bg-muted px-1.5 py-0.5 font-mono text-[9.5px] tracking-[0.04em] text-muted-foreground">
562
+ {t.slide.comingSoon}
563
+ </span>
564
+ </div>
565
+ </TooltipTrigger>
566
+ <TooltipContent side="left" className="max-w-[240px] leading-relaxed">
567
+ {t.slide.pptxComingSoonTooltip}
568
+ </TooltipContent>
569
+ </Tooltip>
570
+ </TooltipProvider>
503
571
  </DropdownMenuContent>
504
572
  </DropdownMenu>
505
573
  )}
@@ -574,6 +642,7 @@ export function Slide() {
574
642
  onSelect={goTo}
575
643
  onReorder={import.meta.env.DEV ? reorderPage : undefined}
576
644
  actions={thumbnailActions}
645
+ moduleTransition={slide.transition}
577
646
  />
578
647
  <main
579
648
  ref={slideViewportRef}
@@ -656,6 +725,7 @@ function ResizableRail(props: {
656
725
  onSelect: (i: number) => void;
657
726
  onReorder?: (from: number, to: number) => void;
658
727
  actions?: ThumbnailActions;
728
+ moduleTransition?: SlideModule['transition'];
659
729
  }) {
660
730
  const t = useLocale();
661
731
  const [width, setWidth] = useState<number>(readStoredRailWidth);
@@ -13,6 +13,7 @@ declare module 'virtual:open-slide/config' {
13
13
  slidesDir?: string;
14
14
  port?: number;
15
15
  locale?: Locale;
16
+ version: string;
16
17
  build: {
17
18
  showSlideBrowser: boolean;
18
19
  showSlideUi: boolean;
package/src/locale/en.ts CHANGED
@@ -44,6 +44,7 @@ export const en: Locale = {
44
44
  folders: 'Folders',
45
45
  newFolder: 'New folder',
46
46
  folderName: 'Folder name',
47
+ updateAvailable: 'open-slide {version} is available — update the package to get the latest.',
47
48
  changeIcon: 'Change icon',
48
49
  iconEmojiTab: 'Emoji',
49
50
  iconColorTab: 'Color',
@@ -105,7 +106,13 @@ export const en: Locale = {
105
106
  toastCopyLinkFailed: 'Failed to copy link',
106
107
  exportAsHtml: 'Export as HTML',
107
108
  exportAsPdf: 'Export as PDF',
109
+ exportAsImagePptx: 'Export as image PPTX',
110
+ exportAsPptx: 'Export as PPTX',
111
+ comingSoon: 'Coming soon',
112
+ pptxComingSoonTooltip:
113
+ 'Editable PPTX export isn’t ready yet. For now, use “Export as image PPTX” instead.',
108
114
  pdfExportFailed: 'PDF export failed',
115
+ imagePptxExportFailed: 'PPTX export failed',
109
116
  pdfExportSafariUnsupported:
110
117
  'Export as PDF is not supported on Safari. Please try a Chromium-based browser instead.',
111
118
  present: 'Present',
@@ -336,6 +343,8 @@ export const en: Locale = {
336
343
  toastDuplicateFailed: 'Could not duplicate page',
337
344
  toastDeleteFailed: 'Could not delete page',
338
345
  resizeRail: 'Resize thumbnail rail',
346
+ transitionIndicator: 'Has slide transition',
347
+ stepsIndicator: 'Has step-by-step reveals',
339
348
  },
340
349
 
341
350
  pdfToast: {
@@ -345,6 +354,13 @@ export const en: Locale = {
345
354
  done: 'Done',
346
355
  },
347
356
 
357
+ pptxToast: {
358
+ title: 'Exporting PPTX',
359
+ processing: 'Rendering page {current} of {total}',
360
+ generating: 'Building presentation…',
361
+ done: 'Done',
362
+ },
363
+
348
364
  themeToggle: {
349
365
  toggleAria: 'Toggle theme',
350
366
  title: 'Theme',
@@ -353,6 +369,11 @@ export const en: Locale = {
353
369
  system: 'System',
354
370
  },
355
371
 
372
+ languageToggle: {
373
+ toggleAria: 'Change language',
374
+ title: 'Language',
375
+ },
376
+
356
377
  imagePlaceholder: {
357
378
  dropOverlay: 'Drop image to use here',
358
379
  uploading: 'Uploading…',
package/src/locale/ja.ts CHANGED
@@ -44,6 +44,8 @@ export const ja: Locale = {
44
44
  folders: 'フォルダ',
45
45
  newFolder: '新規フォルダ',
46
46
  folderName: 'フォルダ名',
47
+ updateAvailable:
48
+ 'open-slide {version} が利用可能です — パッケージを更新して最新版を入手してください。',
47
49
  changeIcon: 'アイコンを変更',
48
50
  iconEmojiTab: '絵文字',
49
51
  iconColorTab: 'カラー',
@@ -105,7 +107,13 @@ export const ja: Locale = {
105
107
  toastCopyLinkFailed: 'リンクのコピーに失敗しました',
106
108
  exportAsHtml: 'HTML として書き出し',
107
109
  exportAsPdf: 'PDF として書き出し',
110
+ exportAsImagePptx: '画像 PPTX として書き出し',
111
+ exportAsPptx: 'PPTX として書き出し',
112
+ comingSoon: '近日公開',
113
+ pptxComingSoonTooltip:
114
+ '編集可能な PPTX の書き出しはまだ対応していません。それまでは「画像 PPTX として書き出し」をご利用ください。',
108
115
  pdfExportFailed: 'PDF の書き出しに失敗しました',
116
+ imagePptxExportFailed: 'PPTX の書き出しに失敗しました',
109
117
  pdfExportSafariUnsupported:
110
118
  'PDF の書き出しは現在 Safari では対応していません。Chromium ベースのブラウザでお試しください。',
111
119
  present: '発表',
@@ -340,6 +348,8 @@ export const ja: Locale = {
340
348
  toastDuplicateFailed: 'ページを複製できませんでした',
341
349
  toastDeleteFailed: 'ページを削除できませんでした',
342
350
  resizeRail: 'サムネイル幅を調整',
351
+ transitionIndicator: 'スライドトランジションあり',
352
+ stepsIndicator: 'ステップ表示あり',
343
353
  },
344
354
 
345
355
  pdfToast: {
@@ -349,6 +359,13 @@ export const ja: Locale = {
349
359
  done: '完了',
350
360
  },
351
361
 
362
+ pptxToast: {
363
+ title: 'PPTX を書き出し中',
364
+ processing: 'ページ {current} / {total} を描画中',
365
+ generating: 'プレゼンテーションを構築中…',
366
+ done: '完了',
367
+ },
368
+
352
369
  themeToggle: {
353
370
  toggleAria: 'テーマを切り替え',
354
371
  title: 'テーマ',
@@ -357,6 +374,11 @@ export const ja: Locale = {
357
374
  system: 'システム',
358
375
  },
359
376
 
377
+ languageToggle: {
378
+ toggleAria: '言語を切り替え',
379
+ title: '言語',
380
+ },
381
+
360
382
  imagePlaceholder: {
361
383
  dropOverlay: 'ここにドロップして使用',
362
384
  uploading: 'アップロード中…',
@@ -44,6 +44,7 @@ export type Locale = {
44
44
  folders: string;
45
45
  newFolder: string;
46
46
  folderName: string;
47
+ updateAvailable: string;
47
48
  changeIcon: string;
48
49
  iconEmojiTab: string;
49
50
  iconColorTab: string;
@@ -107,7 +108,12 @@ export type Locale = {
107
108
  toastCopyLinkFailed: string;
108
109
  exportAsHtml: string;
109
110
  exportAsPdf: string;
111
+ exportAsImagePptx: string;
112
+ exportAsPptx: string;
113
+ comingSoon: string;
114
+ pptxComingSoonTooltip: string;
110
115
  pdfExportFailed: string;
116
+ imagePptxExportFailed: string;
111
117
  pdfExportSafariUnsupported: string;
112
118
  present: string;
113
119
  presentMenuAria: string;
@@ -358,6 +364,8 @@ export type Locale = {
358
364
  toastDuplicateFailed: string;
359
365
  toastDeleteFailed: string;
360
366
  resizeRail: string;
367
+ transitionIndicator: string;
368
+ stepsIndicator: string;
361
369
  };
362
370
 
363
371
  pdfToast: {
@@ -368,6 +376,14 @@ export type Locale = {
368
376
  done: string;
369
377
  };
370
378
 
379
+ pptxToast: {
380
+ title: string;
381
+ /** template: "Rendering page {current} of {total}" */
382
+ processing: string;
383
+ generating: string;
384
+ done: string;
385
+ };
386
+
371
387
  themeToggle: {
372
388
  toggleAria: string;
373
389
  title: string;
@@ -376,6 +392,11 @@ export type Locale = {
376
392
  system: string;
377
393
  };
378
394
 
395
+ languageToggle: {
396
+ toggleAria: string;
397
+ title: string;
398
+ };
399
+
379
400
  imagePlaceholder: {
380
401
  dropOverlay: string;
381
402
  uploading: string;
@@ -44,6 +44,7 @@ export const zhCN: Locale = {
44
44
  folders: '文件夹',
45
45
  newFolder: '新建文件夹',
46
46
  folderName: '文件夹名称',
47
+ updateAvailable: 'open-slide {version} 已发布,请更新软件包以获取最新版本。',
47
48
  changeIcon: '更换图标',
48
49
  iconEmojiTab: 'Emoji',
49
50
  iconColorTab: '颜色',
@@ -104,7 +105,12 @@ export const zhCN: Locale = {
104
105
  toastCopyLinkFailed: '复制链接失败',
105
106
  exportAsHtml: '导出为 HTML',
106
107
  exportAsPdf: '导出为 PDF',
108
+ exportAsImagePptx: '导出图片 PPTX',
109
+ exportAsPptx: '导出 PPTX',
110
+ comingSoon: '即将推出',
111
+ pptxComingSoonTooltip: '可编辑的 PPTX 导出尚未支持,在此之前可以先使用“导出图片 PPTX”。',
107
112
  pdfExportFailed: 'PDF 导出失败',
113
+ imagePptxExportFailed: 'PPTX 导出失败',
108
114
  pdfExportSafariUnsupported:
109
115
  '导出 PDF 目前不支持 Safari 设备,请尝试使用基于 Chromium 的浏览器替代。',
110
116
  present: '演示',
@@ -335,6 +341,8 @@ export const zhCN: Locale = {
335
341
  toastDuplicateFailed: '无法复制页面',
336
342
  toastDeleteFailed: '无法删除页面',
337
343
  resizeRail: '调整缩略图栏宽度',
344
+ transitionIndicator: '有换页转场',
345
+ stepsIndicator: '有逐步揭示',
338
346
  },
339
347
 
340
348
  pdfToast: {
@@ -344,6 +352,13 @@ export const zhCN: Locale = {
344
352
  done: '完成',
345
353
  },
346
354
 
355
+ pptxToast: {
356
+ title: '导出 PPTX',
357
+ processing: '正在渲染第 {current} / {total} 页',
358
+ generating: '正在组合演示文稿…',
359
+ done: '完成',
360
+ },
361
+
347
362
  themeToggle: {
348
363
  toggleAria: '切换主题',
349
364
  title: '主题',
@@ -352,6 +367,11 @@ export const zhCN: Locale = {
352
367
  system: '系统',
353
368
  },
354
369
 
370
+ languageToggle: {
371
+ toggleAria: '切换语言',
372
+ title: '语言',
373
+ },
374
+
355
375
  imagePlaceholder: {
356
376
  dropOverlay: '拖入图片以使用',
357
377
  uploading: '上传中…',
@@ -44,6 +44,7 @@ export const zhTW: Locale = {
44
44
  folders: '資料夾',
45
45
  newFolder: '新增資料夾',
46
46
  folderName: '資料夾名稱',
47
+ updateAvailable: 'open-slide {version} 已發布,請更新套件以取得最新版本。',
47
48
  changeIcon: '變更圖示',
48
49
  iconEmojiTab: 'Emoji',
49
50
  iconColorTab: '顏色',
@@ -104,7 +105,12 @@ export const zhTW: Locale = {
104
105
  toastCopyLinkFailed: '複製連結失敗',
105
106
  exportAsHtml: '匯出為 HTML',
106
107
  exportAsPdf: '匯出為 PDF',
108
+ exportAsImagePptx: '匯出圖片 PPTX',
109
+ exportAsPptx: '匯出 PPTX',
110
+ comingSoon: '即將推出',
111
+ pptxComingSoonTooltip: '可編輯的 PPTX 匯出尚未支援,在此之前可以先使用「匯出圖片 PPTX」。',
107
112
  pdfExportFailed: 'PDF 匯出失敗',
113
+ imagePptxExportFailed: 'PPTX 匯出失敗',
108
114
  pdfExportSafariUnsupported:
109
115
  '匯出 PDF 目前不支援 Safari 裝置,請嘗試用 Chromium 基底瀏覽器替代。',
110
116
  present: '簡報',
@@ -335,6 +341,8 @@ export const zhTW: Locale = {
335
341
  toastDuplicateFailed: '無法複製頁面',
336
342
  toastDeleteFailed: '無法刪除頁面',
337
343
  resizeRail: '調整縮圖欄寬度',
344
+ transitionIndicator: '有換頁轉場',
345
+ stepsIndicator: '有逐步揭示',
338
346
  },
339
347
 
340
348
  pdfToast: {
@@ -344,6 +352,13 @@ export const zhTW: Locale = {
344
352
  done: '完成',
345
353
  },
346
354
 
355
+ pptxToast: {
356
+ title: '匯出 PPTX',
357
+ processing: '正在算繪第 {current} / {total} 頁',
358
+ generating: '正在組合簡報…',
359
+ done: '完成',
360
+ },
361
+
347
362
  themeToggle: {
348
363
  toggleAria: '切換主題',
349
364
  title: '主題',
@@ -352,6 +367,11 @@ export const zhTW: Locale = {
352
367
  system: '系統',
353
368
  },
354
369
 
370
+ languageToggle: {
371
+ toggleAria: '切換語言',
372
+ title: '語言',
373
+ },
374
+
355
375
  imagePlaceholder: {
356
376
  dropOverlay: '拖入圖片以使用',
357
377
  uploading: '上傳中…',