diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index aa7c577d..83f0d3e4 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -11,7 +11,7 @@
API which is required for using the editor. However, you can still explore the user interface.
-
+
diff --git a/frontend/src/components/panels/LayerTree.vue b/frontend/src/components/panels/LayerTree.vue
index e922f624..0cac727f 100644
--- a/frontend/src/components/panels/LayerTree.vue
+++ b/frontend/src/components/panels/LayerTree.vue
@@ -29,7 +29,7 @@
- deselectAllLayers()" @dragover="(e) => draggable && updateInsertLine(e)" @dragend="draggable && drop()">
+ deselectAllLayers()" @dragover="(e) => draggable && updateInsertLine(e)" @dragend="() => draggable && drop()">
-
+ onEditLayerName(listing)">
onEditLayerNameChange(listing, e.target)"
- @blur="onEditLayerNameDeselect(listing)"
+ @blur="() => onEditLayerNameDeselect(listing)"
@keydown.enter="(e) => onEditLayerNameChange(listing, e.target)"
@keydown.escape="onEditLayerNameDeselect(listing)"
/>
@@ -379,7 +380,7 @@ export default defineComponent({
listing.editingName = true;
const tree = (this.$refs.layerTreeList as typeof LayoutCol).$el as HTMLElement;
this.$nextTick(() => {
- (tree.querySelector("input:not([disabled])") as HTMLInputElement).select();
+ (tree.querySelector("[data-text-input]:not([disabled])") as HTMLInputElement).select();
});
},
async onEditLayerNameChange(listing: LayerListingInfo, inputElement: EventTarget | null) {
diff --git a/frontend/src/components/widgets/WidgetRow.vue b/frontend/src/components/widgets/WidgetRow.vue
index 7a385db3..51ec5afd 100644
--- a/frontend/src/components/widgets/WidgetRow.vue
+++ b/frontend/src/components/widgets/WidgetRow.vue
@@ -13,6 +13,7 @@
:incrementCallbackIncrease="() => updateLayout(component.widget_id, 'Increment')"
:incrementCallbackDecrease="() => updateLayout(component.widget_id, 'Decrement')"
/>
+ updateLayout(component.widget_id, value)" />
updateLayout(component.widget_id, value)" />
updateLayout(component.widget_id, value)" />
@@ -40,6 +41,7 @@ import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
import NumberInput from "@/components/widgets/inputs/NumberInput.vue";
import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue";
import RadioInput from "@/components/widgets/inputs/RadioInput.vue";
+import TextInput from "@/components/widgets/inputs/TextInput.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
export default defineComponent({
@@ -57,6 +59,7 @@ export default defineComponent({
Separator,
PopoverButton,
NumberInput,
+ TextInput,
IconButton,
OptionalInput,
RadioInput,
diff --git a/frontend/src/components/widgets/WidgetSection.vue b/frontend/src/components/widgets/WidgetSection.vue
index 0ce946c7..81671cd4 100644
--- a/frontend/src/components/widgets/WidgetSection.vue
+++ b/frontend/src/components/widgets/WidgetSection.vue
@@ -47,9 +47,7 @@ const WidgetSection = defineComponent({
throw new Error("Layout row type does not exist");
},
},
- components: {
- WidgetRow,
- },
+ components: { WidgetRow },
});
export default WidgetSection;
diff --git a/frontend/src/components/widgets/floating-menus/ColorPicker.vue b/frontend/src/components/widgets/floating-menus/ColorPicker.vue
index a048bff9..d7627a3d 100644
--- a/frontend/src/components/widgets/floating-menus/ColorPicker.vue
+++ b/frontend/src/components/widgets/floating-menus/ColorPicker.vue
@@ -131,6 +131,7 @@ type ColorPickerState = "Idle" | "MoveHue" | "MoveOpacity" | "MoveSaturation";
// TODO: Such as removing the `picker*` data variables and reducing the number of functions which call each other in weird, non-obvious ways.
export default defineComponent({
+ emits: ["update:color"],
props: {
color: { type: Object as PropType, required: true },
},
diff --git a/frontend/src/components/widgets/floating-menus/MenuList.vue b/frontend/src/components/widgets/floating-menus/MenuList.vue
index 69003f98..c6e2bfd5 100644
--- a/frontend/src/components/widgets/floating-menus/MenuList.vue
+++ b/frontend/src/components/widgets/floating-menus/MenuList.vue
@@ -7,9 +7,9 @@
:key="entryIndex"
class="row"
:class="{ open: isMenuEntryOpen(entry), active: entry === activeEntry }"
- @click="handleEntryClick(entry)"
- @pointerenter="handleEntryPointerEnter(entry)"
- @pointerleave="handleEntryPointerLeave(entry)"
+ @click="() => handleEntryClick(entry)"
+ @pointerenter="() => handleEntryPointerEnter(entry)"
+ @pointerleave="() => handleEntryPointerLeave(entry)"
:data-hover-menu-spawner-extend="entry.children && []"
>
@@ -160,6 +160,10 @@ const KEYBOARD_LOCK_USE_FULLSCREEN = "This hotkey is reserved by the browser, bu
const KEYBOARD_LOCK_SWITCH_BROWSER = "This hotkey is reserved by the browser, but becomes available in Chrome, Edge, and Opera which support the Keyboard.lock() API";
const MenuList = defineComponent({
+ emits: {
+ "update:activeEntry": null,
+ widthChanged: (width: number) => typeof width === "number",
+ },
inject: ["fullscreen"],
props: {
direction: { type: String as PropType, default: "Bottom" },
diff --git a/frontend/src/components/widgets/inputs/CheckboxInput.vue b/frontend/src/components/widgets/inputs/CheckboxInput.vue
index 5689a660..49872366 100644
--- a/frontend/src/components/widgets/inputs/CheckboxInput.vue
+++ b/frontend/src/components/widgets/inputs/CheckboxInput.vue
@@ -88,6 +88,7 @@ import LayoutRow from "@/components/layout/LayoutRow.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
export default defineComponent({
+ emits: ["update:checked"],
data() {
return {
id: `${Math.random()}`.substring(2),
diff --git a/frontend/src/components/widgets/inputs/DropdownInput.vue b/frontend/src/components/widgets/inputs/DropdownInput.vue
index 32219aac..a28aee1a 100644
--- a/frontend/src/components/widgets/inputs/DropdownInput.vue
+++ b/frontend/src/components/widgets/inputs/DropdownInput.vue
@@ -98,6 +98,7 @@ declare global {
}
export default defineComponent({
+ emits: ["update:selectedIndex"],
props: {
menuEntries: { type: Array as PropType, required: true },
selectedIndex: { type: Number as PropType, required: true },
diff --git a/frontend/src/components/widgets/inputs/FieldInput.vue b/frontend/src/components/widgets/inputs/FieldInput.vue
new file mode 100644
index 00000000..25a7a5ac
--- /dev/null
+++ b/frontend/src/components/widgets/inputs/FieldInput.vue
@@ -0,0 +1,116 @@
+
+
+
+ $emit('textFocused')"
+ @blur="() => $emit('textChanged')"
+ @change="() => $emit('textChanged')"
+ @keydown.enter="() => $emit('textChanged')"
+ @keydown.esc="() => $emit('cancelTextChange')"
+ />
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/widgets/inputs/MenuBarInput.vue b/frontend/src/components/widgets/inputs/MenuBarInput.vue
index 0ee32485..1ab9f195 100644
--- a/frontend/src/components/widgets/inputs/MenuBarInput.vue
+++ b/frontend/src/components/widgets/inputs/MenuBarInput.vue
@@ -1,12 +1,12 @@