@sandlada/mdc
Version:
@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.
145 lines • 6.6 kB
TypeScript
/**
* @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