@peteai/presentation-editor 0.0.1 → 0.0.3

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 (214) hide show
  1. package/README.md +172 -38
  2. package/dist/components/presentation-editor/active-layers-buttons.svelte +53 -0
  3. package/dist/components/presentation-editor/active-layers-buttons.svelte.d.ts +3 -0
  4. package/dist/components/presentation-editor/active-layers.svelte +181 -0
  5. package/dist/components/presentation-editor/active-layers.svelte.d.ts +3 -0
  6. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte +81 -0
  7. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte.d.ts +9 -0
  8. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte +21 -0
  9. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte.d.ts +8 -0
  10. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte +23 -0
  11. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte.d.ts +6 -0
  12. package/dist/components/presentation-editor/color-indicator/index.d.ts +4 -0
  13. package/dist/components/presentation-editor/color-indicator/index.js +6 -0
  14. package/dist/components/presentation-editor/cursor-tooltip.svelte +1 -1
  15. package/dist/components/presentation-editor/dragged.svelte +21 -11
  16. package/dist/components/presentation-editor/fonts.d.ts +3 -0
  17. package/dist/components/presentation-editor/fonts.js +1278 -0
  18. package/dist/components/presentation-editor/header.svelte +21 -33
  19. package/dist/components/presentation-editor/header.svelte.d.ts +16 -6
  20. package/dist/components/presentation-editor/hotkeys.svelte +85 -0
  21. package/dist/components/presentation-editor/{sidebar/layers.svelte.d.ts → hotkeys.svelte.d.ts} +3 -3
  22. package/dist/components/presentation-editor/layers/active-background-border.svelte +3 -7
  23. package/dist/components/presentation-editor/layers/active-layer-border.svelte +2 -5
  24. package/dist/components/presentation-editor/layers/active-layer-border.svelte.d.ts +0 -1
  25. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte +113 -129
  26. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte.d.ts +2 -2
  27. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte +51 -32
  28. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte.d.ts +2 -2
  29. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte +30 -7
  30. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte.d.ts +3 -3
  31. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte +76 -33
  32. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte.d.ts +3 -3
  33. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte +89 -59
  34. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte.d.ts +5 -100
  35. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte +337 -0
  36. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte.d.ts +104 -0
  37. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.d.ts +2 -0
  38. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.js +4 -0
  39. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte +128 -43
  40. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte.d.ts +1 -5
  41. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte +68 -57
  42. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte.d.ts +2 -110
  43. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte +45 -32
  44. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte.d.ts +2 -54
  45. package/dist/components/presentation-editor/layers/index.d.ts +4 -5
  46. package/dist/components/presentation-editor/layers/index.js +7 -8
  47. package/dist/components/presentation-editor/layers/layer-button.svelte +25 -7
  48. package/dist/components/presentation-editor/layers/layer-wrapper.svelte +212 -162
  49. package/dist/components/presentation-editor/layers/layer-wrapper.svelte.d.ts +2 -2
  50. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte +41 -0
  51. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte.d.ts +8 -0
  52. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte +28 -74
  53. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte.d.ts +2 -17
  54. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte +19 -0
  55. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte.d.ts +8 -0
  56. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte +69 -61
  57. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte.d.ts +2 -3
  58. package/dist/components/presentation-editor/layers/types/background/index.d.ts +2 -3
  59. package/dist/components/presentation-editor/layers/types/background/index.js +2 -3
  60. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte +55 -12
  61. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte.d.ts +3 -3
  62. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte +60 -8
  63. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte.d.ts +3 -3
  64. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte +59 -24
  65. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte.d.ts +3 -3
  66. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte +27 -76
  67. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte.d.ts +3 -3
  68. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte +36 -0
  69. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte.d.ts +7 -0
  70. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.d.ts +2 -0
  71. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.js +2 -0
  72. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte +72 -29
  73. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte.d.ts +3 -5
  74. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte +60 -8
  75. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte.d.ts +3 -3
  76. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte +71 -18
  77. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte.d.ts +3 -3
  78. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte +54 -8
  79. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte.d.ts +3 -3
  80. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte +54 -9
  81. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte.d.ts +3 -3
  82. package/dist/components/presentation-editor/layers/types/html/editor/createEditor.js +2 -2
  83. package/dist/components/presentation-editor/layers/types/html/editor/utils.d.ts +11 -0
  84. package/dist/components/presentation-editor/layers/types/html/editor/utils.js +88 -0
  85. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.d.ts +27 -0
  86. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.js +40 -0
  87. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.d.ts +3 -0
  88. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.js +3 -0
  89. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.d.ts +5 -1
  90. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.js +3 -7
  91. package/dist/components/presentation-editor/layers/types/html/extensions.d.ts +1 -0
  92. package/dist/components/presentation-editor/layers/types/html/extensions.js +56 -0
  93. package/dist/components/presentation-editor/layers/types/html/html-content.svelte +26 -5
  94. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte +26 -0
  95. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte.d.ts +9 -0
  96. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte +103 -0
  97. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte.d.ts +8 -0
  98. package/dist/components/presentation-editor/layers/types/html/html-layer.svelte +61 -53
  99. package/dist/components/presentation-editor/layers/types/html/index.d.ts +3 -5
  100. package/dist/components/presentation-editor/layers/types/html/index.js +3 -56
  101. package/dist/components/presentation-editor/layers/types/image/{image-content.svelte → image-layer-content.svelte} +11 -3
  102. package/dist/components/presentation-editor/layers/types/image/image-layer-content.svelte.d.ts +8 -0
  103. package/dist/components/presentation-editor/layers/types/image/image-layer.svelte +51 -21
  104. package/dist/components/presentation-editor/layers/types/image/index.d.ts +2 -4
  105. package/dist/components/presentation-editor/layers/types/image/index.js +2 -4
  106. package/dist/components/presentation-editor/layers/utils.d.ts +68 -9
  107. package/dist/components/presentation-editor/layers/utils.js +260 -25
  108. package/dist/components/presentation-editor/menu/background-menu-content.svelte +80 -0
  109. package/dist/components/presentation-editor/menu/background-menu-content.svelte.d.ts +9 -0
  110. package/dist/components/presentation-editor/menu/layer-menu-content.svelte +183 -0
  111. package/dist/components/presentation-editor/menu/layer-menu-content.svelte.d.ts +3 -0
  112. package/dist/components/presentation-editor/menu/slide-menu-content.svelte +67 -0
  113. package/dist/components/presentation-editor/menu/slide-menu-content.svelte.d.ts +9 -0
  114. package/dist/components/presentation-editor/presentation-editor.svelte +120 -176
  115. package/dist/components/presentation-editor/presentation-editor.svelte.d.ts +1 -4
  116. package/dist/components/presentation-editor/presentation-editor.svelte.js +597 -136
  117. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte +58 -0
  118. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte.d.ts +10 -0
  119. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte +144 -0
  120. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte.d.ts +7 -0
  121. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte +404 -0
  122. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte.d.ts +3 -0
  123. package/dist/components/presentation-editor/sidebar/color-sidebar/index.d.ts +2 -0
  124. package/dist/components/presentation-editor/sidebar/color-sidebar/index.js +2 -0
  125. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte +26 -0
  126. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte.d.ts +8 -0
  127. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte +216 -0
  128. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte.d.ts +3 -0
  129. package/dist/components/presentation-editor/sidebar/font-sidebar/index.d.ts +2 -0
  130. package/dist/components/presentation-editor/sidebar/font-sidebar/index.js +2 -0
  131. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte +130 -0
  132. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte.d.ts +18 -0
  133. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte +90 -0
  134. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte.d.ts +7 -0
  135. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte +82 -0
  136. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte.d.ts +18 -0
  137. package/dist/components/presentation-editor/sidebar/{images-library.svelte → sidebar-uploads-tab.svelte} +0 -1
  138. package/dist/components/presentation-editor/sidebar/sidebar-uploads-tab.svelte.d.ts +3 -0
  139. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte +25 -0
  140. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte.d.ts +7 -0
  141. package/dist/components/presentation-editor/sidebar/sidebar.svelte +71 -15
  142. package/dist/components/presentation-editor/sidebar/sidebar.svelte.d.ts +16 -5
  143. package/dist/components/presentation-editor/sidebar/uploads-image.svelte +28 -11
  144. package/dist/components/presentation-editor/slide-editor.svelte +20 -22
  145. package/dist/components/presentation-editor/slide-inner.svelte +19 -18
  146. package/dist/components/presentation-editor/slides-navigation/slide-preview.svelte +61 -52
  147. package/dist/components/presentation-editor/slides-navigation/slides-navigation.svelte +6 -8
  148. package/dist/components/presentation-editor/snapping-guides.svelte +3 -3
  149. package/dist/components/presentation-editor/types.d.ts +67 -27
  150. package/dist/components/presentation-editor/utils.d.ts +50 -1
  151. package/dist/components/presentation-editor/utils.js +101 -6
  152. package/dist/components/ui/button/button.svelte +3 -2
  153. package/dist/components/ui/button/button.svelte.d.ts +5 -82
  154. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte +43 -0
  155. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte.d.ts +8 -0
  156. package/dist/components/ui/color-picker/color-picker.svelte +344 -0
  157. package/dist/components/ui/color-picker/color-picker.svelte.d.ts +13 -0
  158. package/dist/components/ui/color-picker/index.d.ts +3 -0
  159. package/dist/components/ui/color-picker/index.js +5 -0
  160. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +6 -3
  161. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +1 -1
  162. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
  163. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +6 -3
  164. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  165. package/dist/components/ui/infinite-loader/index.d.ts +4 -0
  166. package/dist/components/ui/infinite-loader/index.js +4 -0
  167. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.d.ts +13 -0
  168. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.js +44 -0
  169. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.d.ts +15 -0
  170. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.js +28 -0
  171. package/dist/components/ui/infinite-loader/infinite-loader.svelte +149 -0
  172. package/dist/components/ui/infinite-loader/infinite-loader.svelte.d.ts +17 -0
  173. package/dist/components/ui/input/input.svelte +1 -1
  174. package/dist/components/ui/slider/slider.svelte +20 -18
  175. package/dist/components/ui/tabs/index.d.ts +6 -0
  176. package/dist/components/ui/tabs/index.js +8 -0
  177. package/dist/components/ui/tabs/tabs-content.svelte +19 -0
  178. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  179. package/dist/components/ui/tabs/tabs-list.svelte +19 -0
  180. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  181. package/dist/components/ui/tabs/tabs-trigger.svelte +19 -0
  182. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  183. package/dist/components/ui/toggle/toggle.svelte +3 -2
  184. package/dist/components/ui/toggle/toggle.svelte.d.ts +2 -46
  185. package/dist/index.d.ts +5 -6
  186. package/dist/index.js +1 -4
  187. package/dist/plugin.js +3 -2
  188. package/dist/utils.d.ts +1 -0
  189. package/dist/utils.js +1 -0
  190. package/package.json +28 -25
  191. package/dist/components/presentation-editor/app.css +0 -12
  192. package/dist/components/presentation-editor/layers/hovered-layer.svelte +0 -34
  193. package/dist/components/presentation-editor/layers/hovered-layer.svelte.d.ts +0 -7
  194. package/dist/components/presentation-editor/layers/types/background/background-content.svelte +0 -11
  195. package/dist/components/presentation-editor/layers/types/background/background-content.svelte.d.ts +0 -7
  196. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte +0 -12
  197. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte.d.ts +0 -7
  198. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte +0 -159
  199. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte.d.ts +0 -8
  200. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte +0 -42
  201. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte.d.ts +0 -10
  202. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte +0 -24
  203. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte.d.ts +0 -8
  204. package/dist/components/presentation-editor/layers/types/image/image-content.svelte.d.ts +0 -8
  205. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte +0 -21
  206. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte.d.ts +0 -7
  207. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte +0 -13
  208. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte.d.ts +0 -8
  209. package/dist/components/presentation-editor/sidebar/images-library.svelte.d.ts +0 -3
  210. package/dist/components/presentation-editor/sidebar/layers.svelte +0 -94
  211. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte +0 -32
  212. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte.d.ts +0 -10
  213. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte +0 -34
  214. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte.d.ts +0 -10
package/README.md CHANGED
@@ -1,58 +1,192 @@
1
- # create-svelte
1
+ # @peteai/presentation-editor
2
2
 
3
- Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
3
+ ## Introduction
4
4
 
5
- Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
5
+ This project is a Svelte component library which lets you create a customizable presentation editors.
6
6
 
7
- ## Creating a project
8
-
9
- If you're seeing this, you've probably already done this step. Congrats!
7
+ ## Install
10
8
 
11
9
  ```bash
12
- # create a new project in the current directory
13
- npx sv create
14
-
15
- # create a new project in my-app
16
- npx sv create my-app
10
+ npm install @peteai/presentation-editor
17
11
  ```
18
12
 
19
- ## Developing
20
-
21
- Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
-
23
- ```bash
24
- npm run dev
25
-
26
- # or start the server and open the app in a new browser tab
27
- npm run dev -- --open
13
+ ## Types
14
+
15
+ ```typescript
16
+ type Image = {
17
+ id: string;
18
+ src: string;
19
+ width: number;
20
+ height: number;
21
+ };
22
+
23
+ interface BaseLayer {
24
+ id: string;
25
+ x: number;
26
+ y: number;
27
+ width: number;
28
+ height: number;
29
+ rotate: number | null;
30
+ opacity: number | null;
31
+ sortOrder: number;
32
+ }
33
+
34
+ interface HtmlLayer extends BaseLayer {
35
+ type: 'html';
36
+ scale: number | null;
37
+ html: JSONContent;
38
+ }
39
+
40
+ type LayerBorder = {
41
+ borderStyle: 'solid' | 'dashed' | 'dotted' | null;
42
+ borderWidth: number | null;
43
+ borderColor: string | null;
44
+ };
45
+
46
+ interface ImageLayer extends BaseLayer, LayerBorder {
47
+ type: 'image';
48
+ scale: number | null;
49
+ image: Image;
50
+ offsetX: number | null;
51
+ offsetY: number | null;
52
+ cornerRadius: number | null;
53
+ flipX: boolean;
54
+ flipY: boolean;
55
+ }
56
+
57
+ type Layer = HtmlLayer | ImageLayer;
58
+
59
+ type Slide = {
60
+ id: string;
61
+ backgroundColor: string | null;
62
+ layers: Layer[];
63
+ sortOrder: number;
64
+ };
28
65
  ```
29
66
 
30
- Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
-
32
- ## Building
67
+ ### Html editor
33
68
 
34
- To build your library:
69
+ PresentationEditor is using `Tiptap` editor for `HtmlLayer` content editing.
35
70
 
36
- ```bash
37
- npm run package
38
- ```
71
+ `JSONContent` type provided by `@tiptap/core` is used for html content of `HtmlLayer` to store data in json format.
39
72
 
40
- To create a production version of your showcase app:
73
+ ## Settings
41
74
 
42
- ```bash
43
- npm run build
44
- ```
75
+ The PresentationEditor component accepts a bunch of settings. Here is a typescript definition of all available settings:
45
76
 
46
- You can preview the production build with `npm run preview`.
77
+ ```typescript
78
+ interface BaseOptions {
79
+ images?: Image[];
80
+ width?: number;
81
+ height?: number;
82
+ generateId?: () => string;
83
+ onImageUpload?: (file: File) => Promise<Image>;
84
+ onLayerAdd?: (slideId: string, layer: Layer) => Promise<Layer>;
85
+ onLayerUpdate?: (slideId: string, layerId: string, layerType: string, changes: object) => void;
86
+ onLayerRemove?: (slideId: string, layerId: string, layerType: string) => Promise<void>;
87
+ }
47
88
 
48
- > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
89
+ interface MultipleModeOption extends BaseOptions {
90
+ mode?: 'multiple';
91
+ slides?: Slide[];
92
+ onSlideAdd?: (slide: Slide) => Promise<Slide>;
93
+ onSlideUpdate?: (slideId: string, changes: object) => void;
94
+ onSlideRemove?: (slideId: string) => Promise<void>;
95
+ }
49
96
 
50
- ## Publishing
97
+ interface SingleModeOption extends BaseOptions {
98
+ mode: 'single';
99
+ slide?: Slide;
100
+ }
51
101
 
52
- Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
102
+ export type PresentationEditorOptions = MultipleModeOption | SingleModeOption;
103
+ ```
53
104
 
54
- To publish your library to [npm](https://www.npmjs.com):
105
+ ## Getting Started
106
+
107
+ ```typescript
108
+ import { createEditor } from '@peteai/presentation-editor';
109
+
110
+ // images list
111
+ const images: Image[];
112
+ // slides list
113
+ const slides: Slide[];
114
+
115
+ const editor = new createEditor({
116
+ target: document.querySelector('.target'),
117
+ props: {
118
+ // function for new slides and layers ids generation
119
+ generateId: () => crypto.randomUUID(),
120
+ images,
121
+ slides,
122
+ onImageUpload: async (file) => {
123
+ // called when user uploads image
124
+ // callback to store file and return Image
125
+ // which will be added to the images list
126
+ // new ImageLayer gonna be created if image file was dropped on slide
127
+ // ...
128
+ return image;
129
+ },
130
+ onSlideAdd: async (slide) => {
131
+ // called when new slide is added
132
+ // expect Slide to be returned to overwrite newly created slide
133
+ },
134
+ onSlideUpdate: async (slideId, values) => {
135
+ // called when slide is updated
136
+ },
137
+ onSlideRemove: async (slideId) => {
138
+ // called when slide is removed
139
+ },
140
+ onLayerAdd: async (slideId, layer) => {
141
+ // called when new layer is added
142
+ // expect Layer to be returned to overwrite newly created layer
143
+ },
144
+ onLayerUpdate: async (slideId, layerId, layerType, values) => {
145
+ // called when layer is updated
146
+ },
147
+ onLayerRemove: async (slideId, layerId, layerType) => {
148
+ // called when layer is removed
149
+ },
150
+ },
151
+ });
152
+ ```
55
153
 
56
- ```bash
57
- npm publish
154
+ ## Single Slide Mode
155
+
156
+ ```typescript
157
+ import { createEditor } from '@peteai/presentation-editor';
158
+
159
+ // images list
160
+ const images: Image[];
161
+ // slides list
162
+ const slide: Slide;
163
+
164
+ const editor = new createEditor({
165
+ target: document.querySelector('.target'),
166
+ props: {
167
+ mode: 'single',
168
+ // function for new slides and layers ids generation
169
+ generateId: () => crypto.randomUUID(),
170
+ images,
171
+ slide,
172
+ onImageUpload: async (file) => {
173
+ // called when user uploads image
174
+ // callback to store file and return Image
175
+ // which will be added to the images list
176
+ // new ImageLayer gonna be created if image file was dropped on slide
177
+ // ...
178
+ return image;
179
+ },
180
+ onLayerAdd: async (slideId, layer) => {
181
+ // called when new layer is added
182
+ // expect Layer to be returned to overwrite newly created layer
183
+ },
184
+ onLayerUpdate: async (slideId, layerId, layerType, values) => {
185
+ // called when layer is updated
186
+ },
187
+ onLayerRemove: async (slideId, layerId, layerType) => {
188
+ // called when layer is removed
189
+ },
190
+ },
191
+ });
58
192
  ```
@@ -0,0 +1,53 @@
1
+ <script lang="ts">
2
+ import { Separator } from '../ui/separator/index.js';
3
+ import { BorderButton } from './layers/buttons/border-button/index.js';
4
+ import { CornerRadiusButton } from './layers/buttons/corner-radius-button/index.js';
5
+ import { FlipButton } from './layers/buttons/flip-button/index.js';
6
+ import { OpacityButton } from './layers/buttons/opacity-button/index.js';
7
+ import { AlignmentButton } from './layers/types/html/buttons/alignment-button/index.js';
8
+ import { BoldButton } from './layers/types/html/buttons/bold-button/index.js';
9
+ import { CaseButton } from './layers/types/html/buttons/case-button/index.js';
10
+ import { ColorButton } from './layers/types/html/buttons/color-button/index.js';
11
+ import { FontFamilyButton } from './layers/types/html/buttons/font-family-button/index.js';
12
+ import { FontSizeButton } from './layers/types/html/buttons/font-size-button/index.js';
13
+ import { ItalicButton } from './layers/types/html/buttons/italic-button/index.js';
14
+ import { ListButton } from './layers/types/html/buttons/list-button/index.js';
15
+ import { StrikethroughButton } from './layers/types/html/buttons/strikethrough-button/index.js';
16
+ import { UnderlineButton } from './layers/types/html/buttons/underline-button/index.js';
17
+ import { getPresentationEditorContext } from './presentation-editor.svelte.js';
18
+
19
+ const editor = getPresentationEditorContext();
20
+
21
+ let noLockedLayers = $derived(editor.activeLayers.filter((layer) => !layer.locked));
22
+ let imageLayers = $derived(noLockedLayers.filter((layer) => layer.type === 'image'));
23
+ let htmlLayers = $derived(noLockedLayers.filter((layer) => layer.type === 'html'));
24
+ </script>
25
+
26
+ {#if editor.activeLayers.length}
27
+ {#if imageLayers.length}
28
+ <Separator orientation="vertical" />
29
+ <BorderButton bind:layers={imageLayers} />
30
+ <CornerRadiusButton bind:layers={imageLayers} />
31
+ {#if htmlLayers.length === 0}
32
+ <Separator orientation="vertical" />
33
+ <FlipButton bind:layers={imageLayers} />
34
+ {/if}
35
+ {/if}
36
+ {#if htmlLayers.length}
37
+ <Separator orientation="vertical" />
38
+ <FontFamilyButton bind:layers={htmlLayers} />
39
+ <FontSizeButton bind:layers={htmlLayers} />
40
+ <ColorButton bind:layers={htmlLayers} />
41
+ <BoldButton bind:layers={htmlLayers} />
42
+ <ItalicButton bind:layers={htmlLayers} />
43
+ <UnderlineButton bind:layers={htmlLayers} />
44
+ <StrikethroughButton bind:layers={htmlLayers} />
45
+ <CaseButton bind:layers={htmlLayers} />
46
+ <AlignmentButton bind:layers={htmlLayers} />
47
+ <ListButton bind:layers={htmlLayers} />
48
+ {/if}
49
+ {#if noLockedLayers.length}
50
+ <Separator orientation="vertical" />
51
+ <OpacityButton bind:layers={noLockedLayers} />
52
+ {/if}
53
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const ActiveLayersButtons: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ActiveLayersButtons = ReturnType<typeof ActiveLayersButtons>;
3
+ export default ActiveLayersButtons;
@@ -0,0 +1,181 @@
1
+ <script lang="ts">
2
+ import { getPresentationEditorContext } from './presentation-editor.svelte.js';
3
+ import {
4
+ calculateLayerTransform,
5
+ calculateGroupRotatedBoundingBox,
6
+ calculateRelativeRects,
7
+ isRotatedVertically,
8
+ } from './layers/utils.js';
9
+ import { SideScaleControl } from './layers/controls/side-scale-control/index.js';
10
+ import { SideResizeControl } from './layers/controls/side-resize-control/index.js';
11
+ import { GroupResizeControl } from './layers/controls/group-resize-control/index.js';
12
+ import { CornerScaleControl } from './layers/controls/corner-scale-control/index.js';
13
+ import { RotateControl } from './layers/controls/rotate-control/index.js';
14
+ import { HtmlLayerEdit } from './layers/index.js';
15
+ import type { HtmlLayer } from './types.js';
16
+
17
+ const editor = getPresentationEditorContext();
18
+
19
+ let htmlLayerEditing: HtmlLayer | undefined = $derived.by(() => {
20
+ if (editor.activeAction?.type === 'edit' && editor.activeLayers.length === 1) {
21
+ const layer = editor.activeLayers[0];
22
+ if (editor.activeAction.id == layer.id && layer.type === 'html') {
23
+ return layer;
24
+ }
25
+ }
26
+ });
27
+
28
+ const group = $derived.by(() => {
29
+ if (editor.activeBackground) {
30
+ return {
31
+ bbox: {
32
+ x: 0,
33
+ y: 0,
34
+ width: editor.width,
35
+ height: editor.height,
36
+ rotate: 0,
37
+ },
38
+ padding: 3,
39
+ items: [],
40
+ };
41
+ } else if (editor.activeLayers.length === 1) {
42
+ return {
43
+ bbox: calculateLayerTransform(editor.activeLayers[0]),
44
+ padding: 0,
45
+ items: [],
46
+ };
47
+ } else if (editor.activeLayers.length > 1) {
48
+ const transforms = editor.activeLayers.map(calculateLayerTransform);
49
+ const bbox = calculateGroupRotatedBoundingBox(transforms, editor.activeGroupRotate);
50
+ const items = calculateRelativeRects(bbox, transforms);
51
+
52
+ return { bbox, padding: 0, items };
53
+ }
54
+ });
55
+
56
+ /**
57
+ * Determines if resizing should be forbidden based on the rotation of the group and its layers.
58
+ *
59
+ * @param {number} groupRotate - The rotation of the group in degrees.
60
+ * @returns {(boolean|string)} - Returns 'horizontal' or 'vertical' if resizing should be forbidden in that direction, otherwise returns false.
61
+ */
62
+ const getConstrainedResizeAxis = (groupRotate: number) => {
63
+ // Check if all active layers are of type 'html'
64
+ const htmlLayersOnly = editor.activeLayers.every((layer) => layer.type === 'html');
65
+ if (!htmlLayersOnly) return false; // If not all layers are 'html', resizing is not forbidden
66
+
67
+ // Calculate the rotation of the first layer relative to the group rotation
68
+ const firstLayerRelativeRotate = (editor.activeLayers[0].rotate || 0) - groupRotate;
69
+ // Determine if the first layer is rotated vertically
70
+ const firstLayerRotatedVertically = isRotatedVertically(firstLayerRelativeRotate);
71
+
72
+ // Check if all layers have the same rotation direction relative to the group rotation
73
+ const allLayersHaveSameRotationDirection = editor.activeLayers.every(
74
+ (layer) =>
75
+ isRotatedVertically((layer.rotate || 0) - groupRotate) === firstLayerRotatedVertically,
76
+ );
77
+ if (!allLayersHaveSameRotationDirection) return false; // If not all layers have the same rotation direction, resizing is not forbidden
78
+
79
+ // Based on the rotation direction, determine the direction in which resizing should be forbidden
80
+ return firstLayerRotatedVertically ? 'horizontal' : 'vertical';
81
+ };
82
+ </script>
83
+
84
+ {#if htmlLayerEditing}
85
+ <HtmlLayerEdit bind:layer={htmlLayerEditing} />
86
+ {/if}
87
+
88
+ {#if group}
89
+ <div
90
+ class="pointer-events-none absolute left-0 top-0 h-full w-full"
91
+ style:width={`${group.bbox.width * editor.zoom + group.padding * 2}px`}
92
+ style:height={`${group.bbox.height * editor.zoom + group.padding * 2}px`}
93
+ style:transform={`translate(${group.bbox.x * editor.zoom - group.padding}px, ${group.bbox.y * editor.zoom - group.padding}px) rotate(${group.bbox.rotate}deg)`}
94
+ >
95
+ {#if group.items.length < 2}
96
+ <div
97
+ class="border-primary absolute -inset-px border-2"
98
+ style:box-shadow="0 0 0 1px hsla(0, 0%, 100%, .07), inset 0 0 0 1px hsla(0, 0%, 100%, .07)"
99
+ ></div>
100
+ {:else}
101
+ <div class="group-border absolute -inset-px"></div>
102
+ {#each group.items as item}
103
+ <div
104
+ class="border-primary absolute -left-px -top-px border-2"
105
+ style:box-shadow="0 0 0 1px hsla(0, 0%, 100%, .07), inset 0 0 0 1px hsla(0, 0%, 100%, .07)"
106
+ style:width={`${item.width * editor.zoom + 2}px`}
107
+ style:height={`${item.height * editor.zoom + 2}px`}
108
+ style:transform={`translate(${item.x * editor.zoom}px, ${item.y * editor.zoom}px) rotate(${item.rotate}deg)`}
109
+ ></div>
110
+ {/each}
111
+ {/if}
112
+
113
+ {#if editor.activeLayers.length > 0 && !editor.activeSlide.locked && !editor.activeLayers.some((l) => l.locked)}
114
+ <div class="h-full w-full outline-none transition-opacity duration-300">
115
+ <div class="flex h-full w-full items-center justify-center">
116
+ {#if editor.activeLayers.length === 1}
117
+ {@const layer = editor.activeLayers[0]}
118
+ {#if layer.type === 'html'}
119
+ <SideScaleControl origin="left" {layer} />
120
+ <SideScaleControl origin="right" {layer} />
121
+ {:else if layer.type === 'image'}
122
+ <SideResizeControl origin="left" {layer} />
123
+ <SideResizeControl origin="right" {layer} />
124
+ <SideResizeControl origin="top" {layer} />
125
+ <SideResizeControl origin="bottom" {layer} />
126
+ {/if}
127
+ {:else}
128
+ {@const constrainedResizeAxis = getConstrainedResizeAxis(group.bbox.rotate)}
129
+ {#if constrainedResizeAxis !== 'horizontal'}
130
+ <GroupResizeControl origin="left" />
131
+ <GroupResizeControl origin="right" />
132
+ {/if}
133
+ {#if constrainedResizeAxis !== 'vertical'}
134
+ <GroupResizeControl origin="top" />
135
+ <GroupResizeControl origin="bottom" />
136
+ {/if}
137
+ {/if}
138
+ <CornerScaleControl origin="bottom-right" />
139
+ <CornerScaleControl origin="bottom-left" />
140
+ <CornerScaleControl origin="top-right" />
141
+ <CornerScaleControl origin="top-left" />
142
+ <RotateControl />
143
+ </div>
144
+ </div>
145
+ {/if}
146
+ </div>
147
+ {/if}
148
+
149
+ <style>
150
+ .group-border {
151
+ background-image: linear-gradient(90deg, #fff 60%, rgba(53, 71, 90, 0.2) 0),
152
+ linear-gradient(180deg, #fff 60%, rgba(53, 71, 90, 0.2) 0),
153
+ linear-gradient(90deg, #fff 60%, rgba(53, 71, 90, 0.2) 0),
154
+ linear-gradient(180deg, #fff 60%, rgba(53, 71, 90, 0.2) 0),
155
+ linear-gradient(90deg, rgba(57, 76, 96, 0.15), rgba(57, 76, 96, 0.15)),
156
+ linear-gradient(180deg, rgba(57, 76, 96, 0.15), rgba(57, 76, 96, 0.15)),
157
+ linear-gradient(90deg, rgba(57, 76, 96, 0.15), rgba(57, 76, 96, 0.15)),
158
+ linear-gradient(180deg, rgba(57, 76, 96, 0.15), rgba(57, 76, 96, 0.15));
159
+ background-position:
160
+ top,
161
+ 100%,
162
+ bottom,
163
+ 0,
164
+ center 2px,
165
+ calc(100% - 2px),
166
+ center calc(100% - 2px),
167
+ 2px;
168
+ background-repeat: repeat-x, repeat-y, repeat-x, repeat-y, no-repeat, no-repeat, no-repeat,
169
+ no-repeat;
170
+ background-size:
171
+ 6px 2px,
172
+ 2px 6px,
173
+ 6px 2px,
174
+ 2px 6px,
175
+ calc(100% - 6px) 1px,
176
+ 1px calc(100% - 4px),
177
+ calc(100% - 6px) 1px,
178
+ 1px calc(100% - 4px);
179
+ box-shadow: 0 0 0 1px rgba(57, 76, 96, 0.15);
180
+ }
181
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const ActiveLayers: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ActiveLayers = ReturnType<typeof ActiveLayers>;
3
+ export default ActiveLayers;
@@ -0,0 +1,81 @@
1
+ <script lang="ts">
2
+ import { stringToGradient } from '../utils.js';
3
+
4
+ interface Props {
5
+ id: string;
6
+ color: string;
7
+ width: number;
8
+ height: number;
9
+ }
10
+
11
+ const { id, color, width, height }: Props = $props();
12
+
13
+ const hexToNumber = (hex: string) => Math.round((parseInt(hex, 16) / 255) * 100) / 100;
14
+
15
+ let gradient = $derived(stringToGradient(color));
16
+ let tag = $derived.by(() => {
17
+ const name = gradient.type.startsWith('linear') ? 'linearGradient' : 'radialGradient';
18
+
19
+ const baseAttrs = { id, gradientUnits: 'userSpaceOnUse' };
20
+
21
+ const calculateRadialAttributes = (cx: number, cy: number, multiplier: number = 1) => ({
22
+ r: Math.hypot(width / 2, height / 2) * multiplier,
23
+ cx,
24
+ cy,
25
+ fx: cx,
26
+ fy: cy,
27
+ });
28
+
29
+ let attributes;
30
+ switch (gradient.type) {
31
+ case 'linear90':
32
+ attributes = { x1: 0, y1: 0, x2: width, y2: 0 };
33
+ break;
34
+ case 'linear180':
35
+ attributes = { x1: 0, y1: 0, x2: 0, y2: height };
36
+ break;
37
+ case 'linear135':
38
+ const halfDiagonal = (width + height) / 2;
39
+ const offsetX = (width - halfDiagonal) / 2;
40
+ const offsetY = (height - halfDiagonal) / 2;
41
+ attributes = {
42
+ x1: offsetX,
43
+ y1: offsetY,
44
+ x2: width - offsetX,
45
+ y2: height - offsetY,
46
+ };
47
+ break;
48
+ case 'radialCenter':
49
+ attributes = calculateRadialAttributes(width / 2, height / 2);
50
+ break;
51
+ case 'radialTopLeft':
52
+ attributes = calculateRadialAttributes(0, 0, 2);
53
+ break;
54
+ }
55
+
56
+ return { name, attrs: { ...baseAttrs, ...attributes } };
57
+ });
58
+ </script>
59
+
60
+ <!-- NOTE: <svelte:element this={tag.name}> making lowercase tag like lineargradient -->
61
+ {#if tag.name === 'linearGradient'}
62
+ <linearGradient {...tag.attrs}>
63
+ {#each gradient.colors as color, index}
64
+ <stop
65
+ stop-color={color.slice(0, 7)}
66
+ stop-opacity={hexToNumber(color.slice(-2))}
67
+ offset={Math.round((index / (gradient.colors.length - 1)) * 1000) / 1000}
68
+ ></stop>
69
+ {/each}
70
+ </linearGradient>
71
+ {:else}
72
+ <radialGradient {...tag.attrs}>
73
+ {#each gradient.colors as color, index}
74
+ <stop
75
+ stop-color={color.slice(0, 7)}
76
+ stop-opacity={hexToNumber(color.slice(-2))}
77
+ offset={Math.round((index / (gradient.colors.length - 1)) * 1000) / 1000}
78
+ ></stop>
79
+ {/each}
80
+ </radialGradient>
81
+ {/if}
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ id: string;
3
+ color: string;
4
+ width: number;
5
+ height: number;
6
+ }
7
+ declare const ColorIndicatorGradientDef: import("svelte").Component<Props, {}, "">;
8
+ type ColorIndicatorGradientDef = ReturnType<typeof ColorIndicatorGradientDef>;
9
+ export default ColorIndicatorGradientDef;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { generateId } from '../../../utils.js';
3
+ import ColorGradientDef from './color-indicator-gradient-def.svelte';
4
+
5
+ interface Props {
6
+ color: string;
7
+ width: number;
8
+ height: number;
9
+ }
10
+
11
+ const { color, width, height }: Props = $props();
12
+
13
+ const gradientId = generateId();
14
+ </script>
15
+
16
+ <svg class="h-full w-full" viewBox="0 0 {width} {height}">
17
+ <defs>
18
+ <ColorGradientDef id={gradientId} {color} {width} {height} />
19
+ </defs>
20
+ <rect x="0" y="0" {width} {height} fill="url(#{gradientId})"></rect>
21
+ </svg>
@@ -0,0 +1,8 @@
1
+ interface Props {
2
+ color: string;
3
+ width: number;
4
+ height: number;
5
+ }
6
+ declare const ColorIndicatorGradient: import("svelte").Component<Props, {}, "">;
7
+ type ColorIndicatorGradient = ReturnType<typeof ColorIndicatorGradient>;
8
+ export default ColorIndicatorGradient;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import Gradient from './color-indicator-gradient.svelte';
3
+
4
+ interface Props {
5
+ color: string;
6
+ }
7
+
8
+ let { color }: Props = $props();
9
+
10
+ let isGradient = $derived(~color.indexOf(':'));
11
+
12
+ let ref = $state<HTMLElement | null>(null);
13
+ </script>
14
+
15
+ {#if isGradient}
16
+ <div bind:this={ref} class="absolute inset-0">
17
+ {#if ref}
18
+ <Gradient {color} width={ref.clientWidth} height={ref.clientHeight} />
19
+ {/if}
20
+ </div>
21
+ {:else}
22
+ <div class="absolute inset-0" style:background-color={color}></div>
23
+ {/if}
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ color: string;
3
+ }
4
+ declare const ColorIndicator: import("svelte").Component<Props, {}, "">;
5
+ type ColorIndicator = ReturnType<typeof ColorIndicator>;
6
+ export default ColorIndicator;
@@ -0,0 +1,4 @@
1
+ import Root from './color-indicator.svelte';
2
+ import Gradient from './color-indicator-gradient.svelte';
3
+ import GradientDef from './color-indicator-gradient-def.svelte';
4
+ export { Root, Gradient, GradientDef, Root as ColorIndicator, Gradient as ColorIndicatorGradient, GradientDef as ColorIndicatorGradientDef, };
@@ -0,0 +1,6 @@
1
+ import Root from './color-indicator.svelte';
2
+ import Gradient from './color-indicator-gradient.svelte';
3
+ import GradientDef from './color-indicator-gradient-def.svelte';
4
+ export { Root, Gradient, GradientDef,
5
+ //
6
+ Root as ColorIndicator, Gradient as ColorIndicatorGradient, GradientDef as ColorIndicatorGradientDef, };
@@ -12,7 +12,7 @@
12
12
  style:transform="translate({tooltip.x}px, {tooltip.y}px)"
13
13
  >
14
14
  <Tooltip.Provider>
15
- <Tooltip.Root controlledOpen open={true}>
15
+ <Tooltip.Root open={true}>
16
16
  <Tooltip.Trigger class="absolute"></Tooltip.Trigger>
17
17
  <Tooltip.Content
18
18
  side="bottom"