@peteai/presentation-editor 0.0.9 → 0.0.10

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 (54) hide show
  1. package/dist/components/editor/design.svelte +92 -0
  2. package/dist/components/editor/design.svelte.d.ts +8 -0
  3. package/dist/components/editor/editor.svelte +1 -1
  4. package/dist/components/editor/editor.svelte.js +14 -2
  5. package/dist/components/editor/header.svelte +1 -1
  6. package/dist/components/editor/index.d.ts +2 -1
  7. package/dist/components/editor/index.js +2 -1
  8. package/dist/components/editor/page-editor.svelte +7 -0
  9. package/dist/components/editor/{pages-navigation/page-preview.svelte → page-preview.svelte} +4 -4
  10. package/dist/components/editor/{pages-navigation/page-preview.svelte.d.ts → page-preview.svelte.d.ts} +2 -2
  11. package/dist/components/editor/page-transition-preview.svelte +34 -0
  12. package/dist/components/editor/page-transition-preview.svelte.d.ts +9 -0
  13. package/dist/components/editor/page-with-transition.svelte +48 -0
  14. package/dist/components/editor/page-with-transition.svelte.d.ts +10 -0
  15. package/dist/components/editor/page.svelte +12 -19
  16. package/dist/components/editor/pages-navigation/pages-navigation-item.svelte +80 -20
  17. package/dist/components/editor/pages-navigation/pages-navigation.svelte +7 -4
  18. package/dist/components/editor/sidebar/color-sidebar/color-sidebar.svelte +91 -81
  19. package/dist/components/editor/sidebar/color-sidebar/color-sidebar.svelte.d.ts +5 -1
  20. package/dist/components/editor/sidebar/font-sidebar/font-sidebar.svelte +9 -5
  21. package/dist/components/editor/sidebar/font-sidebar/font-sidebar.svelte.d.ts +5 -1
  22. package/dist/components/editor/sidebar/image-crop-sidebar.svelte +28 -37
  23. package/dist/components/editor/sidebar/image-crop-sidebar.svelte.d.ts +2 -0
  24. package/dist/components/editor/sidebar/position-sidebar/index.d.ts +2 -0
  25. package/dist/components/editor/sidebar/position-sidebar/index.js +2 -0
  26. package/dist/components/editor/sidebar/position-sidebar/position-sidebar.svelte +130 -0
  27. package/dist/components/editor/sidebar/position-sidebar/position-sidebar.svelte.d.ts +7 -0
  28. package/dist/components/editor/sidebar/sidebar-text-tab.svelte +7 -3
  29. package/dist/components/editor/sidebar/sidebar-text-tab.svelte.d.ts +5 -16
  30. package/dist/components/editor/sidebar/sidebar-uploads-tab.svelte +8 -6
  31. package/dist/components/editor/sidebar/sidebar-uploads-tab.svelte.d.ts +5 -1
  32. package/dist/components/editor/sidebar/sidebar-wrapper.svelte +4 -3
  33. package/dist/components/editor/sidebar/sidebar-wrapper.svelte.d.ts +1 -0
  34. package/dist/components/editor/sidebar/sidebar.svelte +20 -13
  35. package/dist/components/editor/sidebar/transition-sidebar/index.d.ts +2 -0
  36. package/dist/components/editor/sidebar/transition-sidebar/index.js +2 -0
  37. package/dist/components/editor/sidebar/transition-sidebar/transition-sidebar.svelte +257 -0
  38. package/dist/components/editor/sidebar/transition-sidebar/transition-sidebar.svelte.d.ts +7 -0
  39. package/dist/components/editor/types.d.ts +40 -6
  40. package/dist/components/editor/utils.d.ts +2 -2
  41. package/dist/components/editor/utils.js +21 -0
  42. package/dist/components/ui/button/button.svelte +2 -1
  43. package/dist/components/ui/button/button.svelte.d.ts +3 -0
  44. package/dist/transitions/circleWipe.d.ts +10 -0
  45. package/dist/transitions/circleWipe.js +16 -0
  46. package/dist/transitions/lineWipe.d.ts +9 -0
  47. package/dist/transitions/lineWipe.js +17 -0
  48. package/dist/transitions/stack.d.ts +8 -0
  49. package/dist/transitions/stack.js +13 -0
  50. package/package.json +1 -1
  51. package/dist/components/editor/layers/types/image/image-layer-active.svelte +0 -36
  52. package/dist/components/editor/layers/types/image/image-layer-active.svelte.d.ts +0 -7
  53. package/dist/components/editor/sidebar/position-sidebar.svelte +0 -136
  54. package/dist/components/editor/sidebar/position-sidebar.svelte.d.ts +0 -3
@@ -1,12 +1,12 @@
1
1
  <script lang="ts">
2
2
  import PlusIcon from '@lucide/svelte/icons/plus';
3
- // import PaletteIcon from '@lucide/svelte/icons/palette';
3
+ import PaletteIcon from '@lucide/svelte/icons/palette';
4
4
  import { ColorPicker } from '../../../ui/color-picker/index.js';
5
5
  import * as Popover from '../../../ui/popover/index.js';
6
6
  import * as Tabs from '../../../ui/tabs/index.js';
7
7
  import { cn, createDebouncedCallback } from '../../../../utils.js';
8
- import { getEditorContext } from '../../editor.svelte.js';
9
- import type { HistoryAction, Gradient, ImageLayer, TextLayer, Layer, Page } from '../../types.js';
8
+ import type { Editor } from '../../editor.svelte.js';
9
+ import type { HistoryAction, Gradient, ImageLayer, TextLayer, Layer } from '../../types.js';
10
10
  import SidebarWrapper from '../sidebar-wrapper.svelte';
11
11
  import ColorSidebarGradientPicker from './color-sidebar-gradient-picker.svelte';
12
12
  import ColorSidebarColor from './color-sidebar-color.svelte';
@@ -20,7 +20,11 @@
20
20
 
21
21
  let open = $state(false);
22
22
 
23
- const editor = getEditorContext();
23
+ interface Props {
24
+ editor: Editor;
25
+ }
26
+
27
+ const { editor }: Props = $props();
24
28
 
25
29
  const { htmlEditor } = editor;
26
30
 
@@ -311,91 +315,82 @@
311
315
  </script>
312
316
 
313
317
  <SidebarWrapper name="Color">
314
- <div class="flex items-center gap-2 py-2">
315
- <h5 class="text-left text-sm font-bold">Document colors</h5>
316
- </div>
317
- <div class="grid grid-cols-6 items-stretch gap-1">
318
- <div class="relative h-0 w-full" style:padding-top="100%">
319
- <div class="absolute left-0 top-0 h-full w-full">
320
- <Popover.Root bind:open>
321
- <Popover.Trigger
322
- class={cn(
323
- 'relative h-full w-full overflow-hidden rounded-full after:absolute after:inset-0 after:rounded-full after:transition-shadow',
324
- open ? 'after:shadow-active' : 'hover:after:shadow-hover',
325
- )}
326
- >
327
- <div
328
- class="relative h-full w-full after:absolute after:inset-0 after:rounded-full after:shadow-inner-1"
329
- >
330
- <div
331
- class="h-full w-full rounded-full"
332
- style:background={`conic-gradient(red, orange, yellow, green, blue, indigo, violet, red)`}
333
- ></div>
334
- <span class="absolute inset-0 flex h-full w-full items-center justify-center">
335
- <span
336
- class="flex h-6 w-6 items-center justify-center rounded-full bg-background text-foreground"
337
- >
338
- <PlusIcon />
339
- </span>
340
- </span>
341
- </div>
342
- </Popover.Trigger>
343
- <Popover.Content align="start" sideOffset={2} class="w-80 p-4">
344
- {#if gradientsAllowed}
345
- <Tabs.Root
346
- value={isGradient(currentColor) ? 'gradient' : 'solid'}
347
- class="w-full"
348
- onValueChange={switchType}
349
- >
350
- <Tabs.List class="grid w-full grid-cols-2">
351
- <Tabs.Trigger value="solid">Solid color</Tabs.Trigger>
352
- <Tabs.Trigger value="gradient">Gradient</Tabs.Trigger>
353
- </Tabs.List>
354
- <Tabs.Content value="solid">
355
- {#if !isGradient(currentColor)}
356
- <ColorPicker hex={currentColor} onChange={({ hex }) => setColor(hex, true)} />
357
- {/if}
358
- </Tabs.Content>
359
- <Tabs.Content value="gradient">
360
- {#if isGradient(currentColor)}
361
- <ColorSidebarGradientPicker color={currentColor} {setColor} />
362
- {/if}
363
- </Tabs.Content>
364
- </Tabs.Root>
365
- {:else}
366
- <ColorPicker hex={currentColor} onChange={({ hex }) => setColor(hex, true)} />
367
- {/if}
368
- </Popover.Content>
369
- </Popover.Root>
370
- </div>
318
+ <div>
319
+ <div class="flex items-center gap-2 p-2">
320
+ <h5 class="text-left text-sm font-bold">Document colors</h5>
371
321
  </div>
372
- {#each documentColors as color}
322
+ <div class="grid grid-cols-6 items-stretch gap-1 p-2">
373
323
  <div class="relative h-0 w-full" style:padding-top="100%">
374
324
  <div class="absolute left-0 top-0 h-full w-full">
375
- <ColorSidebarColor {color} {currentColor} onclick={() => setColor(color)} />
325
+ <Popover.Root bind:open>
326
+ <Popover.Trigger
327
+ class={cn(
328
+ 'relative h-full w-full overflow-hidden rounded-full after:absolute after:inset-0 after:rounded-full after:transition-shadow',
329
+ open ? 'after:shadow-active' : 'hover:after:shadow-hover',
330
+ )}
331
+ >
332
+ <div
333
+ class="relative h-full w-full after:absolute after:inset-0 after:rounded-full after:shadow-inner-1"
334
+ >
335
+ <div
336
+ class="h-full w-full rounded-full"
337
+ style:background={`conic-gradient(red, orange, yellow, green, blue, indigo, violet, red)`}
338
+ ></div>
339
+ <span class="absolute inset-0 flex h-full w-full items-center justify-center">
340
+ <span
341
+ class="flex h-6 w-6 items-center justify-center rounded-full bg-background text-foreground"
342
+ >
343
+ <PlusIcon />
344
+ </span>
345
+ </span>
346
+ </div>
347
+ </Popover.Trigger>
348
+ <Popover.Content align="start" sideOffset={2} class="w-80 p-4">
349
+ {#if gradientsAllowed}
350
+ <Tabs.Root
351
+ value={isGradient(currentColor) ? 'gradient' : 'solid'}
352
+ class="w-full"
353
+ onValueChange={switchType}
354
+ >
355
+ <Tabs.List class="grid w-full grid-cols-2">
356
+ <Tabs.Trigger value="solid">Solid color</Tabs.Trigger>
357
+ <Tabs.Trigger value="gradient">Gradient</Tabs.Trigger>
358
+ </Tabs.List>
359
+ <Tabs.Content value="solid">
360
+ {#if !isGradient(currentColor)}
361
+ <ColorPicker hex={currentColor} onChange={({ hex }) => setColor(hex, true)} />
362
+ {/if}
363
+ </Tabs.Content>
364
+ <Tabs.Content value="gradient">
365
+ {#if isGradient(currentColor)}
366
+ <ColorSidebarGradientPicker color={currentColor} {setColor} />
367
+ {/if}
368
+ </Tabs.Content>
369
+ </Tabs.Root>
370
+ {:else}
371
+ <ColorPicker hex={currentColor} onChange={({ hex }) => setColor(hex, true)} />
372
+ {/if}
373
+ </Popover.Content>
374
+ </Popover.Root>
376
375
  </div>
377
376
  </div>
378
- {/each}
379
- </div>
380
- <div class="flex items-center gap-2 py-2">
381
- <!-- <PaletteIcon class="h-5 w-5" /> -->
382
- <h5 class="text-left text-sm font-bold">Default colors</h5>
383
- </div>
384
- <div class="text-xs text-muted-foreground">Solid colors</div>
385
- <div class="grid grid-cols-6 items-stretch gap-1">
386
- {#each Object.keys(defaultSolidColors) as color}
387
- <div class="relative h-0 w-full" style:padding-top="100%">
388
- <div class="absolute left-0 top-0 h-full w-full">
389
- <ColorSidebarColor {color} {currentColor} onclick={() => setColor(color)} />
377
+ {#each documentColors as color}
378
+ <div class="relative h-0 w-full" style:padding-top="100%">
379
+ <div class="absolute left-0 top-0 h-full w-full">
380
+ <ColorSidebarColor {color} {currentColor} onclick={() => setColor(color)} />
381
+ </div>
390
382
  </div>
391
- </div>
392
- {/each}
383
+ {/each}
384
+ </div>
393
385
  </div>
394
386
 
395
- {#if gradientsAllowed}
396
- <div class="text-xs text-muted-foreground">Gradients</div>
397
- <div class="grid grid-cols-6 items-stretch gap-1">
398
- {#each defaultGradients as color}
387
+ <div>
388
+ <div class="flex items-center gap-2 p-2">
389
+ <PaletteIcon class="h-5 w-5" />
390
+ <h5 class="text-left text-sm font-bold">Default solid colors</h5>
391
+ </div>
392
+ <div class="grid grid-cols-6 items-stretch gap-1 p-2">
393
+ {#each Object.keys(defaultSolidColors) as color}
399
394
  <div class="relative h-0 w-full" style:padding-top="100%">
400
395
  <div class="absolute left-0 top-0 h-full w-full">
401
396
  <ColorSidebarColor {color} {currentColor} onclick={() => setColor(color)} />
@@ -403,5 +398,20 @@
403
398
  </div>
404
399
  {/each}
405
400
  </div>
401
+ </div>
402
+
403
+ {#if gradientsAllowed}
404
+ <div>
405
+ <div class="text-xs text-muted-foreground">Gradients</div>
406
+ <div class="grid grid-cols-6 items-stretch gap-1">
407
+ {#each defaultGradients as color}
408
+ <div class="relative h-0 w-full" style:padding-top="100%">
409
+ <div class="absolute left-0 top-0 h-full w-full">
410
+ <ColorSidebarColor {color} {currentColor} onclick={() => setColor(color)} />
411
+ </div>
412
+ </div>
413
+ {/each}
414
+ </div>
415
+ </div>
406
416
  {/if}
407
417
  </SidebarWrapper>
@@ -1,3 +1,7 @@
1
- declare const ColorSidebar: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import type { Editor } from '../../editor.svelte.js';
2
+ interface Props {
3
+ editor: Editor;
4
+ }
5
+ declare const ColorSidebar: import("svelte").Component<Props, {}, "">;
2
6
  type ColorSidebar = ReturnType<typeof ColorSidebar>;
3
7
  export default ColorSidebar;
@@ -8,7 +8,7 @@
8
8
  import { Button } from '../../../ui/button/index.js';
9
9
  import { Separator } from '../../../ui/separator/index.js';
10
10
  import { cn } from '../../../../utils.js';
11
- import { getEditorContext } from '../../editor.svelte.js';
11
+ import type { Editor } from '../../editor.svelte.js';
12
12
  import SidebarWrapper from '../sidebar-wrapper.svelte';
13
13
  import {
14
14
  createEditorNotReactive,
@@ -17,7 +17,11 @@
17
17
  } from '../../layers/types/text/editor/utils.js';
18
18
  import FontSidebarButton from './font-sidebar-button.svelte';
19
19
 
20
- const editor = getEditorContext();
20
+ interface Props {
21
+ editor: Editor;
22
+ }
23
+
24
+ const { editor }: Props = $props();
21
25
 
22
26
  let { htmlEditor } = editor;
23
27
 
@@ -133,7 +137,7 @@
133
137
  </script>
134
138
 
135
139
  <SidebarWrapper name="Font">
136
- <div class="relative flex items-center">
140
+ <div class="relative flex items-center p-2">
137
141
  <div class="pointer-events-none absolute flex w-10 items-center justify-center">
138
142
  {#if search}
139
143
  <Button variant="ghost" size="icon-xs" class="pointer-events-auto" onclick={cancelSearch}>
@@ -150,7 +154,7 @@
150
154
  oninput={() => (searchedPagesLoaded = 1)}
151
155
  />
152
156
  </div>
153
- <div class={cn('flex-1 overflow-y-auto', search && 'hidden')}>
157
+ <div class={cn('flex-1 overflow-y-auto p-2', search && 'hidden')}>
154
158
  <div class="flex items-center gap-2 py-2">
155
159
  <DocumentIcon class="h-6 w-6" />
156
160
  <h5 class="text-left text-sm font-bold">Document fonts</h5>
@@ -184,7 +188,7 @@
184
188
  </div>
185
189
 
186
190
  {#if search}
187
- <div class="flex-1 overflow-y-auto">
191
+ <div class="flex-1 overflow-y-auto p-2">
188
192
  {#if searchedFonts.length}
189
193
  <div class="flex items-center gap-2 py-2">
190
194
  <h5 class="text-left text-sm font-bold">All results</h5>
@@ -1,3 +1,7 @@
1
- declare const FontSidebar: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import type { Editor } from '../../editor.svelte.js';
2
+ interface Props {
3
+ editor: Editor;
4
+ }
5
+ declare const FontSidebar: import("svelte").Component<Props, {}, "">;
2
6
  type FontSidebar = ReturnType<typeof FontSidebar>;
3
7
  export default FontSidebar;
@@ -1,22 +1,21 @@
1
1
  <script lang="ts">
2
- import XIcon from '@lucide/svelte/icons/x';
3
2
  import { Button } from '../../ui/button/index.js';
4
3
  import { Slider } from '../../ui/slider/index.js';
5
4
  import { Input } from '../../ui/input/index.js';
6
- import { getEditorContext } from '../editor.svelte.js';
5
+ import type { Editor } from '../editor.svelte.js';
7
6
  import {
8
7
  calculateImageLayerPropsForImageRotate,
9
8
  calculateRelativeRects,
10
9
  } from '../layers/utils.js';
11
10
  import type { ImageLayer } from '../types.js';
11
+ import SidebarWrapper from './sidebar-wrapper.svelte';
12
12
 
13
13
  interface Props {
14
+ editor: Editor;
14
15
  layer: ImageLayer;
15
16
  }
16
17
 
17
- let { layer }: Props = $props();
18
-
19
- const editor = $derived(getEditorContext());
18
+ let { editor, layer }: Props = $props();
20
19
 
21
20
  let value = $derived(Math.round(layer.imageRotate * 10) / 10);
22
21
  let originalLayer = $derived(
@@ -74,39 +73,31 @@
74
73
  });
75
74
  </script>
76
75
 
77
- <div class="flex h-full flex-col gap-2">
78
- <div class="flex items-center justify-between">
79
- <div class="text-sm font-bold">Crop</div>
80
- <Button variant="ghost" size="icon" onclick={() => (editor.imageCropLayer = null)}>
81
- <XIcon />
82
- </Button>
83
- </div>
84
- <div class="flex-1 resize-none overflow-y-auto">
85
- <div class="flex items-center gap-2">
86
- <div class="grow">
87
- <Slider
88
- type="single"
89
- {value}
90
- {min}
91
- {max}
92
- {step}
93
- onValueChange={(value) => setImageRotate(value)}
94
- onValueCommit={() => (layerCache = null)}
95
- />
96
- </div>
97
- <Input
98
- class="w-12 bg-transparent p-0 text-center font-semibold leading-none [&::-webkit-inner-spin-button]:appearance-none"
99
- inputmode="decimal"
100
- placeholder="--"
76
+ <SidebarWrapper name="Crop" onclose={() => (editor.imageCropLayer = null)}>
77
+ <div class="flex items-center gap-2 p-2">
78
+ <div class="grow">
79
+ <Slider
80
+ type="single"
101
81
  {value}
102
- onchange={(e) => setImageRotate(e.currentTarget.value)}
82
+ {min}
83
+ {max}
84
+ {step}
85
+ onValueChange={(value) => setImageRotate(value)}
86
+ onValueCommit={() => (layerCache = null)}
103
87
  />
104
88
  </div>
105
- <div class="flex justify-end gap-2 p-2">
106
- <Button class="flex-1" variant="outline" onclick={() => (editor.imageCropLayer = null)}>
107
- Cancel
108
- </Button>
109
- <Button class="flex-1" onclick={applyChanges}>Done</Button>
110
- </div>
89
+ <Input
90
+ class="w-12 bg-transparent p-0 text-center font-semibold leading-none [&::-webkit-inner-spin-button]:appearance-none"
91
+ inputmode="decimal"
92
+ placeholder="--"
93
+ {value}
94
+ onchange={(e) => setImageRotate(e.currentTarget.value)}
95
+ />
96
+ </div>
97
+ <div class="flex justify-end gap-2 p-2">
98
+ <Button class="flex-1" variant="outline" onclick={() => (editor.imageCropLayer = null)}>
99
+ Cancel
100
+ </Button>
101
+ <Button class="flex-1" onclick={applyChanges}>Done</Button>
111
102
  </div>
112
- </div>
103
+ </SidebarWrapper>
@@ -1,5 +1,7 @@
1
+ import type { Editor } from '../editor.svelte.js';
1
2
  import type { ImageLayer } from '../types.js';
2
3
  interface Props {
4
+ editor: Editor;
3
5
  layer: ImageLayer;
4
6
  }
5
7
  declare const ImageCropSidebar: import("svelte").Component<Props, {}, "">;
@@ -0,0 +1,2 @@
1
+ import PositionSidebar from './position-sidebar.svelte';
2
+ export { PositionSidebar };
@@ -0,0 +1,2 @@
1
+ import PositionSidebar from './position-sidebar.svelte';
2
+ export { PositionSidebar };
@@ -0,0 +1,130 @@
1
+ <script lang="ts">
2
+ import { flip } from 'svelte/animate';
3
+ import { dndzone, type DndEvent } from 'svelte-dnd-action';
4
+ import * as ContextMenu from '../../../ui/context-menu/index.js';
5
+ import {
6
+ LayerButton,
7
+ LayerThumbWrapper,
8
+ TextLayerContent,
9
+ ImageLayerContent,
10
+ BackgroundLayerContent,
11
+ GroupLayerContent,
12
+ } from '../../layers/index.js';
13
+ import type { Editor } from '../../editor.svelte.js';
14
+ import LayerMenuContent from '../../menu/layer-menu-content.svelte';
15
+ import BackgroundMenuContent from '../../menu/background-menu-content.svelte';
16
+ import type { Layer } from '../../types.js';
17
+ import SidebarWrapper from '../sidebar-wrapper.svelte';
18
+
19
+ interface Props {
20
+ editor: Editor;
21
+ }
22
+
23
+ const { editor }: Props = $props();
24
+
25
+ const flipDurationMs = 300;
26
+ const otherOptions = { flipDurationMs, type: 'layers', dropTargetStyle: {} };
27
+
28
+ function handleDndConsider(e: CustomEvent<DndEvent<Layer>>) {
29
+ editor.rootLayers = e.detail.items;
30
+ }
31
+
32
+ async function handleDndFinalize(e: CustomEvent<DndEvent<Layer>>) {
33
+ console.log('handleDndFinalize', e);
34
+
35
+ editor.rootLayers = e.detail.items;
36
+
37
+ const index = e.detail.items.findIndex((item) => item.id === e.detail.info.id);
38
+ const item = e.detail.items[index];
39
+
40
+ let redo;
41
+ const prev = e.detail.items[index - 1];
42
+ const next = e.detail.items[index + 1];
43
+ if (prev && next) {
44
+ if (!(prev.sortOrder < item.sortOrder && next.sortOrder > item.sortOrder)) {
45
+ redo = { sortOrder: (prev.sortOrder + next.sortOrder) / 2 };
46
+ }
47
+ } else if (next) {
48
+ if (next && next.sortOrder <= item.sortOrder) {
49
+ redo = { sortOrder: next.sortOrder - 1 };
50
+ }
51
+ } else if (prev) {
52
+ if (prev && prev.sortOrder >= item.sortOrder) {
53
+ redo = { sortOrder: prev.sortOrder + 1 };
54
+ }
55
+ }
56
+
57
+ if (redo) {
58
+ editor.historyPush({
59
+ type: 'layerUpdate',
60
+ pageId: editor.activePage.id,
61
+ layer: { id: item.id, type: item.type },
62
+ undo: { sortOrder: item.sortOrder },
63
+ redo,
64
+ });
65
+ }
66
+ }
67
+ </script>
68
+
69
+ <SidebarWrapper name="Position">
70
+ <div class="flex flex-col gap-2 p-2">
71
+ <section
72
+ class="flex flex-col-reverse gap-2"
73
+ aria-label="Layers"
74
+ use:dndzone={{
75
+ items: editor.rootLayers,
76
+ dragDisabled: editor.activePage.locked,
77
+ ...otherOptions,
78
+ }}
79
+ onconsider={handleDndConsider}
80
+ onfinalize={handleDndFinalize}
81
+ >
82
+ {#each editor.rootLayers as layer (layer.id)}
83
+ <div aria-label={layer.type} animate:flip={{ duration: flipDurationMs }}>
84
+ <ContextMenu.Root
85
+ onOpenChange={(open) =>
86
+ open &&
87
+ !editor.activeLayers.find((l) => l.id === layer.id) &&
88
+ editor.setActiveLayers(layer.id)}
89
+ >
90
+ <ContextMenu.Trigger>
91
+ <LayerButton {layer}>
92
+ <LayerThumbWrapper {layer} thumb={{ width: 192, height: 32 }}>
93
+ {#snippet children({ thumbScale })}
94
+ {#if layer.type === 'text'}
95
+ <TextLayerContent {layer} {thumbScale} />
96
+ {:else if layer.type === 'image'}
97
+ <ImageLayerContent {layer} {thumbScale} />
98
+ {:else if layer.type === 'group'}
99
+ <GroupLayerContent page={editor.activePage} {layer} {thumbScale} />
100
+ {/if}
101
+ {/snippet}
102
+ </LayerThumbWrapper>
103
+ </LayerButton>
104
+ </ContextMenu.Trigger>
105
+ <ContextMenu.Content class="w-72">
106
+ <LayerMenuContent />
107
+ </ContextMenu.Content>
108
+ </ContextMenu.Root>
109
+ </div>
110
+ {/each}
111
+ </section>
112
+ <ContextMenu.Root>
113
+ <ContextMenu.Trigger>
114
+ <LayerButton>
115
+ {@const thumbScale = Math.max(192 / editor.width, 32 / editor.height)}
116
+ <div
117
+ class="absolute top-1/2 -translate-y-1/2"
118
+ style:width="{editor.width * thumbScale}px"
119
+ style:height="{editor.height * thumbScale}px"
120
+ >
121
+ <BackgroundLayerContent page={editor.activePage} {thumbScale} />
122
+ </div>
123
+ </LayerButton>
124
+ </ContextMenu.Trigger>
125
+ <ContextMenu.Content class="w-72">
126
+ <BackgroundMenuContent {editor} page={editor.activePage} />
127
+ </ContextMenu.Content>
128
+ </ContextMenu.Root>
129
+ </div>
130
+ </SidebarWrapper>
@@ -0,0 +1,7 @@
1
+ import type { Editor } from '../../editor.svelte.js';
2
+ interface Props {
3
+ editor: Editor;
4
+ }
5
+ declare const PositionSidebar: import("svelte").Component<Props, {}, "">;
6
+ type PositionSidebar = ReturnType<typeof PositionSidebar>;
7
+ export default PositionSidebar;
@@ -1,11 +1,15 @@
1
1
  <script lang="ts">
2
2
  import TextIcon from '@lucide/svelte/icons/type';
3
3
  import Button from '../../ui/button/button.svelte';
4
- import { getEditorContext } from '../editor.svelte.js';
4
+ import type { Editor } from '../editor.svelte.js';
5
5
  import { buildParagraphHtml } from '../utils.js';
6
6
  import SidebarTextTabButton from './sidebar-text-tab-button.svelte';
7
7
 
8
- const editor = getEditorContext();
8
+ interface Props {
9
+ editor: Editor;
10
+ }
11
+
12
+ const { editor }: Props = $props();
9
13
 
10
14
  const createTextBox = () => {
11
15
  const fontSize = 80 / 0.75;
@@ -65,7 +69,7 @@
65
69
  ];
66
70
  </script>
67
71
 
68
- <div class="flex flex-col">
72
+ <div class="flex flex-col p-2">
69
73
  <Button variant="default" class="w-full" onclick={createTextBox}>
70
74
  <TextIcon />
71
75
  Add a text box
@@ -1,18 +1,7 @@
1
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
1
+ import type { Editor } from '../editor.svelte.js';
2
+ interface Props {
3
+ editor: Editor;
13
4
  }
14
- declare const SidebarTextTab: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type SidebarTextTab = InstanceType<typeof SidebarTextTab>;
5
+ declare const SidebarTextTab: import("svelte").Component<Props, {}, "">;
6
+ type SidebarTextTab = ReturnType<typeof SidebarTextTab>;
18
7
  export default SidebarTextTab;
@@ -7,9 +7,13 @@
7
7
  import { Label } from '../../ui/label/index.js';
8
8
  import UploadsImage from './uploads-image.svelte';
9
9
  import { checkImage } from '../utils.js';
10
- import { getEditorContext } from '../editor.svelte.js';
10
+ import type { Editor } from '../editor.svelte.js';
11
11
 
12
- const editor = getEditorContext();
12
+ interface Props {
13
+ editor: Editor;
14
+ }
15
+
16
+ const { editor }: Props = $props();
13
17
 
14
18
  let open = $state(false);
15
19
  let url = $state('');
@@ -44,11 +48,9 @@
44
48
  };
45
49
  </script>
46
50
 
47
- <div class="relative flex h-full shrink-0 flex-col gap-2">
51
+ <div class="relative flex h-full shrink-0 flex-col gap-2 p-2">
48
52
  {#if editor.fileDragged}
49
- <div
50
- class="absolute inset-0 z-10 flex h-full w-full flex-col items-center justify-center bg-background"
51
- >
53
+ <div class="absolute inset-0 z-10 flex h-full w-full flex-col items-center justify-center">
52
54
  <div class="grid gap-6">
53
55
  <div class="grid justify-center">
54
56
  <CloudUploadIcon class="m-auto h-8 w-8" />
@@ -1,3 +1,7 @@
1
- declare const SidebarUploadsTab: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import type { Editor } from '../editor.svelte.js';
2
+ interface Props {
3
+ editor: Editor;
4
+ }
5
+ declare const SidebarUploadsTab: import("svelte").Component<Props, {}, "">;
2
6
  type SidebarUploadsTab = ReturnType<typeof SidebarUploadsTab>;
3
7
  export default SidebarUploadsTab;
@@ -5,18 +5,19 @@
5
5
 
6
6
  interface Props {
7
7
  name: string;
8
+ onclose?: () => void;
8
9
  children?: import('svelte').Snippet;
9
10
  }
10
11
 
11
- let { name, children }: Props = $props();
12
+ let { name, children, onclose = () => (editor.activeSidebarPopup = null) }: Props = $props();
12
13
 
13
14
  const editor = getEditorContext();
14
15
  </script>
15
16
 
16
17
  <div class="flex h-full select-none flex-col gap-2">
17
- <div class="flex items-center justify-between">
18
+ <div class="flex items-center justify-between p-2">
18
19
  <div class="text-sm font-bold">{name}</div>
19
- <Button variant="ghost" size="icon" onclick={() => (editor.activeSidebarPopup = null)}>
20
+ <Button variant="ghost" size="icon" onclick={onclose}>
20
21
  <XIcon />
21
22
  </Button>
22
23
  </div>
@@ -1,5 +1,6 @@
1
1
  interface Props {
2
2
  name: string;
3
+ onclose?: () => void;
3
4
  children?: import('svelte').Snippet;
4
5
  }
5
6
  declare const SidebarWrapper: import("svelte").Component<Props, {}, "">;