Orange.Macro (orange v0.4.0)
Macros for creating Orange primitive components
Currently, Orange supports three primitive components:
rect
for creating a rectangleline
for creating a linespan
for creating a span
Examples
Macro provides an ergonomic way to create Orange components. For example, the following code:
rect style: [width: 12, border: true], direction: :row do
span style: [color: :red] do
"Hello"
end
span do
"World"
end
end
will produce the following struct:
%Orange.Rect{
children: [
%Orange.Line{
children: [
%Orange.Span{children: ["Hello"], attributes: [style: [color: :red]]}
],
attributes: []
},
%Orange.Line{
children: [%Orange.Span{children: ["World"], attributes: []}],
attributes: []
}
],
attributes: [style: [width: 12, border: true], direction: :row]
}
Components children
Orange components can have children, provided by the do block. The syntax took inspiration from HTML:
rect do
span do
"Hello"
end
span do
"World"
end
end
The children can also be a list of components. This is useful when you want to render a collection of components. For example:
rect do
[
span do
"Hello"
end,
span do
"World"
end
]
end
Normal Elixir expression works inside the children block. For example, here's how to conditionally render components:
rect do
if :rand.uniform() > 0.5 do
"Hello"
else
"World"
end
end
Styling
Sizing
:width
- the width of the component:height
- the height of the component
The values for width
and height
can be:
An integer - the number of cells in the terminal. For example:
style: [width: 10]
A percentage string - the size is equal to the given percentage of the parent size. For example:
style: [width: "50%"]
An calc expression - the size is calculated based on the given expression. For example:
style: [width: "calc(100% - 10)"]
A fraction string - the size is calculated based on the given fraction of the parent size. All sibling components MUST also have a fraction size. The size will be calculated based on the component fraction divided by the sum of all sibling fractions. For example:
rect style: [width: 12] do rect style: [width: "1fr"] do end rect style: [width: "2fr"] do end end
In this example, the first rect will have a width of 1/3 of the parent rect, and the second rect will have a width of 2/3 of the parent rect.
Padding
Padding for the render box's inner content. The values for padding
can be:
One integer - padding for all sides. For example:
style: [padding: 1]
means[padding_top: 1, padding_bottom: 1, padding_left: 1, padding_right: 1]
Two integers tuple - padding vertical and padding horizontal. For example:
style: [padding: {1, 2}]
means[padding_top: 1, padding_bottom: 1, padding_left: 2, padding_right: 2]
Four integers tuple - padding top, right, bottom, left respectively. For example:
style: [padding: {1, 2, 3, 4}]
means[padding_top: 1, padding_bottom: 3, padding_left: 4, padding_right: 2]
Border
:border
- whether to render a border around the rect. Defaults tofalse
:border_top
- whether to render a top border. Defaults totrue
ifborder
istrue
:border_bottom
- whether to render a bottom border. Defaults totrue
ifborder
istrue
:border_left
- whether to render a left border. Defaults totrue
ifborder
istrue
:border_right
- whether to render a right border. Defaults totrue
ifborder
istrue
:border_color
- the color of the border. See Color section for supported colors
Text modifiers
An array of modifiers which adjust the text style. Supported modifiers are:
:bold
:dim
:italic
:underline
:strikethrough
Color
:color
- the color of the component text. The color value can be inherited from the parent component. If the color value is not specified, the component will inherit the color from the parent component:background_color
- the color of the component background
The values for :color
and :background_color
is a single atom representing the color. Supported colors are:
:white
:black
:grey
:dark_grey
:red
:dark_red
:green
:dark_green
:yellow
:dark_yellow
:blue
:dark_blue
:magenta
:dark_magenta
:cyan
:dark_cyan
Position
Rect elements support positioning. Supported values are:
{:fixed, top, right, bottom, left}
- the rect will be fixed at the given position. The values are offset to the respective edge of the screen. For example:rect position: {:fixed, 1, 2, 1, 2} do "Fixed position" end
will render:
Summary
Functions
Generates a Orange.Line
struct
Generates a Orange.Rect
struct
Generates a Orange.Span
struct
Functions
Generates a Orange.Line
struct
Options
:style
- style attributes for the line. Supported keys are:
Children validation
Line only accepts Orange.Span
as children. To provide better ergonomics, the macro will automatically wrap string to Orange.Span
. For example, the following code:
line do
"Hello"
end
will produce the result:
%Orange.Line{
children: [%Orange.Span{children: ["Hello"], attributes: []}],
attributes: []
}
Examples
iex> import Orange.Macro
iex> line style: [width: 5, color: :red] do
...> span do
...> "foo"
...> end
...> end
%Orange.Line{
children: [%Orange.Span{children: ["foo"], attributes: []}],
attributes: [style: [width: 5, color: :red]]
}
Generates a Orange.Rect
struct
Options
:direction
- the direction to layout children:row
or:column
(default):style
- style attributes for the rect. Supported keys are::title
- the title of the rect. If specified, it impliesborder
istrue
. The title can be a string or a map with supported keys are::text
- the title text. This field is required:color
- the title color. This field is optional:text_modifiers
- the title text modifiers. See Text modifiers section. This field is optional:offset
- an integer specifies the title offset from the left edge. This field is optional and defaults to 0
:scroll_x
- the horizontal scroll offset:scroll_y
- the vertical scroll offset:position
- the position of the rect. See Position section
Children validation
Rect only accepts Orange.Rect
and Orange.Line
as children. To provide better ergonomics, the macro will automatically wrap Orange.Span
and string to Orange.Line
. For example, the following code:
rect do
"Hello"
end
rect do
span do
"Hello"
end
end
will both produce the result:
%Orange.Rect{
children: [
%Orange.Line{
children: [%Orange.Span{children: ["Hello"], attributes: []}],
attributes: []
}
],
attributes: []
}
Examples
iex> import Orange.Macro
iex> rect style: [width: 5, border: true], direction: :row do
...> "foo"
...>
...> span do
...> "bar"
...> end
...> end
%Orange.Rect{
children: [
%Orange.Line{
children: [%Orange.Span{children: ["foo"], attributes: []}],
attributes: []
},
%Orange.Line{
children: [%Orange.Span{children: ["bar"], attributes: []}],
attributes: []
}
],
attributes: [style: [width: 5, border: true], direction: :row]
}
Generates a Orange.Span
struct
Options
:style
- style attributes for the line. Supported keys are:
Children validation
Span only accepts a single string as children
Examples
iex> import Orange.Macro
iex> span style: [color: :red] do
...> "foo"
...> end
%Orange.Span{children: ["foo"], attributes: [style: [color: :red]]}