@gendive/slide 0.1.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 (58) hide show
  1. package/README.md +55 -0
  2. package/dist/App.d.ts +2 -0
  3. package/dist/__vite-browser-external-BcPniuRQ.cjs +2 -0
  4. package/dist/__vite-browser-external-BcPniuRQ.cjs.map +1 -0
  5. package/dist/__vite-browser-external-DYxpcVy9.js +5 -0
  6. package/dist/__vite-browser-external-DYxpcVy9.js.map +1 -0
  7. package/dist/ai/components/AiEditChat.d.ts +9 -0
  8. package/dist/ai/components/AiImageModal.d.ts +11 -0
  9. package/dist/ai/components/AiPanel.d.ts +10 -0
  10. package/dist/ai/components/AiSlideModal.d.ts +11 -0
  11. package/dist/ai/components/AiTextModal.d.ts +11 -0
  12. package/dist/ai/components/ParsedSlideEditor.d.ts +15 -0
  13. package/dist/ai/hooks/useAiGeneration.d.ts +26 -0
  14. package/dist/ai/index.d.ts +14 -0
  15. package/dist/ai/services/aiApiClient.d.ts +30 -0
  16. package/dist/ai/services/providers/devdiveProvider.d.ts +52 -0
  17. package/dist/ai/services/providers/glmProvider.d.ts +26 -0
  18. package/dist/ai/services/providers/index.d.ts +6 -0
  19. package/dist/ai/services/slideDataParser.d.ts +29 -0
  20. package/dist/ai/stores/aiStore.d.ts +36 -0
  21. package/dist/ai/types/index.d.ts +154 -0
  22. package/dist/components/AiChatBar.d.ts +5 -0
  23. package/dist/components/Editor.d.ts +5 -0
  24. package/dist/components/FloatingToolbar.d.ts +5 -0
  25. package/dist/components/Header.d.ts +5 -0
  26. package/dist/components/ImageNode.d.ts +15 -0
  27. package/dist/components/PropertiesPanel.d.ts +5 -0
  28. package/dist/components/ShapeNode.d.ts +25 -0
  29. package/dist/components/SlideCanvas.d.ts +4 -0
  30. package/dist/components/SlideNavigation.d.ts +5 -0
  31. package/dist/components/SlideThumbnails.d.ts +5 -0
  32. package/dist/components/TemplateGallery.d.ts +11 -0
  33. package/dist/components/TextNode.d.ts +14 -0
  34. package/dist/data/templates.d.ts +9 -0
  35. package/dist/devdive-slide.cjs.js +469 -0
  36. package/dist/devdive-slide.cjs.js.map +1 -0
  37. package/dist/devdive-slide.es.js +32580 -0
  38. package/dist/devdive-slide.es.js.map +1 -0
  39. package/dist/hooks/useAutoSave.d.ts +28 -0
  40. package/dist/hooks/useKeyboardShortcuts.d.ts +4 -0
  41. package/dist/index.d.ts +19 -0
  42. package/dist/lib/pptxGenerator.d.ts +5 -0
  43. package/dist/lib/storage/adapters/hybridAdapter.d.ts +19 -0
  44. package/dist/lib/storage/adapters/index.d.ts +7 -0
  45. package/dist/lib/storage/adapters/indexedDBAdapter.d.ts +17 -0
  46. package/dist/lib/storage/adapters/serverAdapter.d.ts +6 -0
  47. package/dist/lib/storage/index.d.ts +7 -0
  48. package/dist/lib/storage/storageService.d.ts +52 -0
  49. package/dist/lib/storage/types.d.ts +41 -0
  50. package/dist/main.d.ts +0 -0
  51. package/dist/slide.css +1 -0
  52. package/dist/stores/editorStore.d.ts +26 -0
  53. package/dist/theme/index.d.ts +154 -0
  54. package/dist/types/index.d.ts +202 -0
  55. package/dist/utils/id.d.ts +5 -0
  56. package/dist/utils/markdown.d.ts +29 -0
  57. package/dist/utils/snap.d.ts +20 -0
  58. package/package.json +78 -0
@@ -0,0 +1,154 @@
1
+ import { MantineColorsTuple } from '@mantine/core';
2
+ /**
3
+ * @description DevDive Slide 기본 테마
4
+ */
5
+ export declare const devdiveTheme: {
6
+ focusRing?: "auto" | "always" | "never" | undefined;
7
+ scale?: number | undefined;
8
+ fontSmoothing?: boolean | undefined;
9
+ white?: string | undefined;
10
+ black?: string | undefined;
11
+ colors?: {
12
+ [x: string & {}]: MantineColorsTuple | undefined;
13
+ dark?: MantineColorsTuple | undefined;
14
+ gray?: MantineColorsTuple | undefined;
15
+ red?: MantineColorsTuple | undefined;
16
+ pink?: MantineColorsTuple | undefined;
17
+ grape?: MantineColorsTuple | undefined;
18
+ violet?: MantineColorsTuple | undefined;
19
+ indigo?: MantineColorsTuple | undefined;
20
+ blue?: MantineColorsTuple | undefined;
21
+ cyan?: MantineColorsTuple | undefined;
22
+ green?: MantineColorsTuple | undefined;
23
+ lime?: MantineColorsTuple | undefined;
24
+ yellow?: MantineColorsTuple | undefined;
25
+ orange?: MantineColorsTuple | undefined;
26
+ teal?: MantineColorsTuple | undefined;
27
+ } | undefined;
28
+ primaryShade?: import('@mantine/core').MantineColorShade | {
29
+ light?: import('@mantine/core').MantineColorShade | undefined;
30
+ dark?: import('@mantine/core').MantineColorShade | undefined;
31
+ } | undefined;
32
+ primaryColor?: string | undefined;
33
+ variantColorResolver?: import('@mantine/core').VariantColorsResolver | undefined;
34
+ autoContrast?: boolean | undefined;
35
+ luminanceThreshold?: number | undefined;
36
+ fontFamily?: string | undefined;
37
+ fontFamilyMonospace?: string | undefined;
38
+ headings?: {
39
+ fontFamily?: string | undefined;
40
+ fontWeight?: string | undefined;
41
+ textWrap?: "wrap" | "nowrap" | "balance" | "pretty" | "stable" | undefined;
42
+ sizes?: {
43
+ h1?: {
44
+ fontSize?: string | undefined;
45
+ fontWeight?: string | undefined;
46
+ lineHeight?: string | undefined;
47
+ } | undefined;
48
+ h2?: {
49
+ fontSize?: string | undefined;
50
+ fontWeight?: string | undefined;
51
+ lineHeight?: string | undefined;
52
+ } | undefined;
53
+ h3?: {
54
+ fontSize?: string | undefined;
55
+ fontWeight?: string | undefined;
56
+ lineHeight?: string | undefined;
57
+ } | undefined;
58
+ h4?: {
59
+ fontSize?: string | undefined;
60
+ fontWeight?: string | undefined;
61
+ lineHeight?: string | undefined;
62
+ } | undefined;
63
+ h5?: {
64
+ fontSize?: string | undefined;
65
+ fontWeight?: string | undefined;
66
+ lineHeight?: string | undefined;
67
+ } | undefined;
68
+ h6?: {
69
+ fontSize?: string | undefined;
70
+ fontWeight?: string | undefined;
71
+ lineHeight?: string | undefined;
72
+ } | undefined;
73
+ } | undefined;
74
+ } | undefined;
75
+ radius?: {
76
+ [x: string & {}]: string | undefined;
77
+ md?: string | undefined;
78
+ xs?: string | undefined;
79
+ sm?: string | undefined;
80
+ lg?: string | undefined;
81
+ xl?: string | undefined;
82
+ } | undefined;
83
+ defaultRadius?: import('@mantine/core').MantineRadius | undefined;
84
+ spacing?: {
85
+ [x: number]: string | undefined;
86
+ [x: string & {}]: string | undefined;
87
+ md?: string | undefined;
88
+ xs?: string | undefined;
89
+ sm?: string | undefined;
90
+ lg?: string | undefined;
91
+ xl?: string | undefined;
92
+ } | undefined;
93
+ fontSizes?: {
94
+ [x: string & {}]: string | undefined;
95
+ md?: string | undefined;
96
+ xs?: string | undefined;
97
+ sm?: string | undefined;
98
+ lg?: string | undefined;
99
+ xl?: string | undefined;
100
+ } | undefined;
101
+ lineHeights?: {
102
+ [x: string & {}]: string | undefined;
103
+ md?: string | undefined;
104
+ xs?: string | undefined;
105
+ sm?: string | undefined;
106
+ lg?: string | undefined;
107
+ xl?: string | undefined;
108
+ } | undefined;
109
+ breakpoints?: {
110
+ [x: string & {}]: string | undefined;
111
+ md?: string | undefined;
112
+ xs?: string | undefined;
113
+ sm?: string | undefined;
114
+ lg?: string | undefined;
115
+ xl?: string | undefined;
116
+ } | undefined;
117
+ shadows?: {
118
+ [x: string & {}]: string | undefined;
119
+ md?: string | undefined;
120
+ xs?: string | undefined;
121
+ sm?: string | undefined;
122
+ lg?: string | undefined;
123
+ xl?: string | undefined;
124
+ } | undefined;
125
+ respectReducedMotion?: boolean | undefined;
126
+ cursorType?: "default" | "pointer" | undefined;
127
+ defaultGradient?: {
128
+ from?: string | undefined;
129
+ to?: string | undefined;
130
+ deg?: number | undefined;
131
+ } | undefined;
132
+ activeClassName?: string | undefined;
133
+ focusClassName?: string | undefined;
134
+ components?: {
135
+ [x: string]: {
136
+ classNames?: any;
137
+ styles?: any;
138
+ vars?: any;
139
+ defaultProps?: any;
140
+ } | undefined;
141
+ } | undefined;
142
+ other?: {
143
+ [x: string]: any;
144
+ } | undefined;
145
+ };
146
+ export declare const themeVars: {
147
+ primary: string;
148
+ bgMain: string;
149
+ uiWhite: string;
150
+ borderLight: string;
151
+ textPrimary: string;
152
+ textSecondary: string;
153
+ textMuted: string;
154
+ };
@@ -0,0 +1,202 @@
1
+ /**
2
+ * @description 요소 타입 정의
3
+ */
4
+ export type ElementType = 'text' | 'shape' | 'image';
5
+ /**
6
+ * @description 도형 타입
7
+ */
8
+ export type ShapeType = 'rect' | 'ellipse' | 'triangle' | 'line' | 'arrow';
9
+ /**
10
+ * @description 텍스트 스타일 타입 (제목/소제목/본문)
11
+ */
12
+ export type TextStyleType = 'title' | 'subtitle' | 'body' | 'caption';
13
+ /**
14
+ * @description 텍스트 스타일 프리셋
15
+ */
16
+ export declare const TEXT_STYLE_PRESETS: Record<TextStyleType, {
17
+ fontSize: number;
18
+ fontWeight: string;
19
+ lineHeight: number;
20
+ }>;
21
+ /**
22
+ * @description 기본 요소 인터페이스
23
+ */
24
+ export interface BaseElement {
25
+ id: string;
26
+ type: ElementType;
27
+ x: number;
28
+ y: number;
29
+ width: number;
30
+ height: number;
31
+ rotation: number;
32
+ }
33
+ /**
34
+ * @description 텍스트 요소
35
+ */
36
+ export interface TextElement extends BaseElement {
37
+ type: 'text';
38
+ content: string;
39
+ fontSize: number;
40
+ fontFamily: string;
41
+ fill: string;
42
+ align: 'left' | 'center' | 'right';
43
+ textStyle: TextStyleType;
44
+ fontWeight?: string;
45
+ lineHeight?: number;
46
+ }
47
+ /**
48
+ * @description 도형 요소
49
+ */
50
+ export interface ShapeElement extends BaseElement {
51
+ type: 'shape';
52
+ shapeType: ShapeType;
53
+ fill: string;
54
+ stroke: string;
55
+ strokeWidth: number;
56
+ text?: string;
57
+ textColor?: string;
58
+ textSize?: number;
59
+ cornerRadius?: number;
60
+ isImagePlaceholder?: boolean;
61
+ }
62
+ /**
63
+ * @description 이미지 크롭 정보
64
+ */
65
+ export interface ImageCrop {
66
+ x: number;
67
+ y: number;
68
+ width: number;
69
+ height: number;
70
+ }
71
+ /**
72
+ * @description 이미지 요소
73
+ */
74
+ export interface ImageElement extends BaseElement {
75
+ type: 'image';
76
+ src: string;
77
+ cornerRadius?: number;
78
+ crop?: ImageCrop;
79
+ }
80
+ export type SlideElement = TextElement | ShapeElement | ImageElement;
81
+ /**
82
+ * @description 슬라이드
83
+ */
84
+ export interface Slide {
85
+ id: string;
86
+ elements: SlideElement[];
87
+ background: string;
88
+ }
89
+ /**
90
+ * @description 에디터 모드
91
+ */
92
+ export type EditorMode = 'select' | 'text' | 'shape';
93
+ /**
94
+ * @description 사용 가능한 폰트 목록
95
+ */
96
+ export declare const AVAILABLE_FONTS: readonly [{
97
+ readonly name: "Noto Sans KR";
98
+ readonly value: "Noto Sans KR";
99
+ }, {
100
+ readonly name: "Inter";
101
+ readonly value: "Inter";
102
+ }];
103
+ export type FontFamily = (typeof AVAILABLE_FONTS)[number]['value'];
104
+ /**
105
+ * @description 페이지 레이아웃 타입
106
+ */
107
+ export type LayoutType = 'title' | 'title-subtitle' | 'content' | 'two-column' | 'image-left' | 'image-right' | 'bullets' | 'blank' | 'section-header' | 'comparison' | 'title-only' | 'content-caption' | 'picture-caption' | 'graph';
108
+ /**
109
+ * @description 컨셉 테마 타입
110
+ */
111
+ export type ThemeType = 'devdive' | 'minimal' | 'dark' | 'business';
112
+ /**
113
+ * @description 테마 색상 정의
114
+ */
115
+ export interface ThemeColors {
116
+ background: string;
117
+ primary: string;
118
+ text: string;
119
+ accent: string;
120
+ }
121
+ /**
122
+ * @description 테마 프리셋
123
+ */
124
+ export declare const THEME_PRESETS: Record<ThemeType, ThemeColors>;
125
+ /**
126
+ * @description 레이아웃 템플릿 정의
127
+ */
128
+ export interface LayoutTemplate {
129
+ id: LayoutType;
130
+ name: string;
131
+ icon: string;
132
+ createElements: (theme: ThemeColors) => any[];
133
+ }
134
+ export interface SnapSettings {
135
+ enabled: boolean;
136
+ snapToCenter: boolean;
137
+ snapToEdges: boolean;
138
+ snapToElements: boolean;
139
+ threshold: number;
140
+ }
141
+ export interface HistoryState {
142
+ slides: Slide[];
143
+ currentSlideIndex: number;
144
+ selectedElementId: string | null;
145
+ selectedElementIds: string[];
146
+ }
147
+ /**
148
+ * @description 에디터 상태
149
+ */
150
+ export interface EditorState {
151
+ slides: Slide[];
152
+ currentSlideIndex: number;
153
+ selectedElementId: string | null;
154
+ selectedElementIds: string[];
155
+ mode: EditorMode;
156
+ currentShapeType: ShapeType;
157
+ currentTextStyle: TextStyleType;
158
+ currentFontFamily: FontFamily;
159
+ clipboard: SlideElement | null;
160
+ snapSettings: SnapSettings;
161
+ history: HistoryState[];
162
+ historyIndex: number;
163
+ defaultBackground: string;
164
+ }
165
+ /**
166
+ * @description 에디터 액션
167
+ */
168
+ export interface EditorActions {
169
+ addSlide: () => void;
170
+ deleteSlide: (index: number) => void;
171
+ selectSlide: (index: number) => void;
172
+ updateSlideBackground: (color: string) => void;
173
+ updateAllSlidesBackground: (color: string) => void;
174
+ addElement: (element: SlideElement) => void;
175
+ updateElement: (id: string, updates: Partial<SlideElement>) => void;
176
+ deleteElement: (id: string) => void;
177
+ selectElement: (id: string | null) => void;
178
+ selectElements: (ids: string[]) => void;
179
+ addToSelection: (id: string) => void;
180
+ clearSelection: () => void;
181
+ commitElementUpdate: () => void;
182
+ copyElement: () => void;
183
+ pasteElement: () => void;
184
+ bringToFront: () => void;
185
+ sendToBack: () => void;
186
+ bringForward: () => void;
187
+ sendBackward: () => void;
188
+ setMode: (mode: EditorMode) => void;
189
+ setShapeType: (shapeType: ShapeType) => void;
190
+ setTextStyle: (textStyle: TextStyleType) => void;
191
+ setFontFamily: (fontFamily: FontFamily) => void;
192
+ applyTemplate: (layoutId: LayoutType, theme: ThemeColors) => void;
193
+ addSlideWithTemplate: (layoutId: LayoutType, theme: ThemeColors) => void;
194
+ toggleSnap: () => void;
195
+ updateSnapSettings: (settings: Partial<SnapSettings>) => void;
196
+ undo: () => void;
197
+ redo: () => void;
198
+ canUndo: () => boolean;
199
+ canRedo: () => boolean;
200
+ resetPresentation: () => void;
201
+ loadSlides: (slides: Slide[], defaultBg?: string) => void;
202
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @description 유니크 ID 생성
3
+ * @returns 유니크 ID 문자열
4
+ */
5
+ export declare const generateId: () => string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @description 마크다운 파싱 유틸리티
3
+ * 지원: **굵게**, *기울임*, # 헤딩
4
+ */
5
+ export interface MarkdownStyles {
6
+ fontWeight: 'normal' | 'bold';
7
+ fontStyle: 'normal' | 'italic';
8
+ }
9
+ /**
10
+ * @description 마크다운 텍스트를 순수 텍스트로 변환
11
+ */
12
+ export declare const parseMarkdownToPlainText: (text: string) => string;
13
+ /**
14
+ * @description 마크다운 텍스트에서 스타일 추출 (전체 텍스트 기준)
15
+ */
16
+ export declare const parseMarkdownStyles: (text: string) => MarkdownStyles;
17
+ /**
18
+ * @description 마크다운을 PPTX용 텍스트 배열로 변환
19
+ * PptxGenJS의 addText는 배열 형태의 텍스트를 받아 부분 스타일링 가능
20
+ */
21
+ export interface PptxTextPart {
22
+ text: string;
23
+ options?: {
24
+ bold?: boolean;
25
+ italic?: boolean;
26
+ fontSize?: number;
27
+ };
28
+ }
29
+ export declare const parseMarkdownToPptxParts: (text: string, _baseFontSize?: number) => PptxTextPart[];
@@ -0,0 +1,20 @@
1
+ import { SlideElement, SnapSettings } from '../types';
2
+ export interface SnapResult {
3
+ x: number;
4
+ y: number;
5
+ guides: SnapGuide[];
6
+ }
7
+ export interface SnapGuide {
8
+ type: 'horizontal' | 'vertical';
9
+ position: number;
10
+ isCenter?: boolean;
11
+ }
12
+ /**
13
+ * @description 요소의 스냅 위치 계산
14
+ */
15
+ export declare const calculateSnap: (element: {
16
+ x: number;
17
+ y: number;
18
+ width: number;
19
+ height: number;
20
+ }, otherElements: SlideElement[], settings: SnapSettings) => SnapResult;
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@gendive/slide",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "DevDive PPTX Slide Editor - React component library for creating and editing presentations",
7
+ "publishConfig": {
8
+ "access": "restricted",
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/devdive/slide.git"
14
+ },
15
+ "license": "UNLICENSED",
16
+ "author": "DevDive",
17
+ "main": "./dist/devdive-slide.cjs.js",
18
+ "module": "./dist/devdive-slide.es.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/devdive-slide.es.js",
24
+ "require": "./dist/devdive-slide.cjs.js"
25
+ },
26
+ "./style.css": "./dist/slide.css"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "sideEffects": [
32
+ "**/*.css"
33
+ ],
34
+ "peerDependencies": {
35
+ "@mantine/core": "^7.0.0 || ^8.0.0",
36
+ "@mantine/hooks": "^7.0.0 || ^8.0.0",
37
+ "react": "^18.0.0",
38
+ "react-dom": "^18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "dexie": "^4.2.1",
42
+ "konva": "^10.2.0",
43
+ "pptxgenjs": "^4.0.1",
44
+ "react-colorful": "^5.6.1",
45
+ "react-konva": "18",
46
+ "react-konva-utils": "^2.0.0",
47
+ "use-image": "^1.1.4",
48
+ "zustand": "^5.0.10"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint/js": "^9.17.0",
52
+ "@mantine/core": "^8.3.13",
53
+ "@mantine/hooks": "^8.3.13",
54
+ "@types/react": "^18.3.18",
55
+ "@types/react-dom": "^18.3.5",
56
+ "@vitejs/plugin-react": "^4.3.4",
57
+ "eslint": "^9.17.0",
58
+ "eslint-plugin-react-hooks": "^5.0.0",
59
+ "eslint-plugin-react-refresh": "^0.4.16",
60
+ "globals": "^15.14.0",
61
+ "postcss": "^8.5.6",
62
+ "postcss-preset-mantine": "^1.18.0",
63
+ "postcss-simple-vars": "^7.0.1",
64
+ "react": "^18.3.1",
65
+ "react-dom": "^18.3.1",
66
+ "typescript": "~5.8.2",
67
+ "typescript-eslint": "^8.18.2",
68
+ "vite": "^6.0.5",
69
+ "vite-plugin-dts": "^4.5.4"
70
+ },
71
+ "scripts": {
72
+ "dev": "vite",
73
+ "build": "tsc -b && vite build",
74
+ "build:lib": "vite build",
75
+ "lint": "eslint .",
76
+ "preview": "vite preview"
77
+ }
78
+ }