UNPKG

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