概要
hypersig::style は型の付いた atomic CSS です。プロパティ名やキーワードの綴りを間違えたり、型の違う値を渡したりするとコンパイルエラーになります。宣言は 1 つごとに 1 つのクラスになります。
スタイルは Rust の値
Style には、標準の CSS プロパティとアンカー配置のプロパティごとに 1 つずつメソッドがあります。プロパティの一覧、各プロパティのキーワード、擬似クラス、擬似要素、名前付きの色は、MDN の CSS データ(mdn-data 2.37.2)から生成しています。要素にスタイルを付けるには El::css を使います。
use hypersig::html::button;
use hypersig::style::Style;
use hypersig::style::value::{Color, Cursor, FontWeight, px, rem};
use hypersig::{Page, Signals};
use serde::{Deserialize, Serialize};
#[derive(Signals, Serialize, Deserialize)]
struct Shop {
count: i32,
}
let buy = button::<Shop>()
.css(
Style::new()
.padding_block(rem(0.5))
.padding_inline(rem(1))
.border_radius(px(6))
.background_color(Color::hex(0x0018_181b))
.color(Color::WHITE)
.font_weight(FontWeight::Number(500.0))
.cursor(Cursor::Pointer),
)
.text("Buy");
let html = Page::new("Shop", Shop { count: 0 }).child(buy).render();
// One class per declaration, named after it, and one rule per class in <head>.
assert!(html.contains("cursor_pointer"));
assert!(html.contains(".cursor_pointer{cursor:pointer}"));同じ条件の下で同じプロパティのメソッドをもう一度呼ぶと、CSS のルールで後に書いた宣言と同じく、後の値が前の値を置き換えます。merge は別のスタイルの宣言を足し、足した側の宣言が元の宣言を上書きします。
宣言ごとに 1 つのクラス
宣言はそれぞれ 1 つのクラスになり、クラス名は cursor_pointer や hover:color_crimson のように宣言から決まります。Panda CSS や Tailwind CSS の atomic CSS と同じ方式です。英字、数字、.、#、%、- 以外の文字を含む値では、値のハッシュをクラス名に使います。同じ宣言を持つ 2 つの要素は同じクラスを使うので、スタイルシートは要素の数ではなく異なる宣言の数に応じて大きくなります。
ページは要素が使うスタイルを集め、各ルールを 1 回だけ <head> に書きます。新しい要素を含むパッチにはその要素のルールも含まれ、ルールはブレークポイントの値が引き続き基本の値を上書きする位置に入ります。
シグナルで切り替わるスタイル
css_when(style, cond) はシグナルの条件が成り立つ間だけスタイルを足し、css_match(value, cases) はシグナルの値ごとにスタイルを 1 つ選びます(Panda CSS の recipe の variants に当たります)。これらのルールは css のルールより後ろのカスケードレイヤーに入るので、有効な間は同じプロパティについて要素自身の宣言を上書きします。
| カスケードレイヤー | 入るもの |
|---|---|
hypersig-tokens | Theme が :root に設定する値 |
hypersig-base | リセットなど、Global のルール |
hypersig-atoms | El::css のクラス |
hypersig-toggled | El::css_when と El::css_match のクラス |
レイヤーはこの順に並ぶので、要素のクラスはグローバルなルールを上書きし、有効になったスタイルはその両方を上書きします。Page::style で足したスタイルシートはどのレイヤーにも入らず、4 つのレイヤーすべてを上書きします。