@gradio/dataframe 0.17.17 → 0.18.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 (40) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/Dataframe.stories.svelte +1 -2
  3. package/Index.svelte +3 -13
  4. package/dist/Index.svelte +3 -10
  5. package/dist/Index.svelte.d.ts +1 -5
  6. package/dist/shared/CellMenu.svelte +37 -0
  7. package/dist/shared/CellMenu.svelte.d.ts +4 -1
  8. package/dist/shared/CellMenuIcons.svelte +48 -0
  9. package/dist/shared/EditableCell.svelte +16 -20
  10. package/dist/shared/EditableCell.svelte.d.ts +1 -2
  11. package/dist/shared/FilterMenu.svelte +235 -0
  12. package/dist/shared/FilterMenu.svelte.d.ts +19 -0
  13. package/dist/shared/Table.svelte +59 -1
  14. package/dist/shared/TableCell.svelte.d.ts +1 -1
  15. package/dist/shared/TableHeader.svelte +26 -0
  16. package/dist/shared/TableHeader.svelte.d.ts +8 -1
  17. package/dist/shared/context/dataframe_context.d.ts +20 -1
  18. package/dist/shared/context/dataframe_context.js +46 -6
  19. package/dist/shared/types.d.ts +1 -1
  20. package/dist/shared/utils/data_processing.d.ts +2 -2
  21. package/dist/shared/utils/filter_utils.d.ts +28 -0
  22. package/dist/shared/utils/filter_utils.js +123 -0
  23. package/dist/shared/utils/keyboard_utils.js +5 -1
  24. package/dist/shared/utils/table_utils.d.ts +7 -0
  25. package/dist/shared/utils/table_utils.js +29 -0
  26. package/package.json +10 -10
  27. package/shared/CellMenu.svelte +45 -1
  28. package/shared/CellMenuIcons.svelte +48 -0
  29. package/shared/EditableCell.svelte +18 -25
  30. package/shared/FilterMenu.svelte +248 -0
  31. package/shared/Table.svelte +79 -5
  32. package/shared/TableCell.svelte +1 -1
  33. package/shared/TableHeader.svelte +32 -1
  34. package/shared/Toolbar.svelte +1 -1
  35. package/shared/context/dataframe_context.ts +81 -18
  36. package/shared/types.ts +1 -1
  37. package/shared/utils/data_processing.ts +2 -2
  38. package/shared/utils/filter_utils.ts +207 -0
  39. package/shared/utils/keyboard_utils.ts +5 -2
  40. package/shared/utils/table_utils.ts +52 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @gradio/dataframe
2
2
 
3
+ ## 0.18.1
4
+
5
+ ### Fixes
6
+
7
+ - [#11436](https://github.com/gradio-app/gradio/pull/11436) [`f49b8da`](https://github.com/gradio-app/gradio/commit/f49b8da1c062dbd81acb8e7fdcdc9a09a272d02f) - Multi-Line DataFrame Editing. Thanks @deckar01!
8
+
9
+ ### Dependency updates
10
+
11
+ - @gradio/atoms@0.16.3
12
+ - @gradio/statustracker@0.10.14
13
+ - @gradio/upload@0.16.10
14
+ - @gradio/client@1.15.5
15
+ - @gradio/markdown-code@0.5.0
16
+ - @gradio/button@0.5.6
17
+ - @gradio/checkbox@0.4.25
18
+
19
+ ## 0.18.0
20
+
21
+ ### Features
22
+
23
+ - [#11392](https://github.com/gradio-app/gradio/pull/11392) [`dc760a6`](https://github.com/gradio-app/gradio/commit/dc760a6dd7d3375f99913059803a826cdf0f7102) - Add column-specific filtering to `gr.Dataframe`. Thanks @tiago-gsantos!
24
+
25
+ ### Fixes
26
+
27
+ - [#11407](https://github.com/gradio-app/gradio/pull/11407) [`f3f9590`](https://github.com/gradio-app/gradio/commit/f3f9590d539b9e6fe3937a1bdc48006ee174fb8f) - Fix Styled DataFrame Sorting. Thanks @deckar01!
28
+
29
+ ### Dependency updates
30
+
31
+ - @gradio/upload@0.16.9
32
+ - @gradio/client@1.15.4
33
+ - @gradio/button@0.5.5
34
+
3
35
  ## 0.17.17
4
36
 
5
37
  ### Fixes
@@ -111,12 +111,11 @@
111
111
  const canvas = within(canvasElement);
112
112
  const cells = canvas.getAllByRole("cell");
113
113
  const initial_value = cells[0].textContent;
114
-
115
114
  await userEvent.click(cells[0]);
116
115
  await userEvent.keyboard("new value");
117
116
 
118
117
  const final_value = cells[0].textContent;
119
- if (initial_value !== final_value) {
118
+ if (initial_value?.trim() !== final_value?.trim()) {
120
119
  throw new Error("Cell content changed when it should be non-editable");
121
120
  }
122
121
 
package/Index.svelte CHANGED
@@ -14,7 +14,6 @@
14
14
  import type { Headers, Datatype, DataframeValue } from "./shared/utils";
15
15
  import Image from "@gradio/image";
16
16
 
17
- export let headers: Headers = [];
18
17
  export let elem_id = "";
19
18
  export let elem_classes: string[] = [];
20
19
  export let visible = true;
@@ -59,15 +58,6 @@
59
58
  export let pinned_columns = 0;
60
59
  export let static_columns: (string | number)[] = [];
61
60
  export let fullscreen = false;
62
-
63
- $: _headers = [...(value.headers || headers)];
64
- $: display_value = value?.metadata?.display_value
65
- ? [...value?.metadata?.display_value]
66
- : null;
67
- $: styling =
68
- !interactive && value?.metadata?.styling
69
- ? [...value?.metadata?.styling]
70
- : null;
71
61
  </script>
72
62
 
73
63
  <Block
@@ -94,9 +84,9 @@
94
84
  {row_count}
95
85
  {col_count}
96
86
  values={value.data}
97
- {display_value}
98
- {styling}
99
- headers={_headers}
87
+ display_value={value.metadata?.display_value}
88
+ styling={value.metadata?.styling}
89
+ headers={value.headers}
100
90
  {fullscreen}
101
91
  on:change={(e) => {
102
92
  value.data = e.detail.data;
package/dist/Index.svelte CHANGED
@@ -8,7 +8,6 @@ export { default as BaseExample } from "./Example.svelte";
8
8
  import Table from "./shared/Table.svelte";
9
9
  import { StatusTracker } from "@gradio/statustracker";
10
10
  import Image from "@gradio/image";
11
- export let headers = [];
12
11
  export let elem_id = "";
13
12
  export let elem_classes = [];
14
13
  export let visible = true;
@@ -42,12 +41,6 @@ export let show_search = "none";
42
41
  export let pinned_columns = 0;
43
42
  export let static_columns = [];
44
43
  export let fullscreen = false;
45
- $:
46
- _headers = [...value.headers || headers];
47
- $:
48
- display_value = value?.metadata?.display_value ? [...value?.metadata?.display_value] : null;
49
- $:
50
- styling = !interactive && value?.metadata?.styling ? [...value?.metadata?.styling] : null;
51
44
  </script>
52
45
 
53
46
  <Block
@@ -74,9 +67,9 @@ $:
74
67
  {row_count}
75
68
  {col_count}
76
69
  values={value.data}
77
- {display_value}
78
- {styling}
79
- headers={_headers}
70
+ display_value={value.metadata?.display_value}
71
+ styling={value.metadata?.styling}
72
+ headers={value.headers}
80
73
  {fullscreen}
81
74
  on:change={(e) => {
82
75
  value.data = e.detail.data;
@@ -3,10 +3,9 @@ export { default as BaseDataFrame } from "./shared/Table.svelte";
3
3
  export { default as BaseExample } from "./Example.svelte";
4
4
  import type { Gradio, SelectData } from "@gradio/utils";
5
5
  import type { LoadingStatus } from "@gradio/statustracker";
6
- import type { Headers, Datatype, DataframeValue } from "./shared/utils";
6
+ import type { Datatype, DataframeValue } from "./shared/utils";
7
7
  declare const __propDef: {
8
8
  props: {
9
- headers?: Headers | undefined;
10
9
  elem_id?: string | undefined;
11
10
  elem_classes?: string[] | undefined;
12
11
  visible?: boolean | undefined;
@@ -56,9 +55,6 @@ export type IndexProps = typeof __propDef.props;
56
55
  export type IndexEvents = typeof __propDef.events;
57
56
  export type IndexSlots = typeof __propDef.slots;
58
57
  export default class Index extends SvelteComponent<IndexProps, IndexEvents, IndexSlots> {
59
- get headers(): Headers | undefined;
60
- /**accessor*/
61
- set headers(_: Headers | undefined);
62
58
  get elem_id(): string | undefined;
63
59
  /**accessor*/
64
60
  set elem_id(_: string | undefined);
@@ -1,5 +1,6 @@
1
1
  <script>import { onMount } from "svelte";
2
2
  import CellMenuIcons from "./CellMenuIcons.svelte";
3
+ import FilterMenu from "./FilterMenu.svelte";
3
4
  export let x;
4
5
  export let y;
5
6
  export let on_add_row_above;
@@ -19,9 +20,15 @@ export let on_clear_sort = () => {
19
20
  };
20
21
  export let sort_direction = null;
21
22
  export let sort_priority = null;
23
+ export let on_filter = () => {
24
+ };
25
+ export let on_clear_filter = () => {
26
+ };
27
+ export let filter_active = null;
22
28
  export let editable = true;
23
29
  export let i18n;
24
30
  let menu_element;
31
+ let active_filter_menu = null;
25
32
  $:
26
33
  is_header = row === -1;
27
34
  $:
@@ -48,6 +55,17 @@ function position_menu() {
48
55
  menu_element.style.left = `${new_x}px`;
49
56
  menu_element.style.top = `${new_y}px`;
50
57
  }
58
+ function toggle_filter_menu() {
59
+ if (filter_active) {
60
+ on_filter("string", "", "");
61
+ return;
62
+ }
63
+ const menu_rect = menu_element.getBoundingClientRect();
64
+ active_filter_menu = {
65
+ x: menu_rect.right,
66
+ y: menu_rect.top + menu_rect.height / 2
67
+ };
68
+ }
51
69
  </script>
52
70
 
53
71
  <div bind:this={menu_element} class="cell-menu" role="menu">
@@ -78,6 +96,21 @@ function position_menu() {
78
96
  <CellMenuIcons icon="clear-sort" />
79
97
  {i18n("dataframe.clear_sort")}
80
98
  </button>
99
+ <button
100
+ role="menuitem"
101
+ on:click|stopPropagation={toggle_filter_menu}
102
+ class:active={filter_active || active_filter_menu}
103
+ >
104
+ <CellMenuIcons icon="filter" />
105
+ {i18n("dataframe.filter")}
106
+ {#if filter_active}
107
+ <span class="priority">1</span>
108
+ {/if}
109
+ </button>
110
+ <button role="menuitem" on:click={on_clear_filter}>
111
+ <CellMenuIcons icon="clear-filter" />
112
+ {i18n("dataframe.clear_filter")}
113
+ </button>
81
114
  {/if}
82
115
 
83
116
  {#if !is_header && can_add_rows}
@@ -140,6 +173,10 @@ function position_menu() {
140
173
  {/if}
141
174
  </div>
142
175
 
176
+ {#if active_filter_menu}
177
+ <FilterMenu {on_filter} />
178
+ {/if}
179
+
143
180
  <style>
144
181
  .cell-menu {
145
182
  position: fixed;
@@ -1,6 +1,6 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  import type { I18nFormatter } from "js/utils/src";
3
- import type { SortDirection } from "./context/dataframe_context";
3
+ import type { SortDirection, FilterDatatype } from "./context/dataframe_context";
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  x: number;
@@ -20,6 +20,9 @@ declare const __propDef: {
20
20
  on_clear_sort?: (() => void) | undefined;
21
21
  sort_direction?: (SortDirection | null) | undefined;
22
22
  sort_priority?: (number | null) | undefined;
23
+ on_filter?: ((datatype: FilterDatatype, selected_filter: string, value: string) => void) | undefined;
24
+ on_clear_filter?: (() => void) | undefined;
25
+ filter_active?: (boolean | null) | undefined;
23
26
  editable?: boolean | undefined;
24
27
  i18n: I18nFormatter;
25
28
  };
@@ -188,4 +188,52 @@
188
188
  stroke-linecap="round"
189
189
  />
190
190
  </svg>
191
+ {:else if icon == "filter"}
192
+ <svg viewBox="0 0 24 24" width="16" height="16">
193
+ <path
194
+ d="M5 5H19"
195
+ stroke="currentColor"
196
+ stroke-width="2"
197
+ stroke-linecap="round"
198
+ />
199
+ <path
200
+ d="M8 9H16"
201
+ stroke="currentColor"
202
+ stroke-width="2"
203
+ stroke-linecap="round"
204
+ />
205
+ <path
206
+ d="M11 13H13"
207
+ stroke="currentColor"
208
+ stroke-width="2"
209
+ stroke-linecap="round"
210
+ />
211
+ </svg>
212
+ {:else if icon == "clear-filter"}
213
+ <svg viewBox="0 0 24 24" width="16" height="16">
214
+ <path
215
+ d="M5 5H19"
216
+ stroke="currentColor"
217
+ stroke-width="2"
218
+ stroke-linecap="round"
219
+ />
220
+ <path
221
+ d="M8 9H16"
222
+ stroke="currentColor"
223
+ stroke-width="2"
224
+ stroke-linecap="round"
225
+ />
226
+ <path
227
+ d="M11 13H13"
228
+ stroke="currentColor"
229
+ stroke-width="2"
230
+ stroke-linecap="round"
231
+ />
232
+ <path
233
+ d="M17 17L21 21M21 17L17 21"
234
+ stroke="currentColor"
235
+ stroke-width="2"
236
+ stroke-linecap="round"
237
+ />
238
+ </svg>
191
239
  {/if}
@@ -23,7 +23,6 @@ export let on_select_column = null;
23
23
  export let on_select_row = null;
24
24
  export let el;
25
25
  const dispatch = createEventDispatcher();
26
- let is_expanded = false;
27
26
  function truncate_text(text, max_length = null, is_image = false) {
28
27
  if (is_image)
29
28
  return String(text);
@@ -35,7 +34,7 @@ function truncate_text(text, max_length = null, is_image = false) {
35
34
  return str.slice(0, max_length) + "...";
36
35
  }
37
36
  $:
38
- should_truncate = !edit && !is_expanded && max_chars !== null && max_chars > 0;
37
+ should_truncate = !edit && max_chars !== null && max_chars > 0;
39
38
  $:
40
39
  display_content = editable ? value : display_value !== null ? display_value : value;
41
40
  $:
@@ -53,18 +52,8 @@ function handle_blur(event) {
53
52
  });
54
53
  }
55
54
  function handle_keydown(event) {
56
- if (event.key === "Enter") {
57
- if (!header) {
58
- is_expanded = !is_expanded;
59
- }
60
- }
61
55
  dispatch("keydown", event);
62
56
  }
63
- function handle_click() {
64
- if (!edit && !header) {
65
- is_expanded = !is_expanded;
66
- }
67
- }
68
57
  function handle_bool_change(new_value) {
69
58
  value = new_value.toString();
70
59
  dispatch("blur", {
@@ -81,10 +70,9 @@ function handle_bool_change(new_value) {
81
70
  </script>
82
71
 
83
72
  {#if edit && datatype !== "bool"}
84
- <input
73
+ <textarea
85
74
  readonly={is_static}
86
75
  aria-readonly={is_static}
87
- role="textbox"
88
76
  aria-label={is_static ? "Cell is read-only" : "Edit cell"}
89
77
  bind:this={el}
90
78
  bind:value
@@ -92,7 +80,6 @@ function handle_bool_change(new_value) {
92
80
  tabindex="-1"
93
81
  on:blur={handle_blur}
94
82
  on:mousedown|stopPropagation
95
- on:mouseup|stopPropagation
96
83
  on:click|stopPropagation
97
84
  use:use_focus
98
85
  on:keydown={handle_keydown}
@@ -108,18 +95,17 @@ function handle_bool_change(new_value) {
108
95
  {:else}
109
96
  <span
110
97
  class:dragging={is_dragging}
111
- on:click={handle_click}
112
98
  on:keydown={handle_keydown}
113
99
  tabindex="0"
114
100
  role="button"
115
101
  class:edit
116
- class:expanded={is_expanded}
102
+ class:expanded={edit}
117
103
  class:multiline={header}
118
104
  on:focus|preventDefault
119
105
  style={styling}
120
106
  data-editable={editable}
121
107
  data-max-chars={max_chars}
122
- data-expanded={is_expanded}
108
+ data-expanded={edit}
123
109
  placeholder=" "
124
110
  class:text={datatype === "str"}
125
111
  class:wrap={wrap_text}
@@ -167,7 +153,7 @@ function handle_bool_change(new_value) {
167
153
  cursor: crosshair !important;
168
154
  }
169
155
 
170
- input {
156
+ textarea {
171
157
  position: absolute;
172
158
  flex: 1 1 0%;
173
159
  transform: translateX(-0.1px);
@@ -176,6 +162,16 @@ function handle_bool_change(new_value) {
176
162
  background: transparent;
177
163
  cursor: text;
178
164
  width: calc(100% - var(--size-2));
165
+ resize: none;
166
+ height: 100%;
167
+ padding-left: 0;
168
+ font-size: inherit;
169
+ font-weight: inherit;
170
+ line-height: var(--line-lg);
171
+ }
172
+
173
+ textarea:focus {
174
+ outline: none;
179
175
  }
180
176
 
181
177
  span {
@@ -227,7 +223,7 @@ function handle_bool_change(new_value) {
227
223
  object-fit: contain;
228
224
  }
229
225
 
230
- input:read-only {
226
+ textarea:read-only {
231
227
  cursor: not-allowed;
232
228
  }
233
229
 
@@ -25,11 +25,10 @@ declare const __propDef: {
25
25
  coords: [number, number];
26
26
  on_select_column?: (((col: number) => void) | null) | undefined;
27
27
  on_select_row?: (((row: number) => void) | null) | undefined;
28
- el: HTMLInputElement | null;
28
+ el: HTMLTextAreaElement | null;
29
29
  };
30
30
  events: {
31
31
  mousedown: MouseEvent;
32
- mouseup: MouseEvent;
33
32
  click: MouseEvent;
34
33
  focus: FocusEvent;
35
34
  blur: CustomEvent<{
@@ -0,0 +1,235 @@
1
+ <script>import { onMount } from "svelte";
2
+ import { Check } from "@gradio/icons";
3
+ import DropdownArrow from "../../icons/src/DropdownArrow.svelte";
4
+ export let on_filter = () => {
5
+ };
6
+ let menu_element;
7
+ let datatype = "string";
8
+ let current_filter = "Contains";
9
+ let filter_dropdown_open = false;
10
+ let filter_input_value = "";
11
+ const filter_options = {
12
+ string: [
13
+ "Contains",
14
+ "Does not contain",
15
+ "Starts with",
16
+ "Ends with",
17
+ "Is",
18
+ "Is not",
19
+ "Is empty",
20
+ "Is not empty"
21
+ ],
22
+ number: ["=", "\u2260", ">", "<", "\u2265", "\u2264", "Is empty", "Is not empty"]
23
+ };
24
+ onMount(() => {
25
+ position_menu();
26
+ });
27
+ function position_menu() {
28
+ if (!menu_element)
29
+ return;
30
+ const viewport_width = window.innerWidth;
31
+ const viewport_height = window.innerHeight;
32
+ const menu_rect = menu_element.getBoundingClientRect();
33
+ const x = (viewport_width - menu_rect.width) / 2;
34
+ const y = (viewport_height - menu_rect.height) / 2;
35
+ menu_element.style.left = `${x}px`;
36
+ menu_element.style.top = `${y}px`;
37
+ }
38
+ function handle_filter_input(e) {
39
+ const target = e.target;
40
+ filter_input_value = target.value;
41
+ }
42
+ </script>
43
+
44
+ <div>
45
+ <div class="background"></div>
46
+ <div bind:this={menu_element} class="filter-menu">
47
+ <div class="filter-datatype-container">
48
+ <span>Filter as</span>
49
+ <button
50
+ on:click|stopPropagation={() => {
51
+ datatype = datatype === "string" ? "number" : "string";
52
+ current_filter = filter_options[datatype][0];
53
+ }}
54
+ aria-label={`Change filter type. Filtering ${datatype}s`}
55
+ >
56
+ {datatype}
57
+ </button>
58
+ </div>
59
+
60
+ <div class="input-container">
61
+ <div class="filter-dropdown">
62
+ <button
63
+ on:click|stopPropagation={() =>
64
+ (filter_dropdown_open = !filter_dropdown_open)}
65
+ aria-label={`Change filter. Using '${current_filter}'`}
66
+ >
67
+ {current_filter}
68
+ <DropdownArrow />
69
+ </button>
70
+
71
+ {#if filter_dropdown_open}
72
+ <div class="dropdown-filter-options">
73
+ {#each filter_options[datatype] as opt}
74
+ <button
75
+ on:click|stopPropagation={() => {
76
+ current_filter = opt;
77
+ filter_dropdown_open = !filter_dropdown_open;
78
+ }}
79
+ class="filter-option"
80
+ >
81
+ {opt}
82
+ </button>
83
+ {/each}
84
+ </div>
85
+ {/if}
86
+ </div>
87
+
88
+ <input
89
+ type="text"
90
+ value={filter_input_value}
91
+ on:click|stopPropagation
92
+ on:input={handle_filter_input}
93
+ placeholder="Type a value"
94
+ class="filter-input"
95
+ />
96
+ </div>
97
+
98
+ <button
99
+ class="check-button"
100
+ on:click={() => on_filter(datatype, current_filter, filter_input_value)}
101
+ >
102
+ <Check />
103
+ </button>
104
+ </div>
105
+ </div>
106
+
107
+ <style>
108
+ .background {
109
+ position: fixed;
110
+ top: 0;
111
+ left: 0;
112
+ width: 100vw;
113
+ height: 100vh;
114
+ background-color: rgba(0, 0, 0, 0.4);
115
+ z-index: 20;
116
+ }
117
+
118
+ .filter-menu {
119
+ position: fixed;
120
+ background: var(--background-fill-primary);
121
+ border: 1px solid var(--border-color-primary);
122
+ border-radius: var(--radius-sm);
123
+ padding: var(--size-2);
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: var(--size-2);
127
+ box-shadow: var(--shadow-drop-lg);
128
+ width: 300px;
129
+ z-index: 21;
130
+ }
131
+
132
+ .filter-datatype-container {
133
+ display: flex;
134
+ gap: var(--size-2);
135
+ align-items: center;
136
+ }
137
+
138
+ .filter-menu span {
139
+ font-size: var(--text-sm);
140
+ color: var(--body-text-color);
141
+ }
142
+
143
+ .filter-menu button {
144
+ height: var(--size-6);
145
+ background: none;
146
+ border: 1px solid var(--border-color-primary);
147
+ border-radius: var(--radius-sm);
148
+ padding: var(--size-1) var(--size-2);
149
+ color: var(--body-text-color);
150
+ font-size: var(--text-sm);
151
+ cursor: pointer;
152
+ display: flex;
153
+ align-items: center;
154
+ justify-content: center;
155
+ gap: var(--size-2);
156
+ }
157
+
158
+ .filter-menu button:hover {
159
+ background-color: var(--background-fill-secondary);
160
+ }
161
+
162
+ .filter-input {
163
+ width: var(--size-full);
164
+ height: var(--size-6);
165
+ padding: var(--size-2);
166
+ padding-right: var(--size-8);
167
+ border: 1px solid var(--border-color-primary);
168
+ border-radius: var(--table-radius);
169
+ font-size: var(--text-sm);
170
+ color: var(--body-text-color);
171
+ background: var(--background-fill-secondary);
172
+ transition: all 0.2s ease;
173
+ }
174
+
175
+ .filter-input:hover {
176
+ border-color: var(--border-color-secondary);
177
+ background: var(--background-fill-primary);
178
+ }
179
+
180
+ .filter-input:focus {
181
+ outline: none;
182
+ border-color: var(--color-accent);
183
+ background: var(--background-fill-primary);
184
+ box-shadow: 0 0 0 1px var(--color-accent);
185
+ }
186
+
187
+ .dropdown-filter-options {
188
+ display: flex;
189
+ flex-direction: column;
190
+ background: var(--background-fill-primary);
191
+ border: 1px solid var(--border-color-primary);
192
+ border-radius: var(--radius-sm);
193
+ box-shadow: var(--shadow-drop-md);
194
+ position: absolute;
195
+ z-index: var(--layer-1);
196
+ }
197
+
198
+ .dropdown-filter-options .filter-option {
199
+ border: none;
200
+ justify-content: flex-start;
201
+ }
202
+
203
+ .input-container {
204
+ display: flex;
205
+ gap: var(--size-2);
206
+ align-items: center;
207
+ }
208
+
209
+ .input-container button {
210
+ width: 130px;
211
+ }
212
+
213
+ :global(svg.dropdown-arrow) {
214
+ width: var(--size-4);
215
+ height: var(--size-4);
216
+ margin-left: auto;
217
+ }
218
+
219
+ .filter-menu .check-button {
220
+ background: var(--color-accent);
221
+ color: white;
222
+ border: none;
223
+ width: var(--size-full);
224
+ height: var(--size-6);
225
+ border-radius: var(--radius-sm);
226
+ display: flex;
227
+ align-items: center;
228
+ justify-content: center;
229
+ padding: var(--size-1);
230
+ }
231
+
232
+ .check-button:hover {
233
+ background: var(--color-accent-soft);
234
+ }
235
+ </style>
@@ -0,0 +1,19 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { FilterDatatype } from "./context/dataframe_context";
3
+ declare const __propDef: {
4
+ props: {
5
+ on_filter?: ((datatype: FilterDatatype, selected_filter: string, value: string) => void) | undefined;
6
+ };
7
+ events: {
8
+ click: MouseEvent;
9
+ } & {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {};
13
+ };
14
+ export type FilterMenuProps = typeof __propDef.props;
15
+ export type FilterMenuEvents = typeof __propDef.events;
16
+ export type FilterMenuSlots = typeof __propDef.slots;
17
+ export default class FilterMenu extends SvelteComponent<FilterMenuProps, FilterMenuEvents, FilterMenuSlots> {
18
+ }
19
+ export {};