@peteai/presentation-editor 0.0.2 → 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 (211) hide show
  1. package/README.md +2 -2
  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 +119 -175
  115. package/dist/components/presentation-editor/presentation-editor.svelte.js +597 -136
  116. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte +58 -0
  117. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte.d.ts +10 -0
  118. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte +144 -0
  119. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte.d.ts +7 -0
  120. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte +404 -0
  121. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte.d.ts +3 -0
  122. package/dist/components/presentation-editor/sidebar/color-sidebar/index.d.ts +2 -0
  123. package/dist/components/presentation-editor/sidebar/color-sidebar/index.js +2 -0
  124. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte +26 -0
  125. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte.d.ts +8 -0
  126. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte +216 -0
  127. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte.d.ts +3 -0
  128. package/dist/components/presentation-editor/sidebar/font-sidebar/index.d.ts +2 -0
  129. package/dist/components/presentation-editor/sidebar/font-sidebar/index.js +2 -0
  130. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte +130 -0
  131. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte.d.ts +18 -0
  132. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte +90 -0
  133. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte.d.ts +7 -0
  134. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte +82 -0
  135. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte.d.ts +18 -0
  136. package/dist/components/presentation-editor/sidebar/{images-library.svelte → sidebar-uploads-tab.svelte} +0 -1
  137. package/dist/components/presentation-editor/sidebar/sidebar-uploads-tab.svelte.d.ts +3 -0
  138. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte +25 -0
  139. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte.d.ts +7 -0
  140. package/dist/components/presentation-editor/sidebar/sidebar.svelte +71 -15
  141. package/dist/components/presentation-editor/sidebar/sidebar.svelte.d.ts +16 -5
  142. package/dist/components/presentation-editor/sidebar/uploads-image.svelte +28 -11
  143. package/dist/components/presentation-editor/slide-editor.svelte +20 -22
  144. package/dist/components/presentation-editor/slide-inner.svelte +19 -18
  145. package/dist/components/presentation-editor/slides-navigation/slide-preview.svelte +61 -52
  146. package/dist/components/presentation-editor/slides-navigation/slides-navigation.svelte +6 -8
  147. package/dist/components/presentation-editor/snapping-guides.svelte +3 -3
  148. package/dist/components/presentation-editor/types.d.ts +67 -27
  149. package/dist/components/presentation-editor/utils.d.ts +50 -1
  150. package/dist/components/presentation-editor/utils.js +101 -6
  151. package/dist/components/ui/button/button.svelte +3 -2
  152. package/dist/components/ui/button/button.svelte.d.ts +5 -82
  153. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte +43 -0
  154. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte.d.ts +8 -0
  155. package/dist/components/ui/color-picker/color-picker.svelte +344 -0
  156. package/dist/components/ui/color-picker/color-picker.svelte.d.ts +13 -0
  157. package/dist/components/ui/color-picker/index.d.ts +3 -0
  158. package/dist/components/ui/color-picker/index.js +5 -0
  159. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +6 -3
  160. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +1 -1
  161. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
  162. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +6 -3
  163. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  164. package/dist/components/ui/infinite-loader/index.d.ts +4 -0
  165. package/dist/components/ui/infinite-loader/index.js +4 -0
  166. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.d.ts +13 -0
  167. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.js +44 -0
  168. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.d.ts +15 -0
  169. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.js +28 -0
  170. package/dist/components/ui/infinite-loader/infinite-loader.svelte +149 -0
  171. package/dist/components/ui/infinite-loader/infinite-loader.svelte.d.ts +17 -0
  172. package/dist/components/ui/input/input.svelte +1 -1
  173. package/dist/components/ui/slider/slider.svelte +20 -18
  174. package/dist/components/ui/tabs/index.d.ts +6 -0
  175. package/dist/components/ui/tabs/index.js +8 -0
  176. package/dist/components/ui/tabs/tabs-content.svelte +19 -0
  177. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  178. package/dist/components/ui/tabs/tabs-list.svelte +19 -0
  179. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  180. package/dist/components/ui/tabs/tabs-trigger.svelte +19 -0
  181. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  182. package/dist/components/ui/toggle/toggle.svelte +3 -2
  183. package/dist/components/ui/toggle/toggle.svelte.d.ts +2 -46
  184. package/dist/plugin.js +3 -2
  185. package/dist/utils.d.ts +1 -0
  186. package/dist/utils.js +1 -0
  187. package/package.json +28 -25
  188. package/dist/components/presentation-editor/app.css +0 -12
  189. package/dist/components/presentation-editor/layers/hovered-layer.svelte +0 -34
  190. package/dist/components/presentation-editor/layers/hovered-layer.svelte.d.ts +0 -7
  191. package/dist/components/presentation-editor/layers/types/background/background-content.svelte +0 -11
  192. package/dist/components/presentation-editor/layers/types/background/background-content.svelte.d.ts +0 -7
  193. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte +0 -12
  194. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte.d.ts +0 -7
  195. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte +0 -159
  196. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte.d.ts +0 -8
  197. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte +0 -42
  198. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte.d.ts +0 -10
  199. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte +0 -24
  200. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte.d.ts +0 -8
  201. package/dist/components/presentation-editor/layers/types/image/image-content.svelte.d.ts +0 -8
  202. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte +0 -21
  203. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte.d.ts +0 -7
  204. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte +0 -13
  205. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte.d.ts +0 -8
  206. package/dist/components/presentation-editor/sidebar/images-library.svelte.d.ts +0 -3
  207. package/dist/components/presentation-editor/sidebar/layers.svelte +0 -94
  208. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte +0 -32
  209. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte.d.ts +0 -10
  210. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte +0 -34
  211. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte.d.ts +0 -10
@@ -1,25 +1,33 @@
1
1
  <script lang="ts">
2
2
  import CornerRadiusIcon from 'svelte-radix/CornerTopLeft.svelte';
3
- import type {
4
- ImageLayer,
5
- LayerChangesAction,
6
- } from '../../../types.js';
3
+ import type { ImageLayer, HistoryAction } from '../../../types.js';
7
4
  import { getPresentationEditorContext } from '../../../presentation-editor.svelte.js';
8
5
  import * as Popover from '../../../../ui/popover/index.js';
9
6
  import { Button } from '../../../../ui/button/index.js';
10
7
  import { Slider } from '../../../../ui/slider/index.js';
8
+ import { Input } from '../../../../ui/input/index.js';
11
9
  import { createDebouncedCallback } from '../../../../../utils.js';
12
10
 
13
11
  interface Props {
14
- layer: ImageLayer;
12
+ layers: ImageLayer[];
15
13
  }
16
14
 
17
- let { layer = $bindable() }: Props = $props();
15
+ let { layers = $bindable() }: Props = $props();
18
16
 
19
17
  const editor = getPresentationEditorContext();
20
18
 
19
+ const cornerRadius = $derived.by(() => {
20
+ if (!layers.length) return;
21
+
22
+ const firstLayerCornerRadius = layers[0].cornerRadius;
23
+ const allSame = layers.every((layer) => layer.cornerRadius === firstLayerCornerRadius);
24
+
25
+ return allSame ? firstLayerCornerRadius || 0 : undefined;
26
+ });
27
+
28
+ let initial: (ImageLayer & { state: ImageLayer })[] | null = null;
21
29
  let undo: { cornerRadius: number | null } | null = null;
22
- const debouncedHistoryPush = createDebouncedCallback((action: LayerChangesAction) => {
30
+ const debouncedHistoryPush = createDebouncedCallback((action: HistoryAction) => {
23
31
  editor.historyPush(action);
24
32
  undo = null;
25
33
  }, 500);
@@ -27,21 +35,30 @@
27
35
  let min = 0;
28
36
  let max = 100;
29
37
  const setCornerRadius = (value: string | number, debounce = false) => {
30
- let cornerRadius = parseInt(value.toString());
31
- if (cornerRadius > max) {
32
- cornerRadius = max;
33
- } else if (cornerRadius < min) {
34
- cornerRadius = min;
38
+ value = parseInt(value.toString());
39
+ if (value > max) {
40
+ value = max;
41
+ } else if (value < min) {
42
+ value = min;
35
43
  }
36
- if (!undo) {
37
- undo = { cornerRadius: layer.cornerRadius };
44
+ if (!initial) {
45
+ initial = layers.map((layer) => ({ ...layer, state: layer }));
38
46
  }
39
- const redo = { cornerRadius: cornerRadius || null };
40
- const action: LayerChangesAction = {
41
- type: 'layer',
42
- layer: { id: layer.id, type: layer.type },
43
- undo,
44
- redo,
47
+ const action: HistoryAction = {
48
+ type: 'layersGroup',
49
+ actions: initial.map((layerWithState) => {
50
+ const { state, ...layer } = layerWithState;
51
+ const undo = { cornerRadius: layer.cornerRadius };
52
+ const redo = { cornerRadius: value || null };
53
+ Object.assign(state, redo);
54
+ return {
55
+ type: 'layer',
56
+ slideId: editor.activeSlide.id,
57
+ layer: { id: layer.id, type: layer.type },
58
+ undo,
59
+ redo,
60
+ };
61
+ }),
45
62
  };
46
63
  if (debounce) {
47
64
  debouncedHistoryPush(action);
@@ -64,21 +81,23 @@
64
81
  <div class="flex flex-col gap-2">
65
82
  <div class="flex flex-col">
66
83
  <div class="text-sm font-medium text-gray-500">Corner rounding</div>
67
- <div class="flex gap-4">
68
- <Slider
69
- type="single"
70
- value={layer.cornerRadius || 0}
71
- {min}
72
- {max}
73
- step={1}
74
- onValueChange={(value) => setCornerRadius(value, true)}
75
- />
76
- <input
77
- class="border-input m-0 h-10 w-10 rounded-md bg-transparent p-0 pb-1 text-center text-sm font-semibold leading-none focus:ring-0 [&::-webkit-inner-spin-button]:appearance-none"
84
+ <div class="flex items-center gap-2">
85
+ <div class="grow">
86
+ <Slider
87
+ type="single"
88
+ value={cornerRadius || 0}
89
+ {min}
90
+ {max}
91
+ step={1}
92
+ onValueChange={(value) => setCornerRadius(value, true)}
93
+ />
94
+ </div>
95
+ <Input
96
+ class="w-10 bg-transparent p-0 text-center font-semibold leading-none [&::-webkit-inner-spin-button]:appearance-none"
78
97
  type="text"
79
98
  inputmode="decimal"
80
99
  placeholder="--"
81
- value={layer.cornerRadius || 0}
100
+ value={cornerRadius}
82
101
  onchange={(e) => setCornerRadius(e.target.value)}
83
102
  />
84
103
  </div>
@@ -1,7 +1,7 @@
1
1
  import type { ImageLayer } from '../../../types.js';
2
2
  interface Props {
3
- layer: ImageLayer;
3
+ layers: ImageLayer[];
4
4
  }
5
- declare const CornerRadiusButton: import("svelte").Component<Props, {}, "layer">;
5
+ declare const CornerRadiusButton: import("svelte").Component<Props, {}, "layers">;
6
6
  type CornerRadiusButton = ReturnType<typeof CornerRadiusButton>;
7
7
  export default CornerRadiusButton;
@@ -1,24 +1,47 @@
1
1
  <script lang="ts">
2
2
  import FlipHorizontalIcon from 'lucide-svelte/icons/flip-horizontal';
3
3
  import FlipVerticalIcon from 'lucide-svelte/icons/flip-vertical';
4
- import type { ImageLayer } from '../../../types.js';
4
+ import type { ImageLayer, BackgroundImage } from '../../../types.js';
5
5
  import { getPresentationEditorContext } from '../../../presentation-editor.svelte.js';
6
6
  import * as DropdownMenu from '../../../../ui/dropdown-menu/index.js';
7
7
  import { buttonVariants } from '../../../../ui/button/index.js';
8
8
 
9
9
  interface Props {
10
- layer: ImageLayer;
10
+ layers: ImageLayer[] | BackgroundImage;
11
11
  }
12
12
 
13
- let { layer = $bindable() }: Props = $props();
13
+ let { layers = $bindable() }: Props = $props();
14
14
 
15
15
  const editor = getPresentationEditorContext();
16
16
 
17
17
  const flipToggle = (isHorizontal?: boolean) => () => {
18
- const undo = isHorizontal ? { flipY: layer.flipY } : { flipX: layer.flipX };
19
- const redo = isHorizontal ? { flipY: !layer.flipY } : { flipX: !layer.flipX };
20
- Object.assign(layer, redo);
21
- editor.historyPush({ type: 'layer', layer: { id: layer.id, type: layer.type }, undo, redo });
18
+ if (Array.isArray(layers)) {
19
+ editor.historyPush({
20
+ type: 'layersGroup',
21
+ actions: layers.map((layer) => {
22
+ const undo = isHorizontal ? { flipY: layer.flipY } : { flipX: layer.flipX };
23
+ const redo = isHorizontal ? { flipY: !layer.flipY } : { flipX: !layer.flipX };
24
+ Object.assign(layer, redo);
25
+ return {
26
+ type: 'layer',
27
+ slideId: editor.activeSlide.id,
28
+ layer: { id: layer.id, type: layer.type },
29
+ undo,
30
+ redo,
31
+ };
32
+ }),
33
+ });
34
+ } else {
35
+ const undo = isHorizontal ? { flipY: layers.flipY } : { flipX: layers.flipX };
36
+ const redo = isHorizontal ? { flipY: !layers.flipY } : { flipX: !layers.flipX };
37
+ Object.assign(layers, redo);
38
+ editor.historyPush({
39
+ type: 'backgroundImage',
40
+ slideId: editor.activeSlide.id,
41
+ undo,
42
+ redo,
43
+ });
44
+ }
22
45
  };
23
46
  </script>
24
47
 
@@ -1,7 +1,7 @@
1
- import type { ImageLayer } from '../../../types.js';
1
+ import type { ImageLayer, BackgroundImage } from '../../../types.js';
2
2
  interface Props {
3
- layer: ImageLayer;
3
+ layers: ImageLayer[] | BackgroundImage;
4
4
  }
5
- declare const FlipButton: import("svelte").Component<Props, {}, "layer">;
5
+ declare const FlipButton: import("svelte").Component<Props, {}, "layers">;
6
6
  type FlipButton = ReturnType<typeof FlipButton>;
7
7
  export default FlipButton;
@@ -1,48 +1,90 @@
1
1
  <script lang="ts">
2
2
  import OpacityIcon from 'svelte-radix/TransparencyGrid.svelte';
3
- import type { Layer, LayerChangesAction } from '../../../types.js';
3
+ import type {
4
+ Layer,
5
+ BackgroundImage,
6
+ HistoryAction,
7
+ } from '../../../types.js';
4
8
  import { getPresentationEditorContext } from '../../../presentation-editor.svelte.js';
5
9
  import * as Popover from '../../../../ui/popover/index.js';
6
10
  import { Button } from '../../../../ui/button/index.js';
7
11
  import { Slider } from '../../../../ui/slider/index.js';
12
+ import { Input } from '../../../../ui/input/index.js';
8
13
  import { createDebouncedCallback } from '../../../../../utils.js';
9
14
 
10
15
  interface Props {
11
- layer: Layer;
16
+ layers: Layer[] | BackgroundImage;
12
17
  }
13
18
 
14
- let { layer = $bindable() }: Props = $props();
19
+ let { layers = $bindable() }: Props = $props();
15
20
 
16
21
  const editor = getPresentationEditorContext();
17
22
 
18
23
  let undo: { opacity: number | null } | null = null;
19
- const debouncedHistoryPush = createDebouncedCallback((action: LayerChangesAction) => {
24
+ let initial: (Layer & { state: Layer })[] | BackgroundImage | null = null;
25
+ const debouncedHistoryPush = createDebouncedCallback((action: HistoryAction) => {
20
26
  editor.historyPush(action);
21
- undo = null;
27
+ initial = null;
22
28
  }, 500);
23
29
 
24
- let trasparency = $derived(parseFloat((100 - (layer.opacity ?? 1) * 100).toFixed(2)));
30
+ const getOpacity = (layer: Layer | BackgroundImage) =>
31
+ parseFloat((100 - (layer.opacity ?? 1) * 100).toFixed(2));
32
+
33
+ const trasparency = $derived.by(() => {
34
+ if (!Array.isArray(layers)) return getOpacity(layers);
35
+ if (!layers.length) return;
36
+
37
+ const firstLayerOpacity = getOpacity(layers[0]);
38
+ const allSame = layers.every((layer) => getOpacity(layer) === firstLayerOpacity);
39
+
40
+ return allSame ? firstLayerOpacity : undefined;
41
+ });
25
42
 
26
43
  let min = 0;
27
44
  let max = 100;
28
45
  const setTransparency = (value: string | number, debounce = false) => {
29
- let transparency = Number(value);
30
- if (transparency > max) {
31
- transparency = max;
32
- } else if (!(transparency >= min || transparency <= max)) {
33
- transparency = min;
46
+ value = Number(value);
47
+ if (value > max) {
48
+ value = max;
49
+ } else if (!(value >= min || value <= max)) {
50
+ value = min;
51
+ }
52
+ const opacity = value ? (100 - value) / 100 : null;
53
+
54
+ if (!initial) {
55
+ initial = Array.isArray(layers)
56
+ ? layers.map((layer) => ({ ...layer, state: layer }))
57
+ : { ...layers };
34
58
  }
35
- if (!undo) {
36
- undo = { opacity: layer.opacity };
59
+
60
+ let action: HistoryAction;
61
+ const redo = { opacity };
62
+ if (Array.isArray(initial)) {
63
+ action = {
64
+ type: 'layersGroup',
65
+ actions: initial.map((layerWithState) => {
66
+ const { state, ...layer } = layerWithState;
67
+ const undo = { opacity: layer.opacity };
68
+ Object.assign(state, redo);
69
+ return {
70
+ type: 'layer',
71
+ slideId: editor.activeSlide.id,
72
+ layer: { id: layer.id, type: layer.type },
73
+ undo,
74
+ redo,
75
+ };
76
+ }),
77
+ };
78
+ } else {
79
+ Object.assign(layers, redo);
80
+ action = {
81
+ type: 'backgroundImage',
82
+ slideId: editor.activeSlide.id,
83
+ undo: { opacity: initial.opacity },
84
+ redo,
85
+ };
37
86
  }
38
- const redo = { opacity: transparency ? (100 - transparency) / 100 : null };
39
- Object.assign(layer, redo);
40
- const action: LayerChangesAction = {
41
- type: 'layer',
42
- layer: { id: layer.id, type: layer.type },
43
- undo,
44
- redo,
45
- };
87
+
46
88
  if (debounce) {
47
89
  debouncedHistoryPush(action);
48
90
  } else {
@@ -69,18 +111,19 @@
69
111
  <div class="flex flex-col gap-2">
70
112
  <div class="flex flex-col">
71
113
  <div class="text-sm font-medium text-gray-500">Transparency</div>
72
- <div class="flex gap-4">
73
- <Slider
74
- type="single"
75
- value={trasparency}
76
- {min}
77
- {max}
78
- step={1}
79
- onValueChange={(value) => setTransparency(value, true)}
80
- />
81
- <input
82
- class="border-input m-0 h-10 w-10 rounded-md bg-transparent p-0 pb-1 text-center text-sm font-semibold leading-none focus:ring-0 [&::-webkit-inner-spin-button]:appearance-none"
83
- type="text"
114
+ <div class="flex items-center gap-2">
115
+ <div class="grow">
116
+ <Slider
117
+ type="single"
118
+ value={trasparency || 0}
119
+ {min}
120
+ {max}
121
+ step={1}
122
+ onValueChange={(value) => setTransparency(value, true)}
123
+ />
124
+ </div>
125
+ <Input
126
+ class="w-10 bg-transparent p-0 text-center font-semibold leading-none [&::-webkit-inner-spin-button]:appearance-none"
84
127
  inputmode="decimal"
85
128
  placeholder="--"
86
129
  value={trasparency}
@@ -1,7 +1,7 @@
1
- import type { Layer } from '../../../types.js';
1
+ import type { Layer, BackgroundImage } from '../../../types.js';
2
2
  interface Props {
3
- layer: Layer;
3
+ layers: Layer[] | BackgroundImage;
4
4
  }
5
- declare const OpacityButton: import("svelte").Component<Props, {}, "layer">;
5
+ declare const OpacityButton: import("svelte").Component<Props, {}, "layers">;
6
6
  type OpacityButton = ReturnType<typeof OpacityButton>;
7
7
  export default OpacityButton;
@@ -1,6 +1,5 @@
1
1
  <script lang="ts" module>
2
2
  import { tv, type VariantProps } from 'tailwind-variants';
3
- import type { Layer } from '../../../types.js';
4
3
 
5
4
  const cornerScaleControlVariants = tv({
6
5
  slots: {
@@ -34,100 +33,125 @@
34
33
  },
35
34
  });
36
35
 
37
- type Origin = VariantProps<typeof cornerScaleControlVariants>['origin'];
36
+ type Variants = VariantProps<typeof cornerScaleControlVariants>;
38
37
 
39
- interface Props {
40
- origin: NonNullable<Origin>;
41
- layer: Layer;
42
- }
38
+ interface Props extends Omit<Variants, 'origin'>, Required<Pick<Variants, 'origin'>> {}
43
39
  </script>
44
40
 
45
41
  <script lang="ts">
46
42
  import { cn } from '../../../../../utils.js';
47
- import { calculateNewPosition } from '../../utils.js';
43
+ import {
44
+ calculateGroupRotatedBoundingBox,
45
+ calculateLayerTransform,
46
+ calculateNewPosition,
47
+ type Transform,
48
+ } from '../../utils.js';
48
49
  import { getPresentationEditorContext } from '../../../presentation-editor.svelte.js';
50
+ import type { Layer } from '../../../types.js';
51
+
52
+ let { origin }: Props = $props();
49
53
 
50
- let { origin, layer = $bindable() }: Props = $props();
54
+ const type = `${origin}-origin-scale`;
51
55
 
52
56
  const editor = getPresentationEditorContext();
53
57
 
54
- let isChanged = false;
58
+ let initial: {
59
+ clientX: number;
60
+ clientY: number;
61
+ bbox: Transform;
62
+ layers: (Layer & { state: Layer })[];
63
+ } | null = null;
64
+ const actionId = editor.generateId();
65
+ let scaleFactor = 1;
55
66
 
56
67
  const { base, handler, cursor } = cornerScaleControlVariants({ origin });
57
68
 
58
69
  const onMouseDown = (e: MouseEvent) => {
70
+ if (e.button !== 0) return;
59
71
  e.preventDefault();
60
72
  e.stopPropagation();
61
- console.log('scale', 'mousedown', layer.id);
62
- isChanged = false;
63
- editor.activeAction = {
64
- type: `${origin}-origin-scale`,
65
- cursor: cursor(),
73
+ console.log(type, 'mousedown', e);
74
+
75
+ scaleFactor = 1;
76
+ initial = {
66
77
  clientX: e.clientX,
67
78
  clientY: e.clientY,
68
- layer: { ...layer },
79
+ bbox:
80
+ editor.activeLayers.length === 1
81
+ ? calculateLayerTransform(editor.activeLayers[0])
82
+ : calculateGroupRotatedBoundingBox(
83
+ editor.activeLayers.map(calculateLayerTransform),
84
+ editor.activeGroupRotate,
85
+ ),
86
+ layers: editor.activeLayers.map((layer) => ({ ...layer, state: layer })),
69
87
  };
88
+ editor.activeAction = { id: actionId, type, cursor: cursor() };
70
89
  addEventListener('mousemove', onMouseMove);
71
90
  addEventListener('mouseup', onMouseUp);
72
91
  };
73
92
 
74
- const onMouseUp = () => {
75
- console.log('scale', 'mouseup', layer.id);
76
- if (isChanged && editor.activeAction) {
77
- if (editor.checkIfLayerInBounds(layer)) {
78
- editor.historyPush({
79
- type: 'layer',
80
- layer: { id: layer.id, type: layer.type },
81
- undo: {
82
- scale: editor.activeAction.layer.scale,
83
- x: editor.activeAction.layer.x,
84
- y: editor.activeAction.layer.y,
85
- },
86
- redo: { scale: layer.scale, x: layer.x, y: layer.y },
87
- });
88
- }
89
- }
90
- editor.activeAction = null;
93
+ const onMouseUp = (e: MouseEvent) => {
94
+ console.log(type, 'mouseup', e);
91
95
  removeEventListener('mousemove', onMouseMove);
92
96
  removeEventListener('mouseup', onMouseUp);
97
+
98
+ if (editor.activeAction?.id !== actionId) return;
99
+ editor.activeAction = null;
100
+ if (!initial || scaleFactor === 1) return;
101
+
102
+ editor.historyPush({
103
+ type: 'layersGroup',
104
+ actions: initial.layers.map((layer) => {
105
+ if (editor.isLayerOutOfBounds(layer.state)) {
106
+ return {
107
+ type: 'layersRemove',
108
+ slideId: editor.activeSlide.id,
109
+ layers: [layer],
110
+ };
111
+ } else {
112
+ return {
113
+ type: 'layer',
114
+ slideId: editor.activeSlide.id,
115
+ layer: { id: layer.id, type: layer.type },
116
+ undo: { x: layer.x, y: layer.y, scale: layer.scale },
117
+ redo: { x: layer.state.x, y: layer.state.y, scale: layer.state.scale },
118
+ };
119
+ }
120
+ }),
121
+ });
93
122
  };
94
123
 
95
124
  const onMouseMove = (e: MouseEvent) => {
96
- if (!editor.activeAction) return;
125
+ if (!initial || editor.activeAction?.id !== actionId) return;
97
126
 
98
- isChanged = true;
99
- const { clientX, clientY } = editor.activeAction;
100
- const { width, height, x, y } = editor.activeAction.layer;
101
- const scale = editor.activeAction.layer.scale || 1;
102
- const rotate = editor.activeAction.layer.rotate || 0;
127
+ const { width, height, x, y, rotate } = initial.bbox;
103
128
  const angle = (rotate * Math.PI) / 180;
104
- const xDiff = (e.clientX - clientX) / editor.zoom;
105
- const yDiff = (e.clientY - clientY) / editor.zoom;
129
+ const xDiff = (e.clientX - initial.clientX) / editor.zoom;
130
+ const yDiff = (e.clientY - initial.clientY) / editor.zoom;
106
131
  const adjustedXDiff = xDiff * Math.cos(angle) + yDiff * Math.sin(angle);
107
132
  const adjustedYDiff = -xDiff * Math.sin(angle) + yDiff * Math.cos(angle);
108
133
 
109
- // Calculate the initial width and height of the layer, adjusted for scale
110
- const initialWidth = width * scale;
111
- const initialHeight = height * scale;
112
-
113
134
  // Define the new x2 and y2 coordinates based on the variant (corner being dragged)
114
135
  const originCoordinates = {
115
136
  'bottom-right': {
116
- x2: x + initialWidth - adjustedXDiff,
117
- y2: y + initialHeight - adjustedYDiff,
137
+ x2: x + width - adjustedXDiff,
138
+ y2: y + height - adjustedYDiff,
118
139
  },
119
140
  'bottom-left': {
120
- x2: x + initialWidth + adjustedXDiff,
121
- y2: y + initialHeight - adjustedYDiff,
141
+ x2: x + width + adjustedXDiff,
142
+ y2: y + height - adjustedYDiff,
143
+ },
144
+ 'top-right': {
145
+ x2: x + width - adjustedXDiff,
146
+ y2: y + height + adjustedYDiff,
122
147
  },
123
- 'top-right': { x2: x + initialWidth - adjustedXDiff, y2: y + initialHeight + adjustedYDiff },
124
- 'top-left': { x2: x + initialWidth + adjustedXDiff, y2: y + initialHeight + adjustedYDiff },
148
+ 'top-left': { x2: x + width + adjustedXDiff, y2: y + height + adjustedYDiff },
125
149
  };
126
150
 
127
151
  const { x2, y2 } = originCoordinates[origin];
128
152
 
129
153
  // Calculate the slope of the rectangle
130
- const slope = initialHeight / initialWidth;
154
+ const slope = height / width;
131
155
 
132
156
  // Calculate the x-coordinate of the intersection point
133
157
  const xIntersect = (y2 + x2 / slope - y + x * slope) / (slope + 1 / slope);
@@ -145,18 +169,24 @@
145
169
  newHeight = 10;
146
170
  }
147
171
 
148
- const scaleFactor = Math.max(newWidth / initialWidth, newHeight / initialHeight);
172
+ scaleFactor = Math.max(newWidth / width, newHeight / height);
149
173
 
150
174
  if (scaleFactor > 0) {
151
- const newScale = scale * scaleFactor;
152
175
  const { newX, newY } = calculateNewPosition(
153
176
  origin,
154
- { x, y, width: initialWidth, height: initialHeight, rotate },
155
- width * newScale,
156
- height * newScale,
177
+ { x, y, width, height, rotate },
178
+ width * scaleFactor,
179
+ height * scaleFactor,
157
180
  );
158
- const newProps = { scale: newScale, x: newX, y: newY };
159
- Object.assign(layer, newProps);
181
+ initial.layers.forEach((layer) => {
182
+ const scale = layer.scale || 1;
183
+ const newProps = {
184
+ scale: scale * scaleFactor,
185
+ x: newX + (layer.x - x) * scaleFactor,
186
+ y: newY + (layer.y - y) * scaleFactor,
187
+ };
188
+ Object.assign(layer.state, newProps);
189
+ });
160
190
  }
161
191
 
162
192
  if (editor.activeAction) {
@@ -173,7 +203,7 @@
173
203
  <!-- svelte-ignore a11y_no_static_element_interactions -->
174
204
  <div class={cn(handler(), cursor())} onmousedown={onMouseDown}></div>
175
205
  <div
176
- class="h-3 w-3 rounded-full bg-white transition-colors group-hover:bg-purple-500 group-active:bg-purple-500"
206
+ class="group-hover:bg-primary group-active:bg-primary h-3 w-3 rounded-full bg-white transition-colors"
177
207
  style:box-shadow="0 0 4px 1px rgba(57,76,96,.15), 0 0 0 1px rgba(43,59,74,.3)"
178
208
  ></div>
179
209
  </div>