gbr/ui/theme/lustre

GBR: UI Theme Lustre Module

Descrição

Módulo que sobre-escreve funções do módulo lustre/element/html utilizando o tipo ui.UITheme como argumento. Utiliza o tipo UILustre os tokens (ADT) que representam as funções lustre. Exemplo:

Sem ui.UITheme:

import lustre/element/html as h

pub fn main() {
  let theme = [
    // codigos p/ selecionar tema primário ou defaul (fallback)
    ...
  ]

  h.span(theme, [h.text("Olá mundo!")])
}

Com ui.Theme:

import gbr/ui/lustre as h

pub fn main() {
  ui.new()
  |> ui.with_variant(ui.primary())
  |> ui.with_appearance(ui.ghost())
  |> ui.with_design_to_tokens(fn(v, a, _) {
    case v, a {
      ui.VariantPrimary, _ -> [
        h.Style("display", "block"),
        h.Class("text-primary-700"),
        h.Classes([#("hover:text-primary-800", a == ui.AppearanceGhost)]),
      ]
      _, _ -> "text-gray-800"
    }
  })
  |> h.span([],[h.text("Olá mundo!")])
}

Implementaçâo Do Tema Usando o Lustre

Lustre + UIThemeBuilder

Utilizamos os design tokens do tema como uma estrutura de uma tupla #(String, Bool), compatível com a assinatura da função attribute.classes do lustre.

pub fn to_lustre(
  theme: UITheme(UILustre),
  attributes: List(a.Attribute(a)),
  elements: List(element.Element(a)),
  to_lustre: fn(List(a.Attribute(a)), List(element.Element(a))) ->
  element.Element(a),
) -> element.Element(a) {
  let engine_lustre = fn(token) {
    case token {
      Class(token) -> a.class(token)
      Classes(token) -> a.classes(token)
      Styles(token) -> a.styles(token)
      Style(key, value) -> a.style(key, value)
      Empty -> a.none()
    }
  }
  ui.view(theme, fn(tokens: List(UILustre)) {
    let attributes =
      list.map(tokens, engine_lustre)
      |> list.append(attributes)

    to_lustre(attributes, elements)
  })
}

A função acima é o coração deste módulo, ela converte a lista de tokens, representando os design tokens lustre gerados pelo tema, em um atributo lustre attribute.Attribute(msg), usando attribute.classes, a.class, a.styles, etc.

Abaixo segue como o tema utiliza a injeção desta implementação

import lustre/attribute as a
import lustre/element/html as h

pub fn new_theme_admin() {
  theme.new()
  |> theme.with_size_to_tokens(size_classes)
  |> theme.with_shape_to_tokens(rounded_classes)
  |> theme.with_elevation_to_tokens(border_classes)
  |> theme.with_stacking_to_tokens(stack_classes)
  |> theme.with_design_to_tokens(design_classes)
}

pub fn size_classes(size) {
  case size {
    ui.SizeMd -> "h-120 w-240"
    ui.SizeSm -> "h-90 w-120"
    // ...
  }
}
// ...

pub fn alert(text) {
  // Estilos externos
  let attributes = [ a.class("mb-2") ]

  // O texto do alerta (inner)
  let elements = [h.text(text)]

  let to_alert = fn(theme) {
    // Motor de design tokens para um elemento lustre
    to_lustre(theme, attributes, elements, h.div)
    |> theme.view(theme, _)
  }

  new_theme_admin()
  |> theme.with_variant(theme.VariantPrimary)
  |> theme.with_appearance(theme.AppearanceFill)
  |> theme.with_state(theme.StateFocus)
  |> theme.with_size(theme.SizeLg)
  |> theme.with_shape(theme.ShapePill)
  |> theme.with_elevation(theme.ElevationFlat)
  |> theme.with_stacking(theme.StackXxl)
  |> to_alert
}

Regra da Propriedade do CSS

Types

Tipos que representam os design tokens convertidos para atributos lustre.

  • Classes: Convertido para a.classes
  • Styles: Convertido para a.styles
  • Style: Convertido para a.style
  • Class: Convertido para a.class
pub type UILustre {
  Classes(List(#(String, Bool)))
  Styles(List(#(String, String)))
  Style(String, String)
  Class(String)
  Attribute(String, String)
  Empty
}

Constructors

  • Classes(List(#(String, Bool)))
  • Styles(List(#(String, String)))
  • Style(String, String)
  • Class(String)
  • Attribute(String, String)
  • Empty

Values

pub fn a(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn article(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define um conteúdo independente, auto-contindo.

pub fn aside(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define um conteúdo a parte do conteúdo principal.

pub fn button(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn details(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define detalhes adicionais que pode ser aberto para visualização.

  • Usado em conjunto com o summary(). Algumas interfaces oferecem uma descrição de resumo, summary, padrão.
pub fn div(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn footer(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define um rodapé para o documento ou seção.

pub fn h1(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn h2(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn h3(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn h4(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn h5(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn h6(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn header(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define um cabeçalho para o documento ou seção.

pub fn img(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
) -> element.Element(a)
pub fn input(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
) -> element.Element(a)
pub fn label(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn li(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn main(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn nav(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define um conjunto de links de navegação.

pub fn option(
  theme: theme.UITheme(UILustre),
  label: String,
  attributes: List(attribute.Attribute(a)),
) -> element.Element(a)

<select…><option …/>

pub fn p(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn pre(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn section(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define uma seção no documento.

pub fn select(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn span(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn summary(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)

Define o cabeçalho para o elemento details(), caso necessário.

pub fn svg(
  theme: theme.UITheme(UILustre),
  with attributes: List(attribute.Attribute(a)),
  inner elements: List(element.Element(a)),
) -> element.Element(a)
pub fn table(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn td(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn text(text: String) -> element.Element(a)
pub fn textarea(
  theme: theme.UITheme(UILustre),
  text: String,
  a: List(attribute.Attribute(a)),
) -> element.Element(a)
pub fn th(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn to_lustre(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
  to_lustre: fn(
    List(attribute.Attribute(a)),
    List(element.Element(a)),
  ) -> element.Element(a),
) -> element.Element(a)

Conversor dos design tokens para um elementos lustre.

  • theme: Design tokens gerados a partir do tema + o construtor de temas.
  • attributes: Atributos do elemento lustre.
  • elements: Elementos internos, caso necessário.
  • to_lustre: Construtor do elemento lustre.
pub fn tr(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
pub fn ul(
  theme: theme.UITheme(UILustre),
  attributes: List(attribute.Attribute(a)),
  elements: List(element.Element(a)),
) -> element.Element(a)
✨ Search Document