([20, 37]);
+
+ const handleChange = (event: Event, newValue: number | number[]) => {
+ setValue(newValue as number[]);
+ };
+
+ return (
+
+ {/* controlled: */}
+ 'Temperature range'}
+ getAriaValueText={valuetext}
+ min={0}
+ max={100}
+ />
+ {/* uncontrolled: */}
+ 'Temperature range'}
+ getAriaValueText={valuetext}
+ min={0}
+ max={100}
+ />
+
+ );
+}
diff --git a/docs/data/material/components/slider/UnstyledSlider.js b/docs/data/base/components/slider/UnstyledSlider.js
similarity index 75%
rename from docs/data/material/components/slider/UnstyledSlider.js
rename to docs/data/base/components/slider/UnstyledSlider.js
index 2a06fdb9568aac..0290a7115fb868 100644
--- a/docs/data/material/components/slider/UnstyledSlider.js
+++ b/docs/data/base/components/slider/UnstyledSlider.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { styled, alpha, Box } from '@mui/system';
-import SliderUnstyled from '@mui/base/SliderUnstyled';
+import SliderUnstyled, { sliderUnstyledClasses } from '@mui/base/SliderUnstyled';
const StyledSlider = styled(SliderUnstyled)(
({ theme }) => `
@@ -14,11 +14,18 @@ const StyledSlider = styled(SliderUnstyled)(
touch-action: none;
-webkit-tap-highlight-color: transparent;
opacity: 0.75;
+
&:hover {
opacity: 1;
}
- & .MuiSlider-rail {
+ &.${sliderUnstyledClasses.disabled} {
+ pointer-events: none;
+ cursor: default;
+ color: #bdbdbd;
+ }
+
+ & .${sliderUnstyledClasses.rail} {
display: block;
position: absolute;
width: 100%;
@@ -28,7 +35,7 @@ const StyledSlider = styled(SliderUnstyled)(
opacity: 0.38;
}
- & .MuiSlider-track {
+ & .${sliderUnstyledClasses.track} {
display: block;
position: absolute;
height: 4px;
@@ -36,7 +43,7 @@ const StyledSlider = styled(SliderUnstyled)(
background-color: currentColor;
}
- & .MuiSlider-thumb {
+ & .${sliderUnstyledClasses.thumb} {
position: absolute;
width: 14px;
height: 14px;
@@ -49,14 +56,14 @@ const StyledSlider = styled(SliderUnstyled)(
background-color: #fff;
:hover,
- &.Mui-focusVisible {
+ &.${sliderUnstyledClasses.focusVisible} {
box-shadow: 0 0 0 0.25rem ${alpha(
theme.palette.mode === 'light' ? '#1976d2' : '#90caf9',
0.15,
)};
}
- &.Mui-active {
+ &.${sliderUnstyledClasses.active} {
box-shadow: 0 0 0 0.25rem ${alpha(
theme.palette.mode === 'light' ? '#1976d2' : '#90caf9',
0.3,
@@ -70,6 +77,7 @@ export default function UnstyledSlider() {
return (
+
);
}
diff --git a/docs/data/material/components/slider/UnstyledSlider.tsx b/docs/data/base/components/slider/UnstyledSlider.tsx
similarity index 75%
rename from docs/data/material/components/slider/UnstyledSlider.tsx
rename to docs/data/base/components/slider/UnstyledSlider.tsx
index 2a06fdb9568aac..0290a7115fb868 100644
--- a/docs/data/material/components/slider/UnstyledSlider.tsx
+++ b/docs/data/base/components/slider/UnstyledSlider.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { styled, alpha, Box } from '@mui/system';
-import SliderUnstyled from '@mui/base/SliderUnstyled';
+import SliderUnstyled, { sliderUnstyledClasses } from '@mui/base/SliderUnstyled';
const StyledSlider = styled(SliderUnstyled)(
({ theme }) => `
@@ -14,11 +14,18 @@ const StyledSlider = styled(SliderUnstyled)(
touch-action: none;
-webkit-tap-highlight-color: transparent;
opacity: 0.75;
+
&:hover {
opacity: 1;
}
- & .MuiSlider-rail {
+ &.${sliderUnstyledClasses.disabled} {
+ pointer-events: none;
+ cursor: default;
+ color: #bdbdbd;
+ }
+
+ & .${sliderUnstyledClasses.rail} {
display: block;
position: absolute;
width: 100%;
@@ -28,7 +35,7 @@ const StyledSlider = styled(SliderUnstyled)(
opacity: 0.38;
}
- & .MuiSlider-track {
+ & .${sliderUnstyledClasses.track} {
display: block;
position: absolute;
height: 4px;
@@ -36,7 +43,7 @@ const StyledSlider = styled(SliderUnstyled)(
background-color: currentColor;
}
- & .MuiSlider-thumb {
+ & .${sliderUnstyledClasses.thumb} {
position: absolute;
width: 14px;
height: 14px;
@@ -49,14 +56,14 @@ const StyledSlider = styled(SliderUnstyled)(
background-color: #fff;
:hover,
- &.Mui-focusVisible {
+ &.${sliderUnstyledClasses.focusVisible} {
box-shadow: 0 0 0 0.25rem ${alpha(
theme.palette.mode === 'light' ? '#1976d2' : '#90caf9',
0.15,
)};
}
- &.Mui-active {
+ &.${sliderUnstyledClasses.active} {
box-shadow: 0 0 0 0.25rem ${alpha(
theme.palette.mode === 'light' ? '#1976d2' : '#90caf9',
0.3,
@@ -70,6 +77,7 @@ export default function UnstyledSlider() {
return (
+
);
}
diff --git a/docs/data/base/components/slider/UnstyledSlider.tsx.preview b/docs/data/base/components/slider/UnstyledSlider.tsx.preview
new file mode 100644
index 00000000000000..d326ff94b11db6
--- /dev/null
+++ b/docs/data/base/components/slider/UnstyledSlider.tsx.preview
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/docs/data/base/components/slider/slider.md b/docs/data/base/components/slider/slider.md
new file mode 100644
index 00000000000000..ac011d62403321
--- /dev/null
+++ b/docs/data/base/components/slider/slider.md
@@ -0,0 +1,63 @@
+---
+product: base
+title: React Slider unstyled component and hook
+components: SliderUnstyled
+githubLabel: 'component: slider'
+waiAria: https://www.w3.org/TR/wai-aria-practices/#slider
+packageName: '@mui/base'
+---
+
+# Slider
+
+The SliderUnstyled component lets users make selections from a range of values along a horizontal or vertical bar.
+
+Users may need to select a single value or a range of values on a slider.
+They are ideal for interface controls that benefit from a visual representation of adjustable content, such as volume or brightness settings, or for applying image filters.
+
+{{"component": "modules/components/ComponentLinkHeader.js", "design": false}}
+
+```js
+import SliderUnstyled from '@mui/base/SliderUnstyled';
+```
+
+{{"demo": "UnstyledSlider.js", "defaultCodeOpen": false}}
+
+## Discrete sliders
+
+The most basic slider is _continuous_, which means it does not have pre-defined (_discrete_) values for the user to select from.
+This is suitable for situations in which an approximate value is good enough for the user, such as brightness or volume.
+
+But if your users need more precise options, you can create a discrete slider that snaps to pre-defined stops along the bar.
+To generate a mark for each stop, use `marks={true}`:
+
+{{"demo": "DiscreteSlider.js"}}
+
+### Custom marks
+
+You can create custom marks by providing a rich array to the `marks` prop:
+
+{{"demo": "DiscreteSliderMarks.js"}}
+
+### Restricted values
+
+If the user should only be able to select from the values provided with the `marks` prop, add `step={null}` to disable all other options:
+
+{{"demo": "DiscreteSliderValues.js"}}
+
+## Range slider
+
+To let users set the start and end of a range on a slider, provide an array of values to the `value` or `defaultValue` prop:
+
+{{"demo": "RangeSlider.js"}}
+
+## Accessibility
+
+(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#slider)
+
+The component handles most of the work necessary to make it accessible.
+However, you need to make sure that:
+
+- Each thumb has a user-friendly label (`aria-label`, `aria-labelledby` or `getAriaLabel` prop).
+- Each thumb has a user-friendly text for its current value.
+ This is not required if the value matches the semantics of the label.
+ You can change the name with the `getAriaValueText` or `aria-valuetext` prop.
diff --git a/docs/data/base/pages.ts b/docs/data/base/pages.ts
index 626667e8c12d54..de736f4782bcea 100644
--- a/docs/data/base/pages.ts
+++ b/docs/data/base/pages.ts
@@ -18,6 +18,7 @@ const pages = [
{ pathname: '/base/react-button', title: 'Button' },
{ pathname: '/base/react-input', title: 'Input' },
{ pathname: '/base/react-select', title: 'Select' },
+ { pathname: '/base/react-slider', title: 'Slider' },
],
},
{
diff --git a/docs/data/material/components/slider/UnstyledSlider.tsx.preview b/docs/data/material/components/slider/UnstyledSlider.tsx.preview
deleted file mode 100644
index 9280bf10ade5d0..00000000000000
--- a/docs/data/material/components/slider/UnstyledSlider.tsx.preview
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/docs/data/material/components/slider/slider.md b/docs/data/material/components/slider/slider.md
index efe9205b79159f..cc3ef260436069 100644
--- a/docs/data/material/components/slider/slider.md
+++ b/docs/data/material/components/slider/slider.md
@@ -1,10 +1,11 @@
---
product: material-ui
title: React Slider component
-components: Slider, SliderUnstyled
+components: Slider
githubLabel: 'component: slider'
materialDesign: https://material.io/components/sliders
waiAria: https://www.w3.org/TR/wai-aria-practices/#slider
+unstyled: /base/react-slider/
---
# Slider
@@ -132,21 +133,6 @@ Increasing _x_ by one increases the represented value by factor _2_.
{{"demo": "NonLinearSlider.js"}}
-## Unstyled
-
-
-
-- 📦 [5.6 kB gzipped](https://bundlephobia.com/package/@mui/base@latest)
-
-The slider also comes with an unstyled version.
-It's ideal for doing heavy customizations and minimizing bundle size.
-
-```js
-import SliderUnstyled from '@mui/base/SliderUnstyled';
-```
-
-{{"demo": "UnstyledSlider.js"}}
-
## Accessibility
(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#slider)
diff --git a/docs/pages/api-docs/slider-unstyled.js b/docs/pages/api-docs/slider-unstyled.js
deleted file mode 100644
index 5c255387f8e51f..00000000000000
--- a/docs/pages/api-docs/slider-unstyled.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import * as React from 'react';
-import ApiPage from 'docs/src/modules/components/ApiPage';
-import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations';
-import jsonPageContent from './slider-unstyled.json';
-
-export default function Page(props) {
- const { descriptions, pageContent } = props;
- return ;
-}
-
-Page.getInitialProps = () => {
- const req = require.context(
- 'docs/translations/api-docs/slider-unstyled',
- false,
- /slider-unstyled.*.json$/,
- );
- const descriptions = mapApiPageTranslations(req);
-
- return {
- descriptions,
- pageContent: jsonPageContent,
- };
-};
diff --git a/docs/pages/api-docs/slider-unstyled.json b/docs/pages/api-docs/slider-unstyled.json
deleted file mode 100644
index aefda45f07d4c3..00000000000000
--- a/docs/pages/api-docs/slider-unstyled.json
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "props": {
- "aria-label": { "type": { "name": "custom", "description": "string" } },
- "aria-labelledby": { "type": { "name": "string" } },
- "aria-valuetext": { "type": { "name": "custom", "description": "string" } },
- "classes": { "type": { "name": "object" } },
- "component": { "type": { "name": "elementType" } },
- "components": {
- "type": {
- "name": "shape",
- "description": "{ Input?: elementType, Mark?: elementType, MarkLabel?: elementType, Rail?: elementType, Root?: elementType, Thumb?: elementType, Track?: elementType, ValueLabel?: elementType }"
- },
- "default": "{}"
- },
- "componentsProps": {
- "type": {
- "name": "shape",
- "description": "{ input?: object, mark?: object, markLabel?: object, rail?: object, root?: object, thumb?: object, track?: object, valueLabel?: { className?: string, components?: { Root?: elementType }, style?: object, value?: Array<number>
| number, valueLabelDisplay?: 'auto'
| 'off'
| 'on' } }"
- },
- "default": "{}"
- },
- "defaultValue": {
- "type": { "name": "union", "description": "Array<number>
| number" }
- },
- "disabled": { "type": { "name": "bool" } },
- "disableSwap": { "type": { "name": "bool" } },
- "getAriaLabel": { "type": { "name": "func" } },
- "getAriaValueText": { "type": { "name": "func" } },
- "isRtl": { "type": { "name": "bool" } },
- "marks": {
- "type": {
- "name": "union",
- "description": "Array<{ label?: node, value: number }>
| bool"
- },
- "default": "false"
- },
- "max": { "type": { "name": "number" }, "default": "100" },
- "min": { "type": { "name": "number" }, "default": "0" },
- "name": { "type": { "name": "string" } },
- "onChange": { "type": { "name": "func" } },
- "onChangeCommitted": { "type": { "name": "func" } },
- "orientation": {
- "type": { "name": "enum", "description": "'horizontal'
| 'vertical'" },
- "default": "'horizontal'"
- },
- "scale": { "type": { "name": "func" }, "default": "(x) => x" },
- "step": { "type": { "name": "number" }, "default": "1" },
- "tabIndex": { "type": { "name": "number" } },
- "track": {
- "type": {
- "name": "enum",
- "description": "'inverted'
| 'normal'
| false"
- },
- "default": "'normal'"
- },
- "value": {
- "type": { "name": "union", "description": "Array<number>
| number" }
- },
- "valueLabelDisplay": {
- "type": { "name": "enum", "description": "'auto'
| 'off'
| 'on'" },
- "default": "'off'"
- },
- "valueLabelFormat": {
- "type": { "name": "union", "description": "func
| string" },
- "default": "(x) => x"
- }
- },
- "name": "SliderUnstyled",
- "styles": {
- "classes": [
- "root",
- "marked",
- "vertical",
- "disabled",
- "dragging",
- "rail",
- "track",
- "trackFalse",
- "trackInverted",
- "thumb",
- "active",
- "focusVisible",
- "valueLabel",
- "valueLabelOpen",
- "valueLabelCircle",
- "valueLabelLabel",
- "mark",
- "markActive",
- "markLabel",
- "markLabelActive"
- ],
- "globalClasses": {
- "root": "MuiSlider-root",
- "marked": "MuiSlider-marked",
- "vertical": "MuiSlider-vertical",
- "disabled": "Mui-disabled",
- "dragging": "MuiSlider-dragging",
- "rail": "MuiSlider-rail",
- "track": "MuiSlider-track",
- "trackFalse": "MuiSlider-trackFalse",
- "trackInverted": "MuiSlider-trackInverted",
- "thumb": "MuiSlider-thumb",
- "active": "Mui-active",
- "focusVisible": "Mui-focusVisible",
- "valueLabel": "MuiSlider-valueLabel",
- "valueLabelOpen": "MuiSlider-valueLabelOpen",
- "valueLabelCircle": "MuiSlider-valueLabelCircle",
- "valueLabelLabel": "MuiSlider-valueLabelLabel",
- "mark": "MuiSlider-mark",
- "markActive": "MuiSlider-markActive",
- "markLabel": "MuiSlider-markLabel",
- "markLabelActive": "MuiSlider-markLabelActive"
- },
- "name": null
- },
- "spread": true,
- "forwardsRefTo": "HTMLSpanElement",
- "filename": "/packages/mui-base/src/SliderUnstyled/SliderUnstyled.js",
- "inheritance": null,
- "demos": "",
- "cssComponent": false
-}
diff --git a/docs/pages/base/api/slider-unstyled.json b/docs/pages/base/api/slider-unstyled.json
index b389675e06a67d..def83e5e452bb6 100644
--- a/docs/pages/base/api/slider-unstyled.json
+++ b/docs/pages/base/api/slider-unstyled.json
@@ -117,6 +117,6 @@
"forwardsRefTo": "HTMLSpanElement",
"filename": "/packages/mui-base/src/SliderUnstyled/SliderUnstyled.js",
"inheritance": null,
- "demos": "",
+ "demos": "",
"cssComponent": false
}
diff --git a/docs/pages/base/react-slider.js b/docs/pages/base/react-slider.js
new file mode 100644
index 00000000000000..8af3db31d4872c
--- /dev/null
+++ b/docs/pages/base/react-slider.js
@@ -0,0 +1,11 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import {
+ demos,
+ docs,
+ demoComponents,
+} from 'docs/data/base/components/slider/slider.md?@mui/markdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/docs/scripts/buildApiUtils.ts b/docs/scripts/buildApiUtils.ts
index 703b0371ac2c08..6514a542b755d7 100644
--- a/docs/scripts/buildApiUtils.ts
+++ b/docs/scripts/buildApiUtils.ts
@@ -116,6 +116,7 @@ const migratedBaseComponents = [
'OptionUnstyled',
'Portal',
'SelectUnstyled',
+ 'SliderUnstyled',
'TablePaginationUnstyled',
'TabPanelUnstyled',
'TabsListUnstyled',
diff --git a/docs/src/pagesApi.js b/docs/src/pagesApi.js
index 1aede10c5423b8..90ed7a1e8f637e 100644
--- a/docs/src/pagesApi.js
+++ b/docs/src/pagesApi.js
@@ -108,7 +108,6 @@ module.exports = [
{ pathname: '/api-docs/skeleton' },
{ pathname: '/api-docs/slide' },
{ pathname: '/api-docs/slider' },
- { pathname: '/api-docs/slider-unstyled' },
{ pathname: '/api-docs/snackbar' },
{ pathname: '/api-docs/snackbar-content' },
{ pathname: '/api-docs/speed-dial' },
diff --git a/packages/mui-base/src/SliderUnstyled/SliderUnstyled.d.ts b/packages/mui-base/src/SliderUnstyled/SliderUnstyled.d.ts
index ffd3d1bd17fe06..76351b512326bc 100644
--- a/packages/mui-base/src/SliderUnstyled/SliderUnstyled.d.ts
+++ b/packages/mui-base/src/SliderUnstyled/SliderUnstyled.d.ts
@@ -5,11 +5,11 @@ import { SliderUnstyledTypeMap } from './SliderUnstyledProps';
*
* Demos:
*
- * - [Slider](https://mui.com/components/slider/)
+ * - [Slider](https://mui.com/base/react-slider/)
*
* API:
*
- * - [SliderUnstyled API](https://mui.com/api/slider-unstyled/)
+ * - [SliderUnstyled API](https://mui.com/base/api/slider-unstyled/)
*/
declare const SliderUnstyled: OverridableComponent;