Type into the app
You'll add tasks from a text box and show a spinner while the list waits to be saved. Both come from npm packages FSR provides, so there is nothing to install. It starts from the app you built in 630.
Before you start
Install from crates.io. You need no Node and no package manager.
cargo install snapfire_compiler
cargo install snapfire_fsr_cli
fsr --version
Every command and screenshot on this page was captured with fsr 0.x.
The packages FSR provides#
A terminal page does not follow npm packages. A few that nearly every Ink tool uses are provided instead, written in TypeScript the way the packages are written, so you import them by their usual names:
| Import | What you get |
|---|---|
ink-text-input | TextInput and UncontrolledTextInput |
ink-spinner | Spinner, with the spinners of cli-spinners |
@snapfire/fsr/terminal | ms, stripAnsi, stringWidth and wrapAnsi |
TextInput reads keys with useInput like any other component and Spinner steps on a timer like any other component. Another package from npm is refused.
Add the imports and the state#
;
;
;
;
;
;Newline is no longer used, since the footer becomes a row. Inside Tasks, below selected, add three pieces of state:
;
;
;adding says whether the text box is open, draft is what is typed into it and saving says a change has not been written yet.
Save half a second after a change#
In 630 every change wrote the file at once. This step waits until the changes stop and writes 500 ms after the last one, which is what the spinner shows. Below the state, add the effect that does it:
,;The effect runs after each render that changed tasks. Its cleanup clears the timer before the next run, so a second change inside the half second starts the wait again. On the first render saving is false, so opening the app writes nothing.
Open the text box#
Change the handler. While the box is open, the list's keys stay quiet and Esc closes it. a opens it. Space now marks the list as needing a save instead of writing at once:
;
;TextInput handles the typing itself: characters, backspace and the cursor. onChange hands you the new text and onSubmit runs on Enter with it.
Draw the box and the spinner#
Replace the footer Text at the bottom of the outer Box with the box and a footer row:
type picks a spinner from cli-spinners by name, dots or line for example. The spinner steps at the interval cli-spinners gives it.
Run it#
Start with no saved list:
Press a. The box opens with its placeholder:
╭──────────────────────────────────────────╮
│ Tasks tasks.json 1 open │
│ │
│ > Write the first task │
│ │
│ new: what needs doing │
│ Enter adds, Esc cancels saved │
╰──────────────────────────────────────────╯
Type Ship it. The space goes into the text and does not mark a task done, because the list's handler returns while the box is open. Press Enter. The task is added and the spinner runs:
╭──────────────────────────────────────────╮
│ Tasks tasks.json 2 open │
│ │
│ > Write the first task │
│ Ship it │
│ │
│ a adds, space marks one done ⠋ saving │
╰──────────────────────────────────────────╯
Half a second later it reads saved and the file has both tasks:
Next up: 650. Move focus between panes.