| Copyright | (c) 2025 Matthieu Court |
|---|---|
| License | Apache-2.0 |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Layoutz
Description
A simple Haskell port of the layoutz library for creating structured terminal layouts.
Synopsis
- class Element a where
- data Border
- class HasBorder a where
- data Color
- data Style
- data L
- data Tree = Tree String [Tree]
- layout :: [L] -> L
- text :: String -> L
- br :: L
- center :: Element a => a -> L
- center' :: Element a => Int -> a -> L
- row :: [L] -> L
- tightRow :: [L] -> L
- underline :: Element a => a -> L
- underline' :: Element a => String -> a -> L
- underlineColored :: Element a => String -> Color -> a -> L
- alignLeft :: Int -> String -> L
- alignRight :: Int -> String -> L
- alignCenter :: Int -> String -> L
- justify :: Int -> String -> L
- wrap :: Int -> String -> L
- box :: String -> [L] -> L
- statusCard :: String -> String -> L
- ul :: [L] -> L
- ol :: [L] -> L
- inlineBar :: String -> Double -> L
- table :: [String] -> [[L]] -> L
- section :: String -> [L] -> L
- section' :: String -> String -> [L] -> L
- section'' :: String -> String -> Int -> [L] -> L
- kv :: [(String, String)] -> L
- tree :: String -> [Tree] -> L
- leaf :: String -> Tree
- branch :: String -> [Tree] -> Tree
- margin :: String -> [L] -> L
- hr :: L
- hr' :: String -> L
- hr'' :: String -> Int -> L
- vr :: L
- vr' :: String -> L
- vr'' :: String -> Int -> L
- pad :: Element a => Int -> a -> L
- chart :: [(String, Double)] -> L
- spinner :: String -> Int -> SpinnerStyle -> L
- data SpinnerStyle
- plotSparkline :: [Double] -> L
- data Series = Series [(Double, Double)] String Color
- plotLine :: Int -> Int -> [Series] -> L
- data Slice = Slice Double String Color
- plotPie :: Int -> Int -> [Slice] -> L
- data BarItem = BarItem Double String Color
- plotBar :: Int -> Int -> [BarItem] -> L
- data StackedBarGroup = StackedBarGroup [BarItem] String
- plotStackedBar :: Int -> Int -> [StackedBarGroup] -> L
- data HeatmapData = HeatmapData [[Double]] [String] [String]
- plotHeatmap :: HeatmapData -> L
- plotHeatmap' :: Int -> HeatmapData -> L
- withBorder :: Border -> L -> L
- withColor :: Color -> L -> L
- withStyle :: Style -> L -> L
- render :: Element a => a -> String
- data LayoutzApp state msg = LayoutzApp {}
- data Key
- data Cmd msg
- cmdFire :: IO () -> Cmd msg
- cmdTask :: IO msg -> Cmd msg
- cmdAfterMs :: Int -> msg -> Cmd msg
- executeCmd :: Cmd msg -> IO (Maybe msg)
- data Sub msg
- = SubNone
- | SubKeyPress (Key -> Maybe msg)
- | SubEveryMs Int msg
- | SubBatch [Sub msg]
- data AppOptions = AppOptions {}
- defaultAppOptions :: AppOptions
- data AppAlignment
- runApp :: LayoutzApp state msg -> IO ()
- runAppWith :: AppOptions -> LayoutzApp state msg -> IO ()
- subKeyPress :: (Key -> Maybe msg) -> Sub msg
- subEveryMs :: Int -> msg -> Sub msg
- subBatch :: [Sub msg] -> Sub msg
Core Types
Constructors
| ColorDefault | |
| ColorBlack | |
| ColorRed | |
| ColorGreen | |
| ColorYellow | |
| ColorBlue | |
| ColorMagenta | |
| ColorCyan | |
| ColorWhite | |
| ColorBrightBlack | |
| ColorBrightRed | |
| ColorBrightGreen | |
| ColorBrightYellow | |
| ColorBrightBlue | |
| ColorBrightMagenta | |
| ColorBrightCyan | |
| ColorBrightWhite | |
| ColorFull Int | 256-color palette (0-255) |
| ColorTrue Int Int Int | 24-bit RGB true color (r, g, b) |
Constructors
| StyleDefault | |
| StyleBold | |
| StyleDim | |
| StyleItalic | |
| StyleUnderline | |
| StyleBlink | |
| StyleReverse | |
| StyleHidden | |
| StyleStrikethrough | |
| StyleCombined [Style] | Combine multiple styles |
L is the universal layout element type - a type-erased wrapper for the DSL.
This allows mixing different element types in layouts while providing a common interface. Uses existential quantification to store any Element type inside L.
Constructors: * L a - Wraps any Element (Text, Box, Table, etc.) * UL [L] - Special case for unordered lists (allows nesting) * AutoCenter L - Smart centering that adapts to layout context width * LBox, LStatusCard, LTable - Specialized constructors for bordered elements
Example usage: layout [text "title", box "content" [...], center (text "footer")] All different types unified as L, so they can be composed together.
Instances
| IsString L Source # | Enable string literals to be used directly as elements with OverloadedStrings With OverloadedStrings enabled, you can write: layout [Hello, World] instead of layout [text Hello, text World] |
Defined in Layoutz Methods fromString :: String -> L # | |
| Show L Source # | |
| Element L Source # | |
| HasBorder L Source # | |
Tree structure for hierarchical data
Basic Elements
Layout Functions
Create horizontal row with no spacing between elements (for gradients, etc.)
Containers
Widgets
section'' :: String -> String -> Int -> [L] -> L Source #
Create section with custom glyph and flanking chars
Visual Elements
margin :: String -> [L] -> L Source #
Create margin with custom prefix
Example usage: margin "[error]" [text "Something went wrong"] margin "[info]" [text "FYI: Check the logs"]
Spinners
spinner :: String -> Int -> SpinnerStyle -> L Source #
Create an animated spinner
Example usage:
spinner Loading 5 SpinnerDots -- Shows the 5th frame of dots spinner
spinner Processing 0 SpinnerLine -- Shows first frame with label
Increment the frame number each render to animate:
layout [spinner Working (tickCount mod 10) SpinnerDots]
data SpinnerStyle Source #
Spinner style with animation frames
Constructors
| SpinnerDots | |
| SpinnerLine | |
| SpinnerClock | |
| SpinnerBounce |
Instances
| Show SpinnerStyle Source # | |
Defined in Layoutz Methods showsPrec :: Int -> SpinnerStyle -> ShowS # show :: SpinnerStyle -> String # showList :: [SpinnerStyle] -> ShowS # | |
| Eq SpinnerStyle Source # | |
Defined in Layoutz | |
Visualizations
plotSparkline :: [Double] -> L Source #
Create a sparkline from a list of values
A data series for line plots: points, label, color
data StackedBarGroup Source #
A group of stacked bars: segments and group label
Constructors
| StackedBarGroup [BarItem] String |
plotStackedBar :: Int -> Int -> [StackedBarGroup] -> L Source #
Create a stacked vertical bar chart
data HeatmapData Source #
Heatmap data: grid of values, row labels, column labels
Constructors
| HeatmapData [[Double]] [String] [String] |
plotHeatmap :: HeatmapData -> L Source #
Create a heatmap with default cell width (6)
plotHeatmap' :: Int -> HeatmapData -> L Source #
Create a heatmap with custom cell width
Border utilities
Color utilities
withColor :: Color -> L -> L Source #
Apply a color to an element
Example usage: withColor ColorBrightYellow $ box Warning [text "Check logs"]
Style utilities
withStyle :: Style -> L -> L Source #
Apply a style to an element Example usage: withStyle StyleBold $ text "Important!"
Rendering
TUI Runtime
data LayoutzApp state msg Source #
The core application structure - Elm Architecture style
Build interactive TUI apps by defining: * Initial state and startup commands * How to update state based on messages * What events to subscribe to * How to render state to UI
Example: @ data CounterMsg = Inc | Dec
counterApp :: LayoutzApp Int CounterMsg
counterApp = LayoutzApp
{ appInit = (0, CmdNone)
, appUpdate = \msg count -> case msg of
Inc -> (count + 1, CmdNone)
Dec -> (count - 1, CmdNone)
, appSubscriptions = \_ -> subKeyPress $ \key -> case key of
KeyChar + -> Just Inc
KeyChar - -> Just Dec
_ -> Nothing
, appView = \count -> layout [text $ "Count: " <> show count]
}
@
Constructors
| LayoutzApp | |
Keyboard input representation
Constructors
| KeyChar Char | Regular character keys: |
| KeyCtrl Char | Ctrl+key: KeyCtrl |
| KeyEnter | Enter/Return key |
| KeyBackspace | Backspace key |
| KeyTab | Tab key |
| KeyEscape | Escape key |
| KeyDelete | Delete key |
| KeyUp | Up arrow |
| KeyDown | Down arrow |
| KeyLeft | Left arrow |
| KeyRight | Right arrow |
| KeySpecial String | Other unrecognized escape sequences |
Commands - side effects the runtime will execute after each update
cmdAfterMs :: Int -> msg -> Cmd msg Source #
Create a command that fires a message after a delay
Subscriptions - event sources your app listens to
Constructors
| SubNone | No subscriptions |
| SubKeyPress (Key -> Maybe msg) | Subscribe to keyboard input |
| SubEveryMs Int msg | Subscribe to periodic ticks (interval in ms + message) |
| SubBatch [Sub msg] | Combine multiple subscriptions |
data AppOptions Source #
Options for running a LayoutzApp. Use defaultAppOptions and override
the fields you care about:
runAppWith defaultAppOptions { optAlignment = AppAlignCenter } myApp
Constructors
| AppOptions | |
Fields
| |
Instances
| Show AppOptions Source # | |
Defined in Layoutz Methods showsPrec :: Int -> AppOptions -> ShowS # show :: AppOptions -> String # showList :: [AppOptions] -> ShowS # | |
| Eq AppOptions Source # | |
Defined in Layoutz | |
defaultAppOptions :: AppOptions Source #
Sensible defaults: left-aligned.
data AppAlignment Source #
App-level alignment within the terminal window
Constructors
| AppAlignLeft | |
| AppAlignCenter | |
| AppAlignRight |
Instances
| Show AppAlignment Source # | |
Defined in Layoutz Methods showsPrec :: Int -> AppAlignment -> ShowS # show :: AppAlignment -> String # showList :: [AppAlignment] -> ShowS # | |
| Eq AppAlignment Source # | |
Defined in Layoutz | |
runApp :: LayoutzApp state msg -> IO () Source #
Run an interactive TUI application with default options.
This function: * Sets up raw terminal mode (no echo, no buffering) * Clears screen and hides cursor * Enters event loop that: - Listens to subscribed events (keyboard, ticks, etc.) - Dispatches messages to update function - Updates state and re-renders * Restores terminal on exit (ESC, Ctrl+C, or Ctrl+D)
Press ESC, Ctrl+C, or Ctrl+D to quit the application.
runAppWith :: AppOptions -> LayoutzApp state msg -> IO () Source #
Run an interactive TUI application with custom options.
runAppWith defaultAppOptions { optAlignment = AppAlignCenter } myApp
Subscriptions
subEveryMs :: Int -> msg -> Sub msg Source #
Subscribe to periodic ticks with custom interval (milliseconds)