Textbox
Updated on September 7, 2024Source codeTests
useTextbox is a composable that controls native HTML inputs and textareas with reactive two-way binding for both the input's value and its selection metadata (start position, end position, and direction). useTextbox also provides an API for autocomplete operations and undo/redo history.
useTextbox uses the Completeable class from Baleada Logic to control your input's value and selection, and to support autocomplete features.
Example
Create a textbox
To start using a controlled textbox, call the useTextbox function, which accepts one optional options object as its only parameter.
<!-- MyComponent.vue -->
<template>...</template>
<script setup>
import { useTextbox } from '@baleada/vue-features'
const textbox = useTextbox([options])
</script>
Here's a breakdown of the options object:
initialValue''historyuseTextbox. See the next table for more info.As mentioned in the table above, useTextbox tracks an undo/redo history, whose behavior can be configured via the options.history object. See the How your textbox manages undo/redo history section for more general info, and see the table below for the optional properties of the options.history object:
maxLengthtruetrueLimits the number of events that useTextbox can record in its undo/redo history.
Set maxLength to true to allow an infinite number of events.
Use your textbox
useTextbox returns textbox—an object with tools you can use to control your HTML input or textarea.
Here's a breakdown of that object:
rootroot.ref should be bound to the HTML input or textarea you want to control.
textCompleteable)The reactive Completeable instance created by useTextbox.
See the How to control value and selection section for more guidance on text usage, and see the Access state and methods section of the Completeable docs for more guidance on how to use text to autocomplete text.
type(string)A function you can use to programmatically type in the textbox.
type requires one parameter: the new string to type into the textbox.
You can assign a new string to text.value.string to achieve the same effect, but type is a convenient shortcut.
select(selection)A function you can use to programmatically select text in the textbox.
select requires one parameter: the new selection object.
See the Completeable docs to learn what the shape of that selection object should be.
You can assign a new selection object to text.value.selection to achieve the same effect, but select is a convenient shortcut.
historyA reactive Navigateable instance that stores and navigates your undo/redo history.
See the How your textbox manages undo/redo history section for more info.
record(entry)A function you can use to programmatically record new entries in your textbox's history.
record requires one parameter: a new history entry, which is an object with a string and selection property.
string is a plain string, and selection is a selection object as defined by Completeable.
undo(options)A function you can use to undo events and revert to a recorded state.
To undo more than one entry at a time, pass the optional options object, with the options.distance property indicating how many entries should be undone.
Note that undo is not exactly the same as calling history's previous method—it's slightly more sophisticated and tailored to useTextbox's specific use case.
redo(options)A function you can use to redo events and move forward to a recorded state.
To redo more than one entry at a time, pass the optional options object, with the options.distance property indicating how many entries should be redone.
Note that redo is not exactly the same as calling history's next method—it's slightly more sophisticated and tailored to useTextbox's specific use case.
rewrite(entries)A function you can use to rewrite history, replacing all of its current entries with an array of new entries.
Here's a more complete example of how to use your textbox and bind the function ref:
<template>
<input type="text" :ref="textbox.root.ref()" />
</template>
<script setup>
import { useTextbox } from '@baleada/vue-features'
const textbox = useTextbox([options])
</script>
How to control value and selection
As mentioned, useTextbox implements reactive two-way binding for both your input's value and its selected text. It stores the value and the selection metadata in textbox.text, a fully reactive Completeable instance.
With this tooling in place, here are the useful side effects that certain actions will have:
textbox.text.value.stringtextbox.text.value.selectiontextbox.text.value.string, or you call the type(...) functiontextbox.text.value.selection, or you call the select methodtextbox.text.value.complete(...) method to perform an autocomplete operationThe HTML input's value will automatically update.
Also, the completed portion of text will be automatically selected, or you can pass options to complete if you'd rather automatically position the cursor right after the completed text.
How your textbox manages undo/redo history
useTextbox supports undo/redo functionality inspired by VS Code's undo/redo. This feature is much more thorough and flexible than browsers' default undo/redo for HTML inputs and textareas.
Users of your textbox can press Command+Z or Control+Z to undo, and Command+Y or Control+Y to redo. You can also call the textbox.undo and textbox.redo functions at any time to programmatically navigate history.
In most cases, you don't need to be concerned with how this undo/redo history is tracked, but just in case you need to watch changes or record new history events, your textbox object has a history property, which holds the reactive Navigateable instance that stores and navigates your history entries.
import { watchEffect } from 'vue'
const textbox = useTextbox()
watchEffect(() => console.log(textbox.history.value.location))
Extend the textbox
The following extensions are compatible with your textbox: