@gradio/imageeditor 0.10.0 → 0.11.0-beta.1

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 (63) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/Index.svelte +5 -2
  3. package/dist/Example.svelte +41 -0
  4. package/dist/Example.svelte.d.ts +19 -0
  5. package/dist/Index.svelte +184 -0
  6. package/dist/Index.svelte.d.ts +192 -0
  7. package/dist/shared/Controls.svelte +73 -0
  8. package/dist/shared/Controls.svelte.d.ts +24 -0
  9. package/dist/shared/ImageEditor.svelte +329 -0
  10. package/dist/shared/ImageEditor.svelte.d.ts +79 -0
  11. package/dist/shared/InteractiveImageEditor.svelte +273 -0
  12. package/dist/shared/InteractiveImageEditor.svelte.d.ts +58 -0
  13. package/dist/shared/layers/Layers.svelte +216 -0
  14. package/dist/shared/layers/Layers.svelte.d.ts +18 -0
  15. package/dist/shared/layers/utils.d.ts +69 -0
  16. package/dist/shared/layers/utils.js +131 -0
  17. package/dist/shared/tools/Brush.svelte +208 -0
  18. package/dist/shared/tools/Brush.svelte.d.ts +29 -0
  19. package/dist/shared/tools/BrushOptions.svelte +162 -0
  20. package/dist/shared/tools/BrushOptions.svelte.d.ts +29 -0
  21. package/dist/shared/tools/BrushSize.svelte +60 -0
  22. package/dist/shared/tools/BrushSize.svelte.d.ts +20 -0
  23. package/dist/shared/tools/ColorField.svelte +159 -0
  24. package/dist/shared/tools/ColorField.svelte.d.ts +20 -0
  25. package/dist/shared/tools/ColorPicker.svelte +179 -0
  26. package/dist/shared/tools/ColorPicker.svelte.d.ts +16 -0
  27. package/dist/shared/tools/ColorSwatch.svelte +183 -0
  28. package/dist/shared/tools/ColorSwatch.svelte.d.ts +30 -0
  29. package/dist/shared/tools/Crop.svelte +155 -0
  30. package/dist/shared/tools/Crop.svelte.d.ts +16 -0
  31. package/dist/shared/tools/Cropper.svelte +271 -0
  32. package/dist/shared/tools/Cropper.svelte.d.ts +41 -0
  33. package/dist/shared/tools/Handle.svelte +260 -0
  34. package/dist/shared/tools/Handle.svelte.d.ts +29 -0
  35. package/dist/shared/tools/Sources.svelte +250 -0
  36. package/dist/shared/tools/Sources.svelte.d.ts +32 -0
  37. package/dist/shared/tools/Tools.svelte +101 -0
  38. package/dist/shared/tools/Tools.svelte.d.ts +48 -0
  39. package/dist/shared/tools/brush.d.ts +62 -0
  40. package/dist/shared/tools/brush.js +133 -0
  41. package/dist/shared/tools/crop.d.ts +15 -0
  42. package/dist/shared/tools/crop.js +154 -0
  43. package/dist/shared/tools/index.d.ts +5 -0
  44. package/dist/shared/tools/index.js +5 -0
  45. package/dist/shared/tools/sources.d.ts +40 -0
  46. package/dist/shared/tools/sources.js +69 -0
  47. package/dist/shared/tools/types.d.ts +1 -0
  48. package/dist/shared/tools/types.js +1 -0
  49. package/dist/shared/utils/commands.d.ts +96 -0
  50. package/dist/shared/utils/commands.js +65 -0
  51. package/dist/shared/utils/events.d.ts +7 -0
  52. package/dist/shared/utils/events.js +22 -0
  53. package/dist/shared/utils/parse_placeholder.d.ts +1 -0
  54. package/dist/shared/utils/parse_placeholder.js +19 -0
  55. package/dist/shared/utils/pixi.d.ts +76 -0
  56. package/dist/shared/utils/pixi.js +152 -0
  57. package/package.json +23 -12
  58. package/shared/ImageEditor.svelte +8 -4
  59. package/shared/InteractiveImageEditor.svelte +9 -2
  60. package/shared/tools/Brush.svelte +4 -6
  61. package/shared/tools/BrushOptions.svelte +1 -1
  62. package/shared/tools/Crop.svelte +2 -1
  63. package/shared/utils/pixi.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @gradio/imageeditor
2
2
 
3
+ ## 0.11.0-beta.1
4
+
5
+ ### Features
6
+
7
+ - [#9201](https://github.com/gradio-app/gradio/pull/9201) [`5492e74`](https://github.com/gradio-app/gradio/commit/5492e742b1f1fa618208cce523f50ad22a6e86f1) - Move buttons from chat_interface into Chatbot. Thanks @freddyaboulton!
8
+ - [#9187](https://github.com/gradio-app/gradio/pull/9187) [`5bf00b7`](https://github.com/gradio-app/gradio/commit/5bf00b7524ebf399b48719120a49d15bb21bd65c) - make all component SSR compatible. Thanks @pngwn!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/atoms@0.8.1-beta.1
13
+ - @gradio/icons@0.8.0-beta.1
14
+ - @gradio/statustracker@0.8.0-beta.1
15
+ - @gradio/utils@0.7.0-beta.1
16
+ - @gradio/client@1.6.0-beta.1
17
+ - @gradio/image@0.16.0-beta.1
18
+ - @gradio/upload@0.12.4-beta.1
19
+ - @gradio/wasm@0.13.1-beta.1
20
+
21
+ ## 0.10.1-beta.0
22
+
23
+ ### Fixes
24
+
25
+ - [#9163](https://github.com/gradio-app/gradio/pull/9163) [`2b6cbf2`](https://github.com/gradio-app/gradio/commit/2b6cbf25908e42cf027324e54ef2cc0baad11a91) - fix exports and generate types. Thanks @pngwn!
26
+
27
+ ### Dependency updates
28
+
29
+ - @gradio/utils@0.7.0-beta.0
30
+ - @gradio/statustracker@0.8.0-beta.0
31
+ - @gradio/atoms@0.8.1-beta.0
32
+ - @gradio/client@1.6.0-beta.0
33
+ - @gradio/icons@0.8.0-beta.0
34
+ - @gradio/upload@0.12.4-beta.0
35
+ - @gradio/wasm@0.13.1-beta.0
36
+ - @gradio/image@0.16.0-beta.0
37
+
3
38
  ## 0.10.0
4
39
 
5
40
  ### Features
package/Index.svelte CHANGED
@@ -29,7 +29,7 @@
29
29
  export let root: string;
30
30
  export let value_is_output = false;
31
31
 
32
- export let height: number | undefined;
32
+ export let height: number | undefined = 400;
33
33
  export let width: number | undefined;
34
34
 
35
35
  export let _selectable = false;
@@ -90,10 +90,12 @@
90
90
  let dragging: boolean;
91
91
 
92
92
  $: value && handle_change();
93
+ const is_browser = typeof window !== "undefined";
94
+ const raf = is_browser ? window.requestAnimationFrame : () => {};
93
95
 
94
96
  function wait_for_next_frame(): Promise<void> {
95
97
  return new Promise((resolve) => {
96
- requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
98
+ raf(() => raf(() => resolve()));
97
99
  });
98
100
  }
99
101
 
@@ -192,6 +194,7 @@
192
194
  {sources}
193
195
  {label}
194
196
  {show_label}
197
+ {height}
195
198
  on:save={(e) => handle_save()}
196
199
  on:edit={() => gradio.dispatch("edit")}
197
200
  on:clear={() => gradio.dispatch("clear")}
@@ -0,0 +1,41 @@
1
+ <script>import { BaseImage as Image } from "@gradio/image";
2
+ export let value;
3
+ export let type;
4
+ export let selected = false;
5
+ </script>
6
+
7
+ <div
8
+ class="container"
9
+ class:table={type === "table"}
10
+ class:gallery={type === "gallery"}
11
+ class:selected
12
+ >
13
+ <Image src={value.composite?.url || value.background?.url} alt="" />
14
+ </div>
15
+
16
+ <style>
17
+ .container :global(img) {
18
+ width: 100%;
19
+ height: 100%;
20
+ }
21
+
22
+ .container.selected {
23
+ border-color: var(--border-color-accent);
24
+ }
25
+
26
+ .container.table {
27
+ margin: 0 auto;
28
+ border: 2px solid var(--border-color-primary);
29
+ border-radius: var(--radius-lg);
30
+ width: var(--size-20);
31
+ height: var(--size-20);
32
+ object-fit: cover;
33
+ }
34
+
35
+ .container.gallery {
36
+ border: 2px solid var(--border-color-primary);
37
+ height: var(--size-20);
38
+ max-height: var(--size-20);
39
+ object-fit: cover;
40
+ }
41
+ </style>
@@ -0,0 +1,19 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { EditorData } from "./shared/InteractiveImageEditor.svelte";
3
+ declare const __propDef: {
4
+ props: {
5
+ value: EditorData;
6
+ type: "gallery" | "table";
7
+ selected?: boolean | undefined;
8
+ };
9
+ events: {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {};
13
+ };
14
+ export type ExampleProps = typeof __propDef.props;
15
+ export type ExampleEvents = typeof __propDef.events;
16
+ export type ExampleSlots = typeof __propDef.slots;
17
+ export default class Example extends SvelteComponent<ExampleProps, ExampleEvents, ExampleSlots> {
18
+ }
19
+ export {};
@@ -0,0 +1,184 @@
1
+ <svelte:options accessors={true} immutable={true} />
2
+
3
+ <script>import { BaseStaticImage as StaticImage } from "@gradio/image";
4
+ import InteractiveImageEditor from "./shared/InteractiveImageEditor.svelte";
5
+ import { Block } from "@gradio/atoms";
6
+ import { StatusTracker } from "@gradio/statustracker";
7
+ import { tick } from "svelte";
8
+ export let elem_id = "";
9
+ export let elem_classes = [];
10
+ export let visible = true;
11
+ export let value = {
12
+ background: null,
13
+ layers: [],
14
+ composite: null
15
+ };
16
+ export let label;
17
+ export let show_label;
18
+ export let show_download_button;
19
+ export let root;
20
+ export let value_is_output = false;
21
+ export let height = 400;
22
+ export let width;
23
+ export let _selectable = false;
24
+ export let container = true;
25
+ export let scale = null;
26
+ export let min_width = void 0;
27
+ export let loading_status;
28
+ export let show_share_button = false;
29
+ export let sources = [
30
+ "upload",
31
+ "clipboard",
32
+ "webcam"
33
+ ];
34
+ export let interactive;
35
+ export let placeholder;
36
+ export let brush;
37
+ export let eraser;
38
+ export let crop_size = null;
39
+ export let transforms = ["crop"];
40
+ export let layers = true;
41
+ export let attached_events = [];
42
+ export let server;
43
+ export let canvas_size;
44
+ export let show_fullscreen_button = true;
45
+ export let gradio;
46
+ let editor_instance;
47
+ let image_id = null;
48
+ export async function get_value() {
49
+ if (image_id) {
50
+ const val = { id: image_id };
51
+ image_id = null;
52
+ return val;
53
+ }
54
+ const blobs = await editor_instance.get_data();
55
+ return blobs;
56
+ }
57
+ let dragging;
58
+ $:
59
+ value && handle_change();
60
+ const is_browser = typeof window !== "undefined";
61
+ const raf = is_browser ? window.requestAnimationFrame : () => {
62
+ };
63
+ function wait_for_next_frame() {
64
+ return new Promise((resolve) => {
65
+ raf(() => raf(() => resolve()));
66
+ });
67
+ }
68
+ async function handle_change() {
69
+ await wait_for_next_frame();
70
+ if (value && (value.background || value.layers?.length || value.composite)) {
71
+ gradio.dispatch("change");
72
+ }
73
+ }
74
+ function handle_save() {
75
+ gradio.dispatch("apply");
76
+ }
77
+ function handle_history_change() {
78
+ gradio.dispatch("change");
79
+ if (!value_is_output) {
80
+ gradio.dispatch("input");
81
+ tick().then((_) => value_is_output = false);
82
+ }
83
+ }
84
+ $:
85
+ has_value = value?.background || value?.layers?.length || value?.composite;
86
+ </script>
87
+
88
+ {#if !interactive}
89
+ <Block
90
+ {visible}
91
+ variant={"solid"}
92
+ border_mode={dragging ? "focus" : "base"}
93
+ padding={false}
94
+ {elem_id}
95
+ {elem_classes}
96
+ height={height || undefined}
97
+ {width}
98
+ allow_overflow={false}
99
+ {container}
100
+ {scale}
101
+ {min_width}
102
+ >
103
+ <StatusTracker
104
+ autoscroll={gradio.autoscroll}
105
+ i18n={gradio.i18n}
106
+ {...loading_status}
107
+ on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
108
+ />
109
+ <StaticImage
110
+ on:select={({ detail }) => gradio.dispatch("select", detail)}
111
+ on:share={({ detail }) => gradio.dispatch("share", detail)}
112
+ on:error={({ detail }) => gradio.dispatch("error", detail)}
113
+ value={value?.composite || null}
114
+ {label}
115
+ {show_label}
116
+ {show_download_button}
117
+ selectable={_selectable}
118
+ {show_share_button}
119
+ i18n={gradio.i18n}
120
+ {show_fullscreen_button}
121
+ />
122
+ </Block>
123
+ {:else}
124
+ <Block
125
+ {visible}
126
+ variant={has_value ? "solid" : "dashed"}
127
+ border_mode={dragging ? "focus" : "base"}
128
+ padding={false}
129
+ {elem_id}
130
+ {elem_classes}
131
+ height={height || undefined}
132
+ {width}
133
+ allow_overflow={false}
134
+ {container}
135
+ {scale}
136
+ {min_width}
137
+ >
138
+ <StatusTracker
139
+ autoscroll={gradio.autoscroll}
140
+ i18n={gradio.i18n}
141
+ {...loading_status}
142
+ on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
143
+ />
144
+
145
+ <InteractiveImageEditor
146
+ bind:dragging
147
+ {canvas_size}
148
+ on:change={() => handle_history_change()}
149
+ bind:image_id
150
+ {crop_size}
151
+ {value}
152
+ bind:this={editor_instance}
153
+ {root}
154
+ {sources}
155
+ {label}
156
+ {show_label}
157
+ {height}
158
+ on:save={(e) => handle_save()}
159
+ on:edit={() => gradio.dispatch("edit")}
160
+ on:clear={() => gradio.dispatch("clear")}
161
+ on:drag={({ detail }) => (dragging = detail)}
162
+ on:upload={() => gradio.dispatch("upload")}
163
+ on:share={({ detail }) => gradio.dispatch("share", detail)}
164
+ on:error={({ detail }) => {
165
+ loading_status = loading_status || {};
166
+ loading_status.status = "error";
167
+ gradio.dispatch("error", detail);
168
+ }}
169
+ on:error
170
+ {brush}
171
+ {eraser}
172
+ changeable={attached_events.includes("apply")}
173
+ realtime={attached_events.includes("change")}
174
+ i18n={gradio.i18n}
175
+ {transforms}
176
+ accept_blobs={server.accept_blobs}
177
+ {layers}
178
+ status={loading_status?.status}
179
+ upload={gradio.client.upload}
180
+ stream_handler={gradio.client.stream}
181
+ {placeholder}
182
+ ></InteractiveImageEditor>
183
+ </Block>
184
+ {/if}
@@ -0,0 +1,192 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Brush, Eraser } from "./shared/tools/Brush.svelte";
3
+ import type { EditorData, ImageBlobs } from "./shared/InteractiveImageEditor.svelte";
4
+ import type { Gradio, SelectData } from "@gradio/utils";
5
+ import type { LoadingStatus } from "@gradio/statustracker";
6
+ declare const __propDef: {
7
+ props: {
8
+ elem_id?: string | undefined;
9
+ elem_classes?: string[] | undefined;
10
+ visible?: boolean | undefined;
11
+ value?: (EditorData | null) | undefined;
12
+ label: string;
13
+ show_label: boolean;
14
+ show_download_button: boolean;
15
+ root: string;
16
+ value_is_output?: boolean | undefined;
17
+ height?: number | undefined;
18
+ width: number | undefined;
19
+ _selectable?: boolean | undefined;
20
+ container?: boolean | undefined;
21
+ scale?: (number | null) | undefined;
22
+ min_width?: number | undefined;
23
+ loading_status: LoadingStatus;
24
+ show_share_button?: boolean | undefined;
25
+ sources?: ("clipboard" | "webcam" | "upload")[] | undefined;
26
+ interactive: boolean;
27
+ placeholder: string | undefined;
28
+ brush: Brush;
29
+ eraser: Eraser;
30
+ crop_size?: ([number, number] | `${string}:${string}` | null) | undefined;
31
+ transforms?: "crop"[] | undefined;
32
+ layers?: boolean | undefined;
33
+ attached_events?: string[] | undefined;
34
+ server: {
35
+ accept_blobs: (a: any) => void;
36
+ };
37
+ canvas_size: [number, number] | undefined;
38
+ show_fullscreen_button?: boolean | undefined;
39
+ gradio: Gradio<{
40
+ change: never;
41
+ error: string;
42
+ input: never;
43
+ edit: never;
44
+ drag: never;
45
+ apply: never;
46
+ upload: never;
47
+ clear: never;
48
+ select: SelectData;
49
+ share: ShareData;
50
+ clear_status: LoadingStatus;
51
+ }>;
52
+ get_value?: (() => Promise<ImageBlobs | {
53
+ id: string;
54
+ }>) | undefined;
55
+ };
56
+ events: {
57
+ error: CustomEvent<any>;
58
+ } & {
59
+ [evt: string]: CustomEvent<any>;
60
+ };
61
+ slots: {};
62
+ };
63
+ export type IndexProps = typeof __propDef.props;
64
+ export type IndexEvents = typeof __propDef.events;
65
+ export type IndexSlots = typeof __propDef.slots;
66
+ export default class Index extends SvelteComponent<IndexProps, IndexEvents, IndexSlots> {
67
+ get get_value(): () => Promise<ImageBlobs | {
68
+ id: string;
69
+ }>;
70
+ get elem_id(): string | undefined;
71
+ /**accessor*/
72
+ set elem_id(_: string | undefined);
73
+ get elem_classes(): string[] | undefined;
74
+ /**accessor*/
75
+ set elem_classes(_: string[] | undefined);
76
+ get visible(): boolean | undefined;
77
+ /**accessor*/
78
+ set visible(_: boolean | undefined);
79
+ get value(): EditorData | null | undefined;
80
+ /**accessor*/
81
+ set value(_: EditorData | null | undefined);
82
+ get label(): string;
83
+ /**accessor*/
84
+ set label(_: string);
85
+ get show_label(): boolean;
86
+ /**accessor*/
87
+ set show_label(_: boolean);
88
+ get show_download_button(): boolean;
89
+ /**accessor*/
90
+ set show_download_button(_: boolean);
91
+ get root(): string;
92
+ /**accessor*/
93
+ set root(_: string);
94
+ get value_is_output(): boolean | undefined;
95
+ /**accessor*/
96
+ set value_is_output(_: boolean | undefined);
97
+ get height(): number | undefined;
98
+ /**accessor*/
99
+ set height(_: number | undefined);
100
+ get width(): number | undefined;
101
+ /**accessor*/
102
+ set width(_: number | undefined);
103
+ get _selectable(): boolean | undefined;
104
+ /**accessor*/
105
+ set _selectable(_: boolean | undefined);
106
+ get container(): boolean | undefined;
107
+ /**accessor*/
108
+ set container(_: boolean | undefined);
109
+ get scale(): number | null | undefined;
110
+ /**accessor*/
111
+ set scale(_: number | null | undefined);
112
+ get min_width(): number | undefined;
113
+ /**accessor*/
114
+ set min_width(_: number | undefined);
115
+ get loading_status(): LoadingStatus;
116
+ /**accessor*/
117
+ set loading_status(_: LoadingStatus);
118
+ get show_share_button(): boolean | undefined;
119
+ /**accessor*/
120
+ set show_share_button(_: boolean | undefined);
121
+ get sources(): ("upload" | "clipboard" | "webcam")[] | undefined;
122
+ /**accessor*/
123
+ set sources(_: ("upload" | "clipboard" | "webcam")[] | undefined);
124
+ get interactive(): boolean;
125
+ /**accessor*/
126
+ set interactive(_: boolean);
127
+ get placeholder(): string | undefined;
128
+ /**accessor*/
129
+ set placeholder(_: string | undefined);
130
+ get brush(): Brush;
131
+ /**accessor*/
132
+ set brush(_: Brush);
133
+ get eraser(): Eraser;
134
+ /**accessor*/
135
+ set eraser(_: Eraser);
136
+ get crop_size(): [number, number] | `${string}:${string}` | null | undefined;
137
+ /**accessor*/
138
+ set crop_size(_: [number, number] | `${string}:${string}` | null | undefined);
139
+ get transforms(): "crop"[] | undefined;
140
+ /**accessor*/
141
+ set transforms(_: "crop"[] | undefined);
142
+ get layers(): boolean | undefined;
143
+ /**accessor*/
144
+ set layers(_: boolean | undefined);
145
+ get attached_events(): string[] | undefined;
146
+ /**accessor*/
147
+ set attached_events(_: string[] | undefined);
148
+ get server(): {
149
+ accept_blobs: (a: any) => void;
150
+ };
151
+ /**accessor*/
152
+ set server(_: {
153
+ accept_blobs: (a: any) => void;
154
+ });
155
+ get canvas_size(): [number, number] | undefined;
156
+ /**accessor*/
157
+ set canvas_size(_: [number, number] | undefined);
158
+ get show_fullscreen_button(): boolean | undefined;
159
+ /**accessor*/
160
+ set show_fullscreen_button(_: boolean | undefined);
161
+ get gradio(): Gradio<{
162
+ change: never;
163
+ error: string;
164
+ input: never;
165
+ edit: never;
166
+ drag: never;
167
+ apply: never;
168
+ upload: never;
169
+ clear: never;
170
+ select: SelectData;
171
+ share: ShareData;
172
+ clear_status: LoadingStatus;
173
+ }>;
174
+ /**accessor*/
175
+ set gradio(_: Gradio<{
176
+ change: never;
177
+ error: string;
178
+ input: never;
179
+ edit: never;
180
+ drag: never;
181
+ apply: never;
182
+ upload: never;
183
+ clear: never;
184
+ select: SelectData;
185
+ share: ShareData;
186
+ clear_status: LoadingStatus;
187
+ }>);
188
+ get undefined(): any;
189
+ /**accessor*/
190
+ set undefined(_: any);
191
+ }
192
+ export {};
@@ -0,0 +1,73 @@
1
+ <script>import { createEventDispatcher } from "svelte";
2
+ import { IconButton } from "@gradio/atoms";
3
+ import { Clear, Undo, Redo, Check, Trash } from "@gradio/icons";
4
+ export let can_undo = false;
5
+ export let can_redo = false;
6
+ export let can_save = false;
7
+ export let changeable = false;
8
+ const dispatch = createEventDispatcher();
9
+ </script>
10
+
11
+ <div class="controls-wrap">
12
+ <div class="row-wrap">
13
+ <IconButton
14
+ disabled={!can_undo}
15
+ Icon={Undo}
16
+ label="Undo"
17
+ on:click={(event) => {
18
+ dispatch("undo");
19
+ event.stopPropagation();
20
+ }}
21
+ />
22
+ <IconButton
23
+ disabled={!can_redo}
24
+ Icon={Redo}
25
+ label="Redo"
26
+ on:click={(event) => {
27
+ dispatch("redo");
28
+ event.stopPropagation();
29
+ }}
30
+ />
31
+ <IconButton
32
+ Icon={Trash}
33
+ label="Clear canvas"
34
+ on:click={(event) => {
35
+ dispatch("remove_image");
36
+ event.stopPropagation();
37
+ }}
38
+ />
39
+ </div>
40
+ {#if changeable}
41
+ <div class="row-wrap save">
42
+ <IconButton
43
+ disabled={!can_save}
44
+ Icon={Check}
45
+ label="Save changes"
46
+ on:click={(event) => {
47
+ dispatch("save");
48
+ event.stopPropagation();
49
+ }}
50
+ background={"var(--color-green-500)"}
51
+ color={"#fff"}
52
+ />
53
+ </div>
54
+ {/if}
55
+ </div>
56
+
57
+ <style>
58
+ .controls-wrap {
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: var(--spacing-lg);
62
+ position: absolute;
63
+ top: var(--size-2);
64
+ right: var(--size-2);
65
+ }
66
+ .row-wrap {
67
+ display: flex;
68
+
69
+ justify-content: flex-end;
70
+ gap: var(--spacing-sm);
71
+ z-index: var(--layer-5);
72
+ }
73
+ </style>
@@ -0,0 +1,24 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ can_undo?: boolean | undefined;
5
+ can_redo?: boolean | undefined;
6
+ can_save?: boolean | undefined;
7
+ changeable?: boolean | undefined;
8
+ };
9
+ events: {
10
+ remove_image: CustomEvent<void>;
11
+ undo: CustomEvent<void>;
12
+ redo: CustomEvent<void>;
13
+ save: CustomEvent<void>;
14
+ } & {
15
+ [evt: string]: CustomEvent<any>;
16
+ };
17
+ slots: {};
18
+ };
19
+ export type ControlsProps = typeof __propDef.props;
20
+ export type ControlsEvents = typeof __propDef.events;
21
+ export type ControlsSlots = typeof __propDef.slots;
22
+ export default class Controls extends SvelteComponent<ControlsProps, ControlsEvents, ControlsSlots> {
23
+ }
24
+ export {};