レイヤーのメニューLayerMenuExperimental
地図に重ねて出すもの(雲・雨・国境など)を、組に分けて表示・非表示にするメニューです。タップで開き、長押しでまとめて消す・戻す。
プレビュー
いま:一部だけ表示(6件表示中)
状態とバリエーション
「すべて」が一部だけ
一部だけ表示しているとき、「すべて」の印は横棒になります(aria-pressed="mixed")。
天気
位置
地図
すべて表示
全部表示しているとき、「すべて」にもほかの行と同じチェックが付きます。
天気
位置
地図
すべて非表示
全部消えているとき、「すべて」の印は空になります。メニューを開くボタンも、背景色が薄くなります。
天気
位置
地図
使えない理由
地図の拡大が足りないなど、いま切り替えられないものは、行と状態を残したまま理由を一言出します。「すべて」を押しても、この行の状態は変わりません。
天気
位置
地図
プロパティ
表は横にスクロールできます
| プロパティ | 型 | 初期値 | 説明 |
|---|---|---|---|
| groups | LayerMenuGroup[] | - | 組と、その中の重ねるもの。 |
| value | string[] | - | 表示中のものの id。 |
| onValueChange | (value: string[]) => void | - | 表示・非表示が変わったとき。 |
| icon | ReactNode | - | メニューを開くボタンのアイコン。 |
| label | string | - | ボタンの名前とツールチップ。長押しで何が起きるかも、この文字列に含めます。 |
| allLabel | ReactNode | "All" | 先頭の「すべて」の行の言葉。 |
| longPressMs | number | 450 | 長押しとみなす長さ(ms)。0 で長押しなし。 |
| onLongPress | () => void | - | 長押しで切り替えたあと(端末を振動させて知らせる、などに)。 |
| size | "default" | "sm" | "lg" | "default" | ボタンの大きさ。 |
| side / align | string | "top" / "center" | メニューを開く位置。 |
| portalContainer | HTMLElement | null | - | メニューを描く先(全画面の地図の中など)。 |
| inline | boolean | false | ボタンを出さず、一覧だけを描く(広い画面の横の欄に)。 |
| open / onOpenChange | boolean / (open) => void | - | 開閉の状態を、使う側のコードで管理するとき。 |
使い方
"use client";
import * as React from "react";
import { LayerMenu, type LayerMenuGroup } from "@gunjo/ui";
import { IconEye } from "@tabler/icons-react";
const GROUPS: LayerMenuGroup[] = [
{
id: "weather",
label: "天気",
items: [
{ id: "cloud", label: "雲" },
// 使えないあいだは理由を一言。状態はそのまま残ります
{ id: "rain", label: "雨", disabledReason: "もっと拡大すると使えます" },
{ id: "night", label: "夜景", note: "夜側の街明かり" },
],
},
{
id: "map",
label: "地図",
items: [{ id: "border", label: "国境・県境" }],
},
];
export function MapLayers() {
const [value, setValue] = React.useState(["cloud", "night", "border"]);
return (
<LayerMenu
groups={GROUPS}
value={value}
onValueChange={setValue}
icon={<IconEye />}
// 長押しで何が起きるかも、名前に書いておきます
label="重ねるものを選ぶ(長押しでまとめて消す)"
allLabel="すべて"
onLongPress={() => navigator.vibrate?.(10)}
/>
);
}設計の判断
- 行を押してもメニューは閉じません。チェックが変わるところを見て確かめられるようにするためです。外を押すか Esc で閉じます。
- 「すべて」で戻る先は、消す前の組み合わせです。一度消して見比べ、元の見え方に戻すためです。覚えた組み合わせが無ければ、すべて表示になります。
- 使えない行を消さないのは、地図を拡大したときに何が出てくるかを、先に見せておくためです。
- 組の見出しと、右端の補足(「拡大すると出る」など)は、地図の上に重ねる文字専用の小さなサイズです。
text-canvas-sm(11px)を使います。地図の外に置く inline では、ふつうの 12px に戻します。項目の名前はしっかり読む文字なので、どちらでも 14px です。
使用コンポーネント
関連コンポーネント
- DropdownMenu
操作を選ぶと閉じるメニュー。長押しも3つの状態も無い。
- Checkbox
地図の上ではなく、ふつうのページのフォームで使う入力。
- FilterChips
一覧を絞り込む。重ねて描くものは選ばない。
- MapControlButton
このメニューを開くボタンそのもの。
いつ・なぜ使うか(UIXHERO)
「いつ・なぜ使うか」の判断は、姉妹サイト UIXHERO の記事で解説しています。