@gradio/dataframe 0.16.5 → 0.17.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 (87) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/Dataframe.stories.svelte +202 -9
  3. package/Index.svelte +7 -13
  4. package/dist/Index.svelte +5 -9
  5. package/dist/Index.svelte.d.ts +9 -2
  6. package/dist/shared/CellMenu.svelte +91 -10
  7. package/dist/shared/CellMenu.svelte.d.ts +6 -0
  8. package/dist/shared/CellMenuButton.svelte +45 -0
  9. package/dist/shared/CellMenuButton.svelte.d.ts +16 -0
  10. package/dist/shared/CellMenuIcons.svelte +79 -0
  11. package/dist/shared/EditableCell.svelte +83 -14
  12. package/dist/shared/EditableCell.svelte.d.ts +12 -3
  13. package/dist/shared/EmptyRowButton.svelte +28 -0
  14. package/dist/shared/EmptyRowButton.svelte.d.ts +16 -0
  15. package/dist/shared/RowNumber.svelte +40 -0
  16. package/dist/shared/RowNumber.svelte.d.ts +17 -0
  17. package/dist/shared/Table.svelte +564 -1121
  18. package/dist/shared/Table.svelte.d.ts +4 -0
  19. package/dist/shared/TableCell.svelte +291 -0
  20. package/dist/shared/TableCell.svelte.d.ts +57 -0
  21. package/dist/shared/TableHeader.svelte +239 -0
  22. package/dist/shared/TableHeader.svelte.d.ts +45 -0
  23. package/dist/shared/Toolbar.svelte +18 -8
  24. package/dist/shared/VirtualTable.svelte +66 -19
  25. package/dist/shared/VirtualTable.svelte.d.ts +4 -0
  26. package/dist/shared/context/keyboard_context.d.ts +37 -0
  27. package/dist/shared/context/keyboard_context.js +12 -0
  28. package/dist/shared/context/selection_context.d.ts +32 -0
  29. package/dist/shared/context/selection_context.js +107 -0
  30. package/dist/shared/context/table_context.d.ts +141 -0
  31. package/dist/shared/context/table_context.js +375 -0
  32. package/dist/shared/icons/Padlock.svelte +24 -0
  33. package/dist/shared/icons/Padlock.svelte.d.ts +23 -0
  34. package/dist/shared/icons/SelectionButtons.svelte +85 -0
  35. package/dist/shared/icons/SelectionButtons.svelte.d.ts +18 -0
  36. package/dist/shared/icons/SortArrowDown.svelte +24 -0
  37. package/dist/shared/icons/SortArrowDown.svelte.d.ts +16 -0
  38. package/dist/shared/icons/SortArrowUp.svelte +24 -0
  39. package/dist/shared/icons/SortArrowUp.svelte.d.ts +16 -0
  40. package/dist/shared/icons/SortButtonDown.svelte +14 -0
  41. package/dist/shared/icons/SortButtonDown.svelte.d.ts +23 -0
  42. package/dist/shared/icons/SortButtonUp.svelte +15 -0
  43. package/dist/shared/icons/SortButtonUp.svelte.d.ts +23 -0
  44. package/dist/shared/icons/SortIcon.svelte +46 -68
  45. package/dist/shared/icons/SortIcon.svelte.d.ts +3 -2
  46. package/dist/shared/selection_utils.d.ts +2 -1
  47. package/dist/shared/selection_utils.js +39 -10
  48. package/dist/shared/utils/data_processing.d.ts +13 -0
  49. package/dist/shared/utils/data_processing.js +45 -0
  50. package/dist/shared/utils/drag_utils.d.ts +15 -0
  51. package/dist/shared/utils/drag_utils.js +57 -0
  52. package/dist/shared/utils/keyboard_utils.d.ts +2 -0
  53. package/dist/shared/utils/keyboard_utils.js +186 -0
  54. package/dist/shared/utils/sort_utils.d.ts +22 -3
  55. package/dist/shared/utils/sort_utils.js +44 -24
  56. package/dist/shared/utils/table_utils.d.ts +6 -5
  57. package/dist/shared/utils/table_utils.js +13 -56
  58. package/package.json +7 -7
  59. package/shared/CellMenu.svelte +90 -10
  60. package/shared/CellMenuButton.svelte +46 -0
  61. package/shared/CellMenuIcons.svelte +79 -0
  62. package/shared/EditableCell.svelte +97 -18
  63. package/shared/EmptyRowButton.svelte +29 -0
  64. package/shared/RowNumber.svelte +41 -0
  65. package/shared/Table.svelte +604 -1235
  66. package/shared/TableCell.svelte +324 -0
  67. package/shared/TableHeader.svelte +256 -0
  68. package/shared/Toolbar.svelte +19 -8
  69. package/shared/VirtualTable.svelte +72 -19
  70. package/shared/context/keyboard_context.ts +65 -0
  71. package/shared/context/selection_context.ts +168 -0
  72. package/shared/context/table_context.ts +625 -0
  73. package/shared/icons/Padlock.svelte +24 -0
  74. package/shared/icons/SelectionButtons.svelte +93 -0
  75. package/shared/icons/SortArrowDown.svelte +25 -0
  76. package/shared/icons/SortArrowUp.svelte +25 -0
  77. package/shared/icons/SortButtonDown.svelte +14 -0
  78. package/shared/icons/SortButtonUp.svelte +15 -0
  79. package/shared/icons/SortIcon.svelte +47 -70
  80. package/shared/selection_utils.ts +39 -13
  81. package/shared/utils/data_processing.ts +72 -0
  82. package/shared/utils/drag_utils.ts +92 -0
  83. package/shared/utils/keyboard_utils.ts +238 -0
  84. package/shared/utils/sort_utils.test.ts +262 -14
  85. package/shared/utils/sort_utils.ts +67 -31
  86. package/shared/utils/table_utils.test.ts +66 -45
  87. package/shared/utils/table_utils.ts +16 -86
@@ -17,6 +17,7 @@ declare const __propDef: {
17
17
  right: string;
18
18
  display: boolean;
19
19
  }[];
20
+ components?: Record<string, any> | undefined;
20
21
  editable?: boolean | undefined;
21
22
  wrap?: boolean | undefined;
22
23
  root: string;
@@ -33,8 +34,10 @@ declare const __propDef: {
33
34
  max_chars?: number | undefined;
34
35
  show_search?: ("none" | "search" | "filter") | undefined;
35
36
  pinned_columns?: number | undefined;
37
+ static_columns?: (string | number)[] | undefined;
36
38
  display_value?: (string[][] | null) | undefined;
37
39
  styling?: (string[][] | null) | undefined;
40
+ reset_sort_state?: (() => void) | undefined;
38
41
  };
39
42
  events: {
40
43
  change: CustomEvent<DataframeValue>;
@@ -50,5 +53,6 @@ export type TableProps = typeof __propDef.props;
50
53
  export type TableEvents = typeof __propDef.events;
51
54
  export type TableSlots = typeof __propDef.slots;
52
55
  export default class Table extends SvelteComponent<TableProps, TableEvents, TableSlots> {
56
+ get reset_sort_state(): () => void;
53
57
  }
54
58
  export {};
@@ -0,0 +1,291 @@
1
+ <script>import EditableCell from "./EditableCell.svelte";
2
+ import CellMenuButton from "./CellMenuButton.svelte";
3
+ import { is_cell_in_selection } from "./selection_utils";
4
+ export let value;
5
+ export let index;
6
+ export let j;
7
+ export let actual_pinned_columns;
8
+ export let get_cell_width;
9
+ export let handle_cell_click;
10
+ export let toggle_cell_menu;
11
+ export let is_cell_selected;
12
+ export let should_show_cell_menu;
13
+ export let selected_cells;
14
+ export let copy_flash;
15
+ export let active_cell_menu;
16
+ export let styling;
17
+ export let latex_delimiters;
18
+ export let line_breaks;
19
+ export let datatype;
20
+ export let editing;
21
+ export let clear_on_focus;
22
+ export let max_chars;
23
+ export let root;
24
+ export let editable;
25
+ export let is_static = false;
26
+ export let i18n;
27
+ export let components = {};
28
+ export let el;
29
+ export let handle_select_column;
30
+ export let handle_select_row;
31
+ export let is_dragging;
32
+ function get_cell_position(col_index) {
33
+ if (col_index >= actual_pinned_columns) {
34
+ return "auto";
35
+ }
36
+ if (col_index === 0) {
37
+ return "0";
38
+ }
39
+ const previous_widths = Array(col_index).fill(0).map((_, idx) => {
40
+ return get_cell_width(idx);
41
+ }).join(" + ");
42
+ return `calc(${previous_widths})`;
43
+ }
44
+ $:
45
+ cell_classes = is_cell_selected([index, j], selected_cells || []);
46
+ $:
47
+ is_in_selection = is_cell_in_selection([index, j], selected_cells);
48
+ $:
49
+ has_no_top = cell_classes.includes("no-top");
50
+ $:
51
+ has_no_bottom = cell_classes.includes("no-bottom");
52
+ $:
53
+ has_no_left = cell_classes.includes("no-left");
54
+ $:
55
+ has_no_right = cell_classes.includes("no-right");
56
+ </script>
57
+
58
+ <td
59
+ class:pinned-column={j < actual_pinned_columns}
60
+ class:last-pinned={j === actual_pinned_columns - 1}
61
+ tabindex={j < actual_pinned_columns ? -1 : 0}
62
+ bind:this={el.cell}
63
+ data-row={index}
64
+ data-col={j}
65
+ data-testid={`cell-${index}-${j}`}
66
+ on:mousedown={(e) => handle_cell_click(e, index, j)}
67
+ on:contextmenu|preventDefault={(e) => toggle_cell_menu(e, index, j)}
68
+ style="width: {get_cell_width(j)}; left: {get_cell_position(j)}; {styling ||
69
+ ''}"
70
+ class:flash={copy_flash && is_in_selection}
71
+ class:cell-selected={is_in_selection}
72
+ class:no-top={has_no_top}
73
+ class:no-bottom={has_no_bottom}
74
+ class:no-left={has_no_left}
75
+ class:no-right={has_no_right}
76
+ class:menu-active={active_cell_menu &&
77
+ active_cell_menu.row === index &&
78
+ active_cell_menu.col === j}
79
+ class:dragging={is_dragging}
80
+ >
81
+ <div class="cell-wrap">
82
+ <EditableCell
83
+ bind:value
84
+ bind:el={el.input}
85
+ display_value={String(value)}
86
+ {latex_delimiters}
87
+ {line_breaks}
88
+ {editable}
89
+ {is_static}
90
+ edit={editing && editing[0] === index && editing[1] === j}
91
+ {datatype}
92
+ on:blur={() => {
93
+ clear_on_focus = false;
94
+ }}
95
+ on:focus={() => {
96
+ const row = index;
97
+ const col = j;
98
+ if (!selected_cells.some(([r, c]) => r === row && c === col)) {
99
+ selected_cells = [[row, col]];
100
+ }
101
+ }}
102
+ {clear_on_focus}
103
+ {root}
104
+ {max_chars}
105
+ {i18n}
106
+ {components}
107
+ show_selection_buttons={selected_cells.length === 1 &&
108
+ selected_cells[0][0] === index &&
109
+ selected_cells[0][1] === j}
110
+ coords={[index, j]}
111
+ on_select_column={handle_select_column}
112
+ on_select_row={handle_select_row}
113
+ {is_dragging}
114
+ />
115
+ {#if editable && should_show_cell_menu([index, j], selected_cells, editable)}
116
+ <CellMenuButton on_click={(event) => toggle_cell_menu(event, index, j)} />
117
+ {/if}
118
+ </div>
119
+ </td>
120
+
121
+ <style>
122
+ td {
123
+ --ring-color: transparent;
124
+ position: relative;
125
+ outline: none;
126
+ box-shadow: inset 0 0 0 1px var(--ring-color);
127
+ padding: 0;
128
+ border-right-width: 0px;
129
+ border-left-width: 1px;
130
+ border-style: solid;
131
+ border-color: var(--border-color-primary);
132
+ }
133
+
134
+ .cell-wrap {
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: flex-start;
138
+ outline: none;
139
+ min-height: var(--size-9);
140
+ position: relative;
141
+ height: 100%;
142
+ padding: var(--size-2);
143
+ box-sizing: border-box;
144
+ margin: 0;
145
+ gap: var(--size-1);
146
+ overflow: visible;
147
+ min-width: 0;
148
+ border-radius: var(--table-radius);
149
+ }
150
+
151
+ .cell-selected {
152
+ --ring-color: var(--color-accent);
153
+ box-shadow: inset 0 0 0 2px var(--ring-color);
154
+ z-index: 2;
155
+ position: relative;
156
+ }
157
+
158
+ .cell-selected :global(.cell-menu-button) {
159
+ display: flex;
160
+ }
161
+
162
+ .flash.cell-selected {
163
+ animation: flash-color 700ms ease-out;
164
+ }
165
+
166
+ @keyframes flash-color {
167
+ 0%,
168
+ 30% {
169
+ background: var(--color-accent-copied);
170
+ }
171
+
172
+ 100% {
173
+ background: transparent;
174
+ }
175
+ }
176
+
177
+ .pinned-column {
178
+ position: sticky;
179
+ z-index: 3;
180
+ border-right: none;
181
+ }
182
+
183
+ .pinned-column:nth-child(odd) {
184
+ background: var(--table-odd-background-fill);
185
+ }
186
+
187
+ .pinned-column:nth-child(even) {
188
+ background: var(--table-even-background-fill);
189
+ }
190
+
191
+ td:first-child {
192
+ border-left-width: 0px;
193
+ }
194
+
195
+ :global(tr:last-child) td:first-child {
196
+ border-bottom-left-radius: var(--table-radius);
197
+ }
198
+
199
+ :global(tr:last-child) td:last-child {
200
+ border-bottom-right-radius: var(--table-radius);
201
+ }
202
+
203
+ .dragging {
204
+ cursor: crosshair;
205
+ }
206
+
207
+ /* Add back the cell selection border styles */
208
+ .cell-selected.no-top {
209
+ box-shadow:
210
+ inset 2px 0 0 var(--ring-color),
211
+ inset -2px 0 0 var(--ring-color),
212
+ inset 0 -2px 0 var(--ring-color);
213
+ }
214
+
215
+ .cell-selected.no-bottom {
216
+ box-shadow:
217
+ inset 2px 0 0 var(--ring-color),
218
+ inset -2px 0 0 var(--ring-color),
219
+ inset 0 2px 0 var(--ring-color);
220
+ }
221
+
222
+ .cell-selected.no-left {
223
+ box-shadow:
224
+ inset 0 2px 0 var(--ring-color),
225
+ inset -2px 0 0 var(--ring-color),
226
+ inset 0 -2px 0 var(--ring-color);
227
+ }
228
+
229
+ .cell-selected.no-right {
230
+ box-shadow:
231
+ inset 0 2px 0 var(--ring-color),
232
+ inset 2px 0 0 var(--ring-color),
233
+ inset 0 -2px 0 var(--ring-color);
234
+ }
235
+
236
+ .cell-selected.no-top.no-left {
237
+ box-shadow:
238
+ inset -2px 0 0 var(--ring-color),
239
+ inset 0 -2px 0 var(--ring-color);
240
+ }
241
+
242
+ .cell-selected.no-top.no-right {
243
+ box-shadow:
244
+ inset 2px 0 0 var(--ring-color),
245
+ inset 0 -2px 0 var(--ring-color);
246
+ }
247
+
248
+ .cell-selected.no-bottom.no-left {
249
+ box-shadow:
250
+ inset -2px 0 0 var(--ring-color),
251
+ inset 0 2px 0 var(--ring-color);
252
+ }
253
+
254
+ .cell-selected.no-bottom.no-right {
255
+ box-shadow:
256
+ inset 2px 0 0 var(--ring-color),
257
+ inset 0 2px 0 var(--ring-color);
258
+ }
259
+
260
+ .cell-selected.no-top.no-bottom {
261
+ box-shadow:
262
+ inset 2px 0 0 var(--ring-color),
263
+ inset -2px 0 0 var(--ring-color);
264
+ }
265
+
266
+ .cell-selected.no-left.no-right {
267
+ box-shadow:
268
+ inset 0 2px 0 var(--ring-color),
269
+ inset 0 -2px 0 var(--ring-color);
270
+ }
271
+
272
+ .cell-selected.no-top.no-left.no-right {
273
+ box-shadow: inset 0 -2px 0 var(--ring-color);
274
+ }
275
+
276
+ .cell-selected.no-bottom.no-left.no-right {
277
+ box-shadow: inset 0 2px 0 var(--ring-color);
278
+ }
279
+
280
+ .cell-selected.no-left.no-top.no-bottom {
281
+ box-shadow: inset -2px 0 0 var(--ring-color);
282
+ }
283
+
284
+ .cell-selected.no-right.no-top.no-bottom {
285
+ box-shadow: inset 2px 0 0 var(--ring-color);
286
+ }
287
+
288
+ .cell-selected.no-top.no-bottom.no-left.no-right {
289
+ box-shadow: none;
290
+ }
291
+ </style>
@@ -0,0 +1,57 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { I18nFormatter } from "js/core/src/gradio_helper";
3
+ import type { Datatype } from "./utils";
4
+ declare const __propDef: {
5
+ props: {
6
+ value: string | number;
7
+ index: number;
8
+ j: number;
9
+ actual_pinned_columns: number;
10
+ get_cell_width: (index: number) => string;
11
+ handle_cell_click: (event: MouseEvent, row: number, col: number) => void;
12
+ toggle_cell_menu: (event: MouseEvent, row: number, col: number) => void;
13
+ is_cell_selected: (coords: [number, number], selected_cells: [number, number][]) => string;
14
+ should_show_cell_menu: (coords: [number, number], selected_cells: [number, number][], editable: boolean) => boolean;
15
+ selected_cells: [number, number][];
16
+ copy_flash: boolean;
17
+ active_cell_menu: {
18
+ row: number;
19
+ col: number;
20
+ x: number;
21
+ y: number;
22
+ } | null;
23
+ styling: string | undefined;
24
+ latex_delimiters: {
25
+ left: string;
26
+ right: string;
27
+ display: boolean;
28
+ }[];
29
+ line_breaks: boolean;
30
+ datatype: Datatype;
31
+ editing: [number, number] | false;
32
+ clear_on_focus: boolean;
33
+ max_chars: number | undefined;
34
+ root: string;
35
+ editable: boolean;
36
+ is_static?: boolean | undefined;
37
+ i18n: I18nFormatter;
38
+ components?: Record<string, any> | undefined;
39
+ el: {
40
+ cell: HTMLTableCellElement | null;
41
+ input: HTMLInputElement | null;
42
+ };
43
+ handle_select_column: (col: number) => void;
44
+ handle_select_row: (row: number) => void;
45
+ is_dragging: boolean;
46
+ };
47
+ events: {
48
+ [evt: string]: CustomEvent<any>;
49
+ };
50
+ slots: {};
51
+ };
52
+ export type TableCellProps = typeof __propDef.props;
53
+ export type TableCellEvents = typeof __propDef.events;
54
+ export type TableCellSlots = typeof __propDef.slots;
55
+ export default class TableCell extends SvelteComponent<TableCellProps, TableCellEvents, TableCellSlots> {
56
+ }
57
+ export {};
@@ -0,0 +1,239 @@
1
+ <script>import EditableCell from "./EditableCell.svelte";
2
+ import CellMenuButton from "./CellMenuButton.svelte";
3
+ import Padlock from "./icons/Padlock.svelte";
4
+ import SortArrowUp from "./icons/SortArrowUp.svelte";
5
+ import SortArrowDown from "./icons/SortArrowDown.svelte";
6
+ export let value;
7
+ export let i;
8
+ export let actual_pinned_columns;
9
+ export let header_edit;
10
+ export let selected_header;
11
+ export let get_sort_status;
12
+ export let headers;
13
+ export let get_cell_width;
14
+ export let handle_header_click;
15
+ export let toggle_header_menu;
16
+ export let end_header_edit;
17
+ export let sort_columns = [];
18
+ export let latex_delimiters;
19
+ export let line_breaks;
20
+ export let max_chars;
21
+ export let root;
22
+ export let editable;
23
+ export let i18n;
24
+ export let el;
25
+ export let is_static;
26
+ export let col_count;
27
+ $:
28
+ can_add_columns = col_count && col_count[1] === "dynamic";
29
+ $:
30
+ sort_index = sort_columns.findIndex((item) => item.col === i);
31
+ $:
32
+ sort_priority = sort_index !== -1 ? sort_index + 1 : null;
33
+ $:
34
+ current_direction = sort_index !== -1 ? sort_columns[sort_index].direction : null;
35
+ function get_header_position(col_index) {
36
+ if (col_index >= actual_pinned_columns) {
37
+ return "auto";
38
+ }
39
+ if (col_index === 0) {
40
+ return "0";
41
+ }
42
+ const previous_widths = Array(col_index).fill(0).map((_, idx) => {
43
+ return get_cell_width(idx);
44
+ }).join(" + ");
45
+ return `calc(${previous_widths})`;
46
+ }
47
+ </script>
48
+
49
+ <th
50
+ class:pinned-column={i < actual_pinned_columns}
51
+ class:last-pinned={i === actual_pinned_columns - 1}
52
+ class:focus={header_edit === i || selected_header === i}
53
+ class:sorted={sort_index !== -1}
54
+ aria-sort={get_sort_status(value, headers) === "none"
55
+ ? "none"
56
+ : get_sort_status(value, headers) === "asc"
57
+ ? "ascending"
58
+ : "descending"}
59
+ style="width: {get_cell_width(i)}; left: {get_header_position(i)};"
60
+ on:click={(event) => handle_header_click(event, i)}
61
+ on:mousedown={(event) => {
62
+ event.preventDefault();
63
+ event.stopPropagation();
64
+ }}
65
+ title={value}
66
+ >
67
+ <div class="cell-wrap">
68
+ <div class="header-content">
69
+ <button
70
+ class="header-button"
71
+ on:click={(event) => handle_header_click(event, i)}
72
+ on:mousedown={(event) => {
73
+ event.preventDefault();
74
+ event.stopPropagation();
75
+ }}
76
+ title={value}
77
+ >
78
+ <EditableCell
79
+ {max_chars}
80
+ bind:value
81
+ bind:el
82
+ {latex_delimiters}
83
+ {line_breaks}
84
+ edit={header_edit === i}
85
+ on:keydown={(event) => {
86
+ if (
87
+ event.detail.key === "Enter" ||
88
+ event.detail.key === "Escape" ||
89
+ event.detail.key === "Tab"
90
+ ) {
91
+ end_header_edit(event);
92
+ }
93
+ }}
94
+ header
95
+ {root}
96
+ {editable}
97
+ {is_static}
98
+ {i18n}
99
+ />
100
+ {#if sort_index !== -1}
101
+ <div class="sort-indicators">
102
+ <span class="sort-arrow">
103
+ {#if current_direction === "asc"}
104
+ <SortArrowUp size={12} />
105
+ {:else}
106
+ <SortArrowDown size={12} />
107
+ {/if}
108
+ </span>
109
+ {#if sort_columns.length > 1}
110
+ <span class="sort-priority">
111
+ {sort_priority}
112
+ </span>
113
+ {/if}
114
+ </div>
115
+ {/if}
116
+ </button>
117
+ {#if is_static}
118
+ <Padlock />
119
+ {/if}
120
+ </div>
121
+ {#if can_add_columns}
122
+ <CellMenuButton on_click={(event) => toggle_header_menu(event, i)} />
123
+ {/if}
124
+ </div>
125
+ </th>
126
+
127
+ <style>
128
+ th {
129
+ --ring-color: transparent;
130
+ position: relative;
131
+ outline: none;
132
+ box-shadow: inset 0 0 0 1px var(--ring-color);
133
+ padding: 0;
134
+ background: var(--table-even-background-fill);
135
+ border-right-width: 0px;
136
+ border-left-width: 1px;
137
+ border-style: solid;
138
+ border-color: var(--border-color-primary);
139
+ }
140
+
141
+ th:first-child {
142
+ border-top-left-radius: var(--table-radius);
143
+ border-bottom-left-radius: var(--table-radius);
144
+ border-left-width: 0px;
145
+ }
146
+
147
+ th:last-child {
148
+ border-top-right-radius: var(--table-radius);
149
+ border-bottom-right-radius: var(--table-radius);
150
+ }
151
+
152
+ th.focus {
153
+ --ring-color: var(--color-accent);
154
+ box-shadow: inset 0 0 0 2px var(--ring-color);
155
+ z-index: 4;
156
+ }
157
+
158
+ th.focus :global(.cell-menu-button) {
159
+ display: flex;
160
+ }
161
+
162
+ th:hover :global(.cell-menu-button) {
163
+ display: flex;
164
+ }
165
+
166
+ .cell-wrap {
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: flex-start;
170
+ outline: none;
171
+ min-height: var(--size-9);
172
+ position: relative;
173
+ height: 100%;
174
+ padding: var(--size-2);
175
+ box-sizing: border-box;
176
+ margin: 0;
177
+ gap: var(--size-1);
178
+ overflow: visible;
179
+ min-width: 0;
180
+ border-radius: var(--table-radius);
181
+ }
182
+
183
+ .header-content {
184
+ display: flex;
185
+ align-items: center;
186
+ overflow: hidden;
187
+ flex-grow: 1;
188
+ min-width: 0;
189
+ white-space: normal;
190
+ overflow-wrap: break-word;
191
+ word-break: normal;
192
+ height: 100%;
193
+ gap: var(--size-1);
194
+ }
195
+
196
+ .header-button {
197
+ display: flex;
198
+ text-align: left;
199
+ width: 100%;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ display: flex;
203
+ align-items: center;
204
+ position: relative;
205
+ }
206
+
207
+ .sort-indicators {
208
+ display: flex;
209
+ align-items: center;
210
+ margin-left: var(--size-1);
211
+ gap: var(--size-1);
212
+ }
213
+
214
+ .sort-arrow {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ color: var(--body-text-color);
219
+ }
220
+
221
+ .sort-priority {
222
+ display: flex;
223
+ align-items: center;
224
+ justify-content: center;
225
+ font-size: var(--size-2);
226
+ background-color: var(--button-secondary-background-fill);
227
+ color: var(--body-text-color);
228
+ border-radius: var(--radius-sm);
229
+ width: var(--size-2-5);
230
+ height: var(--size-2-5);
231
+ padding: var(--size-1-5);
232
+ }
233
+
234
+ .pinned-column {
235
+ position: sticky;
236
+ z-index: 5;
237
+ border-right: none;
238
+ }
239
+ </style>
@@ -0,0 +1,45 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { I18nFormatter } from "js/core/src/gradio_helper";
3
+ import type { SortDirection } from "./context/table_context";
4
+ declare const __propDef: {
5
+ props: {
6
+ value: string;
7
+ i: number;
8
+ actual_pinned_columns: number;
9
+ header_edit: number | false;
10
+ selected_header: number | false;
11
+ get_sort_status: (value: string, headers: string[]) => "none" | "asc" | "desc";
12
+ headers: string[];
13
+ get_cell_width: (index: number) => string;
14
+ handle_header_click: (event: MouseEvent, col: number) => void;
15
+ toggle_header_menu: (event: MouseEvent, col: number) => void;
16
+ end_header_edit: (event: CustomEvent<KeyboardEvent>) => void;
17
+ sort_columns?: {
18
+ col: number;
19
+ direction: SortDirection;
20
+ }[] | undefined;
21
+ latex_delimiters: {
22
+ left: string;
23
+ right: string;
24
+ display: boolean;
25
+ }[];
26
+ line_breaks: boolean;
27
+ max_chars: number | undefined;
28
+ root: string;
29
+ editable: boolean;
30
+ i18n: I18nFormatter;
31
+ el: HTMLInputElement | null;
32
+ is_static: boolean;
33
+ col_count: [number, "fixed" | "dynamic"];
34
+ };
35
+ events: {
36
+ [evt: string]: CustomEvent<any>;
37
+ };
38
+ slots: {};
39
+ };
40
+ export type TableHeaderProps = typeof __propDef.props;
41
+ export type TableHeaderEvents = typeof __propDef.events;
42
+ export type TableHeaderSlots = typeof __propDef.slots;
43
+ export default class TableHeader extends SvelteComponent<TableHeaderProps, TableHeaderEvents, TableHeaderSlots> {
44
+ }
45
+ export {};
@@ -1,7 +1,6 @@
1
- <script>import { Maximize, Minimize, Copy } from "@gradio/icons";
1
+ <script>import { Maximize, Minimize, Copy, Check } from "@gradio/icons";
2
2
  import { onDestroy } from "svelte";
3
3
  import { createEventDispatcher } from "svelte";
4
- import FilterIcon from "./icons/FilterIcon.svelte";
5
4
  export let show_fullscreen_button = false;
6
5
  export let show_copy_button = false;
7
6
  export let show_search = "none";
@@ -12,8 +11,16 @@ const dispatch = createEventDispatcher();
12
11
  let copied = false;
13
12
  let timer;
14
13
  export let current_search_query = null;
15
- $:
16
- dispatch("search", current_search_query);
14
+ let input_value = "";
15
+ function handle_search_input(e) {
16
+ const target = e.target;
17
+ input_value = target.value;
18
+ const new_query = input_value || null;
19
+ if (current_search_query !== new_query) {
20
+ current_search_query = new_query;
21
+ dispatch("search", current_search_query);
22
+ }
23
+ }
17
24
  function copy_feedback() {
18
25
  copied = true;
19
26
  if (timer)
@@ -38,9 +45,12 @@ onDestroy(() => {
38
45
  <div class="search-container">
39
46
  <input
40
47
  type="text"
41
- bind:value={current_search_query}
42
- placeholder="Search..."
48
+ value={current_search_query || ""}
49
+ on:input={handle_search_input}
50
+ placeholder={show_search === "filter" ? "Filter..." : "Search..."}
43
51
  class="search-input"
52
+ class:filter-mode={show_search === "filter"}
53
+ title={`Enter text to ${show_search} the table`}
44
54
  />
45
55
  {#if current_search_query && show_search === "filter"}
46
56
  <button
@@ -49,7 +59,7 @@ onDestroy(() => {
49
59
  aria-label="Apply filter and update dataframe values"
50
60
  title="Apply filter and update dataframe values"
51
61
  >
52
- <FilterIcon />
62
+ <Check />
53
63
  </button>
54
64
  {/if}
55
65
  </div>
@@ -62,7 +72,7 @@ onDestroy(() => {
62
72
  title={copied ? "Copied to clipboard" : "Copy table data"}
63
73
  >
64
74
  {#if copied}
65
- <FilterIcon />
75
+ <Check />
66
76
  {:else}
67
77
  <Copy />
68
78
  {/if}