Stylesheet primitives for LiveView Native
The library is usually the dependency of another high level lib
If available in Hex, the package can be installed
by adding live_view_native_stylesheet
to your list of dependencies in mix.exs
:
def deps do
[
{:live_view_native_stylesheet, "~> 0.3.0"}
]
end
All LiveViewNative Stylesheet output can be configured. By default
annotations and pretty printing is enabled. If you want smaller outputs
for prod
environments you'll need these options off:
config :live_view_native_stylesheet,
annotations: false,
pretty: false
defmodule MyCustomerRulesParser do
use LiveViewNative.Stylesheet.RulesParser, :swiftui
defmacro __using__(_) do
quote do
import MyCustomRulesParser, only: [sigil_RULES: 2]
import MyCustomRulesHelpers
end
end
def parse(rules) do
# your custom parser defined here
end
end
The format
passed in during the use
will define a new sigil_RULES/2
function within
your customer parser. The format
is carried through this function so make sure it matches
the format
used for the sheet itself.
You must implement the __using__/1
macro and at least import
sigil_RULES/2
from your
custom parser. sigil_RULES/2
is injected into your module from LiveViewNative.Stylesheet.RulesParser
.
This is also a good place to include other import
s that are necessary to support the compilation of
the final stylsheet. In the example above import MyCustomRulesHelpers
may include additional helpers
available to your parser's rule set.
You must implement the parse/1
function as this is your primary hook for parsing the rules
found within the body of each class from the sheet
New stylesheets can be defined specific to each platform.
Note that variable interpolation is done with { }
within the rules.
defmodule MySheet do
use LiveViewNative.Stylesheet, :swiftui
~SHEET"""
"color-" <> color_name do
color(.{color_name})
end
"""
def class("color-" <> color_name) do
~RULES"""
color(.{color_name})
"""
end
def class("star-red") do
~RULES"""
background(alignment: .leading){:star-red}
"""
end
def class("star-blue") do
~RULES"""
background(alignment: .trailing){:star-blue}
"""
end
end
Stylesheets output only exactly what class names are matched in the templates. This is true of pattern matched class names as well. This keeps the output small lookups fast on the client.
To compile a stylesheet you simply provide a list of class names and a map of ASTs will be produced. Using MySheet
from above:
MySheet.compile_ast(~w[color-blue star-red])
=> %{
"color-blue" => [{:color, [], [{:., [], [nil, :blue]}]}] [["color", [[".blue", :IME]], nil]]
"star-red" => [{:background, [], [[alignment: {:., [], [nil, :trailing]}, content: :"star-red"]]}]
}
This map will be sent to the client for looking up the styles at runtime and applying with little to no parsing on the client side:
<Text class="color-blue star-red">
ABCDEF
<Star template="star-red" class="color-red"/>
</Text>
Some style/modifier values make more sense as attrs on the element itself. Custom parsers should
support attr(value)
:
def class("searchable") do
~RULES"""
searchable(placeholder: attr(placeholder))
"""
end
This will instruct the client to get the value from the element the class name matches on:
<Text class="searchable" placeholder={@placeholder}>Hello, world!</Text>
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/live_view_native_stylesheet.