@gradio/imageslider 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/ImageSlider.stories.svelte +57 -0
- package/ImageSlider.test.ts +15 -0
- package/Index.svelte +13 -2
- package/dist/Index.svelte +13 -2
- package/dist/shared/Image.svelte +3 -0
- package/dist/shared/Image.svelte.d.ts +1 -0
- package/dist/shared/Slider.svelte +4 -1
- package/dist/shared/Slider.svelte.d.ts +1 -0
- package/dist/shared/SliderPreview.svelte +3 -0
- package/dist/shared/SliderPreview.svelte.d.ts +1 -0
- package/dist/shared/SliderUpload.svelte +6 -3
- package/dist/shared/SliderUpload.svelte.d.ts +2 -0
- package/package.json +7 -7
- package/shared/Image.svelte +3 -0
- package/shared/Slider.svelte +4 -1
- package/shared/SliderPreview.svelte +3 -0
- package/shared/SliderUpload.svelte +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @gradio/imageslider
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#13862](https://github.com/gradio-app/gradio/pull/13862) [`3353446`](https://github.com/gradio-app/gradio/commit/3353446616a56838e7e3cb3477fcd02664a0db40) - Expose live camera and slider position to event handlers. Thanks @abidlabs!/n `camera_position` on `gr.Model3D` and `slider_position` on `gr.ImageSlider` now follow the user, so a function whose parameter is annotated with the component reads the view that is actually on screen. Both can still be set from the backend to move the camera or the divider./n Also fixes, in the same area:/n - `camera_position` is applied on load for `display_mode="point_cloud"` and `display_mode="wireframe"`, not only for `"solid"`./n - `camera_position` is applied to interactive (uploadable) `gr.Model3D`, and `slider_position` to interactive `gr.ImageSlider`; both previously ignored it./n - `pan_speed` is passed through to the `gr.Model3D` viewer; it was silently stuck at its default./n - A Model3D camera observer was added on every camera update without ever being removed; exactly one is now registered, and it is cleaned up with the component.
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/utils@0.14.2
|
|
12
|
+
- @gradio/client@2.7.0
|
|
13
|
+
|
|
14
|
+
## 0.7.1
|
|
15
|
+
|
|
16
|
+
### Dependency updates
|
|
17
|
+
|
|
18
|
+
- @gradio/client@2.6.0
|
|
19
|
+
- @gradio/atoms@0.26.2
|
|
20
|
+
- @gradio/utils@0.14.1
|
|
21
|
+
- @gradio/upload@0.18.3
|
|
22
|
+
|
|
23
|
+
## 0.7.1
|
|
24
|
+
|
|
25
|
+
### Dependency updates
|
|
26
|
+
|
|
27
|
+
- @gradio/client@2.5.1
|
|
28
|
+
|
|
29
|
+
## 0.7.1
|
|
30
|
+
|
|
31
|
+
### Dependency updates
|
|
32
|
+
|
|
33
|
+
- @gradio/client@2.5.0
|
|
34
|
+
|
|
35
|
+
## 0.7.1
|
|
36
|
+
|
|
37
|
+
### Dependency updates
|
|
38
|
+
|
|
39
|
+
- @gradio/client@2.4.0
|
|
40
|
+
- @gradio/utils@0.14.0
|
|
41
|
+
- @gradio/atoms@0.26.1
|
|
42
|
+
- @gradio/statustracker@0.15.2
|
|
43
|
+
- @gradio/upload@0.18.2
|
|
44
|
+
|
|
3
45
|
## 0.7.0
|
|
4
46
|
|
|
5
47
|
### Features
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from "@storybook/addon-svelte-csf";
|
|
3
|
+
import { userEvent, within } from "storybook/test";
|
|
4
|
+
import ImageSlider from "./Index.svelte";
|
|
5
|
+
import { allModes } from "../storybook/modes";
|
|
6
|
+
import { wrapProps } from "../storybook/wrapProps";
|
|
7
|
+
|
|
8
|
+
const cheetah = "/cheetah.jpg";
|
|
9
|
+
const lion = "/lion.jpg";
|
|
10
|
+
const fileData = (url, name) => ({
|
|
11
|
+
path: url,
|
|
12
|
+
url,
|
|
13
|
+
orig_name: name,
|
|
14
|
+
size: null,
|
|
15
|
+
mime_type: "image/jpeg",
|
|
16
|
+
is_stream: false,
|
|
17
|
+
meta: { _type: "gradio.FileData" }
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const { Story } = defineMeta({
|
|
21
|
+
title: "Components/Image Slider",
|
|
22
|
+
component: ImageSlider,
|
|
23
|
+
parameters: {
|
|
24
|
+
chromatic: {
|
|
25
|
+
modes: {
|
|
26
|
+
desktop: allModes["desktop"],
|
|
27
|
+
mobile: allModes["mobile"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<Story
|
|
35
|
+
name="Mobile fullscreen"
|
|
36
|
+
args={{
|
|
37
|
+
value: [fileData(cheetah, "cheetah.jpg"), fileData(lion, "lion.jpg")],
|
|
38
|
+
interactive: false,
|
|
39
|
+
show_label: true,
|
|
40
|
+
label: "Fullscreen comparison",
|
|
41
|
+
buttons: ["fullscreen"],
|
|
42
|
+
slider_position: 50,
|
|
43
|
+
upload_count: 2,
|
|
44
|
+
slider_color: "#ff8c00",
|
|
45
|
+
max_height: 500
|
|
46
|
+
}}
|
|
47
|
+
play={async ({ canvasElement }) => {
|
|
48
|
+
const canvas = within(canvasElement);
|
|
49
|
+
await userEvent.click(canvas.getByRole("button", { name: "Fullscreen" }));
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
{#snippet template(args)}
|
|
53
|
+
<div style="width: 360px; height: 440px; position: relative;">
|
|
54
|
+
<ImageSlider {...wrapProps(args)} />
|
|
55
|
+
</div>
|
|
56
|
+
{/snippet}
|
|
57
|
+
</Story>
|
package/ImageSlider.test.ts
CHANGED
|
@@ -521,6 +521,21 @@ describe("Events: clear", () => {
|
|
|
521
521
|
expect(clear).toHaveBeenCalledTimes(1);
|
|
522
522
|
});
|
|
523
523
|
|
|
524
|
+
test("clearing keeps the configured slider_position", async () => {
|
|
525
|
+
// One image keeps the component on the uploader branch, which is where the
|
|
526
|
+
// X lives while a slider is still waiting for its second image.
|
|
527
|
+
const { get_data, getByLabelText } = await render(ImageSlider, {
|
|
528
|
+
...default_props,
|
|
529
|
+
interactive: true,
|
|
530
|
+
slider_position: 30,
|
|
531
|
+
value: [img_a, null]
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
await fireEvent.click(getByLabelText("Remove Image"));
|
|
535
|
+
|
|
536
|
+
expect((await get_data()).slider_position).toBe(30);
|
|
537
|
+
});
|
|
538
|
+
|
|
524
539
|
test("value is [null, null] after clicking Remove Image", async () => {
|
|
525
540
|
const { get_data, getByLabelText } = await render(ImageSlider, {
|
|
526
541
|
...default_props,
|
package/Index.svelte
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<svelte:options accessors={true} />
|
|
2
|
-
|
|
3
1
|
<script lang="ts">
|
|
4
2
|
import { tick } from "svelte";
|
|
5
3
|
import type { ImageSliderProps, ImageSliderEvents } from "./types";
|
|
@@ -39,6 +37,16 @@
|
|
|
39
37
|
Math.max(0, Math.min(100, gradio.props.slider_position)) / 100
|
|
40
38
|
);
|
|
41
39
|
|
|
40
|
+
function handle_slider_position(position: number): void {
|
|
41
|
+
const percentage = Math.max(
|
|
42
|
+
0,
|
|
43
|
+
Math.min(100, Math.round(position * 1e5) / 1e3)
|
|
44
|
+
);
|
|
45
|
+
if (gradio.props.slider_position !== percentage) {
|
|
46
|
+
gradio.props.slider_position = percentage;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
gradio.watch_for_change();
|
|
43
51
|
|
|
44
52
|
$effect(() => {
|
|
@@ -96,6 +104,7 @@
|
|
|
96
104
|
gradio.dispatch("custom_button_click", { id });
|
|
97
105
|
}}
|
|
98
106
|
position={normalised_slider_position}
|
|
107
|
+
onposition={handle_slider_position}
|
|
99
108
|
slider_color={gradio.props.slider_color}
|
|
100
109
|
max_height={gradio.props.max_height}
|
|
101
110
|
/>
|
|
@@ -140,6 +149,8 @@
|
|
|
140
149
|
label={gradio.shared.label}
|
|
141
150
|
show_label={gradio.shared.show_label}
|
|
142
151
|
upload_count={gradio.props.upload_count}
|
|
152
|
+
position={normalised_slider_position}
|
|
153
|
+
onposition={handle_slider_position}
|
|
143
154
|
max_file_size={gradio.shared.max_file_size}
|
|
144
155
|
i18n={gradio.i18n}
|
|
145
156
|
upload={(...args) => gradio.shared.client.upload(...args)}
|
package/dist/Index.svelte
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<svelte:options accessors={true} />
|
|
2
|
-
|
|
3
1
|
<script lang="ts">
|
|
4
2
|
import { tick } from "svelte";
|
|
5
3
|
import type { ImageSliderProps, ImageSliderEvents } from "./types";
|
|
@@ -39,6 +37,16 @@
|
|
|
39
37
|
Math.max(0, Math.min(100, gradio.props.slider_position)) / 100
|
|
40
38
|
);
|
|
41
39
|
|
|
40
|
+
function handle_slider_position(position: number): void {
|
|
41
|
+
const percentage = Math.max(
|
|
42
|
+
0,
|
|
43
|
+
Math.min(100, Math.round(position * 1e5) / 1e3)
|
|
44
|
+
);
|
|
45
|
+
if (gradio.props.slider_position !== percentage) {
|
|
46
|
+
gradio.props.slider_position = percentage;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
gradio.watch_for_change();
|
|
43
51
|
|
|
44
52
|
$effect(() => {
|
|
@@ -96,6 +104,7 @@
|
|
|
96
104
|
gradio.dispatch("custom_button_click", { id });
|
|
97
105
|
}}
|
|
98
106
|
position={normalised_slider_position}
|
|
107
|
+
onposition={handle_slider_position}
|
|
99
108
|
slider_color={gradio.props.slider_color}
|
|
100
109
|
max_height={gradio.props.max_height}
|
|
101
110
|
/>
|
|
@@ -140,6 +149,8 @@
|
|
|
140
149
|
label={gradio.shared.label}
|
|
141
150
|
show_label={gradio.shared.show_label}
|
|
142
151
|
upload_count={gradio.props.upload_count}
|
|
152
|
+
position={normalised_slider_position}
|
|
153
|
+
onposition={handle_slider_position}
|
|
143
154
|
max_file_size={gradio.shared.max_file_size}
|
|
144
155
|
i18n={gradio.i18n}
|
|
145
156
|
upload={(...args) => gradio.shared.client.upload(...args)}
|
package/dist/shared/Image.svelte
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
show_label,
|
|
19
19
|
root,
|
|
20
20
|
position = $bindable(0.5),
|
|
21
|
+
onposition,
|
|
21
22
|
upload_count = 2,
|
|
22
23
|
show_download_button = true,
|
|
23
24
|
slider_color,
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
show_label: boolean;
|
|
39
40
|
root: string;
|
|
40
41
|
position?: number;
|
|
42
|
+
onposition?: (position: number) => void;
|
|
41
43
|
upload_count?: number;
|
|
42
44
|
show_download_button?: boolean;
|
|
43
45
|
slider_color: string;
|
|
@@ -126,6 +128,7 @@
|
|
|
126
128
|
{/if}
|
|
127
129
|
<Slider
|
|
128
130
|
bind:position
|
|
131
|
+
{onposition}
|
|
129
132
|
disabled={upload_count == 2 || !value?.[0]}
|
|
130
133
|
{slider_color}
|
|
131
134
|
>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
image_size = { top: 0, left: 0, width: 0, height: 0 },
|
|
15
15
|
el = $bindable<HTMLDivElement | undefined>(undefined),
|
|
16
16
|
parent_el = $bindable<HTMLDivElement | undefined>(undefined),
|
|
17
|
+
onposition,
|
|
17
18
|
children
|
|
18
19
|
}: {
|
|
19
20
|
position?: number;
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
};
|
|
28
29
|
el?: HTMLDivElement;
|
|
29
30
|
parent_el?: HTMLDivElement;
|
|
31
|
+
onposition?: (position: number) => void;
|
|
30
32
|
children?: Snippet;
|
|
31
33
|
} = $props();
|
|
32
34
|
|
|
@@ -55,7 +57,8 @@
|
|
|
55
57
|
|
|
56
58
|
function update_position(x: number): void {
|
|
57
59
|
px = clamp(x, 0, container_width);
|
|
58
|
-
position = round((x - image_size.left) / image_size.width, 5);
|
|
60
|
+
position = clamp(round((x - image_size.left) / image_size.width, 5), 0, 1);
|
|
61
|
+
onposition?.(position);
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
function drag_start(event: any): void {
|
|
@@ -11,6 +11,7 @@ type $$ComponentProps = {
|
|
|
11
11
|
};
|
|
12
12
|
el?: HTMLDivElement;
|
|
13
13
|
parent_el?: HTMLDivElement;
|
|
14
|
+
onposition?: (position: number) => void;
|
|
14
15
|
children?: Snippet;
|
|
15
16
|
};
|
|
16
17
|
declare const Slider: import("svelte").Component<$$ComponentProps, {}, "position" | "el" | "parent_el">;
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
show_label,
|
|
25
25
|
i18n,
|
|
26
26
|
position = $bindable(0.5),
|
|
27
|
+
onposition,
|
|
27
28
|
layer_images = true,
|
|
28
29
|
show_single = false,
|
|
29
30
|
slider_color,
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
show_label: boolean;
|
|
44
45
|
i18n: I18nFormatter;
|
|
45
46
|
position?: number;
|
|
47
|
+
onposition?: (position: number) => void;
|
|
46
48
|
layer_images?: boolean;
|
|
47
49
|
show_single?: boolean;
|
|
48
50
|
slider_color: string;
|
|
@@ -213,6 +215,7 @@
|
|
|
213
215
|
>
|
|
214
216
|
<Slider
|
|
215
217
|
bind:position
|
|
218
|
+
{onposition}
|
|
216
219
|
{slider_color}
|
|
217
220
|
bind:el={slider_wrap}
|
|
218
221
|
bind:parent_el
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<svelte:options accessors={true} />
|
|
2
|
-
|
|
3
1
|
<script lang="ts">
|
|
4
2
|
import type { Snippet } from "svelte";
|
|
5
3
|
import type { I18nFormatter } from "@gradio/utils";
|
|
@@ -24,6 +22,8 @@
|
|
|
24
22
|
onclear,
|
|
25
23
|
ondrag,
|
|
26
24
|
onupload,
|
|
25
|
+
onposition,
|
|
26
|
+
position = 0.5,
|
|
27
27
|
children
|
|
28
28
|
}: {
|
|
29
29
|
value?: [FileData | null, FileData | null];
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
onclear?: () => void;
|
|
42
42
|
ondrag?: (dragging: boolean) => void;
|
|
43
43
|
onupload?: (value: [FileData | null, FileData | null]) => void;
|
|
44
|
+
onposition?: (position: number) => void;
|
|
45
|
+
position?: number;
|
|
44
46
|
children?: Snippet;
|
|
45
47
|
} = $props();
|
|
46
48
|
</script>
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
<Image
|
|
49
51
|
bind:upload_promise
|
|
50
52
|
slider_color="var(--border-color-primary)"
|
|
51
|
-
position
|
|
53
|
+
{position}
|
|
54
|
+
{onposition}
|
|
52
55
|
bind:value
|
|
53
56
|
bind:dragging
|
|
54
57
|
{root}
|
|
@@ -18,6 +18,8 @@ type $$ComponentProps = {
|
|
|
18
18
|
onclear?: () => void;
|
|
19
19
|
ondrag?: (dragging: boolean) => void;
|
|
20
20
|
onupload?: (value: [FileData | null, FileData | null]) => void;
|
|
21
|
+
onposition?: (position: number) => void;
|
|
22
|
+
position?: number;
|
|
21
23
|
children?: Snippet;
|
|
22
24
|
};
|
|
23
25
|
declare const SliderUpload: import("svelte").Component<$$ComponentProps, {}, "value" | "dragging" | "upload_promise">;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/imageslider",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"@types/d3-selection": "^3.0.11",
|
|
12
12
|
"d3-drag": "^3.0.0",
|
|
13
13
|
"d3-selection": "^3.0.0",
|
|
14
|
+
"@gradio/atoms": "^0.26.2",
|
|
14
15
|
"@gradio/icons": "^0.16.0",
|
|
15
|
-
"@gradio/
|
|
16
|
-
"@gradio/
|
|
17
|
-
"@gradio/utils": "^0.
|
|
18
|
-
"@gradio/
|
|
19
|
-
"@gradio/client": "^2.3.1"
|
|
16
|
+
"@gradio/statustracker": "^0.15.3",
|
|
17
|
+
"@gradio/upload": "^0.18.3",
|
|
18
|
+
"@gradio/utils": "^0.14.2",
|
|
19
|
+
"@gradio/client": "^2.7.0"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"./package.json": "./package.json"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@gradio/preview": "^0.
|
|
35
|
+
"@gradio/preview": "^0.17.1"
|
|
36
36
|
},
|
|
37
37
|
"main_changeset": true,
|
|
38
38
|
"peerDependencies": {
|
package/shared/Image.svelte
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
show_label,
|
|
19
19
|
root,
|
|
20
20
|
position = $bindable(0.5),
|
|
21
|
+
onposition,
|
|
21
22
|
upload_count = 2,
|
|
22
23
|
show_download_button = true,
|
|
23
24
|
slider_color,
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
show_label: boolean;
|
|
39
40
|
root: string;
|
|
40
41
|
position?: number;
|
|
42
|
+
onposition?: (position: number) => void;
|
|
41
43
|
upload_count?: number;
|
|
42
44
|
show_download_button?: boolean;
|
|
43
45
|
slider_color: string;
|
|
@@ -126,6 +128,7 @@
|
|
|
126
128
|
{/if}
|
|
127
129
|
<Slider
|
|
128
130
|
bind:position
|
|
131
|
+
{onposition}
|
|
129
132
|
disabled={upload_count == 2 || !value?.[0]}
|
|
130
133
|
{slider_color}
|
|
131
134
|
>
|
package/shared/Slider.svelte
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
image_size = { top: 0, left: 0, width: 0, height: 0 },
|
|
15
15
|
el = $bindable<HTMLDivElement | undefined>(undefined),
|
|
16
16
|
parent_el = $bindable<HTMLDivElement | undefined>(undefined),
|
|
17
|
+
onposition,
|
|
17
18
|
children
|
|
18
19
|
}: {
|
|
19
20
|
position?: number;
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
};
|
|
28
29
|
el?: HTMLDivElement;
|
|
29
30
|
parent_el?: HTMLDivElement;
|
|
31
|
+
onposition?: (position: number) => void;
|
|
30
32
|
children?: Snippet;
|
|
31
33
|
} = $props();
|
|
32
34
|
|
|
@@ -55,7 +57,8 @@
|
|
|
55
57
|
|
|
56
58
|
function update_position(x: number): void {
|
|
57
59
|
px = clamp(x, 0, container_width);
|
|
58
|
-
position = round((x - image_size.left) / image_size.width, 5);
|
|
60
|
+
position = clamp(round((x - image_size.left) / image_size.width, 5), 0, 1);
|
|
61
|
+
onposition?.(position);
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
function drag_start(event: any): void {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
show_label,
|
|
25
25
|
i18n,
|
|
26
26
|
position = $bindable(0.5),
|
|
27
|
+
onposition,
|
|
27
28
|
layer_images = true,
|
|
28
29
|
show_single = false,
|
|
29
30
|
slider_color,
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
show_label: boolean;
|
|
44
45
|
i18n: I18nFormatter;
|
|
45
46
|
position?: number;
|
|
47
|
+
onposition?: (position: number) => void;
|
|
46
48
|
layer_images?: boolean;
|
|
47
49
|
show_single?: boolean;
|
|
48
50
|
slider_color: string;
|
|
@@ -213,6 +215,7 @@
|
|
|
213
215
|
>
|
|
214
216
|
<Slider
|
|
215
217
|
bind:position
|
|
218
|
+
{onposition}
|
|
216
219
|
{slider_color}
|
|
217
220
|
bind:el={slider_wrap}
|
|
218
221
|
bind:parent_el
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<svelte:options accessors={true} />
|
|
2
|
-
|
|
3
1
|
<script lang="ts">
|
|
4
2
|
import type { Snippet } from "svelte";
|
|
5
3
|
import type { I18nFormatter } from "@gradio/utils";
|
|
@@ -24,6 +22,8 @@
|
|
|
24
22
|
onclear,
|
|
25
23
|
ondrag,
|
|
26
24
|
onupload,
|
|
25
|
+
onposition,
|
|
26
|
+
position = 0.5,
|
|
27
27
|
children
|
|
28
28
|
}: {
|
|
29
29
|
value?: [FileData | null, FileData | null];
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
onclear?: () => void;
|
|
42
42
|
ondrag?: (dragging: boolean) => void;
|
|
43
43
|
onupload?: (value: [FileData | null, FileData | null]) => void;
|
|
44
|
+
onposition?: (position: number) => void;
|
|
45
|
+
position?: number;
|
|
44
46
|
children?: Snippet;
|
|
45
47
|
} = $props();
|
|
46
48
|
</script>
|
|
@@ -48,7 +50,8 @@
|
|
|
48
50
|
<Image
|
|
49
51
|
bind:upload_promise
|
|
50
52
|
slider_color="var(--border-color-primary)"
|
|
51
|
-
position
|
|
53
|
+
{position}
|
|
54
|
+
{onposition}
|
|
52
55
|
bind:value
|
|
53
56
|
bind:dragging
|
|
54
57
|
{root}
|