# 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; }) ]; }; }