@open-aippt/core 1.13.2

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 (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/bin.js +2 -0
  4. package/dist/build-DxTqmvsO.js +17 -0
  5. package/dist/cli/bin.d.ts +1 -0
  6. package/dist/cli/bin.js +86 -0
  7. package/dist/config-CjzqjrEA.js +4280 -0
  8. package/dist/config-DIC-yVPp.d.ts +23 -0
  9. package/dist/design-cpzS8aud.js +35 -0
  10. package/dist/dev-BYuTeJbA.js +20 -0
  11. package/dist/format-BCeKbTOM.js +1605 -0
  12. package/dist/index.d.ts +134 -0
  13. package/dist/index.js +467 -0
  14. package/dist/locale/index.d.ts +24 -0
  15. package/dist/locale/index.js +3 -0
  16. package/dist/preview-DlQvnJPq.js +18 -0
  17. package/dist/sync-BPZ0m27m.js +139 -0
  18. package/dist/sync-EsYusbbL.js +3 -0
  19. package/dist/types-CHmFPIG_.d.ts +430 -0
  20. package/dist/vite/index.d.ts +14 -0
  21. package/dist/vite/index.js +4 -0
  22. package/env.d.ts +59 -0
  23. package/package.json +103 -0
  24. package/skills/apply-comments/SKILL.md +83 -0
  25. package/skills/create-slide/SKILL.md +91 -0
  26. package/skills/create-theme/SKILL.md +250 -0
  27. package/skills/current-slide/SKILL.md +110 -0
  28. package/skills/slide-authoring/SKILL.md +625 -0
  29. package/src/app/app.tsx +47 -0
  30. package/src/app/components/asset-view.tsx +966 -0
  31. package/src/app/components/history-provider.tsx +120 -0
  32. package/src/app/components/image-placeholder.tsx +243 -0
  33. package/src/app/components/inspector/asset-picker-dialog.tsx +196 -0
  34. package/src/app/components/inspector/comment-widget.tsx +93 -0
  35. package/src/app/components/inspector/image-crop-dialog.tsx +212 -0
  36. package/src/app/components/inspector/inspect-overlay.tsx +387 -0
  37. package/src/app/components/inspector/inspector-panel.tsx +1115 -0
  38. package/src/app/components/inspector/inspector-provider.tsx +1218 -0
  39. package/src/app/components/inspector/save-bar.tsx +48 -0
  40. package/src/app/components/language-toggle.tsx +39 -0
  41. package/src/app/components/notes-drawer.tsx +120 -0
  42. package/src/app/components/overview-grid.tsx +363 -0
  43. package/src/app/components/panel/panel-fields.tsx +60 -0
  44. package/src/app/components/panel/panel-shell.tsx +80 -0
  45. package/src/app/components/panel/save-card.tsx +142 -0
  46. package/src/app/components/pdf-progress-toast.tsx +32 -0
  47. package/src/app/components/player.tsx +466 -0
  48. package/src/app/components/pptx-progress-toast.tsx +32 -0
  49. package/src/app/components/present/blackout-overlay.tsx +18 -0
  50. package/src/app/components/present/control-bar.tsx +315 -0
  51. package/src/app/components/present/help-overlay.tsx +57 -0
  52. package/src/app/components/present/jump-input.tsx +74 -0
  53. package/src/app/components/present/laser-pointer.tsx +39 -0
  54. package/src/app/components/present/progress-bar.tsx +26 -0
  55. package/src/app/components/present/use-idle.ts +46 -0
  56. package/src/app/components/present/use-pointer-near-bottom.ts +34 -0
  57. package/src/app/components/present/use-presenter-channel.ts +66 -0
  58. package/src/app/components/present/use-touch-swipe.ts +66 -0
  59. package/src/app/components/shared-element.tsx +48 -0
  60. package/src/app/components/sidebar/folder-item.tsx +258 -0
  61. package/src/app/components/sidebar/icon-picker.tsx +61 -0
  62. package/src/app/components/sidebar/mobile-pill.tsx +34 -0
  63. package/src/app/components/sidebar/sidebar-footer.tsx +105 -0
  64. package/src/app/components/sidebar/sidebar.tsx +284 -0
  65. package/src/app/components/slide-canvas.tsx +102 -0
  66. package/src/app/components/slide-transition-layer.tsx +844 -0
  67. package/src/app/components/style-panel/design-provider.tsx +148 -0
  68. package/src/app/components/style-panel/style-panel.tsx +349 -0
  69. package/src/app/components/style-panel/use-design.ts +112 -0
  70. package/src/app/components/theme-toggle.tsx +59 -0
  71. package/src/app/components/themes/theme-detail.tsx +305 -0
  72. package/src/app/components/themes/themes-gallery.tsx +149 -0
  73. package/src/app/components/thumbnail-rail.tsx +805 -0
  74. package/src/app/components/ui/badge.tsx +45 -0
  75. package/src/app/components/ui/button.tsx +99 -0
  76. package/src/app/components/ui/card.tsx +92 -0
  77. package/src/app/components/ui/context-menu.tsx +237 -0
  78. package/src/app/components/ui/dialog.tsx +157 -0
  79. package/src/app/components/ui/dropdown-menu.tsx +245 -0
  80. package/src/app/components/ui/input.tsx +25 -0
  81. package/src/app/components/ui/label.tsx +24 -0
  82. package/src/app/components/ui/popover.tsx +75 -0
  83. package/src/app/components/ui/progress.tsx +31 -0
  84. package/src/app/components/ui/scroll-area.tsx +53 -0
  85. package/src/app/components/ui/select.tsx +196 -0
  86. package/src/app/components/ui/separator.tsx +28 -0
  87. package/src/app/components/ui/slider.tsx +61 -0
  88. package/src/app/components/ui/sonner.tsx +48 -0
  89. package/src/app/components/ui/tabs.tsx +79 -0
  90. package/src/app/components/ui/textarea.tsx +22 -0
  91. package/src/app/components/ui/toggle-group.tsx +83 -0
  92. package/src/app/components/ui/toggle.tsx +45 -0
  93. package/src/app/components/ui/tooltip.tsx +58 -0
  94. package/src/app/favicon.ico +0 -0
  95. package/src/app/index.html +13 -0
  96. package/src/app/lib/assets.ts +242 -0
  97. package/src/app/lib/design-presets.ts +94 -0
  98. package/src/app/lib/design.ts +58 -0
  99. package/src/app/lib/export-html.ts +326 -0
  100. package/src/app/lib/export-pdf.ts +298 -0
  101. package/src/app/lib/export-pptx.ts +284 -0
  102. package/src/app/lib/folders.ts +239 -0
  103. package/src/app/lib/inspector/fiber.test.ts +154 -0
  104. package/src/app/lib/inspector/fiber.ts +85 -0
  105. package/src/app/lib/inspector/use-comments.ts +74 -0
  106. package/src/app/lib/inspector/use-editor.ts +73 -0
  107. package/src/app/lib/inspector/use-notes.ts +134 -0
  108. package/src/app/lib/locale-store.ts +67 -0
  109. package/src/app/lib/page-context.tsx +38 -0
  110. package/src/app/lib/print-ready.test.ts +32 -0
  111. package/src/app/lib/print-ready.ts +51 -0
  112. package/src/app/lib/sdk.test.ts +13 -0
  113. package/src/app/lib/sdk.ts +37 -0
  114. package/src/app/lib/slides.ts +26 -0
  115. package/src/app/lib/step-context.tsx +261 -0
  116. package/src/app/lib/themes.ts +22 -0
  117. package/src/app/lib/transition.ts +30 -0
  118. package/src/app/lib/use-agent-socket.ts +18 -0
  119. package/src/app/lib/use-click-page-navigation.ts +60 -0
  120. package/src/app/lib/use-is-mobile.ts +21 -0
  121. package/src/app/lib/use-locale.ts +8 -0
  122. package/src/app/lib/use-prefers-reduced-motion.ts +19 -0
  123. package/src/app/lib/use-slide-module.ts +48 -0
  124. package/src/app/lib/use-wheel-page-navigation.ts +99 -0
  125. package/src/app/lib/utils.test.ts +25 -0
  126. package/src/app/lib/utils.ts +6 -0
  127. package/src/app/main.tsx +14 -0
  128. package/src/app/routes/assets.tsx +9 -0
  129. package/src/app/routes/home-shell.tsx +213 -0
  130. package/src/app/routes/home.tsx +807 -0
  131. package/src/app/routes/presenter.tsx +418 -0
  132. package/src/app/routes/slide.tsx +1108 -0
  133. package/src/app/routes/themes.tsx +34 -0
  134. package/src/app/styles.css +429 -0
  135. package/src/app/virtual.d.ts +51 -0
  136. package/src/locale/en.ts +416 -0
  137. package/src/locale/format.ts +12 -0
  138. package/src/locale/index.ts +6 -0
  139. package/src/locale/ja.ts +422 -0
  140. package/src/locale/types.ts +443 -0
  141. package/src/locale/zh-cn.ts +414 -0
  142. package/src/locale/zh-tw.ts +414 -0
@@ -0,0 +1,80 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { ScrollArea } from '@/components/ui/scroll-area';
3
+
4
+ export const PANEL_W = 320;
5
+ export const PANEL_TRANSITION_MS = 240;
6
+
7
+ // Defer the width expansion to the next frame so the browser paints once
8
+ // at width=0 first; otherwise the transition has no starting frame.
9
+ export function useAnimatedOpen(open: boolean): boolean {
10
+ const [animVisible, setAnimVisible] = useState(false);
11
+ useEffect(() => {
12
+ if (open) {
13
+ const id = requestAnimationFrame(() => setAnimVisible(true));
14
+ return () => cancelAnimationFrame(id);
15
+ }
16
+ setAnimVisible(false);
17
+ }, [open]);
18
+ return animVisible;
19
+ }
20
+
21
+ // Stay mounted through the close-out width transition so the panel
22
+ // visibly collapses instead of vanishing.
23
+ export function usePanelMount(open: boolean): { mounted: boolean; animVisible: boolean } {
24
+ const [mounted, setMounted] = useState(false);
25
+ useEffect(() => {
26
+ if (open) {
27
+ setMounted(true);
28
+ return;
29
+ }
30
+ const t = setTimeout(() => setMounted(false), PANEL_TRANSITION_MS);
31
+ return () => clearTimeout(t);
32
+ }, [open]);
33
+ const animVisible = useAnimatedOpen(open && mounted);
34
+ return { mounted, animVisible };
35
+ }
36
+
37
+ type PanelShellProps = {
38
+ animVisible: boolean;
39
+ uiAttr: 'inspector' | 'design';
40
+ header: React.ReactNode;
41
+ banner?: React.ReactNode;
42
+ footer?: React.ReactNode;
43
+ children: React.ReactNode;
44
+ };
45
+
46
+ export function PanelShell({
47
+ animVisible,
48
+ uiAttr,
49
+ header,
50
+ banner,
51
+ footer,
52
+ children,
53
+ }: PanelShellProps) {
54
+ const dataAttrs = uiAttr === 'inspector' ? { 'data-inspector-ui': '' } : { 'data-design-ui': '' };
55
+ return (
56
+ <aside
57
+ {...dataAttrs}
58
+ className="flex h-full shrink-0 justify-end overflow-hidden bg-sidebar transition-[width,border-left-width] ease-out"
59
+ style={{
60
+ width: animVisible ? PANEL_W : 0,
61
+ borderLeftWidth: animVisible ? 1 : 0,
62
+ borderLeftColor: 'var(--hairline)',
63
+ transitionDuration: `${PANEL_TRANSITION_MS}ms`,
64
+ }}
65
+ >
66
+ <div style={{ width: PANEL_W }} className="flex h-full shrink-0 flex-col">
67
+ <header className="flex h-9 shrink-0 items-center justify-between gap-2 border-b border-hairline px-3">
68
+ {header}
69
+ </header>
70
+ {banner}
71
+ <ScrollArea className="min-h-0 flex-1">
72
+ <div className="flex min-h-full flex-col">
73
+ {children}
74
+ {footer && <div className="mt-auto border-t border-hairline">{footer}</div>}
75
+ </div>
76
+ </ScrollArea>
77
+ </div>
78
+ </aside>
79
+ );
80
+ }
@@ -0,0 +1,142 @@
1
+ import { Check, Loader2, Redo2, Save, Undo2 } from 'lucide-react';
2
+ import { useEffect, useState } from 'react';
3
+ import { Button } from '@/components/ui/button';
4
+ import { useLocale } from '@/lib/use-locale';
5
+
6
+ type SaveCardProps = {
7
+ dirty: boolean;
8
+ committing: boolean;
9
+ onSave: () => Promise<void> | void;
10
+ onDiscard: () => void;
11
+ unsavedLabel: React.ReactNode;
12
+ savedLabel?: string;
13
+ uiAttr: 'inspector' | 'design';
14
+ onUndo?: () => void;
15
+ onRedo?: () => void;
16
+ canUndo?: boolean;
17
+ canRedo?: boolean;
18
+ };
19
+
20
+ // Optimistic DOM updates make the canvas *look* saved, so without this
21
+ // affordance a user could close the tab thinking their tweaks hit disk
22
+ // when they're still buffered in memory.
23
+ export function SaveCard({
24
+ dirty,
25
+ committing,
26
+ onSave,
27
+ onDiscard,
28
+ unsavedLabel,
29
+ savedLabel,
30
+ uiAttr,
31
+ onUndo,
32
+ onRedo,
33
+ canUndo = false,
34
+ canRedo = false,
35
+ }: SaveCardProps) {
36
+ const t = useLocale();
37
+ const [justSaved, setJustSaved] = useState(false);
38
+ const resolvedSavedLabel = savedLabel ?? t.common.saved;
39
+
40
+ useEffect(() => {
41
+ if (!justSaved) return;
42
+ const t = setTimeout(() => setJustSaved(false), 1200);
43
+ return () => clearTimeout(t);
44
+ }, [justSaved]);
45
+
46
+ const visible = dirty || committing || justSaved || canUndo || canRedo;
47
+ if (!visible) return null;
48
+
49
+ const handleSave = async () => {
50
+ await onSave();
51
+ setJustSaved(true);
52
+ };
53
+
54
+ const dataAttrs = uiAttr === 'inspector' ? { 'data-inspector-ui': '' } : { 'data-design-ui': '' };
55
+
56
+ const showHistory = !justSaved && (onUndo || onRedo);
57
+
58
+ return (
59
+ <div
60
+ {...dataAttrs}
61
+ className="pointer-events-none absolute bottom-6 left-1/2 z-30 -translate-x-1/2 animate-in fade-in slide-in-from-bottom-2 duration-200 ease-out"
62
+ >
63
+ <div className="pointer-events-auto flex h-9 items-center gap-1 rounded-[8px] border border-border bg-popover/95 py-0.5 pr-0.5 pl-1 shadow-overlay backdrop-blur-md">
64
+ {showHistory && (
65
+ <div className="flex items-center">
66
+ <Button
67
+ size="icon-sm"
68
+ variant="ghost"
69
+ className="text-muted-foreground hover:text-foreground"
70
+ onClick={onUndo}
71
+ disabled={committing || !canUndo}
72
+ aria-label={t.common.undo}
73
+ title={t.common.undo}
74
+ >
75
+ <Undo2 className="size-3.5" />
76
+ </Button>
77
+ <Button
78
+ size="icon-sm"
79
+ variant="ghost"
80
+ className="text-muted-foreground hover:text-foreground"
81
+ onClick={onRedo}
82
+ disabled={committing || !canRedo}
83
+ aria-label={t.common.redo}
84
+ title={t.common.redo}
85
+ >
86
+ <Redo2 className="size-3.5" />
87
+ </Button>
88
+ {(justSaved || dirty || committing) && (
89
+ <span aria-hidden className="ml-1 mr-0.5 h-4 w-px bg-hairline" />
90
+ )}
91
+ </div>
92
+ )}
93
+ {justSaved ? (
94
+ <span className="flex items-center gap-1.5 whitespace-nowrap px-2.5 text-[12px] font-medium text-foreground">
95
+ <Check className="size-3.5 shrink-0 text-[oklch(0.55_0.13_165)]" strokeWidth={2.5} />
96
+ {resolvedSavedLabel}
97
+ </span>
98
+ ) : dirty || committing ? (
99
+ <span className="inline-flex items-center gap-1.5 whitespace-nowrap px-2.5 text-[12px] font-medium text-foreground">
100
+ <span
101
+ aria-hidden
102
+ className="size-1.5 shrink-0 rounded-full bg-brand shadow-[0_0_0_3px_var(--brand-soft)]"
103
+ />
104
+ <span className="nums">{unsavedLabel}</span>
105
+ </span>
106
+ ) : null}
107
+ {!justSaved && dirty && (
108
+ <Button
109
+ size="sm"
110
+ variant="ghost"
111
+ className="text-muted-foreground hover:text-foreground"
112
+ onClick={onDiscard}
113
+ disabled={committing || !dirty}
114
+ >
115
+ {t.common.discard}
116
+ </Button>
117
+ )}
118
+ {(dirty || committing) && (
119
+ <Button
120
+ size="sm"
121
+ variant="brand"
122
+ className="h-7 px-3"
123
+ onClick={handleSave}
124
+ disabled={committing || !dirty}
125
+ >
126
+ {committing ? (
127
+ <>
128
+ <Loader2 className="size-3.5 animate-spin" />
129
+ {t.common.saving}
130
+ </>
131
+ ) : (
132
+ <>
133
+ <Save className="size-3.5" />
134
+ {t.common.save}
135
+ </>
136
+ )}
137
+ </Button>
138
+ )}
139
+ </div>
140
+ </div>
141
+ );
142
+ }
@@ -0,0 +1,32 @@
1
+ import { Loader2 } from 'lucide-react';
2
+ import { format, useLocale } from '@/lib/use-locale';
3
+ import type { PdfExportProgress } from '../lib/export-pdf';
4
+ import { Progress } from './ui/progress';
5
+
6
+ export function PdfProgressToast({ progress }: { progress: PdfExportProgress }) {
7
+ const t = useLocale();
8
+ const text =
9
+ progress.phase === 'processing'
10
+ ? format(t.pdfToast.processing, {
11
+ current: progress.current.toString().padStart(2, '0'),
12
+ total: progress.total.toString().padStart(2, '0'),
13
+ })
14
+ : progress.phase === 'printing'
15
+ ? t.pdfToast.printing
16
+ : t.pdfToast.done;
17
+
18
+ return (
19
+ <div className="flex w-80 items-start gap-3 rounded-[8px] border border-border bg-popover px-3.5 py-3 text-popover-foreground shadow-floating">
20
+ <Loader2 className="mt-0.5 size-3.5 shrink-0 animate-spin text-brand" />
21
+ <div className="min-w-0 flex-1">
22
+ <p className="font-heading text-[12.5px] font-semibold tracking-tight">
23
+ {t.pdfToast.title}
24
+ </p>
25
+ <p className="truncate font-mono text-[10.5px] tracking-[0.04em] text-muted-foreground">
26
+ {text}
27
+ </p>
28
+ <Progress value={Math.round(progress.percent)} className="mt-2 h-[3px]" />
29
+ </div>
30
+ </div>
31
+ );
32
+ }