|
1 | 1 | <script lang="ts"> |
2 | 2 | import { onMount, tick } from 'svelte'; |
3 | | - import { writable } from 'svelte/store'; |
| 3 | + import { derived, readable, writable } from 'svelte/store'; |
4 | 4 |
|
5 | 5 | import { |
6 | 6 | type ClipboardHandler, |
7 | 7 | getClipboardHandlerStoreFromContext, |
8 | 8 | } from '@mathesar/stores/clipboard'; |
9 | 9 | import { getModifierKeyCombo } from '@mathesar/utils/pointerUtils'; |
10 | 10 | import type { ClientPosition } from '@mathesar-component-library'; |
11 | | - import { ImmutableMap } from '@mathesar-component-library/types'; |
| 11 | + import { |
| 12 | + ImmutableMap, |
| 13 | + ImmutableSet, |
| 14 | + defined, |
| 15 | + } from '@mathesar-component-library/types'; |
12 | 16 |
|
13 | 17 | import { |
14 | 18 | type SheetCellDetails, |
|
51 | 55 |
|
52 | 56 | export let sheetElement: HTMLElement | undefined = undefined; |
53 | 57 |
|
| 58 | + /** [columnId, width] pairs to persist to the database. */ |
| 59 | + export let persistColumnWidths: ( |
| 60 | + widthsMap: [string, number | null][], |
| 61 | + ) => void = () => {}; |
| 62 | +
|
54 | 63 | interface SheetContextMenuCallbackArgs { |
55 | 64 | targetCell: SheetCellDetails; |
56 | 65 | position: ClientPosition; |
|
61 | 70 | | ((p: SheetContextMenuCallbackArgs) => 'opened' | 'empty') |
62 | 71 | | undefined = undefined; |
63 | 72 |
|
| 73 | + $: fullySelectedColumnIds = |
| 74 | + defined(selection, (s) => derived(s, (v) => v.fullySelectedColumnIds)) ?? |
| 75 | + readable(new ImmutableSet<string>()); |
| 76 | +
|
| 77 | + /** |
| 78 | + * Returns a mapping of column ids to widths so that the user can resize |
| 79 | + * multiple columns via a single column resizer. If the given column id is |
| 80 | + * part of the selection, this returns a mapping for all selected columns. |
| 81 | + * Otherwise, it just uses the given column id. |
| 82 | + */ |
| 83 | + function getSmartColumnWidthsMap( |
| 84 | + columnId: string, |
| 85 | + width: number | null, |
| 86 | + ): [string, number | null][] { |
| 87 | + return $fullySelectedColumnIds.has(columnId) |
| 88 | + ? [...$fullySelectedColumnIds].map((id) => [id, width]) |
| 89 | + : [[columnId, width]]; |
| 90 | + } |
| 91 | +
|
64 | 92 | $: ({ columnStyleMap, rowWidth } = calculateColumnStyleMapAndRowWidth( |
65 | 93 | columns, |
66 | 94 | getColumnIdentifier, |
|
89 | 117 | stores, |
90 | 118 | api: { |
91 | 119 | getColumnWidth: (id) => normalizeColumnWidth(columnWidths.get(id)), |
92 | | - setColumnWidth: (key, width) => { |
93 | | - columnWidths = columnWidths.with(key, width); |
| 120 | + handleDraggingColumnWidth: (id, width) => { |
| 121 | + const widthsMap = getSmartColumnWidthsMap(id, width); |
| 122 | + columnWidths = widthsMap.reduce( |
| 123 | + (newColumnWidths, [columnId, newWidth]) => |
| 124 | + newWidth === null |
| 125 | + ? newColumnWidths.without(columnId) |
| 126 | + : newColumnWidths.with(columnId, newWidth), |
| 127 | + columnWidths, |
| 128 | + ); |
94 | 129 | }, |
95 | | - resetColumnWidth: (key) => { |
96 | | - columnWidths = columnWidths.without(key); |
| 130 | + handleReleaseColumnWidth: (id, width) => { |
| 131 | + persistColumnWidths(getSmartColumnWidthsMap(id, width)); |
97 | 132 | }, |
98 | 133 | setHorizontalScrollOffset: (offset) => { |
99 | 134 | horizontalScrollOffset = offset; |
|
0 commit comments