UNPKG

@sandlada/mdc

Version:

@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.

145 lines 6.6 kB
/** * @license * Copyright 2026 Kai-Orion & Sandlada * SPDX-License-Identifier: MIT * * @fileoverview * `mdc-expressive-slider` — Material Design 3 Expressive slider. * * Layout pulled from the Figma prototype (node-id `58008:10353`): * - Standard: `[active-track] [handle] [inactive-track]`, with the visible * track inset by `handleWidth/2` from each slider edge so the handle * never sits flush against the slider edge. * - Centered: two inactive halves split at 50%, with the same inset * mirrored around the center (`--_center-inset`) so the active overlay * has a center gap and rounded ends on BOTH sides. * - Range: two inactive halves with two handles symmetric about the * center and a center dot at the 50% mark. * * Five size presets (`extra-small` / `small` / `medium` / `large` / * `extra-large`) and two orientations (`horizontal` / `vertical`). * * @link https://m3.material.io/components/sliders/specs */ import { BaseSlider } from '../slider/internal/base-slider'; import { type ExpressiveSliderDirection, type ExpressiveSliderSize, type ExpressiveSliderType, type IExpressiveSlider } from './expressive-slider.interface'; declare global { interface HTMLElementTagNameMap { 'mdc-expressive-slider': MDCExpressiveSlider; } } /** * @version * Material Design 3 Expressive */ export declare class MDCExpressiveSlider extends BaseSlider implements IExpressiveSlider { static styles: import("lit").CSSResult[]; /** * Size preset: `'extra-small'`, `'small'`, `'medium'` (default), * `'large'`, or `'extra-large'`. Reflects to the `size` attribute. */ size: ExpressiveSliderSize; /** Slider orientation. Reflects to the `direction` attribute. */ direction: ExpressiveSliderDirection; /** Behavioral type. Reflects to the `type` attribute. */ type: ExpressiveSliderType; /** * Whether the value scale is reversed. * * - When `false` (default): * - `horizontal`: small to large, left-to-right (min at left, max at right). * - `vertical`: small to large, top-to-bottom (min at top, max at bottom). * - When `true`: * - `horizontal`: large to small, left-to-right (max at left, min at right). * - `vertical`: large to small, top-to-bottom (max at top, min at bottom). * * Reflects to the `reversed` attribute. */ reversed: boolean; /** * Backward-compat alias for the legacy `range` boolean. Setting * `range=true` switches `type` to `'range'`; reading returns whether * `type === 'range'`. */ get range(): boolean; set range(value: boolean); /** * Compose the classes for the `.container` element. Per CLAUDE.md * convention for non-host root elements. The classes map every * reflected attribute (size / direction / type / reversed) onto the container * so CSS selectors can target combinations like * `:host([size='medium']) .container` without duplicating the lookup. */ protected getRenderClasses(): { [x: string]: boolean; ranged: boolean; centered: boolean; reversed: boolean; }; protected render(): import("lit-html").TemplateResult<1>; /** * Compute the fractions needed by the render tree, based on * the current `type`, `direction`, `reversed`, and the slider's value state. * Centralised so each render method doesn't recompute. */ private computeFractions; /** * Left/top track segment. Standard: the active track (fills from * the left edge up to the handle position). Centered / Range: the * inactive background of the left half. */ protected renderTrackStart(): import("lit-html").TemplateResult<1>; /** Right/bottom track segment. */ protected renderTrackEnd(): import("lit-html").TemplateResult<1>; /** * Middle track for range sliders — represents the selected portion * (valueStart..valueEnd). Both edges are inset from the handle * centers by `--_thumb-track-gap`; both caps are rounded (CornerFull). */ protected renderTrackMiddle(minVisualFraction: number, maxVisualFraction: number): import("lit-html").TemplateResult<1>; protected renderTrackSegment(position: 'start' | 'end'): import("lit-html").TemplateResult<1>; /** * Centered mode's active overlay. Sits on top of the value-side * inactive track segment, between the center gap and the handle's * leading edge. BOTH ends are rounded (CornerFull via * --_active-leading-shape) since the center-side edge sits against * the center gap rather than against the handle. * * When `value === 0` the overlay length is 0; we render a single * `.center-stop` dot at the 50% mark instead (per MD3E spec). */ protected renderCenteredOverlay(fractions: ReturnType<MDCExpressiveSlider['computeFractions']>): import("lit-html").TemplateResult<1>; /** Center dot for range sliders — marks the geometric center. */ protected renderCenterDot(): import("lit-html").TemplateResult<1>; /** * Override the base slider's input renderer so we can drive the actual * `.min` / `.max` properties on the native `<input type="range">`, * not just the `aria-valuemin` / `aria-valuemax` attributes. The base * implementation only sets the ARIA attributes, which leaves the * input's clamp range at the slider's configured `[min, max]`. For * `type='centered'` we need the native clamp range to be * `[-max, +max]` so the cursor position matches the handle position. * For `type='range'` the clip-path (driven by `--_clip-to-start` / * `--_clip-to-end` published from the inline container style) decides * which half of the slider each input owns; the inputs themselves span * the full container so the cursor-to-value mapping stays linear. */ protected renderInput({ start, value, ariaLabel, ariaValueText, ariaMin, ariaMax, inputMin, inputMax, }: { start: boolean; value?: number; ariaLabel: string; ariaValueText: string; ariaMin: number; ariaMax: number; inputMin: number; inputMax: number; }): import("lit-html").TemplateResult<1>; protected renderHandle({ start, hover, label, style, }: { start: boolean; hover: boolean; label: string; style?: string; }): import("lit-html").TemplateResult<1>; protected renderLabel(value: string): import("lit-html").TemplateResult<1>; } //# sourceMappingURL=expressive-slider.d.ts.map