@gradio/dataframe 0.17.14 → 0.17.15
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 +13 -0
- package/Dataframe.stories.svelte +11 -10
- package/dist/shared/BooleanCell.svelte +62 -0
- package/dist/shared/BooleanCell.svelte.d.ts +18 -0
- package/dist/shared/EditableCell.svelte +67 -44
- package/dist/shared/Table.svelte +23 -4
- package/dist/shared/utils/drag_utils.js +4 -0
- package/dist/shared/utils/keyboard_utils.js +1 -1
- package/package.json +7 -6
- package/shared/BooleanCell.svelte +68 -0
- package/shared/EditableCell.svelte +69 -45
- package/shared/Table.svelte +24 -6
- package/shared/utils/drag_utils.ts +5 -0
- package/shared/utils/keyboard_utils.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @gradio/dataframe
|
|
2
2
|
|
|
3
|
+
## 0.17.15
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#11237](https://github.com/gradio-app/gradio/pull/11237) [`a6f6b40`](https://github.com/gradio-app/gradio/commit/a6f6b40dda5194fa5bc9926ef67f2a75f503e9a4) - Enhance boolean cell types in `gr.Dataframe`. Thanks @hannahblair!
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/upload@0.16.7
|
|
12
|
+
- @gradio/checkbox@0.4.23
|
|
13
|
+
- @gradio/client@1.15.2
|
|
14
|
+
- @gradio/button@0.5.3
|
|
15
|
+
|
|
3
16
|
## 0.17.14
|
|
4
17
|
|
|
5
18
|
### Fixes
|
package/Dataframe.stories.svelte
CHANGED
|
@@ -60,11 +60,12 @@
|
|
|
60
60
|
name="Interactive dataframe with label"
|
|
61
61
|
args={{
|
|
62
62
|
values: [
|
|
63
|
-
["Cat", 5],
|
|
64
|
-
["Horse", 3],
|
|
65
|
-
["Snake", 1]
|
|
63
|
+
["Cat", 5, true],
|
|
64
|
+
["Horse", 3, false],
|
|
65
|
+
["Snake", 1, false]
|
|
66
66
|
],
|
|
67
|
-
headers: ["Animal", "Votes"],
|
|
67
|
+
headers: ["Animal", "Votes", "Is Pet"],
|
|
68
|
+
datatype: ["str", "number", "bool"],
|
|
68
69
|
label: "Animals",
|
|
69
70
|
show_label: true,
|
|
70
71
|
col_count: [2, "dynamic"],
|
|
@@ -93,14 +94,14 @@
|
|
|
93
94
|
name="Static dataframe"
|
|
94
95
|
args={{
|
|
95
96
|
values: [
|
|
96
|
-
["Cat", 5],
|
|
97
|
-
["Horse", 3],
|
|
98
|
-
["Snake", 1]
|
|
97
|
+
["Cat", 5, true],
|
|
98
|
+
["Horse", 3, false],
|
|
99
|
+
["Snake", 1, false]
|
|
99
100
|
],
|
|
100
|
-
headers: ["Animal", "Votes"],
|
|
101
|
-
|
|
101
|
+
headers: ["Animal", "Votes", "Is Pet"],
|
|
102
|
+
datatype: ["str", "number", "bool"],
|
|
102
103
|
label: "Animals",
|
|
103
|
-
col_count: [
|
|
104
|
+
col_count: [3, "dynamic"],
|
|
104
105
|
row_count: [3, "dynamic"],
|
|
105
106
|
editable: false
|
|
106
107
|
}}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script>import { BaseCheckbox } from "@gradio/checkbox";
|
|
2
|
+
export let value = false;
|
|
3
|
+
export let editable = true;
|
|
4
|
+
export let on_change;
|
|
5
|
+
$:
|
|
6
|
+
bool_value = typeof value === "string" ? value.toLowerCase() === "true" : !!value;
|
|
7
|
+
function handle_change(event) {
|
|
8
|
+
on_change(event.detail);
|
|
9
|
+
}
|
|
10
|
+
function handle_click(event) {
|
|
11
|
+
event.stopPropagation();
|
|
12
|
+
}
|
|
13
|
+
function handle_keydown(event) {
|
|
14
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div
|
|
21
|
+
class="bool-cell checkbox"
|
|
22
|
+
on:click={handle_click}
|
|
23
|
+
on:keydown={handle_keydown}
|
|
24
|
+
role="button"
|
|
25
|
+
tabindex="-1"
|
|
26
|
+
>
|
|
27
|
+
<BaseCheckbox
|
|
28
|
+
bind:value={bool_value}
|
|
29
|
+
label=""
|
|
30
|
+
interactive={editable}
|
|
31
|
+
on:change={handle_change}
|
|
32
|
+
/>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<style>
|
|
36
|
+
.bool-cell {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
width: var(--size-full);
|
|
41
|
+
height: var(--size-full);
|
|
42
|
+
}
|
|
43
|
+
.bool-cell :global(input:disabled) {
|
|
44
|
+
opacity: 0.8;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.bool-cell.checkbox {
|
|
48
|
+
justify-content: center;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.bool-cell :global(label) {
|
|
52
|
+
margin: 0;
|
|
53
|
+
width: 100%;
|
|
54
|
+
display: flex;
|
|
55
|
+
justify-content: center;
|
|
56
|
+
align-items: center;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.bool-cell :global(span) {
|
|
60
|
+
display: none;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
value?: (boolean | string) | undefined;
|
|
5
|
+
editable?: boolean | undefined;
|
|
6
|
+
on_change: (value: boolean) => void;
|
|
7
|
+
};
|
|
8
|
+
events: {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
};
|
|
11
|
+
slots: {};
|
|
12
|
+
};
|
|
13
|
+
export type BooleanCellProps = typeof __propDef.props;
|
|
14
|
+
export type BooleanCellEvents = typeof __propDef.events;
|
|
15
|
+
export type BooleanCellSlots = typeof __propDef.slots;
|
|
16
|
+
export default class BooleanCell extends SvelteComponent<BooleanCellProps, BooleanCellEvents, BooleanCellSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>import { createEventDispatcher } from "svelte";
|
|
2
2
|
import { MarkdownCode } from "@gradio/markdown-code";
|
|
3
3
|
import SelectionButtons from "./icons/SelectionButtons.svelte";
|
|
4
|
+
import BooleanCell from "./BooleanCell.svelte";
|
|
4
5
|
export let edit;
|
|
5
6
|
export let value = "";
|
|
6
7
|
export let display_value = null;
|
|
@@ -21,9 +22,9 @@ export let show_selection_buttons = false;
|
|
|
21
22
|
export let coords;
|
|
22
23
|
export let on_select_column = null;
|
|
23
24
|
export let on_select_row = null;
|
|
25
|
+
export let el;
|
|
24
26
|
const dispatch = createEventDispatcher();
|
|
25
27
|
let is_expanded = false;
|
|
26
|
-
export let el;
|
|
27
28
|
function truncate_text(text, max_length = null, is_image = false) {
|
|
28
29
|
if (is_image)
|
|
29
30
|
return String(text);
|
|
@@ -65,9 +66,22 @@ function handle_click() {
|
|
|
65
66
|
is_expanded = !is_expanded;
|
|
66
67
|
}
|
|
67
68
|
}
|
|
69
|
+
function handle_bool_change(new_value) {
|
|
70
|
+
value = new_value.toString();
|
|
71
|
+
dispatch("blur", {
|
|
72
|
+
blur_event: {
|
|
73
|
+
target: {
|
|
74
|
+
type: "checkbox",
|
|
75
|
+
checked: new_value,
|
|
76
|
+
value: new_value.toString()
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
coords
|
|
80
|
+
});
|
|
81
|
+
}
|
|
68
82
|
</script>
|
|
69
83
|
|
|
70
|
-
{#if edit}
|
|
84
|
+
{#if edit && datatype !== "bool"}
|
|
71
85
|
<input
|
|
72
86
|
readonly={is_static}
|
|
73
87
|
aria-readonly={is_static}
|
|
@@ -86,48 +100,57 @@ function handle_click() {
|
|
|
86
100
|
/>
|
|
87
101
|
{/if}
|
|
88
102
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
103
|
+
{#if datatype === "bool"}
|
|
104
|
+
<BooleanCell
|
|
105
|
+
value={String(display_content)}
|
|
106
|
+
{editable}
|
|
107
|
+
on_change={handle_bool_change}
|
|
108
|
+
/>
|
|
109
|
+
{:else}
|
|
110
|
+
<span
|
|
111
|
+
class:dragging={is_dragging}
|
|
112
|
+
on:click={handle_click}
|
|
113
|
+
on:keydown={handle_keydown}
|
|
114
|
+
tabindex="0"
|
|
115
|
+
role="button"
|
|
116
|
+
class:edit
|
|
117
|
+
class:expanded={is_expanded}
|
|
118
|
+
class:multiline={header}
|
|
119
|
+
on:focus|preventDefault
|
|
120
|
+
style={styling}
|
|
121
|
+
data-editable={editable}
|
|
122
|
+
data-max-chars={max_chars}
|
|
123
|
+
data-expanded={is_expanded}
|
|
124
|
+
placeholder=" "
|
|
125
|
+
class:text={datatype === "str"}
|
|
126
|
+
class:wrap={wrap_text}
|
|
127
|
+
>
|
|
128
|
+
{#if datatype === "image" && components.image}
|
|
129
|
+
<svelte:component
|
|
130
|
+
this={components.image}
|
|
131
|
+
value={{ url: display_text }}
|
|
132
|
+
show_label={false}
|
|
133
|
+
label="cell-image"
|
|
134
|
+
show_download_button={false}
|
|
135
|
+
{i18n}
|
|
136
|
+
gradio={{ dispatch: () => {} }}
|
|
137
|
+
/>
|
|
138
|
+
{:else if datatype === "html"}
|
|
139
|
+
{@html display_text}
|
|
140
|
+
{:else if datatype === "markdown"}
|
|
141
|
+
<MarkdownCode
|
|
142
|
+
message={display_text.toLocaleString()}
|
|
143
|
+
{latex_delimiters}
|
|
144
|
+
{line_breaks}
|
|
145
|
+
chatbot={false}
|
|
146
|
+
{root}
|
|
147
|
+
/>
|
|
148
|
+
{:else}
|
|
149
|
+
{display_text}
|
|
150
|
+
{/if}
|
|
151
|
+
</span>
|
|
152
|
+
{/if}
|
|
153
|
+
|
|
131
154
|
{#if show_selection_buttons && coords && on_select_column && on_select_row}
|
|
132
155
|
<SelectionButtons
|
|
133
156
|
position="column"
|
package/dist/shared/Table.svelte
CHANGED
|
@@ -103,7 +103,7 @@ onMount(() => {
|
|
|
103
103
|
const observer = new IntersectionObserver((entries) => {
|
|
104
104
|
entries.forEach((entry) => {
|
|
105
105
|
if (entry.isIntersecting && !is_visible) {
|
|
106
|
-
|
|
106
|
+
width_calculated = false;
|
|
107
107
|
}
|
|
108
108
|
is_visible = entry.isIntersecting;
|
|
109
109
|
});
|
|
@@ -111,10 +111,17 @@ onMount(() => {
|
|
|
111
111
|
observer.observe(parent);
|
|
112
112
|
document.addEventListener("click", handle_click_outside);
|
|
113
113
|
window.addEventListener("resize", handle_resize);
|
|
114
|
+
const global_mouse_up = (event) => {
|
|
115
|
+
if (is_dragging || drag_start) {
|
|
116
|
+
handle_mouse_up(event);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
document.addEventListener("mouseup", global_mouse_up);
|
|
114
120
|
return () => {
|
|
115
121
|
observer.disconnect();
|
|
116
122
|
document.removeEventListener("click", handle_click_outside);
|
|
117
123
|
window.removeEventListener("resize", handle_resize);
|
|
124
|
+
document.removeEventListener("mouseup", global_mouse_up);
|
|
118
125
|
};
|
|
119
126
|
});
|
|
120
127
|
$: {
|
|
@@ -170,6 +177,7 @@ $:
|
|
|
170
177
|
}
|
|
171
178
|
last_width_data_length = 0;
|
|
172
179
|
last_width_column_count = 0;
|
|
180
|
+
width_calculated = false;
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
183
|
const is_reset = values.length === 0 || values.length === 1 && values[0].length === 0;
|
|
@@ -193,8 +201,8 @@ $:
|
|
|
193
201
|
if ($df_state.current_search_query) {
|
|
194
202
|
df_actions.handle_search(null);
|
|
195
203
|
}
|
|
196
|
-
if (parent && cells.length > 0) {
|
|
197
|
-
|
|
204
|
+
if (parent && cells.length > 0 && (is_reset || is_different_structure)) {
|
|
205
|
+
width_calculated = false;
|
|
198
206
|
}
|
|
199
207
|
}
|
|
200
208
|
$:
|
|
@@ -328,8 +336,18 @@ function handle_click_outside(event) {
|
|
|
328
336
|
}
|
|
329
337
|
$:
|
|
330
338
|
max = get_max(data);
|
|
339
|
+
let width_calc_timeout;
|
|
331
340
|
$:
|
|
332
|
-
cells[0] && cells[0]?.clientWidth
|
|
341
|
+
if (cells[0] && cells[0]?.clientWidth) {
|
|
342
|
+
clearTimeout(width_calc_timeout);
|
|
343
|
+
width_calc_timeout = setTimeout(() => set_cell_widths(), 100);
|
|
344
|
+
}
|
|
345
|
+
let width_calculated = false;
|
|
346
|
+
$:
|
|
347
|
+
if (cells[0] && !width_calculated) {
|
|
348
|
+
set_cell_widths();
|
|
349
|
+
width_calculated = true;
|
|
350
|
+
}
|
|
333
351
|
let cells = [];
|
|
334
352
|
let parent;
|
|
335
353
|
let table;
|
|
@@ -512,6 +530,7 @@ function handle_resize() {
|
|
|
512
530
|
selected_cells = [];
|
|
513
531
|
selected = false;
|
|
514
532
|
editing = false;
|
|
533
|
+
width_calculated = false;
|
|
515
534
|
set_cell_widths();
|
|
516
535
|
}
|
|
517
536
|
function add_row_at(index, position) {
|
|
@@ -43,6 +43,10 @@ export function create_drag_handlers(state, set_is_dragging, set_selected_cells,
|
|
|
43
43
|
handle_mouse_move(event) {
|
|
44
44
|
if (!state.drag_start || !state.mouse_down_pos)
|
|
45
45
|
return;
|
|
46
|
+
if (!(event.buttons & 1)) {
|
|
47
|
+
end_drag(event);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
46
50
|
const dx = Math.abs(event.clientX - state.mouse_down_pos.x);
|
|
47
51
|
const dy = Math.abs(event.clientY - state.mouse_down_pos.y);
|
|
48
52
|
if (!state.is_dragging && (dx > 3 || dy > 3)) {
|
|
@@ -23,7 +23,7 @@ export async function handle_cell_blur(event, ctx, coords) {
|
|
|
23
23
|
const input_el = event.target;
|
|
24
24
|
if (!input_el || input_el.value === undefined)
|
|
25
25
|
return;
|
|
26
|
-
await save_cell_value(input_el.value, ctx, coords[0], coords[1]);
|
|
26
|
+
await save_cell_value(input_el.type === "checkbox" ? String(input_el.checked) : input_el.value, ctx, coords[0], coords[1]);
|
|
27
27
|
}
|
|
28
28
|
function handle_header_navigation(event, ctx) {
|
|
29
29
|
const state = get(ctx.state);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/dataframe",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.15",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -17,14 +17,15 @@
|
|
|
17
17
|
"dompurify": "^3.0.3",
|
|
18
18
|
"katex": "^0.16.7",
|
|
19
19
|
"marked": "^12.0.0",
|
|
20
|
+
"@gradio/button": "^0.5.3",
|
|
20
21
|
"@gradio/atoms": "^0.16.1",
|
|
21
|
-
"@gradio/
|
|
22
|
-
"@gradio/client": "^1.15.
|
|
22
|
+
"@gradio/checkbox": "^0.4.23",
|
|
23
|
+
"@gradio/client": "^1.15.2",
|
|
23
24
|
"@gradio/icons": "^0.12.0",
|
|
24
|
-
"@gradio/markdown-code": "^0.4.3",
|
|
25
|
-
"@gradio/upload": "^0.16.6",
|
|
26
25
|
"@gradio/statustracker": "^0.10.12",
|
|
27
|
-
"@gradio/
|
|
26
|
+
"@gradio/upload": "^0.16.7",
|
|
27
|
+
"@gradio/utils": "^0.10.2",
|
|
28
|
+
"@gradio/markdown-code": "^0.4.3"
|
|
28
29
|
},
|
|
29
30
|
"exports": {
|
|
30
31
|
".": {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { BaseCheckbox } from "@gradio/checkbox";
|
|
3
|
+
|
|
4
|
+
export let value: boolean | string = false;
|
|
5
|
+
export let editable = true;
|
|
6
|
+
export let on_change: (value: boolean) => void;
|
|
7
|
+
|
|
8
|
+
$: bool_value =
|
|
9
|
+
typeof value === "string" ? value.toLowerCase() === "true" : !!value;
|
|
10
|
+
|
|
11
|
+
function handle_change(event: CustomEvent<boolean>): void {
|
|
12
|
+
on_change(event.detail);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function handle_click(event: MouseEvent): void {
|
|
16
|
+
event.stopPropagation();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function handle_keydown(event: KeyboardEvent): void {
|
|
20
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
21
|
+
event.stopPropagation();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="bool-cell checkbox"
|
|
28
|
+
on:click={handle_click}
|
|
29
|
+
on:keydown={handle_keydown}
|
|
30
|
+
role="button"
|
|
31
|
+
tabindex="-1"
|
|
32
|
+
>
|
|
33
|
+
<BaseCheckbox
|
|
34
|
+
bind:value={bool_value}
|
|
35
|
+
label=""
|
|
36
|
+
interactive={editable}
|
|
37
|
+
on:change={handle_change}
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
.bool-cell {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
width: var(--size-full);
|
|
47
|
+
height: var(--size-full);
|
|
48
|
+
}
|
|
49
|
+
.bool-cell :global(input:disabled) {
|
|
50
|
+
opacity: 0.8;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.bool-cell.checkbox {
|
|
54
|
+
justify-content: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.bool-cell :global(label) {
|
|
58
|
+
margin: 0;
|
|
59
|
+
width: 100%;
|
|
60
|
+
display: flex;
|
|
61
|
+
justify-content: center;
|
|
62
|
+
align-items: center;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.bool-cell :global(span) {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { MarkdownCode } from "@gradio/markdown-code";
|
|
4
4
|
import type { I18nFormatter } from "@gradio/utils";
|
|
5
5
|
import SelectionButtons from "./icons/SelectionButtons.svelte";
|
|
6
|
+
import BooleanCell from "./BooleanCell.svelte";
|
|
7
|
+
|
|
6
8
|
export let edit: boolean;
|
|
7
9
|
export let value: string | number = "";
|
|
8
10
|
export let display_value: string | null = null;
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
export let coords: [number, number];
|
|
36
38
|
export let on_select_column: ((col: number) => void) | null = null;
|
|
37
39
|
export let on_select_row: ((row: number) => void) | null = null;
|
|
40
|
+
export let el: HTMLInputElement | null;
|
|
38
41
|
|
|
39
42
|
const dispatch = createEventDispatcher<{
|
|
40
43
|
blur: { blur_event: FocusEvent; coords: [number, number] };
|
|
@@ -43,8 +46,6 @@
|
|
|
43
46
|
|
|
44
47
|
let is_expanded = false;
|
|
45
48
|
|
|
46
|
-
export let el: HTMLInputElement | null;
|
|
47
|
-
|
|
48
49
|
function truncate_text(
|
|
49
50
|
text: string | number,
|
|
50
51
|
max_length: number | null = null,
|
|
@@ -99,9 +100,23 @@
|
|
|
99
100
|
is_expanded = !is_expanded;
|
|
100
101
|
}
|
|
101
102
|
}
|
|
103
|
+
|
|
104
|
+
function handle_bool_change(new_value: boolean): void {
|
|
105
|
+
value = new_value.toString();
|
|
106
|
+
dispatch("blur", {
|
|
107
|
+
blur_event: {
|
|
108
|
+
target: {
|
|
109
|
+
type: "checkbox",
|
|
110
|
+
checked: new_value,
|
|
111
|
+
value: new_value.toString()
|
|
112
|
+
}
|
|
113
|
+
} as unknown as FocusEvent,
|
|
114
|
+
coords: coords
|
|
115
|
+
});
|
|
116
|
+
}
|
|
102
117
|
</script>
|
|
103
118
|
|
|
104
|
-
{#if edit}
|
|
119
|
+
{#if edit && datatype !== "bool"}
|
|
105
120
|
<input
|
|
106
121
|
readonly={is_static}
|
|
107
122
|
aria-readonly={is_static}
|
|
@@ -120,48 +135,57 @@
|
|
|
120
135
|
/>
|
|
121
136
|
{/if}
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
138
|
+
{#if datatype === "bool"}
|
|
139
|
+
<BooleanCell
|
|
140
|
+
value={String(display_content)}
|
|
141
|
+
{editable}
|
|
142
|
+
on_change={handle_bool_change}
|
|
143
|
+
/>
|
|
144
|
+
{:else}
|
|
145
|
+
<span
|
|
146
|
+
class:dragging={is_dragging}
|
|
147
|
+
on:click={handle_click}
|
|
148
|
+
on:keydown={handle_keydown}
|
|
149
|
+
tabindex="0"
|
|
150
|
+
role="button"
|
|
151
|
+
class:edit
|
|
152
|
+
class:expanded={is_expanded}
|
|
153
|
+
class:multiline={header}
|
|
154
|
+
on:focus|preventDefault
|
|
155
|
+
style={styling}
|
|
156
|
+
data-editable={editable}
|
|
157
|
+
data-max-chars={max_chars}
|
|
158
|
+
data-expanded={is_expanded}
|
|
159
|
+
placeholder=" "
|
|
160
|
+
class:text={datatype === "str"}
|
|
161
|
+
class:wrap={wrap_text}
|
|
162
|
+
>
|
|
163
|
+
{#if datatype === "image" && components.image}
|
|
164
|
+
<svelte:component
|
|
165
|
+
this={components.image}
|
|
166
|
+
value={{ url: display_text }}
|
|
167
|
+
show_label={false}
|
|
168
|
+
label="cell-image"
|
|
169
|
+
show_download_button={false}
|
|
170
|
+
{i18n}
|
|
171
|
+
gradio={{ dispatch: () => {} }}
|
|
172
|
+
/>
|
|
173
|
+
{:else if datatype === "html"}
|
|
174
|
+
{@html display_text}
|
|
175
|
+
{:else if datatype === "markdown"}
|
|
176
|
+
<MarkdownCode
|
|
177
|
+
message={display_text.toLocaleString()}
|
|
178
|
+
{latex_delimiters}
|
|
179
|
+
{line_breaks}
|
|
180
|
+
chatbot={false}
|
|
181
|
+
{root}
|
|
182
|
+
/>
|
|
183
|
+
{:else}
|
|
184
|
+
{display_text}
|
|
185
|
+
{/if}
|
|
186
|
+
</span>
|
|
187
|
+
{/if}
|
|
188
|
+
|
|
165
189
|
{#if show_selection_buttons && coords && on_select_column && on_select_row}
|
|
166
190
|
<SelectionButtons
|
|
167
191
|
position="column"
|
package/shared/Table.svelte
CHANGED
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
const observer = new IntersectionObserver((entries) => {
|
|
121
121
|
entries.forEach((entry) => {
|
|
122
122
|
if (entry.isIntersecting && !is_visible) {
|
|
123
|
-
|
|
123
|
+
width_calculated = false;
|
|
124
124
|
}
|
|
125
125
|
is_visible = entry.isIntersecting;
|
|
126
126
|
});
|
|
@@ -129,10 +129,18 @@
|
|
|
129
129
|
document.addEventListener("click", handle_click_outside);
|
|
130
130
|
window.addEventListener("resize", handle_resize);
|
|
131
131
|
|
|
132
|
+
const global_mouse_up = (event: MouseEvent): void => {
|
|
133
|
+
if (is_dragging || drag_start) {
|
|
134
|
+
handle_mouse_up(event);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
document.addEventListener("mouseup", global_mouse_up);
|
|
138
|
+
|
|
132
139
|
return () => {
|
|
133
140
|
observer.disconnect();
|
|
134
141
|
document.removeEventListener("click", handle_click_outside);
|
|
135
142
|
window.removeEventListener("resize", handle_resize);
|
|
143
|
+
document.removeEventListener("mouseup", global_mouse_up);
|
|
136
144
|
};
|
|
137
145
|
});
|
|
138
146
|
|
|
@@ -223,6 +231,7 @@
|
|
|
223
231
|
}
|
|
224
232
|
last_width_data_length = 0;
|
|
225
233
|
last_width_column_count = 0;
|
|
234
|
+
width_calculated = false;
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
237
|
|
|
@@ -256,8 +265,8 @@
|
|
|
256
265
|
df_actions.handle_search(null);
|
|
257
266
|
}
|
|
258
267
|
|
|
259
|
-
if (parent && cells.length > 0) {
|
|
260
|
-
|
|
268
|
+
if (parent && cells.length > 0 && (is_reset || is_different_structure)) {
|
|
269
|
+
width_calculated = false;
|
|
261
270
|
}
|
|
262
271
|
}
|
|
263
272
|
|
|
@@ -421,9 +430,17 @@
|
|
|
421
430
|
|
|
422
431
|
$: max = get_max(data);
|
|
423
432
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
433
|
+
let width_calc_timeout: ReturnType<typeof setTimeout>;
|
|
434
|
+
$: if (cells[0] && cells[0]?.clientWidth) {
|
|
435
|
+
clearTimeout(width_calc_timeout);
|
|
436
|
+
width_calc_timeout = setTimeout(() => set_cell_widths(), 100);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
let width_calculated = false;
|
|
440
|
+
$: if (cells[0] && !width_calculated) {
|
|
441
|
+
set_cell_widths();
|
|
442
|
+
width_calculated = true;
|
|
443
|
+
}
|
|
427
444
|
let cells: HTMLTableCellElement[] = [];
|
|
428
445
|
let parent: HTMLDivElement;
|
|
429
446
|
let table: HTMLTableElement;
|
|
@@ -649,6 +666,7 @@
|
|
|
649
666
|
selected_cells = [];
|
|
650
667
|
selected = false;
|
|
651
668
|
editing = false;
|
|
669
|
+
width_calculated = false;
|
|
652
670
|
set_cell_widths();
|
|
653
671
|
}
|
|
654
672
|
|
|
@@ -75,6 +75,11 @@ export function create_drag_handlers(
|
|
|
75
75
|
handle_mouse_move(event: MouseEvent): void {
|
|
76
76
|
if (!state.drag_start || !state.mouse_down_pos) return;
|
|
77
77
|
|
|
78
|
+
if (!(event.buttons & 1)) {
|
|
79
|
+
end_drag(event);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
const dx = Math.abs(event.clientX - state.mouse_down_pos.x);
|
|
79
84
|
const dy = Math.abs(event.clientY - state.mouse_down_pos.y);
|
|
80
85
|
|
|
@@ -37,7 +37,12 @@ export async function handle_cell_blur(
|
|
|
37
37
|
const input_el = event.target as HTMLInputElement;
|
|
38
38
|
if (!input_el || input_el.value === undefined) return;
|
|
39
39
|
|
|
40
|
-
await save_cell_value(
|
|
40
|
+
await save_cell_value(
|
|
41
|
+
input_el.type === "checkbox" ? String(input_el.checked) : input_el.value,
|
|
42
|
+
ctx,
|
|
43
|
+
coords[0],
|
|
44
|
+
coords[1]
|
|
45
|
+
);
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
function handle_header_navigation(
|