Skip to content
fandhe-frontendcore v0.4.3
GitHub

hero-image-tiles

badge / heading / text / button / image の 5 部品だけで組み立てた、画像タイルのコラージュ付きヒーローです。新しい UI 部品は追加していません。

左側に告知バッジ・見出し・リード文・CTA ボタン 2 個を縦に並べ、右側には縦長の画像タイル 5 枚を 3 列(1・2・2 枚)に分けて配置します。各列は上下にオフセットさせ、段違いに見えるコラージュにしています。タイルの角丸・影はテーマトークン(--fandhe-radius-xl・--fandhe-shadow-lg)で付けています。

lg(1024px)未満ではテキストの下にタイル列を横並びで配置し、はみ出す分は overflow: hidden で隠します。breakpoint は lg の 1 段のみで、<form> は使わず送信処理・データ取得を持たない静的な合成例です。画像はすべて同一のプレースホルダーで実データを持たず、装飾用途として alt="" にしています。

Demo

Now in preview

チームの制作物を、届くところまで速く

撮影から公開までの制作フローを一つの場所にまとめ、チーム全員が同じ進捗を見ながら進められます。

使用部品

Rust コード

Rust
use crate::blocks::dummy_assets;
use fandhe_frontend_core::{div, text, Node};
use fandhe_frontend_pre_styled_ui::badge::{self, BadgeProps};
use fandhe_frontend_pre_styled_ui::button::{self, ButtonProps, ButtonVariant};
use fandhe_frontend_pre_styled_ui::heading::{
    self as styled_heading, HeadingLevel, HeadingProps, HeadingSize,
};
use fandhe_frontend_pre_styled_ui::image::{self, AspectRatio, ImageProps};
use fandhe_frontend_pre_styled_ui::text::{self as styled_text, TextProps, TextSize, TextVariant};

/// 列ごとのタイル枚数配分(左から 1・2・2 枚、合計 5 枚固定)。
const COLUMNS: [usize; 3] = [1, 2, 2];

/// テキスト列(告知バッジ → 見出し → リード文 → CTA 2 個)。
fn copy() -> Node {
    let eyebrow = badge::badge(&BadgeProps::default(), vec![], vec![text("Now in preview")]);
    let title = styled_heading::heading(
        HeadingLevel::H3,
        &HeadingProps {
            size: HeadingSize::Xl4,
            ..HeadingProps::default()
        },
        vec![],
        vec![text("チームの制作物を、届くところまで速く")],
    );
    let lead = styled_text::text(
        &TextProps {
            size: TextSize::Lg,
            variant: TextVariant::Muted,
            ..TextProps::default()
        },
        vec![],
        vec![text(
            "撮影から公開までの制作フローを一つの場所にまとめ、チーム全員が同じ進捗を見ながら進められます。",
        )],
    );
    let actions = div(
        vec![("class", "blocks-hero-image-tiles-actions")],
        vec![
            button::button(&ButtonProps::default(), vec![], vec![text("Get started")]),
            button::button(
                &ButtonProps {
                    variant: ButtonVariant::Outline,
                    ..ButtonProps::default()
                },
                vec![],
                vec![text("See how it works")],
            ),
        ],
    );
    div(
        vec![("class", "blocks-hero-image-tiles-copy")],
        vec![eyebrow, title, lead, actions],
    )
}

/// タイル 1 枚分。角丸・影はラッパ `div` 側で付け、`image` 自体は既定
/// shape のまま使う(モジュール doc「タイルの角丸・影」節)。
fn tile() -> Node {
    div(
        vec![("class", "blocks-hero-image-tiles-tile")],
        vec![image::image(
            &ImageProps {
                aspect_ratio: AspectRatio::Portrait,
                ..ImageProps::new(dummy_assets::PRODUCT_SRC, "")
            },
            vec![("data-blocks-hero-image-tiles-image", "")],
        )],
    )
}

/// 列 1 本分(`count` 枚のタイルを縦に並べる)。
fn column(index: usize, count: usize) -> Node {
    let column_number = (index + 1).to_string();
    div(
        vec![
            ("class", "blocks-hero-image-tiles-column"),
            (
                "data-blocks-hero-image-tiles-column",
                column_number.as_str(),
            ),
        ],
        (0..count).map(|_| tile()).collect(),
    )
}

/// 右側のコラージュ(3 列、枚数配分は [`COLUMNS`])。
fn collage() -> Node {
    div(
        vec![("class", "blocks-hero-image-tiles-collage")],
        COLUMNS
            .iter()
            .enumerate()
            .map(|(i, &count)| column(i, count))
            .collect(),
    )
}

/// `hero-image-tiles` の Demo 本体。呼び出しごとに同一の `Node` を返す
/// 純関数。
pub fn demo() -> Node {
    div(
        vec![("class", "blocks-hero-image-tiles-grid")],
        vec![copy(), collage()],
    )
}

原案差分メモ

参照(対応表 ID R1012)はローカル取り込み前の一時ディレクトリ(_/blocks-intake/)を出典としていますが、本実装セッションからは参照素材そのものを読めない状態でした。そのため以下はイシュー本文のレイアウト仕様(左テキスト・右 3 列コラージュ・列ごとの上下オフセット・lg 未満の横並び退行)のみから独自に設計したものであり、参照元の文言・配色・装飾は持ち込んでいません。

  • 文言・見出し・リード文はすべて独自に書き起こしたもので、実在ブランドの文言・配色は含みません。
  • タイルの角丸・影はテーマトークン(--fandhe-radius-xl・--fandhe-shadow-lg)で付け、色そのものはテーマ既定に委ねています(参照元の配色は持ち込みません)。
  • 列の幅配分・オフセット量(--fandhe-space-* トークン)は参照素材が読めないため、イシューの「上下にずらす」という記述から違和感のない値を選んで実装しました。素材が閲覧できる環境での見た目の微調整はスコープ外としています。
  • breakpoint は lg(1024px)の 1 段のみとし、sm/md は新設していません。
  • 画像は dummy_assets のプレースホルダーで alt=""(装飾扱い)にしました。
  • id・href・<form> は出力しません。