Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(leaves): New list component. #35

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<img src="./fullscreen/demo.gif"/>
</a>

## List

<a href="./list/main.ml">
<img src="./list/demo.gif"/>
</a>

## Progress

<a href="./progress/main.ml">
Expand Down
Binary file added examples/list/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions examples/list/demo.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Output demo.gif

Require echo

Set Shell "bash"
Set Framerate 24
Set FontSize 20
Set Width 1200
Set Height 600

Sleep 1s
Type "dune exec --no-print-directory ./main.exe"
Enter

Sleep 1s
Type " "
Type "j "
Sleep 500ms
Type "j "
Sleep 500ms
Type "/"
Sleep 500ms
Type "str"
Sleep 500ms
Enter
Sleep 500ms
Type " "
Sleep 500ms
Enter
Sleep 2s
3 changes: 3 additions & 0 deletions examples/list/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(executable
(name main)
(libraries minttea spices leaves str))
110 changes: 110 additions & 0 deletions examples/list/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
open Minttea
module Input = Leaves.Text_input
module FList = Leaves.Filtered_list

type model = {
elements : FList.t;
choices : string list option;
edit_filter : bool;
filter_input : Input.t;
}

let initial_model =
{
(* Choices is to Some list at the end of the program *)
choices = None;
(* A Text_input is used to enter a substring used for filtering *)
filter_input = Input.make "" ~prompt:"/" ();
edit_filter = false;
elements =
FList.make
[
"brain 🧠";
"bread 🍞";
"butter 🧈";
"cake 🍰";
"carrots 🥕";
"chocolate 🍫";
"cupcakes 🧁";
"empanadas 🥟";
"hamburgers 🍔";
"ice cream 🍦";
"milk 🥛";
"pizza 🍕";
"strawberries 🍓";
"waffles 🧇";
"yogurt 🥛";
]
~style_selected:Spices.(default |> bold true)
();
}

let init _model = Command.Noop

let update event model : model * Command.t =
if model.edit_filter then
match event with
(* validate the search and go back to navigating the list *)
| Event.KeyDown Enter ->
let elements =
FList.show_string_contains model.elements
(Input.current_text model.filter_input)
in
({ model with elements; edit_filter = false }, Command.Noop)
(* cancel the search and go back to navigating the list *)
| Event.KeyDown Escape ->
let elements = FList.show_all model.elements in
( {
model with
elements;
edit_filter = false;
filter_input = Input.set_text "" model.filter_input;
},
Command.Noop )
(* everything else is passed to underlying component *)
| _ ->
let filter_input = Input.update model.filter_input event in
(* incremental search: update the search on all event *)
let elements =
FList.show_string_contains model.elements
(Input.current_text filter_input)
in
({ model with filter_input; elements }, Command.Noop)
else
match event with
(* Validate the selection, print it and quit *)
| Event.KeyDown Enter ->
let elements = FList.get_selection model.elements in
({ model with choices = Some elements }, Command.Quit)
(* Quit right away *)
| Event.KeyDown (Key "q" | Escape) -> (model, Command.Quit)
(* Open the search Text_input *)
| Event.KeyDown (Key "/") ->
({ model with edit_filter = true }, Command.Noop)
(* Delegate the rest to the list *)
| _ ->
let elements = FList.update event model.elements in
({ model with elements }, Command.Noop)

let view model =
match model.choices with
(* ready to leave *)
| Some elements -> String.concat "\n" elements
(* normal running *)
| None ->
let help_msg =
if model.edit_filter then "Esc: cancel filter, Enter: validate filter"
else "q: quit, /: search, j/k: up/down, space: select, enter: validate."
in
Format.sprintf {|Pick your favorite food:

%s
%s

%s|}
(FList.view model.elements)
(if model.edit_filter then Input.view model.filter_input else "")
help_msg

let app = Minttea.app ~init ~update ~view ()
let () = Minttea.start app ~initial_model
2 changes: 1 addition & 1 deletion leaves/dune
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
(library
(public_name leaves)
(name leaves)
(libraries minttea spices ptime ptime.clock.os uuseg))
(libraries minttea spices ptime ptime.clock.os uuseg str))
Loading