Macaw.Layers.Theme.Extension behaviour (macaw_layers v0.3.0)

Copy Markdown View Source

What an adopter registers beyond the library's vocabulary (spec/04 §3.4), so one theme styles it: palette names in a group of the palette, and names of the color table, each with its default, and the words its styles and defaults use, for the theme's JSON reader.

defmodule MyApp.Marks do
  @behaviour Macaw.Layers.Theme.Extension
  def name, do: "marks"
  def styles, do: %{lane: {:furniture, %{stroke: %{type: :solid, color: {:color, :lane}}}}}
  def colors, do: %{lane: Macaw.Layers.Color.parse!("#8a8f99")}
  def words, do: %{keys: [:curve_kind], atoms: [:monotone_x]}
end

Macaw.Layers.Theme.new(extensions: [MyApp.Marks])

A name is a string inside a theme, an extension's as the library's (spec/04 §2.1): the names styles/0 and colors/0 give, and the names in their entries' typed colors, are read as their strings, so :lane and "lane" are one name; giving one both ways in one map raises ArgumentError naming the extension.

words/0, optional, is the vocabulary its styles and defaults use beyond the library's: the keys and the atom values a theme document's JSON form may spell (spec/01 §5). A theme built in Elixir keeps every word as given; the JSON reader makes an atom of a word only from the library's tables and the registered extensions' words/0 (Macaw.Layers.Theme.Document.from_json/2's extensions:), so no atom is made from a document.

style_type/0, optional, is the adopter's style type: a fragment type of a style node (Macaw.Layers.Fragment, as Macaw.Layers.Theme.Style is) with its own hooks, normalize/4 and under/3 (spec/02 §3.3), with which the theme stacks its palette entries in place of Macaw.Layers.Theme.Style, in style/2, its list entries and its contracts alike. At most one of a theme's extensions gives one; two raise ArgumentError naming both.

A theme carries its extensions in extensions, given explicitly and default closed: a palette or color name that neither the library nor an extension has is a fault naming it. The names an extension adds are held to the contracts of their group, its default entries included. Two extensions adding one name, or an extension adding a library name, raise ArgumentError naming both. A color an extension adds is a color value, a literal %Macaw.Layers.Color{} or a typed color; text raises ArgumentError naming the extension, since a string is never a color.

Summary

Types

A group of the palette an extension's style joins.

Callbacks

The names it adds to the color table, each with its default value: a color value.

The extension's name, for faults.

The style type the theme stacks its palette entries with: a fragment type of a style node with the adopter's own hooks (spec/02 §3.3).

The palette names it adds, each in a group with its default entry.

The words its styles and defaults use beyond the library's: the keys, and the atom values, a theme document's JSON form may spell.

Types

group()

@type group() :: :state | :furniture | :modifier

A group of the palette an extension's style joins.

Callbacks

colors()

@callback colors() :: %{
  required(atom() | String.t()) => Macaw.Layers.Color.value() | map()
}

The names it adds to the color table, each with its default value: a color value.

name()

@callback name() :: String.t()

The extension's name, for faults.

style_type()

(optional)
@callback style_type() :: module()

The style type the theme stacks its palette entries with: a fragment type of a style node with the adopter's own hooks (spec/02 §3.3).

styles()

@callback styles() :: %{required(atom() | String.t()) => {group(), map() | list()}}

The palette names it adds, each in a group with its default entry.

words()

(optional)
@callback words() :: %{optional(:keys) => [atom()], optional(:atoms) => [atom()]}

The words its styles and defaults use beyond the library's: the keys, and the atom values, a theme document's JSON form may spell.