Range FX <mv-range-fx>
하나의 접근성 모델 위에 만든 표현력 있는 슬라이더입니다. 드래그하면 트랙이 물결치는 파도가 되거나(wave), 값 말풍선이 튀어나와 속도에 따라 기울거나(bubble), 고정된 바늘 아래로 눈금자가 관성을 가지고 스크롤되거나(ruler), 액체 캡이 늘어나거나(fluid), 라벨이 트랙 안에 있다가 채움 영역 아래에서 색이 반전됩니다(inline).
작동 방식
하나의 접근성 모델 위에 만든 표현력 있는 슬라이더: 드래그하면 트랙이 물결처럼 일렁이고(wave), 값 말풍선이 튀어나와 속도에 따라 기울며(bubble), 고정된 바늘 아래에서 눈금자가 관성으로 스크롤되고(ruler), 액체 캡이 늘어나거나(fluid), 라벨이 트랙 안에 있다가 채워진 부분 아래에서 색이 반전됩니다(inline). 폼 연동(form-associated)을 지원합니다.
| 카테고리 | 기본 요소 |
|---|---|
| 유형 | Web Component (<mv-range-fx>) |
| 상태 | 안정 |
| Keywords | slider, range, wave, bubble, ruler, fluid, inline-label, spring, velocity, form-associated |
When to use
- A showcase or creative tool needs a slider with personality, such as a rippling wave, tilting bubble or liquid cap
- A value is picked on a ruler that scrolls under a fixed needle, like a measurement or tuning control
- The label and value must live inside the track to save space
Avoid when
- Dual thumbs, ticks, labeled marks or a sober look for dense forms are needed → use Slider instead
- The fill should slosh like liquid with inertia, or the control should look like a vertical tank → use Slosh Slider instead
설치
node scripts/add.mjs range-fx --out ./src/marvelousMarvelous UI MCP 서버를 사용하는 AI 에이전트: install_components({ slugs: ["range-fx"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
복사되는 파일(의존성 포함): tokens/tokens.css, core/base.css, core/canvas.js, core/dom.js, core/element.js, core/form.js, core/motion.js, core/observe.js, components/range-fx/range-fx.js, components/range-fx/range-fx.css.
사용법
기본 마크업입니다. 여기서 시작해 속성, data-*, CSS 변수로 커스터마이즈하세요:
<form id="rfx-demo" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(17rem,1fr));gap:1.25rem;width:min(100%,46rem)">
<section style="display:grid;gap:.5rem;padding:1.125rem 1.25rem 1.25rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-xl);background:var(--mv-surface)">
<small style="color:var(--mv-fg-subtle);font-weight:500">wave</small>
<mv-range-fx variant="wave" label="Volume" name="volume" value="62" value-suffix="%"></mv-range-fx>
</section>
<section style="display:grid;gap:.5rem;padding:1.125rem 1.25rem 1.25rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-xl);background:var(--mv-surface)">
<small style="color:var(--mv-fg-subtle);font-weight:500">bubble</small>
<mv-range-fx variant="bubble" label="Monthly budget" name="budget" min="0" max="2000" step="50" value="850" value-prefix="$"></mv-range-fx>
</section>
<section style="grid-column:1/-1;display:grid;gap:.5rem;padding:1.125rem 1.25rem 1rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-xl);background:var(--mv-surface)">
<small style="color:var(--mv-fg-subtle);font-weight:500">ruler: flick the ruler and it settles on the nearest tick</small>
<mv-range-fx variant="ruler" label="Weight" name="weight" min="70" max="330" step="0.5" major="10" value="151.5" value-suffix=" lb"></mv-range-fx>
</section>
<section style="display:grid;gap:.625rem;padding:1.125rem 1.25rem 1.25rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-xl);background:var(--mv-surface)">
<small style="color:var(--mv-fg-subtle);font-weight:500">fluid</small>
<mv-range-fx variant="fluid" label="Brightness" name="brightness" value="70" value-suffix="%"></mv-range-fx>
</section>
<section style="display:grid;gap:.625rem;padding:1.125rem 1.25rem 1.25rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-xl);background:var(--mv-surface)">
<small style="color:var(--mv-fg-subtle);font-weight:500">inline</small>
<mv-range-fx variant="inline" label="Layer opacity" name="opacity" value="40" value-suffix="%"></mv-range-fx>
</section>
</form>
<script type="module">
document.getElementById("rfx-demo").addEventListener("submit", (e) => e.preventDefault());
</script>API
Attributes
| Name | 유형 | Default | Description |
|---|---|---|---|
variant | wave | bubble | ruler | fluid | inline | wave | Rendering and velocity-driven effect. |
min / max / step | number | 0 / 100 / 1 | Bounds and step (step decimals are respected, e.g. 0.5). |
value | number | Initial value, restored on form reset. | |
name | string | Form field name. | |
label | string | Visible label (above, or inside the track for fluid/inline) and accessible name. Otherwise use aria-label / aria-labelledby. | |
value-prefix / value-suffix | string | Text around the formatted value (Intl). | |
large-step | number | 10% of the range | Step for PageUp/PageDown and Shift+Arrow. |
major | number | 10 | ruler: a labeled major tick every N steps. |
stops | number | 10 | inline: number of intervals marked with dots (hidden under the text). |
disabled / readonly / required | boolean | Standard states. |
Properties
| Name | 유형 | Description |
|---|---|---|
value / valueAsNumber | string / number | Current value; setting it animates the slider. |
formatter | (value) => string | Custom formatting (display and aria-valuetext). |
form / labels / validity | Via ElementInternals. |
Methods
| Name | Description |
|---|---|
focus() | Focuses the slider. |
Events
| Name | Description |
|---|---|
mv-input | On every value change (drag, wheel, keyboard). detail: { value }. |
mv-change | End of interaction (release, ruler stop, key press). |
CSS classes
| Name | Description |
|---|---|
mv-range-fx-head / -label / -value | Label + value header. |
mv-range-fx-control | Focusable role="slider" element. |
mv-range-fx-thumb / -wave / -bubble / -needle / -scale / -fill / -cap / -bar / -stops / -text | Variant-specific parts. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-range-fx-color | var(--mv-accent) | Color of the fill, wave and needle. |
--mv-range-fx-tick-gap | 10px | ruler: gap between two ticks. |
--mv-range-fx-bubble-bg / -fg | bubble: bubble colors. |
Accessibility
role="slider" on the control area, with aria-valuenow/min/max, a formatted aria-valuetext (prefix/suffix) and a name taken from the label. Keyboard: arrows (±step, reversed in RTL), Shift+Arrow and PageUp/PageDown (large step), Home/End. All decorations are aria-hidden. Reduced motion: springs, ripple and inertia are disabled and the value jumps into place. Forced colors: tracks in GrayText, the filled part and the needle in Highlight, the text over the fill in HighlightText. The ruler scale is a canvas drawn with the theme colors.