site/docs/hown/tty.nix
2026-01-31 10:31:31 +10:00

100 lines
2.3 KiB
Nix

# XXX: TODO: The howl.Div, howl.Text, ... types implement
# XXX: TODO: the HtmlTag' typeclass, which in turn implements
# XXX: TODO: a morphism to the nt.String type. This makes compiling
# XXX: TODO: to html super duper simple!!
{
nt,
howl,
...
}: let
inherit
(nt)
projectOnto
;
inherit
(howl)
# HTML
Div
Text
# CSS
StyleClass
StyleSheet
ContinuousAnimation
DiscreteAnimation
;
in {
typing = StyleSheet {
include = [./tty.css];
classes = {
typing-wrapper = null;
typing-prompt = promptLength: commandLength: duration: period:
StyleClass {
width = promptLength + commandLength; # ignore cursor
border.right = "TODO"; # cursor
# hide what the animation hasn't shown yet
whitespace = "nowrap";
overflow = "hidden";
# run typing animation then start cursor blink
animations = [
(DiscreteAnimation {
inherit duration;
keyframes = {
"0"
};
})
];
};
typing-result = typingDuration: delay:
StyleClass {
visibility = "hidden";
whitespace = "pre-wrap"; # preserve linebreaks
# show result once typing duration + delay is over
animations = [
(ContinuousAnimation {
name = "unhide-result";
duration = 1; # animation-duration
# timingFn = ; # animation-timing-function
delay = typingDuration + delay; # animation-delay
# animation-iteration-count
direction = "forwards"; # animation-direction
# animation-fill-mode
# animation-play-state
keyframes = {
"100" = {
visibility = "visible";
};
};
})
];
};
};
};
mkTypingEffect = decl': let
decl =
decl'
|> projectOnto
{
head = "";
body = "";
};
in
Div {
id = "typing-wrapper";
content = [
(Div {
id = "typing-prompt";
content = Text decl.head;
})
(Div {
id = "typing-result";
content = Text decl.body;
})
];
};
}