Skip to content
fandhe-frontendcore v0.4.3
GitHub

Color Picker

HSV 色相環 + アルファ選択のポップオーバー型入力です。色領域・チャンネルスライダーの見た目は CSS グラデーションと thumb 位置のみで表現し、canvas/web-sys には依存しません(値の算出は決定的な純粋関数が担います)。

fandhe-frontend-headless-ui の color_picker mod が提供する構造・アクセシビリティ(WAI-ARIA・キーボード操作)・表示状態(data-*)のみを持つ unstyled 部品です。Themes 版が備える見た目(実際のグラデーション CSS 等)は持たず、anatomy・ARIA・data-* のみを提供します。CSS は利用者が当てます。

ColorPickerProps(disabled/readonly/invalid/required)が Root/Label/Control/Trigger/Area/AreaBackground/AreaThumb/ChannelInput へ data-disabled/data-readonly/data-invalid を一律付与し、Label のみ追加で data-required を付与します(required は <input type="hidden"> である HiddenInput には効果を持たせません)。ChannelSlider/ChannelSliderTrack/ChannelSliderThumb は Channel::as_str() の固定語彙(hue/saturation/value/alpha)による data-channel と、Orientation 引数による data-orientation を出力します(ChannelSliderThumb には aria-orientation も付与)。ChannelInput は data-channel="hex" 固定リテラルを出力し、readonly のときネイティブ readonly 属性、invalid のとき aria-invalid="true" を追加します(valid のときは aria-invalid 自体を省略します)。

キーボード操作

キー対象効果
EnterTriggerpopover を開く(dispatch "open")
EnterChannelInputHEX 文字列を確定する(dispatch "set_hex")
EscContentpopover を閉じる(dispatch "close"。trigger へのフォーカス復帰は呼び出し側の DOM 配線が担います)
ArrowLeft / ArrowRightChannelSliderThumb該当チャンネルを 1 減らす/増やす(dispatch "decrement"/"increment"、0..=Channel::max() へ clamp、ラップしません)
ArrowUp / ArrowDownAreaThumb彩度・明度をそれぞれ 1 単位変化させる(dispatch "set_channel" で表現)
Home / EndChannelSliderThumb最小値・最大値へ設定する(dispatch "set_channel" の 0/最大値ペイロードで表現)

ポインタ・キーボード操作の実際の DOM 配線(fandhe-frontend-wasm-full)は本イシューのスコープ外です。本部品は SSR 静的マークアップと dispatch 契約のみを提供します。

スタイル済みの表示例は Color Picker を参照してください。

関連 API: fandhe-frontend-headless-ui API

自前 CSS の最小例

Themes 版を使わず本部品を直接使う場合、[data-scope="color-picker"][data-part="..."] セレクタでスタイルを当てます。以下は area/area-thumb の配置、hue スライダーのグラデーション、状態セレクタの最小例です。

CSS
[data-scope="color-picker"][data-part="area"] {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
}

[data-scope="color-picker"][data-part="area-thumb"] {
  position: absolute;
  /* --fandhe-color-picker-x/-y は呼び出し側が area-thumb の attrs
     経由で style 属性に設定する(例:
     ("style", "--fandhe-color-picker-x: 40%; --fandhe-color-picker-y: 30%"))。 */
  left: var(--fandhe-color-picker-x, 0%);
  top: var(--fandhe-color-picker-y, 0%);
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  border: 2px solid #fff;
  transform: translate(-50%, -50%);
}

[data-scope="color-picker"][data-part="hue-slider-track"] {
  height: 0.75rem;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    red,
    yellow,
    lime,
    cyan,
    blue,
    magenta,
    red
  );
}

[data-scope="color-picker"][data-part="root"][data-disabled] {
  opacity: 0.5;
}

[data-scope="color-picker"][data-part="channel-input"][data-invalid] {
  outline: 2px solid crimson;
}

[data-scope="color-picker"][data-part="trigger"][data-state="open"] {
  outline: 2px solid #333;
}

Demo

枠線・余白は docs サイト側のデモ枠であり、fandhe-frontend-headless-ui 自体はスタイルを持ちません。

Color
Color (readonly/invalid)

Features

  • root/label/control/trigger/positioner/content/area/area_background/area_thumb/channel_slider(+track/+thumb)/channel_input/value_text/hidden_input の anatomy を持ち、Disclosure(開閉)+ HSV + アルファの値状態機械と組み合わせる(color_picker.rs:1-9)。
  • ColorPickerProps(disabled/readonly/invalid/required)を root/label/control/trigger/area/area_background/area_thumb/channel_input へ一律付与し、label のみ data-required を追加する(イシュー #1604 参照突合、color_picker.rs:277-291)。
  • trigger は type="button" + aria-haspopup="dialog" を固定付与し、controls が Some のとき aria-controls で content と関連付ける(color_picker.rs:426-452)。
  • content(role="dialog")・area_thumb/channel_slider_thumb(role="slider")が WAI-ARIA の該当パターンへ従う(color_picker.rs:470-489, 524-547, 592-628)。
  • channel_slider(+track/+thumb) は Channel::as_str() 固定語彙による data-channel と、Orientation 引数による data-orientation(thumb には aria-orientation も)を出力する(color_picker.rs:549-628)。
  • channel_input は data-channel="hex" 固定リテラルを出力し、readonly ネイティブ属性・aria-invalid(invalid のときのみ)を追加する(color_picker.rs:632-657)。
  • increment/decrement dispatch(Channel 固定語彙 payload)は現在値を ±1 し 0..=Channel::max() へ clamp する(ラップしない、color_picker.rs:1049-1103)。
  • 色領域・スライダーの見た目は CSS グラデーションと決定的な導出 getter のみで表現し、canvas/web-sys へ一切依存しない(color_picker.rs:11-18)。

Anatomy

root
  label
  control
    trigger
  positioner
    content
      area
        area-background
        area-thumb
      hue-slider
        hue-slider-track
          hue-slider-thumb
      channel-input
      value-text
      hidden-input

API Reference

Arguments

NameTypeDefaultDescription
root(state) / control(state) / trigger(state) / content(state)OpenStateOpenState::Closed開閉状態。data-state・aria-expanded・positioner の hidden 出力の判定に使われる(同じ型のため代表 1 行に集約)。
root/label/control/trigger/area/area_background/area_thumb/channel_input(props)&ColorPickerProps&ColorPickerProps::default()disabled/readonly/invalid を一律付与する(label のみ追加で required→data-required)。
trigger(controls)Option<&str>NoneSome のとき aria-controls で content と関連付ける(color_picker.rs:439-441)。
area_thumb(hex)&str—2 次元 slider(role="slider")の aria-valuetext。現在色の HEX 正規形(color_picker.rs:524-537)。
channel_slider/channel_slider_track/channel_slider_thumb(channel, orientation)Channel, Orientation—data-channel(固定語彙)と data-orientation(thumb には aria-orientation も)を出力する(color_picker.rs:549-628)。
channel_slider_thumb(min, max, now)&str, &str, &str—WAI-ARIA slider パターンの aria-valuemin/aria-valuemax/aria-valuenow(color_picker.rs:592-628)。
hidden_input(name, value, props)&str, &str, &ColorPickerProps—フォーム送信用の実体(type="hidden"、props.disabled のときのみ disabled 属性、required は付けない、color_picker.rs:676-691)。

Data Attributes

PartAttributeObserved Values
channel-inputdata-channelhex
channel-inputdata-invalid(値なし)
channel-inputdata-readonly(値なし)
contentdata-stateclosed, open
controldata-invalid(値なし)
controldata-readonly(値なし)
controldata-stateclosed, open
hue-sliderdata-channelhue
hue-sliderdata-orientationhorizontal
hue-slider-thumbdata-channelhue
hue-slider-thumbdata-orientationhorizontal
hue-slider-trackdata-channelhue
hue-slider-trackdata-orientationhorizontal
labeldata-invalid(値なし)
labeldata-readonly(値なし)
labeldata-required(値なし)
positionerdata-stateclosed, open
rootdata-invalid(値なし)
rootdata-readonly(値なし)
rootdata-stateclosed, open
triggerdata-invalid(値なし)
triggerdata-readonly(値なし)
triggerdata-stateclosed, open

Examples

Closed trigger

aria-expanded="false" の閉じた Color Picker trigger/content の例です。

閉じた状態(aria-expanded="false")の Color Picker trigger/content の組み立て例です。

Accent color

自前 CSS の最小例

headless-ui 自体はスタイルを持たないため、data-* 属性セレクタで見た目を組み立てる最小例です。

利用者が data-scope / data-part / data-state / data-disabled / data-invalid 属性セレクタで自前 CSS を当てる最小例です。headless-ui 自体はスタイルを持ちません。

Accent color
CSS
[data-scope="color-picker"][data-part="area"] {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
}
[data-scope="color-picker"][data-part="area-thumb"] {
  position: absolute;
  left: var(--fandhe-color-picker-x, 0%);
  top: var(--fandhe-color-picker-y, 0%);
}
[data-scope="color-picker"][data-part="hue-slider-track"] {
  background: linear-gradient(to right, red, yellow, lime, cyan, blue, magenta, red);
}
[data-scope="color-picker"][data-part="root"][data-disabled] {
  opacity: 0.5;
}
[data-scope="color-picker"][data-part="channel-input"][data-invalid] {
  outline: 2px solid crimson;
}
[data-scope="color-picker"][data-part="trigger"][data-state="open"] {
  outline: 2px solid #333;
}

Accessibility

Keyboard Interactions

KeyDescription
Entertrigger にフォーカス時: popover を開く(dispatch "open")。channel_input にフォーカス時: HEX 文字列を確定する(dispatch "set_hex")。
Esccontent が開いているとき popover を閉じる(dispatch "close")。trigger へのフォーカス復帰は呼び出し側の DOM 配線が担う(スコープ外、モジュール doc「参照突合」節参照)。
ArrowLeft / ArrowRightchannel_slider_thumb にフォーカス時: 該当チャンネルを 1 減らす/増やす(dispatch "decrement"/"increment"、0..=Channel::max() へ clamp、ラップしない)。
ArrowUp / ArrowDownarea_thumb にフォーカス時: 彩度・明度をそれぞれ 1 単位変化させる(dispatch "set_channel" で表現)。
Home / Endchannel_slider_thumb にフォーカス時: 最小値・最大値へ設定する(dispatch "set_channel" の 0/最大値ペイロードで表現、専用 dispatch は追加しない)。

WAI-ARIA

AttributeDescription
aria-haspopup="dialog"trigger パーツへ固定付与する(color_picker.rs:435)。
aria-expandedtrigger の開閉状態(state.is_open())を反映する(color_picker.rs:436)。
role="dialog"content パーツへ固定付与する(color_picker.rs:478)。
role="slider" / aria-valuetextarea_thumb・channel_slider_thumb の両方が role="slider" を固定付与する(area_thumb は aria-label="Color" + aria-valuetext のみ、channel_slider_thumb は aria-valuemin/max/now + aria-orientation も付与、color_picker.rs:524-547, 592-628)。
aria-invalid="true"channel_input が props.invalid のときのみ付与する(valid のときは属性自体を省略、color_picker.rs:632-657)。
aria-disabled="true"area_thumb・channel_slider_thumb が props.disabled のとき tabindex="-1" と対で付与する(color_picker.rs:524-547, 592-628)。