Compare commits
2 commits
b701270d88
...
c6ac79f1de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6ac79f1de | ||
|
|
d575c058ee |
3 changed files with 61 additions and 26 deletions
12
svelte/src/datum-editor-common.svelte.ts
Normal file
12
svelte/src/datum-editor-common.svelte.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Propagating blur events upwards from the `<DatumEditor>` component is
|
||||||
|
* debounced so that switching focus between elements does not cause spurious
|
||||||
|
* `on_blur()` calls.
|
||||||
|
*
|
||||||
|
* The `<TableViewer>` component must wait at least 1 tick longer than this
|
||||||
|
* before updating selections on cell click, or any updates to the previous
|
||||||
|
* selection may be applied to the new selection instead. (This approach is not
|
||||||
|
* technically airtight if click events are happening very quickly, but it's
|
||||||
|
* plenty close enough when we're working with a human user.)
|
||||||
|
*/
|
||||||
|
export const BLUR_DEBOUNCE_MS = 100;
|
||||||
|
|
@ -86,7 +86,7 @@ example within the `<TableViewer />` or `<ExpressionEditor />`.
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_blur(ev: FocusEvent) {
|
function handle_blur(ev: FocusEvent) {
|
||||||
// Propagating of blur events upwards is debounced, so that switching focus
|
// Propagating blur events upwards is debounced so that switching focus
|
||||||
// between elements does not cause spurious `on_blur()` calls.
|
// between elements does not cause spurious `on_blur()` calls.
|
||||||
if (blur_timeout !== undefined) {
|
if (blur_timeout !== undefined) {
|
||||||
clearTimeout(blur_timeout);
|
clearTimeout(blur_timeout);
|
||||||
|
|
@ -145,6 +145,17 @@ example within the `<TableViewer />` or `<ExpressionEditor />`.
|
||||||
// Cancel edit before blurring, or else the table will try to commit it.
|
// Cancel edit before blurring, or else the table will try to commit it.
|
||||||
on_cancel_edit?.();
|
on_cancel_edit?.();
|
||||||
on_restore_focus?.();
|
on_restore_focus?.();
|
||||||
|
} else if (ev.key === "Backspace") {
|
||||||
|
if (
|
||||||
|
editor_state &&
|
||||||
|
["Dropdown", "Numeric", "Text", "Uuid"].includes(
|
||||||
|
current_presentation.t ?? "",
|
||||||
|
) &&
|
||||||
|
editor_state.text_value === ""
|
||||||
|
) {
|
||||||
|
editor_state.is_null = !editor_state.is_null;
|
||||||
|
handle_input();
|
||||||
|
}
|
||||||
} else if (
|
} else if (
|
||||||
current_presentation.t === "Dropdown" &&
|
current_presentation.t === "Dropdown" &&
|
||||||
filtered_dropdown_options.length > 0
|
filtered_dropdown_options.length > 0
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
parse_datum_from_text,
|
parse_datum_from_text,
|
||||||
} from "./datum.svelte";
|
} from "./datum.svelte";
|
||||||
import DatumEditor from "./datum-editor.svelte";
|
import DatumEditor from "./datum-editor.svelte";
|
||||||
|
import { BLUR_DEBOUNCE_MS } from "./datum-editor-common.svelte";
|
||||||
import { type Row, type FieldInfo, field_info_schema } from "./field.svelte";
|
import { type Row, type FieldInfo, field_info_schema } from "./field.svelte";
|
||||||
import FieldAdder from "./field-adder.svelte";
|
import FieldAdder from "./field-adder.svelte";
|
||||||
import FieldHeader from "./field-header.svelte";
|
import FieldHeader from "./field-header.svelte";
|
||||||
|
|
@ -393,7 +394,7 @@
|
||||||
!ev.altKey &&
|
!ev.altKey &&
|
||||||
!ev.ctrlKey &&
|
!ev.ctrlKey &&
|
||||||
!ev.metaKey &&
|
!ev.metaKey &&
|
||||||
/^[a-zA-Z0-9`~!@#$%^&*()_=+[\]{}\\|;:'",<.>/?-]$/.test(ev.key)
|
/^([a-zA-Z0-9`~!@#$%^&*()_=+[\]{}\\|;:'",<.>/?-]|Backspace)$/.test(ev.key)
|
||||||
) {
|
) {
|
||||||
const sel = selections[0];
|
const sel = selections[0];
|
||||||
if (sel) {
|
if (sel) {
|
||||||
|
|
@ -401,6 +402,7 @@
|
||||||
lazy_data.fields[sel.coords.field_idx].field.presentation,
|
lazy_data.fields[sel.coords.field_idx].field.presentation,
|
||||||
);
|
);
|
||||||
datum_editor?.focus();
|
datum_editor?.focus();
|
||||||
|
try_sync_edit_to_cells();
|
||||||
}
|
}
|
||||||
} else if (ev.key === "Enter") {
|
} else if (ev.key === "Enter") {
|
||||||
if (ev.shiftKey) {
|
if (ev.shiftKey) {
|
||||||
|
|
@ -671,18 +673,23 @@
|
||||||
region: "main",
|
region: "main",
|
||||||
rows: lazy_data.rows,
|
rows: lazy_data.rows,
|
||||||
on_cell_click: (ev: MouseEvent, coords: Coords) => {
|
on_cell_click: (ev: MouseEvent, coords: Coords) => {
|
||||||
if (ev.metaKey || ev.ctrlKey) {
|
// Must wait out `BLUR_DEBOUNCE_MS` before switching selection to
|
||||||
set_selections([
|
// avoid committing updates to the wrong cells. Refer to docs for
|
||||||
coords,
|
// `BLUR_DEBOUNCE_MS`.
|
||||||
...selections
|
setTimeout(() => {
|
||||||
.filter((sel) => !coords_eq(sel.coords, coords))
|
if (ev.metaKey || ev.ctrlKey) {
|
||||||
.map((sel) => sel.coords),
|
set_selections([
|
||||||
]);
|
coords,
|
||||||
} else if (ev.shiftKey) {
|
...selections
|
||||||
move_cursor(coords, { additive: true });
|
.filter((sel) => !coords_eq(sel.coords, coords))
|
||||||
} else {
|
.map((sel) => sel.coords),
|
||||||
move_cursor(coords);
|
]);
|
||||||
}
|
} else if (ev.shiftKey) {
|
||||||
|
move_cursor(coords, { additive: true });
|
||||||
|
} else {
|
||||||
|
move_cursor(coords);
|
||||||
|
}
|
||||||
|
}, BLUR_DEBOUNCE_MS + 1);
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -704,18 +711,23 @@
|
||||||
region: "inserter",
|
region: "inserter",
|
||||||
rows: inserter_rows,
|
rows: inserter_rows,
|
||||||
on_cell_click: (ev: MouseEvent, coords: Coords) => {
|
on_cell_click: (ev: MouseEvent, coords: Coords) => {
|
||||||
if (ev.metaKey || ev.ctrlKey) {
|
// Must wait out `BLUR_DEBOUNCE_MS` before switching selection
|
||||||
set_selections([
|
// to avoid committing updates to the wrong cells. Refer to docs
|
||||||
coords,
|
// for `BLUR_DEBOUNCE_MS`.
|
||||||
...selections
|
setTimeout(() => {
|
||||||
.filter((sel) => !coords_eq(sel.coords, coords))
|
if (ev.metaKey || ev.ctrlKey) {
|
||||||
.map((sel) => sel.coords),
|
set_selections([
|
||||||
]);
|
coords,
|
||||||
} else if (ev.shiftKey) {
|
...selections
|
||||||
move_cursor(coords, { additive: true });
|
.filter((sel) => !coords_eq(sel.coords, coords))
|
||||||
} else {
|
.map((sel) => sel.coords),
|
||||||
move_cursor(coords);
|
]);
|
||||||
}
|
} else if (ev.shiftKey) {
|
||||||
|
move_cursor(coords, { additive: true });
|
||||||
|
} else {
|
||||||
|
move_cursor(coords);
|
||||||
|
}
|
||||||
|
}, BLUR_DEBOUNCE_MS + 1);
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue