English

レイアウトのパターン

hypersig::style::pattern には、よく使うレイアウトのスタイルを返す関数があります。返されたスタイルは自分のスタイルと merge して使います。

use hypersig::html::{div, span};
use hypersig::style::Media;
use hypersig::style::pattern::{center, circle, container, grid, hstack, spacer, stack, visually_hidden};
use hypersig::style::value::rem;
use hypersig::Signals;
use serde::{Deserialize, Serialize};

#[derive(Signals, Serialize, Deserialize)]
struct Gallery {
    count: i32,
}

let page = div::<Gallery>()
    // At most 64rem wide, centered, with 1rem on both sides.
    .css(container(rem(64), rem(1)))
    .child(
        div()
            .css(hstack(rem(0.5)))
            .child(div().css(circle(rem(2)).merge(center())).text("A"))
            .child(span().text("Ada"))
            .child(div().css(spacer()))
            .child(span().css(visually_hidden()).text("3 new messages")),
    )
    .child(
        // One column, then three from the medium breakpoint.
        div()
            .css(grid(1, rem(1)).on(Media::Md, grid(3, rem(1))))
            .children((1..=6).map(|n| div().css(stack(rem(0.25))).text(n.to_string()))),
    );
パターン並べ方
stack(gap)、vstack(gap)子を縦 1 列に並べ、vstack は横方向の中央に揃えます
hstack(gap)子を横 1 行に並べ、行の中で縦の中央に揃えます
wrap(gap)子を横に並べ、収まらない分を次の行に折り返します
grid(columns, gap)、grid_item(columns)等しい幅の列のグリッドと、複数の列にまたがる子
container(max, padding)幅が max を超えない中央寄せのブロックで、左右に余白があります
center()、spacer()子を縦横の中央に置くボックスと、空いた場所を埋める空の flex の子
square(size)、circle(size)、aspect_ratio(ratio)形の決まったボックス
divider(width, color)ボックスを横切る線
visually_hidden()画面には見えず、スクリーンリーダーには読まれる要素
link_overlay()位置指定された祖先を覆うリンクで、カード全体をクリックできるようにします

実行結果

layout.rs
use hypersig::html::{div, span};
use hypersig::style::Style;
use hypersig::style::pattern::{center, circle, grid, hstack, spacer, stack};
use hypersig::style::value::{Color, FontWeight, px, rem};
use hypersig::{Page, Signals};
use hypersig_ui::{BadgeVariant, ButtonSize, ButtonVariant, badge, button, token};
use serde::{Deserialize, Serialize};

#[derive(Signals, Serialize, Deserialize)]
pub struct Team {
    columns: i32,
}

pub fn page() -> Page<Team> {
    let tile = || {
        div().css(
            center()
                .height(rem(3))
                .border_radius(px(6))
                .background_color(token::muted().var()),
        )
    };
    Page::new(
        "チーム",
        Team { columns: 0 },
    )
    .child(
        div()
            .css(stack(rem(1.25)))
            .child(
                div()
                    .css(hstack(rem(0.75)))
                    .child(
                        div()
                            .css(
                                circle(rem(2.5))
                                    .background_color(Color::hex(0x0018_181b))
                                    .color(Color::WHITE),
                            )
                            .text("AL"),
                    )
                    .child(
                        span()
                            .css(Style::new().font_weight(FontWeight::Number(600.0)))
                            .text("Ada Lovelace"),
                    )
                    .child(badge(BadgeVariant::Secondary).text("管理者"))
                    .child(div().css(spacer()))
                    .child(
                        button(ButtonVariant::Outline, ButtonSize::Sm).text("メッセージ"),
                    ),
            )
            .child(
                div()
                    .css(grid(3, rem(0.75)))
                    .children((1..=6).map(|n| tile().text(n.to_string()))),
            ),
    )
}