XYPad
2 次元のスライダーのコンポーネント。
Source Style- React
- Svelte
- Vue
Loading...
function App() { const [valueX, setValueX] = useState(32) const [valueY, setValueY] = useState(56) return ( <div> <XYPad.Root className={xyPadTheme.root} value={[valueX, valueY]} min={0} max={100} onChange={([x, y]) => { setValueX(x) setValueY(y) }} > <XYPad.Area className={xyPadTheme.area}> <XYPad.Thumb className={xyPadTheme.thumb} aria-label={['X position', 'Y position']} /> </XYPad.Area> </XYPad.Root> <p> x: {valueX}, y: {valueY} </p> </div> ) }
/** The demo theme for `XYPad`, as a CSS Module: one class per part, applied by* the caller. Copy this file into your project and edit it.*//** The size the thumb is drawn at, the room the pad leaves for it, and the* smallest the area may become. Three parts need the value and nothing* inherits it, so it is composed into each of them.*/.thumbSize {--thumb-size: 22px;}.root {composes: thumbSize;display: inline-block;margin: calc(var(--thumb-size) / 2);cursor: pointer;-webkit-tap-highlight-color: transparent;&[data-readonly] {cursor: not-allowed;}}.area {composes: thumbSize;/* Room for the thumb to travel. A percentage size, or a flex row thatoverrides the automatic minimum size, may shrink the area to nothingwith the thumb left sitting on a line. */--min-width: calc(var(--thumb-size) * 2);--min-height: calc(var(--thumb-size) * 2);width: 120px;height: 120px;min-width: var(--min-width);min-height: var(--min-height);background-color: oklch(95% 0 0);}.thumb {composes: thumbSize;--color: oklch(59.5% 0.17548 266.373);width: var(--thumb-size);height: var(--thumb-size);border-radius: 50%;outline: none;background-color: var(--color);&[data-disabled] {background-color: oklch(50.462% 0.03307 270.021);}&:focus-within {box-shadow: 0px 0px 0px 3pxcolor-mix(in srgb, var(--color) 20%, transparent);}}/** Dark mode follows whatever marks the page — `.dark` and `[data-theme=dark]`* are what this site and Storybook set.*/:global(.dark) .area,:global([data-theme='dark']) .area {background-color: oklch(41.7% 0 0);}:global(.dark) .thumb,:global([data-theme='dark']) .thumb {--color: oklch(64.5% 0.17548 266.373);&:hover {--color: oklch(67.5% 0.17548 266.373);}}
App.svelte
<script lang="ts">
import { XYPad } from '@tremolo-ui/svelte'
// Copy this file from the Styling page into your own project.
import xyPadTheme from './XYPad.module.css'
let value: [number, number] = $state([32, 56])
</script>
<XYPad.Root class={xyPadTheme.root} bind:value min={0} max={100}>
<XYPad.Area class={xyPadTheme.area}>
<XYPad.Thumb
class={xyPadTheme.thumb}
aria-label={['X position', 'Y position']}
/>
</XYPad.Area>
</XYPad.Root>
<p>x: {value[0]}, y: {value[1]}</p>
App.vue
<script setup lang="ts">
import { ref } from 'vue'
import type { XY } from '@tremolo-ui/dom'
import { XYPad, XYPadArea, XYPadThumb } from '@tremolo-ui/vue'
// Copy this file from the Styling page into your own project.
import xyPadTheme from './XYPad.module.css'
const value = ref<XY<number>>([32, 56])
</script>
<template>
<XYPad v-model="value" :class="xyPadTheme.root" :min="0" :max="100">
<XYPadArea :class="xyPadTheme.area">
<XYPadThumb
:class="xyPadTheme.thumb"
:aria-label="['X position', 'Y position']"
/>
</XYPadArea>
</XYPad>
<p>x: {{ value[0] }}, y: {{ value[1] }}</p>
</template>
インポート
- React
- Svelte
- Vue
import { XYPad } from '@tremolo-ui/react'
import { XYPad } from '@tremolo-ui/svelte'
import { XYPad, XYPadArea, XYPadThumb } from '@tremolo-ui/vue'
API リファレンス
各パートには、そのパート独自の props を載せています。これに加えて、描画する要素の属性(className や style など)も受け取ります。
Svelte / Vue でも props は同じで、書き方だけがそれぞれの流儀になります(className ではなく class、bind:value や v-model、中身は snippet やスロットなど)。Svelte と Vue を参照してください。
状態は data 属性として要素に乗っているので、セレクタ 1 つで届きます(スタイリングを参照)。属性はその状態が on の間だけ付きます。
Root
両軸の値と設定を持ち、中のパートに渡します。
| Prop | 型 | 既定値 |
|---|---|---|
value* | XY<number> | — |
min* | number | readonly [number, number] | — |
max* | number | readonly [number, number] | — |
step | number | readonly [number, number] | 1 |
scale | Scale | readonly [Scale, Scale] | linearScale |
reverse | boolean | readonly [boolean, boolean] | false |
wheel | ModifierValue<InputEventOption> | null | ['raw', 1] |
dragSensitivity | ModifierValue<number> | { default: 1, shift: 0.1 } |
keyboard | ModifierValue<InputEventOption> | null | { default: ['raw', 1], shift: ['raw', 0.1] } |
dragCursor | Cursor | 'pointer' |
disabled | boolean | — |
readOnly | boolean | — |
onChange | (value: XY<number>) => void | — |
onChangeStart | (value: XY<number>, source: ChangeSource) => void | — |
onChangeEnd | (value: XY<number>, source: ChangeSource) => void | — |
changeEndDelay | number | 500 |
children* | ReactNode | — |
actionsRef | Ref<XYPadMethods> | — |
すべての説明: XYPadProps
| Data 属性 | 値 |
|---|---|
[data-disabled] | disabled のときに付きます |
[data-readonly] | readonly のときに付きます |
Area
つまみが動く面。XYPad.Thumb はこの中に置きます。
幅・高さ・背景色は CSS または style で指定します。<div> の属性も受け取ります。
Thumb
つまみ。中にある軸ごとの 2 つの視覚的に隠れた range input が、フォーカスを受け取り ARIA を持ちます。
子はつまみの中に描かれます。つまみはどちらにしても 1 つの要素なので、子はつまみを置き換えるのではなく、その上に載る飾りです。つまみ自体の見た目は className と style で変えます。
| Prop | 型 | 既定値 |
|---|---|---|
color | string | — |
aria-label | string | readonly [string | undefined, string | undefined] | — |
aria-labelledby | string | readonly [string | undefined, string | undefined] | — |
aria-describedby | string | readonly [string | undefined, string | undefined] | — |
aria-valuetext | string | readonly [string | undefined, string | undefined] | — |
actionsRef | Ref<XYPadThumbMethods> | — |
すべての説明: XYPadThumbProps
| カスタムプロパティ | 書き込む prop | 決めるもの |
|---|---|---|
--color | color | つまみの色。 |
| Data 属性 | 値 |
|---|---|
[data-disabled] | disabled のときに付きます |
[data-readonly] | readonly のときに付きます |