mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-31 02:07:21 +00:00
Svelte: Fix calling DOM API functions on the actual elements
This commit is contained in:
parent
0019340096
commit
fb10e5194e
15 changed files with 162 additions and 96 deletions
|
@ -321,7 +321,6 @@ impl NodeGraphMessageHandler {
|
|||
disabled: network.disabled.contains(id),
|
||||
})
|
||||
}
|
||||
log::debug!("Frontend Nodes:\n{:#?}\n\nLinks:\n{:#?}", nodes, links);
|
||||
responses.push_back(FrontendMessage::UpdateNodeGraph { nodes, links }.into());
|
||||
}
|
||||
|
||||
|
@ -423,7 +422,6 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||
input_node,
|
||||
input_node_connector_index,
|
||||
} => {
|
||||
log::debug!("Connect primary output from node {output_node} to input of index {input_node_connector_index} on node {input_node}.");
|
||||
let node_id = input_node;
|
||||
|
||||
let Some(network) = self.get_active_network(document) else {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
const dialog = getContext<DialogState>("dialog");
|
||||
|
||||
let dialogModal: FloatingMenu;
|
||||
let self: FloatingMenu;
|
||||
|
||||
export function dismiss() {
|
||||
dialog.dismissDialog();
|
||||
|
@ -19,12 +19,12 @@
|
|||
|
||||
onMount(() => {
|
||||
// Focus the first button in the popup
|
||||
const emphasizedOrFirstButton = (dialogModal.div().querySelector("[data-emphasized]") || dialogModal.div().querySelector("[data-text-button]") || undefined) as HTMLButtonElement | undefined;
|
||||
const emphasizedOrFirstButton = (self.div().querySelector("[data-emphasized]") || self.div().querySelector("[data-text-button]") || undefined) as HTMLButtonElement | undefined;
|
||||
emphasizedOrFirstButton?.focus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<FloatingMenu open={true} class="dialog-modal" type="Dialog" direction="Center" bind:this={dialogModal} data-dialog-modal>
|
||||
<FloatingMenu open={true} class="dialog-modal" type="Dialog" direction="Center" bind:this={self} data-dialog-modal>
|
||||
<LayoutRow>
|
||||
<LayoutCol class="icon-column">
|
||||
<!-- `$dialog.icon` class exists to provide special sizing in CSS to specific icons -->
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import TextLabel from "@/components/widgets/labels/TextLabel.svelte";
|
||||
import UserInputLabel from "@/components/widgets/labels/UserInputLabel.svelte";
|
||||
|
||||
let floatingMenu: FloatingMenu;
|
||||
let self: FloatingMenu;
|
||||
let scroller: LayoutCol;
|
||||
|
||||
// emits: ["update:open", "update:activeEntry", "naturalWidth"],
|
||||
|
@ -35,8 +35,8 @@
|
|||
// Called only when `open` is changed from outside this component (with v-model)
|
||||
$: watchOpen(open);
|
||||
$: dispatch("open", isOpen);
|
||||
$: watchEntries(entries, floatingMenu);
|
||||
$: watchDrawIcon(drawIcon, floatingMenu);
|
||||
$: watchEntries(entries, self);
|
||||
$: watchDrawIcon(drawIcon, self);
|
||||
$: virtualScrollingTotalHeight = entries.length === 0 ? 0 : entries[0].length * virtualScrollingEntryHeight;
|
||||
$: virtualScrollingStartIndex = Math.floor(virtualScrollingEntriesStart / virtualScrollingEntryHeight) || 0;
|
||||
$: virtualScrollingEndIndex = entries.length === 0 ? 0 : Math.min(entries[0].length, virtualScrollingStartIndex + 1 + 400 / virtualScrollingEntryHeight);
|
||||
|
@ -48,12 +48,12 @@
|
|||
|
||||
// TODO: Svelte: fix infinite loop and reenable
|
||||
function watchEntries(_: MenuListEntry[][], floatingMenu: FloatingMenu) {
|
||||
// floatingMenu?.measureAndEmitNaturalWidth();
|
||||
// floatingMenu?.div().measureAndEmitNaturalWidth();
|
||||
}
|
||||
|
||||
// TODO: Svelte: fix infinite loop and reenable
|
||||
function watchDrawIcon(_: boolean, floatingMenu: FloatingMenu) {
|
||||
// floatingMenu?.measureAndEmitNaturalWidth();
|
||||
// floatingMenu?.div().measureAndEmitNaturalWidth();
|
||||
}
|
||||
|
||||
function onScroll(e: Event) {
|
||||
|
@ -198,7 +198,7 @@
|
|||
{direction}
|
||||
{minWidth}
|
||||
scrollableY={scrollableY && virtualScrollingEntryHeight === 0}
|
||||
bind:this={floatingMenu}
|
||||
bind:this={self}
|
||||
>
|
||||
<!-- If we put the scrollableY on the layoutcol for non-font dropdowns then for some reason it always creates a tiny scrollbar.
|
||||
However when we are using the virtual scrolling then we need the layoutcol to be scrolling so we can bind the events without using $refs. -->
|
||||
|
|
|
@ -132,10 +132,10 @@
|
|||
// Required to correctly position content when scrolled (it has a `position: fixed` to prevent clipping)
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
const tailOffset = type === "Popover" ? 10 : 0;
|
||||
if (direction === "Bottom") floatingMenuContent.style.top = `${tailOffset + floatingMenuBounds.top}px`;
|
||||
if (direction === "Top") floatingMenuContent.style.bottom = `${tailOffset + floatingMenuBounds.bottom}px`;
|
||||
if (direction === "Right") floatingMenuContent.style.left = `${tailOffset + floatingMenuBounds.left}px`;
|
||||
if (direction === "Left") floatingMenuContent.style.right = `${tailOffset + floatingMenuBounds.right}px`;
|
||||
if (direction === "Bottom") floatingMenuContent.div().style.top = `${tailOffset + floatingMenuBounds.top}px`;
|
||||
if (direction === "Top") floatingMenuContent.div().style.bottom = `${tailOffset + floatingMenuBounds.bottom}px`;
|
||||
if (direction === "Right") floatingMenuContent.div().style.left = `${tailOffset + floatingMenuBounds.left}px`;
|
||||
if (direction === "Left") floatingMenuContent.div().style.right = `${tailOffset + floatingMenuBounds.right}px`;
|
||||
|
||||
// Required to correctly position tail when scrolled (it has a `position: fixed` to prevent clipping)
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
|
@ -154,11 +154,11 @@
|
|||
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
if (floatingMenuContentBounds.left - windowEdgeMargin <= workspaceBounds.left) {
|
||||
floatingMenuContent.style.left = `${windowEdgeMargin}px`;
|
||||
floatingMenuContent.div().style.left = `${windowEdgeMargin}px`;
|
||||
if (workspaceBounds.left + floatingMenuContainerBounds.left === 12) zeroedBorderHorizontal = "Left";
|
||||
}
|
||||
if (floatingMenuContentBounds.right + windowEdgeMargin >= workspaceBounds.right) {
|
||||
floatingMenuContent.style.right = `${windowEdgeMargin}px`;
|
||||
floatingMenuContent.div().style.right = `${windowEdgeMargin}px`;
|
||||
if (workspaceBounds.right - floatingMenuContainerBounds.right === 12) zeroedBorderHorizontal = "Right";
|
||||
}
|
||||
}
|
||||
|
@ -167,11 +167,11 @@
|
|||
|
||||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
if (floatingMenuContentBounds.top - windowEdgeMargin <= workspaceBounds.top) {
|
||||
floatingMenuContent.style.top = `${windowEdgeMargin}px`;
|
||||
floatingMenuContent.div().style.top = `${windowEdgeMargin}px`;
|
||||
if (workspaceBounds.top + floatingMenuContainerBounds.top === 12) zeroedBorderVertical = "Top";
|
||||
}
|
||||
if (floatingMenuContentBounds.bottom + windowEdgeMargin >= workspaceBounds.bottom) {
|
||||
floatingMenuContent.style.bottom = `${windowEdgeMargin}px`;
|
||||
floatingMenuContent.div().style.bottom = `${windowEdgeMargin}px`;
|
||||
if (workspaceBounds.bottom - floatingMenuContainerBounds.bottom === 12) zeroedBorderVertical = "Bottom";
|
||||
}
|
||||
}
|
||||
|
@ -181,16 +181,16 @@
|
|||
// We use `.style` on a ref (instead of a `:style` Vue binding) because the binding causes the `updated()` hook to call the function we're in recursively forever
|
||||
switch (`${zeroedBorderVertical}${zeroedBorderHorizontal}`) {
|
||||
case "TopLeft":
|
||||
floatingMenuContent.style.borderTopLeftRadius = "0";
|
||||
floatingMenuContent.div().style.borderTopLeftRadius = "0";
|
||||
break;
|
||||
case "TopRight":
|
||||
floatingMenuContent.style.borderTopRightRadius = "0";
|
||||
floatingMenuContent.div().style.borderTopRightRadius = "0";
|
||||
break;
|
||||
case "BottomLeft":
|
||||
floatingMenuContent.style.borderBottomLeftRadius = "0";
|
||||
floatingMenuContent.div().style.borderBottomLeftRadius = "0";
|
||||
break;
|
||||
case "BottomRight":
|
||||
floatingMenuContent.style.borderBottomRightRadius = "0";
|
||||
floatingMenuContent.div().style.borderBottomRightRadius = "0";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -219,7 +219,7 @@
|
|||
|
||||
// Measure the width of the floating menu content element, if it's currently visible
|
||||
// The result will be `undefined` if the menu is invisible, perhaps because an ancestor component is hidden with a falsy `v-if` condition
|
||||
const naturalWidth: number | undefined = floatingMenuContent?.clientWidth;
|
||||
const naturalWidth: number | undefined = floatingMenuContent?.div().clientWidth;
|
||||
|
||||
// Turn off measuring mode for the component, which triggers another call to the `updated()` Vue event, so we can turn off the protection after that has happened
|
||||
measuringOngoing = false;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
export let scrollableX: boolean = false;
|
||||
export let scrollableY: boolean = false;
|
||||
|
||||
let divElement: HTMLDivElement;
|
||||
let self: HTMLDivElement;
|
||||
|
||||
$: extraClasses = Object.entries(classes)
|
||||
.flatMap((classAndState) => (classAndState[1] ? [classAndState[0]] : []))
|
||||
|
@ -19,7 +19,7 @@
|
|||
.join(" ");
|
||||
|
||||
export function div(): HTMLDivElement {
|
||||
return divElement;
|
||||
return self;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -29,21 +29,52 @@
|
|||
class:scrollable-y={scrollableY}
|
||||
style={`${styleName} ${extraStyles}`.trim() || undefined}
|
||||
title={tooltip}
|
||||
bind:this={divElement}
|
||||
bind:this={self}
|
||||
on:focus
|
||||
on:blur
|
||||
on:fullscreenchange
|
||||
on:fullscreenerror
|
||||
on:scroll
|
||||
on:cut
|
||||
on:copy
|
||||
on:paste
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:auxclick
|
||||
on:click
|
||||
on:contextmenu
|
||||
on:dblclick
|
||||
on:mousedown
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:mousemove
|
||||
on:mouseover
|
||||
on:mouseout
|
||||
on:mouseup
|
||||
on:select
|
||||
on:wheel
|
||||
on:drag
|
||||
on:dragend
|
||||
on:dragenter
|
||||
on:dragstart
|
||||
on:dragleave
|
||||
on:dragover
|
||||
on:drop
|
||||
on:touchcancel
|
||||
on:touchend
|
||||
on:touchmove
|
||||
on:touchstart
|
||||
on:pointerover
|
||||
on:pointerenter
|
||||
on:pointerdown
|
||||
on:pointermove
|
||||
on:pointerup
|
||||
on:dragleave
|
||||
on:dragover
|
||||
on:dragstart
|
||||
on:dragend
|
||||
on:drop
|
||||
on:wheel
|
||||
on:scroll
|
||||
on:focus
|
||||
on:blur
|
||||
on:pointercancel
|
||||
on:pointerout
|
||||
on:pointerleave
|
||||
on:gotpointercapture
|
||||
on:lostpointercapture
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
export let scrollableX: boolean = false;
|
||||
export let scrollableY: boolean = false;
|
||||
|
||||
let divElement: HTMLDivElement;
|
||||
let self: HTMLDivElement;
|
||||
|
||||
$: extraClasses = Object.entries(classes)
|
||||
.flatMap((classAndState) => (classAndState[1] ? [classAndState[0]] : []))
|
||||
|
@ -19,7 +19,7 @@
|
|||
.join(" ");
|
||||
|
||||
export function div(): HTMLDivElement {
|
||||
return divElement;
|
||||
return self;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -29,21 +29,52 @@
|
|||
class:scrollable-y={scrollableY}
|
||||
style={`${styleName} ${extraStyles}`.trim() || undefined}
|
||||
title={tooltip}
|
||||
bind:this={divElement}
|
||||
bind:this={self}
|
||||
on:focus
|
||||
on:blur
|
||||
on:fullscreenchange
|
||||
on:fullscreenerror
|
||||
on:scroll
|
||||
on:cut
|
||||
on:copy
|
||||
on:paste
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:auxclick
|
||||
on:click
|
||||
on:contextmenu
|
||||
on:dblclick
|
||||
on:mousedown
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:mousemove
|
||||
on:mouseover
|
||||
on:mouseout
|
||||
on:mouseup
|
||||
on:select
|
||||
on:wheel
|
||||
on:drag
|
||||
on:dragend
|
||||
on:dragenter
|
||||
on:dragstart
|
||||
on:dragleave
|
||||
on:dragover
|
||||
on:drop
|
||||
on:touchcancel
|
||||
on:touchend
|
||||
on:touchmove
|
||||
on:touchstart
|
||||
on:pointerover
|
||||
on:pointerenter
|
||||
on:pointerdown
|
||||
on:pointermove
|
||||
on:pointerup
|
||||
on:dragleave
|
||||
on:dragover
|
||||
on:dragstart
|
||||
on:dragend
|
||||
on:drop
|
||||
on:wheel
|
||||
on:scroll
|
||||
on:focus
|
||||
on:blur
|
||||
on:pointercancel
|
||||
on:pointerout
|
||||
on:pointerleave
|
||||
on:gotpointercapture
|
||||
on:lostpointercapture
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
import { type Editor } from "@/wasm-communication/editor";
|
||||
import { type DocumentState } from "@/state-providers/document";
|
||||
|
||||
let self: LayoutCol;
|
||||
let rulerHorizontal: CanvasRuler;
|
||||
let rulerVertical: CanvasRuler;
|
||||
let canvasDiv: HTMLDivElement;
|
||||
let canvasContainer: HTMLDivElement;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const document = getContext<DocumentState>("document");
|
||||
|
@ -116,7 +115,7 @@
|
|||
function canvasPointerDown(e: PointerEvent) {
|
||||
const onEditbox = e.target instanceof HTMLDivElement && e.target.contentEditable;
|
||||
|
||||
if (!onEditbox) canvasDiv?.setPointerCapture(e.pointerId);
|
||||
if (!onEditbox) canvasContainer?.setPointerCapture(e.pointerId);
|
||||
}
|
||||
|
||||
// Update rendered SVGs
|
||||
|
@ -127,7 +126,7 @@
|
|||
await tick();
|
||||
|
||||
if (textInput) {
|
||||
const foreignObject = canvasDiv.getElementsByTagName("foreignObject")[0] as SVGForeignObjectElement;
|
||||
const foreignObject = canvasContainer.getElementsByTagName("foreignObject")[0] as SVGForeignObjectElement;
|
||||
if (foreignObject.children.length > 0) return;
|
||||
|
||||
const addedInput = foreignObject.appendChild(textInput);
|
||||
|
@ -285,8 +284,8 @@
|
|||
// Resize elements to render the new viewport size
|
||||
export function viewportResize() {
|
||||
// Resize the canvas
|
||||
canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(canvasDiv).width));
|
||||
canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(canvasDiv).height));
|
||||
canvasSvgWidth = Math.ceil(parseFloat(getComputedStyle(canvasContainer).width));
|
||||
canvasSvgHeight = Math.ceil(parseFloat(getComputedStyle(canvasContainer).height));
|
||||
|
||||
// Resize the rulers
|
||||
rulerHorizontal?.resize();
|
||||
|
@ -382,7 +381,7 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<LayoutCol class="document" bind:this={self}>
|
||||
<LayoutCol class="document">
|
||||
<LayoutRow class="options-bar" scrollableX={true}>
|
||||
<WidgetLayout layout={$document.documentModeLayout} />
|
||||
<WidgetLayout layout={$document.toolOptionsLayout} />
|
||||
|
@ -422,7 +421,7 @@
|
|||
y={cursorTop}
|
||||
/>
|
||||
{/if}
|
||||
<div class="canvas" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={canvasDiv} data-canvas>
|
||||
<div class="canvas" on:pointerdown={(e) => canvasPointerDown(e)} on:dragover={(e) => e.preventDefault()} on:drop={(e) => pasteFile(e)} bind:this={canvasContainer} data-canvas>
|
||||
<svg class="artboards" style:width={canvasWidthCSS} style:height={canvasHeightCSS}>
|
||||
{@html artboardSvg}
|
||||
</svg>
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
|
||||
await tick();
|
||||
|
||||
const textInput: HTMLInputElement | undefined = list?.querySelector("[data-text-input]:not([disabled])") || undefined;
|
||||
const textInput = (list?.div().querySelector("[data-text-input]:not([disabled])") || undefined) as HTMLInputElement | undefined;
|
||||
textInput?.select();
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@
|
|||
|
||||
function calculateDragIndex(tree: LayoutCol, clientY: number, select?: () => void): DraggingData {
|
||||
const treeChildren = tree.div().children;
|
||||
const treeOffset = tree.getBoundingClientRect().top;
|
||||
const treeOffset = tree.div().getBoundingClientRect().top;
|
||||
|
||||
// Closest distance to the middle of the row along the Y axis
|
||||
let closest = Infinity;
|
||||
|
|
|
@ -180,7 +180,7 @@
|
|||
let zoomFactor = 1 + Math.abs(scrollY) * WHEEL_RATE;
|
||||
if (scrollY > 0) zoomFactor = 1 / zoomFactor;
|
||||
|
||||
const { x, y, width, height } = graph.getBoundingClientRect();
|
||||
const { x, y, width, height } = graph.div().getBoundingClientRect();
|
||||
|
||||
transform.scale *= zoomFactor;
|
||||
|
||||
|
@ -222,7 +222,7 @@
|
|||
|
||||
// Handle the add node popup on right click
|
||||
if (e.button === 2) {
|
||||
const graphBounds = graph.getBoundingClientRect();
|
||||
const graphBounds = graph.div().getBoundingClientRect();
|
||||
nodeListLocation = {
|
||||
x: Math.round(((e.clientX - graphBounds.x) / transform.scale - transform.x) / GRID_SIZE),
|
||||
y: Math.round(((e.clientY - graphBounds.y) / transform.scale - transform.y) / GRID_SIZE),
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
export let sharpRightCorners = false;
|
||||
export let placeholder: string | undefined = undefined;
|
||||
|
||||
let input: HTMLInputElement | HTMLTextAreaElement;
|
||||
let inputOrTextarea: HTMLInputElement | HTMLTextAreaElement;
|
||||
let id = `${Math.random()}`.substring(2);
|
||||
let macKeyboardLayout = platformIsMac();
|
||||
let inputValue = value;
|
||||
|
@ -40,20 +40,28 @@
|
|||
export function selectAllText(currentText: string) {
|
||||
// Setting the value directly is required to make `input.select()` work
|
||||
// TODO: Svelte: Test if the above message is still true
|
||||
input.value = currentText;
|
||||
input.select();
|
||||
inputOrTextarea.value = currentText;
|
||||
inputOrTextarea.select();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
inputOrTextarea.focus();
|
||||
}
|
||||
|
||||
export function unFocus() {
|
||||
input.blur();
|
||||
inputOrTextarea.blur();
|
||||
}
|
||||
|
||||
export function getInputElementValue(): string {
|
||||
return input.value;
|
||||
export function getValue(): string {
|
||||
return inputOrTextarea.value;
|
||||
}
|
||||
|
||||
export function setInputElementValue(value: string) {
|
||||
input.value = value;
|
||||
inputOrTextarea.value = value;
|
||||
}
|
||||
|
||||
export function element(): HTMLInputElement | HTMLTextAreaElement {
|
||||
return inputOrTextarea;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -68,7 +76,7 @@
|
|||
{disabled}
|
||||
{placeholder}
|
||||
bind:value={inputValue}
|
||||
bind:this={input}
|
||||
bind:this={inputOrTextarea}
|
||||
on:focus={() => dispatch("textFocused")}
|
||||
on:blur={() => dispatch("textChanged")}
|
||||
on:change={() => dispatch("textChanged")}
|
||||
|
@ -85,7 +93,7 @@
|
|||
{spellcheck}
|
||||
{disabled}
|
||||
bind:value={inputValue}
|
||||
bind:this={input}
|
||||
bind:this={inputOrTextarea}
|
||||
on:focus={() => dispatch("textFocused")}
|
||||
on:blur={() => dispatch("textChanged")}
|
||||
on:change={() => dispatch("textChanged")}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
export let incrementCallbackIncrease: (() => void) | undefined = undefined;
|
||||
export let incrementCallbackDecrease: (() => void) | undefined = undefined;
|
||||
|
||||
let fieldInput: FieldInput;
|
||||
let self: FieldInput;
|
||||
let text = displayText(value);
|
||||
let editing = false;
|
||||
// Stays in sync with a binding to the actual input range slider element.
|
||||
|
@ -127,7 +127,7 @@
|
|||
function sliderPointerUp() {
|
||||
// User clicked but didn't drag, so we focus the text input element
|
||||
if (rangeSliderClickDragState === "mousedown") {
|
||||
const inputElement = fieldInput.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
|
||||
|
@ -148,7 +148,7 @@
|
|||
|
||||
editing = true;
|
||||
|
||||
fieldInput.selectAllText(text);
|
||||
self.selectAllText(text);
|
||||
}
|
||||
|
||||
// Called only when `value` is changed from the <input> element via user input and committed, either with the
|
||||
|
@ -164,7 +164,7 @@
|
|||
|
||||
editing = false;
|
||||
|
||||
fieldInput.unFocus();
|
||||
self.unFocus();
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
|
@ -172,7 +172,7 @@
|
|||
|
||||
editing = false;
|
||||
|
||||
fieldInput.unFocus();
|
||||
self.unFocus();
|
||||
}
|
||||
|
||||
function onIncrement(direction: "Decrease" | "Increase") {
|
||||
|
@ -245,7 +245,7 @@
|
|||
{sharpRightCorners}
|
||||
spellcheck={false}
|
||||
styles={{ "min-width": minWidth > 0 ? `${minWidth}px` : undefined, "--progress-factor": (rangeSliderValueAsRendered - rangeMin) / (rangeMax - rangeMin) }}
|
||||
bind:this={fieldInput}
|
||||
bind:this={self}
|
||||
>
|
||||
{#if value !== undefined && mode === "Increment" && incrementBehavior !== "None"}
|
||||
<button class="arrow left" on:click={() => onIncrement("Decrease")} tabindex="-1" />
|
||||
|
|
|
@ -1,24 +1,17 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
import { type IconName } from "@/utility-functions/icons";
|
||||
|
||||
import LayoutRow from "@/components/layout/LayoutRow.svelte";
|
||||
import CheckboxInput from "@/components/widgets/inputs/CheckboxInput.svelte";
|
||||
|
||||
// emits: ["update:checked"],
|
||||
const dispatch = createEventDispatcher<{ checked: boolean }>();
|
||||
|
||||
export let checked: boolean;
|
||||
export let disabled = false;
|
||||
export let icon: IconName = "Checkmark";
|
||||
export let tooltip: string | undefined = undefined;
|
||||
|
||||
let checkboxInput: CheckboxInput;
|
||||
</script>
|
||||
|
||||
<LayoutRow class="optional-input" classes={{ disabled }}>
|
||||
<CheckboxInput {checked} on:checked {disabled} {icon} {tooltip} bind:this={checkboxInput} />
|
||||
<CheckboxInput {checked} on:checked {disabled} {icon} {tooltip} />
|
||||
</LayoutRow>
|
||||
|
||||
<style lang="scss" global>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
export let tooltip: string | undefined = undefined;
|
||||
export let disabled = false;
|
||||
|
||||
let fieldInput: FieldInput;
|
||||
let self: FieldInput;
|
||||
let editing = false;
|
||||
let inputValue = value;
|
||||
|
||||
|
@ -30,16 +30,20 @@
|
|||
onCancelTextChange();
|
||||
|
||||
// TODO: Find a less hacky way to do this
|
||||
dispatch("commitText", fieldInput.getInputElementValue());
|
||||
dispatch("commitText", self.getValue());
|
||||
|
||||
// Required if value is not changed by the parent component upon update:value event
|
||||
fieldInput.setInputElementValue(value);
|
||||
self.setInputElementValue(value);
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
editing = false;
|
||||
|
||||
fieldInput.unFocus();
|
||||
self.unFocus();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
self.focus();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -59,7 +63,7 @@
|
|||
{disabled}
|
||||
{tooltip}
|
||||
value={inputValue}
|
||||
bind:this={fieldInput}
|
||||
bind:this={self}
|
||||
/>
|
||||
|
||||
<style lang="scss" global>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
export let minWidth = 0;
|
||||
export let sharpRightCorners = false;
|
||||
|
||||
let fieldInput: FieldInput;
|
||||
let self: FieldInput;
|
||||
let editing = false;
|
||||
let text = value;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
function onTextFocused() {
|
||||
editing = true;
|
||||
|
||||
fieldInput.selectAllText(text);
|
||||
self.selectAllText(text);
|
||||
}
|
||||
|
||||
// Called only when `value` is changed from the <input> element via user input and committed, either with the
|
||||
|
@ -40,16 +40,20 @@
|
|||
onCancelTextChange();
|
||||
|
||||
// TODO: Find a less hacky way to do this
|
||||
dispatch("commitText", fieldInput.getInputElementValue());
|
||||
dispatch("commitText", self.getValue());
|
||||
|
||||
// Required if value is not changed by the parent component upon update:value event
|
||||
fieldInput.setInputElementValue(value);
|
||||
self.setInputElementValue(value);
|
||||
}
|
||||
|
||||
function onCancelTextChange() {
|
||||
editing = false;
|
||||
|
||||
fieldInput.unFocus();
|
||||
self.unFocus();
|
||||
}
|
||||
|
||||
export function focus() {
|
||||
self.focus();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -68,7 +72,7 @@
|
|||
{tooltip}
|
||||
{placeholder}
|
||||
{sharpRightCorners}
|
||||
bind:this={fieldInput}
|
||||
bind:this={self}
|
||||
/>
|
||||
|
||||
<style lang="scss" global>
|
||||
|
|
|
@ -115,8 +115,6 @@ fn handle_message(message: String) -> String {
|
|||
let serialized = ron::to_string(&send_frontend_message_to_js(response.clone())).unwrap();
|
||||
if let Err(error) = ron::from_str::<FrontendMessage>(&serialized) {
|
||||
log::error!("Error deserializing message: {}", error);
|
||||
log::debug!("{:#?}", response);
|
||||
log::debug!("{}", serialized);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue