mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 13:28:12 +08:00
Fix Eyedropper tool and make Svelte's bind:this more robust
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
export let icon: IconName = "Checkmark";
|
||||
export let tooltip: string | undefined = undefined;
|
||||
|
||||
let inputElement: HTMLInputElement;
|
||||
let inputElement: HTMLInputElement | undefined;
|
||||
|
||||
let id = `${Math.random()}`.substring(2);
|
||||
|
||||
$: displayIcon = (!checked && icon === "Checkmark" ? "Empty12px" : icon) as IconName;
|
||||
@@ -23,7 +24,7 @@
|
||||
return checked;
|
||||
}
|
||||
|
||||
export function input(): HTMLInputElement {
|
||||
export function input(): HTMLInputElement | undefined {
|
||||
return inputElement;
|
||||
}
|
||||
|
||||
@@ -35,7 +36,7 @@
|
||||
</script>
|
||||
|
||||
<LayoutRow class="checkbox-input">
|
||||
<input type="checkbox" id={`checkbox-input-${id}`} {checked} on:change={(e) => dispatch("checked", inputElement.checked)} {disabled} tabindex={disabled ? -1 : 0} bind:this={inputElement} />
|
||||
<input type="checkbox" id={`checkbox-input-${id}`} {checked} on:change={(e) => dispatch("checked", inputElement?.checked)} {disabled} tabindex={disabled ? -1 : 0} bind:this={inputElement} />
|
||||
<label class:disabled class:checked for={`checkbox-input-${id}`} on:keydown={(e) => e.key === "Enter" && toggleCheckboxFromLabel(e)} title={tooltip}>
|
||||
<LayoutRow class="checkbox-box">
|
||||
<IconLabel icon={displayIcon} />
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// emits: ["update:selectedIndex"],
|
||||
const dispatch = createEventDispatcher<{ selectedIndex: number }>();
|
||||
|
||||
let menuList: MenuList;
|
||||
let self: LayoutRow;
|
||||
let menuList: MenuList | undefined;
|
||||
let self: LayoutRow | undefined;
|
||||
|
||||
export let entries: MenuListEntry[][];
|
||||
export let selectedIndex: number | undefined = undefined; // When not provided, a dash is displayed
|
||||
@@ -57,8 +57,8 @@
|
||||
}
|
||||
|
||||
function unFocusDropdownBox(e: FocusEvent) {
|
||||
const blurTarget = (e.target as HTMLDivElement | undefined)?.closest("[data-dropdown-input]");
|
||||
if (blurTarget !== self.div()) open = false;
|
||||
const blurTarget = (e.target as HTMLDivElement | undefined)?.closest("[data-dropdown-input]") || undefined;
|
||||
if (blurTarget !== self?.div()) open = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
{tooltip}
|
||||
on:click={() => !disabled && (open = true)}
|
||||
on:blur={unFocusDropdownBox}
|
||||
on:keydown={(e) => menuList.keydown(e, false)}
|
||||
on:keydown={(e) => menuList?.keydown(e, false)}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
data-floating-menu-spawner
|
||||
>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
export let sharpRightCorners = false;
|
||||
export let placeholder: string | undefined = undefined;
|
||||
|
||||
let inputOrTextarea: HTMLInputElement | HTMLTextAreaElement;
|
||||
let inputOrTextarea: HTMLInputElement | HTMLTextAreaElement | undefined;
|
||||
let id = `${Math.random()}`.substring(2);
|
||||
let macKeyboardLayout = platformIsMac();
|
||||
|
||||
@@ -37,28 +37,32 @@
|
||||
|
||||
// Select (highlight) all the text. For technical reasons, it is necessary to pass the current text.
|
||||
export function selectAllText(currentText: string) {
|
||||
if (!inputOrTextarea) return;
|
||||
|
||||
// Setting the value directly is required to make the following `select()` call work
|
||||
inputOrTextarea.value = currentText;
|
||||
inputOrTextarea.select();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
inputOrTextarea.focus();
|
||||
inputOrTextarea?.focus();
|
||||
}
|
||||
|
||||
export function unFocus() {
|
||||
inputOrTextarea.blur();
|
||||
inputOrTextarea?.blur();
|
||||
}
|
||||
|
||||
export function getValue(): string {
|
||||
return inputOrTextarea.value;
|
||||
return inputOrTextarea?.value || "";
|
||||
}
|
||||
|
||||
export function setInputElementValue(value: string) {
|
||||
if (!inputOrTextarea) return;
|
||||
|
||||
inputOrTextarea.value = value;
|
||||
}
|
||||
|
||||
export function element(): HTMLInputElement | HTMLTextAreaElement {
|
||||
export function element(): HTMLInputElement | HTMLTextAreaElement | undefined {
|
||||
return inputOrTextarea;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
changeFont: { fontFamily: string; fontStyle: string; fontFileUrl: string | undefined };
|
||||
}>();
|
||||
|
||||
let menuList: MenuList;
|
||||
let menuList: MenuList | undefined;
|
||||
|
||||
export let fontFamily: string;
|
||||
export let fontStyle: string;
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
if (activeEntry) {
|
||||
const index = entries.indexOf(activeEntry);
|
||||
menuList.scrollViewTo(Math.max(0, index * 20 - 190));
|
||||
menuList?.scrollViewTo(Math.max(0, index * 20 - 190));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
{tooltip}
|
||||
tabindex={disabled ? -1 : 0}
|
||||
on:click={toggleOpen}
|
||||
on:keydown={(e) => menuList.keydown(e, false)}
|
||||
on:keydown={(e) => menuList?.keydown(e, false)}
|
||||
data-floating-menu-spawner
|
||||
>
|
||||
<TextLabel class="dropdown-label">{activeEntry?.value || ""}</TextLabel>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
export let incrementCallbackIncrease: (() => void) | undefined = undefined;
|
||||
export let incrementCallbackDecrease: (() => void) | undefined = undefined;
|
||||
|
||||
let self: FieldInput;
|
||||
let self: FieldInput | undefined;
|
||||
let text = displayText(value, displayDecimalPlaces, unit);
|
||||
let editing = false;
|
||||
// Stays in sync with a binding to the actual input range slider element.
|
||||
@@ -130,7 +130,7 @@
|
||||
function onSliderPointerUp() {
|
||||
// User clicked but didn't drag, so we focus the text input element
|
||||
if (rangeSliderClickDragState === "mousedown") {
|
||||
const inputElement = self.element().querySelector("[data-input-element]") as HTMLInputElement | undefined;
|
||||
const inputElement = self?.element()?.querySelector("[data-input-element]") as HTMLInputElement | undefined;
|
||||
if (!inputElement) return;
|
||||
|
||||
// Set the slider position back to the original position to undo the user moving it
|
||||
@@ -151,7 +151,7 @@
|
||||
|
||||
editing = true;
|
||||
|
||||
self.selectAllText(text);
|
||||
self?.selectAllText(text);
|
||||
}
|
||||
|
||||
// Called only when `value` is changed from the <input> element via user input and committed, either with the
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||
editing = false;
|
||||
|
||||
self.unFocus();
|
||||
self?.unFocus();
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
@@ -175,7 +175,7 @@
|
||||
|
||||
editing = false;
|
||||
|
||||
self.unFocus();
|
||||
self?.unFocus();
|
||||
}
|
||||
|
||||
function onIncrement(direction: "Decrease" | "Increase") {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
export let tooltip: string | undefined = undefined;
|
||||
export let disabled = false;
|
||||
|
||||
let self: FieldInput;
|
||||
let self: FieldInput | undefined;
|
||||
let editing = false;
|
||||
|
||||
function onTextFocused() {
|
||||
@@ -27,20 +27,20 @@
|
||||
onCancelTextChange();
|
||||
|
||||
// TODO: Find a less hacky way to do this
|
||||
dispatch("commitText", self.getValue());
|
||||
if (self) dispatch("commitText", self.getValue());
|
||||
|
||||
// Required if value is not changed by the parent component upon update:value event
|
||||
self.setInputElementValue(value);
|
||||
self?.setInputElementValue(value);
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
editing = false;
|
||||
|
||||
self.unFocus();
|
||||
self?.unFocus();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
self.focus();
|
||||
self?.focus();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
export let minWidth = 0;
|
||||
export let sharpRightCorners = false;
|
||||
|
||||
let self: FieldInput;
|
||||
let self: FieldInput | undefined;
|
||||
let editing = false;
|
||||
|
||||
function onTextFocused() {
|
||||
editing = true;
|
||||
|
||||
self.selectAllText(value);
|
||||
self?.selectAllText(value);
|
||||
}
|
||||
|
||||
// Called only when `value` is changed from the <input> element via user input and committed, either with the
|
||||
@@ -37,20 +37,20 @@
|
||||
onCancelTextChange();
|
||||
|
||||
// TODO: Find a less hacky way to do this
|
||||
dispatch("commitText", self.getValue());
|
||||
if (self) dispatch("commitText", self.getValue());
|
||||
|
||||
// Required if value is not changed by the parent component upon update:value event
|
||||
self.setInputElementValue(value);
|
||||
self?.setInputElementValue(value);
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
editing = false;
|
||||
|
||||
self.unFocus();
|
||||
self?.unFocus();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
self.focus();
|
||||
self?.focus();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user