UNPKG

16.2 kBJavaScriptView Raw
1'use client';
2
3import _extends from "@babel/runtime/helpers/esm/extends";
4import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5const _excluded = ["aria-label", "aria-valuetext", "aria-labelledby", "className", "disableSwap", "disabled", "getAriaLabel", "getAriaValueText", "marks", "max", "min", "name", "onChange", "onChangeCommitted", "orientation", "shiftStep", "scale", "step", "tabIndex", "track", "value", "valueLabelFormat", "isRtl", "defaultValue", "slotProps", "slots"];
6import * as React from 'react';
7import PropTypes from 'prop-types';
8import clsx from 'clsx';
9import { chainPropTypes } from '@mui/utils';
10import { isHostComponent } from '../utils/isHostComponent';
11import { unstable_composeClasses as composeClasses } from '../composeClasses';
12import { getSliderUtilityClass } from './sliderClasses';
13import { useSlider, valueToPercent } from '../useSlider';
14import { useSlotProps } from '../utils/useSlotProps';
15import { resolveComponentProps } from '../utils/resolveComponentProps';
16import { useClassNamesOverride } from '../utils/ClassNameConfigurator';
17
18// @ts-ignore
19import { jsx as _jsx } from "react/jsx-runtime";
20import { jsxs as _jsxs } from "react/jsx-runtime";
21function Identity(x) {
22 return x;
23}
24const useUtilityClasses = ownerState => {
25 const {
26 disabled,
27 dragging,
28 marked,
29 orientation,
30 track
31 } = ownerState;
32 const slots = {
33 root: ['root', disabled && 'disabled', dragging && 'dragging', marked && 'marked', orientation === 'vertical' && 'vertical', track === 'inverted' && 'trackInverted', track === false && 'trackFalse'],
34 rail: ['rail'],
35 track: ['track'],
36 mark: ['mark'],
37 markActive: ['markActive'],
38 markLabel: ['markLabel'],
39 markLabelActive: ['markLabelActive'],
40 valueLabel: ['valueLabel'],
41 thumb: ['thumb', disabled && 'disabled'],
42 active: ['active'],
43 disabled: ['disabled'],
44 focusVisible: ['focusVisible']
45 };
46 return composeClasses(slots, useClassNamesOverride(getSliderUtilityClass));
47};
48
49/**
50 *
51 * Demos:
52 *
53 * - [Slider](https://mui.com/base-ui/react-slider/)
54 *
55 * API:
56 *
57 * - [Slider API](https://mui.com/base-ui/react-slider/components-api/#slider)
58 */
59const Slider = /*#__PURE__*/React.forwardRef(function Slider(props, forwardedRef) {
60 const {
61 'aria-label': ariaLabel,
62 'aria-valuetext': ariaValuetext,
63 'aria-labelledby': ariaLabelledby,
64 className,
65 disableSwap = false,
66 disabled = false,
67 getAriaLabel,
68 getAriaValueText,
69 marks: marksProp = false,
70 max = 100,
71 min = 0,
72 orientation = 'horizontal',
73 shiftStep = 10,
74 scale = Identity,
75 step = 1,
76 track = 'normal',
77 valueLabelFormat = Identity,
78 isRtl = false,
79 defaultValue,
80 slotProps = {},
81 slots = {}
82 } = props,
83 other = _objectWithoutPropertiesLoose(props, _excluded);
84
85 // all props with defaults
86 // consider extracting to hook an reusing the lint rule for the variants
87 const partialOwnerState = _extends({}, props, {
88 marks: marksProp,
89 disabled,
90 disableSwap,
91 isRtl,
92 defaultValue,
93 max,
94 min,
95 orientation,
96 scale,
97 step,
98 shiftStep,
99 track,
100 valueLabelFormat
101 });
102 const {
103 axisProps,
104 getRootProps,
105 getHiddenInputProps,
106 getThumbProps,
107 active,
108 axis,
109 range,
110 focusedThumbIndex,
111 dragging,
112 marks,
113 values,
114 trackOffset,
115 trackLeap,
116 getThumbStyle
117 } = useSlider(_extends({}, partialOwnerState, {
118 rootRef: forwardedRef
119 }));
120 const ownerState = _extends({}, partialOwnerState, {
121 marked: marks.length > 0 && marks.some(mark => mark.label),
122 dragging,
123 focusedThumbIndex,
124 activeThumbIndex: active
125 });
126 const classes = useUtilityClasses(ownerState);
127 const Root = slots.root ?? 'span';
128 const rootProps = useSlotProps({
129 elementType: Root,
130 getSlotProps: getRootProps,
131 externalSlotProps: slotProps.root,
132 externalForwardedProps: other,
133 ownerState,
134 className: [classes.root, className]
135 });
136 const Rail = slots.rail ?? 'span';
137 const railProps = useSlotProps({
138 elementType: Rail,
139 externalSlotProps: slotProps.rail,
140 ownerState,
141 className: classes.rail
142 });
143 const Track = slots.track ?? 'span';
144 const trackProps = useSlotProps({
145 elementType: Track,
146 externalSlotProps: slotProps.track,
147 additionalProps: {
148 style: _extends({}, axisProps[axis].offset(trackOffset), axisProps[axis].leap(trackLeap))
149 },
150 ownerState,
151 className: classes.track
152 });
153 const Thumb = slots.thumb ?? 'span';
154 const thumbProps = useSlotProps({
155 elementType: Thumb,
156 getSlotProps: getThumbProps,
157 externalSlotProps: slotProps.thumb,
158 ownerState,
159 skipResolvingSlotProps: true
160 });
161 const ValueLabel = slots.valueLabel;
162 const valueLabelProps = useSlotProps({
163 elementType: ValueLabel,
164 externalSlotProps: slotProps.valueLabel,
165 ownerState
166 });
167 const Mark = slots.mark ?? 'span';
168 const markProps = useSlotProps({
169 elementType: Mark,
170 externalSlotProps: slotProps.mark,
171 ownerState,
172 className: classes.mark
173 });
174 const MarkLabel = slots.markLabel ?? 'span';
175 const markLabelProps = useSlotProps({
176 elementType: MarkLabel,
177 externalSlotProps: slotProps.markLabel,
178 ownerState
179 });
180 const Input = slots.input || 'input';
181 const inputProps = useSlotProps({
182 elementType: Input,
183 getSlotProps: getHiddenInputProps,
184 externalSlotProps: slotProps.input,
185 ownerState
186 });
187 return /*#__PURE__*/_jsxs(Root, _extends({}, rootProps, {
188 children: [/*#__PURE__*/_jsx(Rail, _extends({}, railProps)), /*#__PURE__*/_jsx(Track, _extends({}, trackProps)), marks.filter(mark => mark.value >= min && mark.value <= max).map((mark, index) => {
189 const percent = valueToPercent(mark.value, min, max);
190 const style = axisProps[axis].offset(percent);
191 let markActive;
192 if (track === false) {
193 markActive = values.indexOf(mark.value) !== -1;
194 } else {
195 markActive = track === 'normal' && (range ? mark.value >= values[0] && mark.value <= values[values.length - 1] : mark.value <= values[0]) || track === 'inverted' && (range ? mark.value <= values[0] || mark.value >= values[values.length - 1] : mark.value >= values[0]);
196 }
197 return /*#__PURE__*/_jsxs(React.Fragment, {
198 children: [/*#__PURE__*/_jsx(Mark, _extends({
199 "data-index": index
200 }, markProps, !isHostComponent(Mark) && {
201 markActive
202 }, {
203 style: _extends({}, style, markProps.style),
204 className: clsx(markProps.className, markActive && classes.markActive)
205 })), mark.label != null ? /*#__PURE__*/_jsx(MarkLabel, _extends({
206 "aria-hidden": true,
207 "data-index": index
208 }, markLabelProps, !isHostComponent(MarkLabel) && {
209 markLabelActive: markActive
210 }, {
211 style: _extends({}, style, markLabelProps.style),
212 className: clsx(classes.markLabel, markLabelProps.className, markActive && classes.markLabelActive),
213 children: mark.label
214 })) : null]
215 }, index);
216 }), values.map((value, index) => {
217 const percent = valueToPercent(value, min, max);
218 const style = axisProps[axis].offset(percent);
219 const resolvedSlotProps = resolveComponentProps(slotProps.thumb, ownerState, {
220 index,
221 focused: focusedThumbIndex === index,
222 active: active === index
223 });
224 return /*#__PURE__*/_jsxs(Thumb, _extends({
225 "data-index": index
226 }, thumbProps, resolvedSlotProps, {
227 className: clsx(classes.thumb, thumbProps.className, resolvedSlotProps?.className, active === index && classes.active, focusedThumbIndex === index && classes.focusVisible),
228 style: _extends({}, style, getThumbStyle(index), thumbProps.style, resolvedSlotProps?.style),
229 children: [/*#__PURE__*/_jsx(Input, _extends({
230 "data-index": index,
231 "aria-label": getAriaLabel ? getAriaLabel(index) : ariaLabel,
232 "aria-valuenow": scale(value),
233 "aria-labelledby": ariaLabelledby,
234 "aria-valuetext": getAriaValueText ? getAriaValueText(scale(value), index) : ariaValuetext,
235 value: values[index]
236 }, inputProps)), ValueLabel ? /*#__PURE__*/_jsx(ValueLabel, _extends({}, !isHostComponent(ValueLabel) && {
237 valueLabelFormat,
238 index,
239 disabled
240 }, valueLabelProps, {
241 children: typeof valueLabelFormat === 'function' ? valueLabelFormat(scale(value), index) : valueLabelFormat
242 })) : null]
243 }), index);
244 })]
245 }));
246});
247process.env.NODE_ENV !== "production" ? Slider.propTypes /* remove-proptypes */ = {
248 // ┌────────────────────────────── Warning ──────────────────────────────┐
249 // │ These PropTypes are generated from the TypeScript type definitions. │
250 // │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
251 // └─────────────────────────────────────────────────────────────────────┘
252 /**
253 * The label of the slider.
254 */
255 'aria-label': chainPropTypes(PropTypes.string, props => {
256 const range = Array.isArray(props.value || props.defaultValue);
257 if (range && props['aria-label'] != null) {
258 return new Error('MUI: You need to use the `getAriaLabel` prop instead of `aria-label` when using a range slider.');
259 }
260 return null;
261 }),
262 /**
263 * The id of the element containing a label for the slider.
264 */
265 'aria-labelledby': PropTypes.string,
266 /**
267 * A string value that provides a user-friendly name for the current value of the slider.
268 */
269 'aria-valuetext': chainPropTypes(PropTypes.string, props => {
270 const range = Array.isArray(props.value || props.defaultValue);
271 if (range && props['aria-valuetext'] != null) {
272 return new Error('MUI: You need to use the `getAriaValueText` prop instead of `aria-valuetext` when using a range slider.');
273 }
274 return null;
275 }),
276 /**
277 * The default value. Use when the component is not controlled.
278 */
279 defaultValue: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]),
280 /**
281 * If `true`, the component is disabled.
282 * @default false
283 */
284 disabled: PropTypes.bool,
285 /**
286 * If `true`, the active thumb doesn't swap when moving pointer over a thumb while dragging another thumb.
287 * @default false
288 */
289 disableSwap: PropTypes.bool,
290 /**
291 * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider.
292 * This is important for screen reader users.
293 * @param {number} index The thumb label's index to format.
294 * @returns {string}
295 */
296 getAriaLabel: PropTypes.func,
297 /**
298 * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider.
299 * This is important for screen reader users.
300 * @param {number} value The thumb label's value to format.
301 * @param {number} index The thumb label's index to format.
302 * @returns {string}
303 */
304 getAriaValueText: PropTypes.func,
305 /**
306 * If `true` the Slider will be rendered right-to-left (with the lowest value on the right-hand side).
307 * @default false
308 */
309 isRtl: PropTypes.bool,
310 /**
311 * Marks indicate predetermined values to which the user can move the slider.
312 * If `true` the marks are spaced according the value of the `step` prop.
313 * If an array, it should contain objects with `value` and an optional `label` keys.
314 * @default false
315 */
316 marks: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.shape({
317 label: PropTypes.node,
318 value: PropTypes.number.isRequired
319 })), PropTypes.bool]),
320 /**
321 * The maximum allowed value of the slider.
322 * Should not be equal to min.
323 * @default 100
324 */
325 max: PropTypes.number,
326 /**
327 * The minimum allowed value of the slider.
328 * Should not be equal to max.
329 * @default 0
330 */
331 min: PropTypes.number,
332 /**
333 * Name attribute of the hidden `input` element.
334 */
335 name: PropTypes.string,
336 /**
337 * Callback function that is fired when the slider's value changed.
338 *
339 * @param {Event} event The event source of the callback.
340 * You can pull out the new value by accessing `event.target.value` (any).
341 * **Warning**: This is a generic event not a change event.
342 * @param {number | number[]} value The new value.
343 * @param {number} activeThumb Index of the currently moved thumb.
344 */
345 onChange: PropTypes.func,
346 /**
347 * Callback function that is fired when the `mouseup` is triggered.
348 *
349 * @param {React.SyntheticEvent | Event} event The event source of the callback. **Warning**: This is a generic event not a change event.
350 * @param {number | number[]} value The new value.
351 */
352 onChangeCommitted: PropTypes.func,
353 /**
354 * The component orientation.
355 * @default 'horizontal'
356 */
357 orientation: PropTypes.oneOf(['horizontal', 'vertical']),
358 /**
359 * A transformation function, to change the scale of the slider.
360 * @param {any} x
361 * @returns {any}
362 * @default function Identity(x) {
363 * return x;
364 * }
365 */
366 scale: PropTypes.func,
367 /**
368 * The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down.
369 * @default 10
370 */
371 shiftStep: PropTypes.number,
372 /**
373 * The props used for each slot inside the Slider.
374 * @default {}
375 */
376 slotProps: PropTypes.shape({
377 input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
378 mark: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
379 markLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
380 rail: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
381 root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
382 thumb: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
383 track: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
384 valueLabel: PropTypes.oneOfType([PropTypes.any, PropTypes.func])
385 }),
386 /**
387 * The components used for each slot inside the Slider.
388 * Either a string to use a HTML element or a component.
389 * @default {}
390 */
391 slots: PropTypes.shape({
392 input: PropTypes.elementType,
393 mark: PropTypes.elementType,
394 markLabel: PropTypes.elementType,
395 rail: PropTypes.elementType,
396 root: PropTypes.elementType,
397 thumb: PropTypes.elementType,
398 track: PropTypes.elementType,
399 valueLabel: PropTypes.elementType
400 }),
401 /**
402 * The granularity with which the slider can step through values. (A "discrete" slider.)
403 * The `min` prop serves as the origin for the valid values.
404 * We recommend (max - min) to be evenly divisible by the step.
405 *
406 * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop.
407 * @default 1
408 */
409 step: PropTypes.number,
410 /**
411 * Tab index attribute of the hidden `input` element.
412 */
413 tabIndex: PropTypes.number,
414 /**
415 * The track presentation:
416 *
417 * - `normal` the track will render a bar representing the slider value.
418 * - `inverted` the track will render a bar representing the remaining slider value.
419 * - `false` the track will render without a bar.
420 * @default 'normal'
421 */
422 track: PropTypes.oneOf(['inverted', 'normal', false]),
423 /**
424 * The value of the slider.
425 * For ranged sliders, provide an array with two values.
426 */
427 value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]),
428 /**
429 * The format function the value label's value.
430 *
431 * When a function is provided, it should have the following signature:
432 *
433 * - {number} value The value label's value to format
434 * - {number} index The value label's index to format
435 * @param {any} x
436 * @returns {any}
437 * @default function Identity(x) {
438 * return x;
439 * }
440 */
441 valueLabelFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string])
442} : void 0;
443export { Slider };
\No newline at end of file