From f966e237fbc8bbd92155aeb68954561c163b1bf3 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 29 Aug 2020 10:59:04 +0200 Subject: [PATCH 001/125] wip --- packages/material-ui/package.json | 4 + packages/material-ui/src/Slider/Slider.js | 388 ++++++------------ .../material-ui/src/Slider/SliderStyled.js | 261 ++++++++++++ packages/material-ui/src/Slider/ValueLabel.js | 1 + packages/material-ui/src/Slider/index.d.ts | 4 +- packages/material-ui/src/Slider/index.js | 2 +- 6 files changed, 401 insertions(+), 259 deletions(-) create mode 100644 packages/material-ui/src/Slider/SliderStyled.js diff --git a/packages/material-ui/package.json b/packages/material-ui/package.json index c0d19851109128..f27eb7191e0d8a 100644 --- a/packages/material-ui/package.json +++ b/packages/material-ui/package.json @@ -39,7 +39,10 @@ "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json && tsc -p tsconfig.build.json" }, "peerDependencies": { + "@emotion/core": "^10.0.27", + "@emotion/styled": "^10.0.27", "@types/react": "^16.8.6", + "emotion-theming": "^10.0.27", "react": "^16.8.0", "react-dom": "^16.8.0" }, @@ -50,6 +53,7 @@ }, "dependencies": { "@babel/runtime": "^7.4.4", + "@emotion/is-prop-valid": "^0.8.8", "@material-ui/styles": "^5.0.0-alpha.7", "@material-ui/system": "^5.0.0-alpha.6", "@material-ui/types": "^5.1.0", diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 35a62d356b9fa2..f14b3e966311b6 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -2,16 +2,13 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { chainPropTypes } from '@material-ui/utils'; -import withStyles from '../styles/withStyles'; -import useTheme from '../styles/useTheme'; -import { fade, lighten, darken } from '../styles/colorManipulator'; import useIsFocusVisible from '../utils/useIsFocusVisible'; import ownerDocument from '../utils/ownerDocument'; import useEventCallback from '../utils/useEventCallback'; import useForkRef from '../utils/useForkRef'; import capitalize from '../utils/capitalize'; import useControlled from '../utils/useControlled'; -import ValueLabel from './ValueLabel'; +import ValueLabelComponent from './ValueLabel'; function asc(a, b) { return a - b; @@ -144,227 +141,40 @@ function doesSupportTouchActionNone() { return cachedSupportsTouchActionNone; } -export const styles = (theme) => ({ - /* Styles applied to the root element. */ - root: { - height: 2, - width: '100%', - boxSizing: 'content-box', - padding: '13px 0', - display: 'inline-block', - position: 'relative', - cursor: 'pointer', - // Disable scroll capabilities. - touchAction: 'none', - color: theme.palette.primary.main, - WebkitTapHighlightColor: 'transparent', - '&$disabled': { - pointerEvents: 'none', - cursor: 'default', - color: theme.palette.grey[400], - }, - '&$vertical': { - width: 2, - height: '100%', - padding: '0 13px', - }, - // The primary input mechanism of the device includes a pointing device of limited accuracy. - '@media (pointer: coarse)': { - // Reach 42px touch target, about ~8mm on screen. - padding: '20px 0', - '&$vertical': { - padding: '0 20px', - }, - }, - '@media print': { - colorAdjust: 'exact', - }, - }, - /* Styles applied to the root element if `color="primary"`. */ - colorPrimary: { - // TODO v5: move the style here - }, - /* Styles applied to the root element if `color="secondary"`. */ - colorSecondary: { - color: theme.palette.secondary.main, - }, - /* Styles applied to the root element if `marks` is provided with at least one label. */ - marked: { - marginBottom: 20, - '&$vertical': { - marginBottom: 'auto', - marginRight: 20, - }, - }, - /* Pseudo-class applied to the root element if `orientation="vertical"`. */ - vertical: {}, - /* Pseudo-class applied to the root and thumb element if `disabled={true}`. */ - disabled: {}, - /* Styles applied to the rail element. */ - rail: { - display: 'block', - position: 'absolute', - width: '100%', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - opacity: 0.38, - '$vertical &': { - height: '100%', - width: 2, - }, - }, - /* Styles applied to the track element. */ - track: { - display: 'block', - position: 'absolute', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - '$vertical &': { - width: 2, - }, - }, - /* Styles applied to the track element if `track={false}`. */ - trackFalse: { - '& $track': { - display: 'none', - }, - }, - /* Styles applied to the track element if `track="inverted"`. */ - trackInverted: { - '& $track': { - backgroundColor: - // Same logic as the LinearProgress track color - theme.palette.type === 'light' - ? lighten(theme.palette.primary.main, 0.62) - : darken(theme.palette.primary.main, 0.5), - }, - '& $rail': { - opacity: 1, - }, - }, - /* Styles applied to the thumb element. */ - thumb: { - position: 'absolute', - width: 12, - height: 12, - marginLeft: -6, - marginTop: -5, - boxSizing: 'border-box', - borderRadius: '50%', - outline: 0, - backgroundColor: 'currentColor', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - transition: theme.transitions.create(['box-shadow'], { - duration: theme.transitions.duration.shortest, +const getUtilityClass = (name) => { + return `MuiSlider-${name}`; +}; + +const useSliderClasses = (props) => { + const { color, disabled, marked, orientation, track } = props; + + const utilityClasses = { + root: clsx(getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { + [getUtilityClass('disabled')]: disabled, + [getUtilityClass('marked')]: marked, + [getUtilityClass('vertical')]: orientation === 'vertical', + [getUtilityClass('trackInverted')]: track === 'inverted', + [getUtilityClass('trackFalse')]: track === false, }), - '&::after': { - position: 'absolute', - content: '""', - borderRadius: '50%', - // reach 42px hit target (2 * 15 + thumb diameter) - left: -15, - top: -15, - right: -15, - bottom: -15, - }, - '&$focusVisible,&:hover': { - boxShadow: `0px 0px 0px 8px ${fade(theme.palette.primary.main, 0.16)}`, - '@media (hover: none)': { - boxShadow: 'none', - }, - }, - '&$active': { - boxShadow: `0px 0px 0px 14px ${fade(theme.palette.primary.main, 0.16)}`, - }, - '&$disabled': { - width: 8, - height: 8, - marginLeft: -4, - marginTop: -3, - '&:hover': { - boxShadow: 'none', - }, - }, - '$vertical &': { - marginLeft: -5, - marginBottom: -6, - }, - '$vertical &$disabled': { - marginLeft: -3, - marginBottom: -4, - }, - }, - /* Styles applied to the thumb element if `color="primary"`. */ - thumbColorPrimary: { - // TODO v5: move the style here - }, - /* Styles applied to the thumb element if `color="secondary"`. */ - thumbColorSecondary: { - '&$focusVisible,&:hover': { - boxShadow: `0px 0px 0px 8px ${fade(theme.palette.secondary.main, 0.16)}`, - }, - '&$active': { - boxShadow: `0px 0px 0px 14px ${fade(theme.palette.secondary.main, 0.16)}`, - }, - }, - /* Pseudo-class applied to the thumb element if it's active. */ - active: {}, - /* Pseudo-class applied to the thumb element if keyboard focused. */ - focusVisible: {}, - /* Styles applied to the thumb label element. */ - valueLabel: { - // IE 11 centering bug, to remove from the customization demos once no longer supported - left: 'calc(-50% - 4px)', - }, - /* Styles applied to the mark element. */ - mark: { - position: 'absolute', - width: 2, - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - }, - /* Styles applied to the mark element if active (depending on the value). */ - markActive: { - backgroundColor: theme.palette.background.paper, - opacity: 0.8, - }, - /* Styles applied to the mark label element. */ - markLabel: { - ...theme.typography.body2, - color: theme.palette.text.secondary, - position: 'absolute', - top: 26, - transform: 'translateX(-50%)', - whiteSpace: 'nowrap', - '$vertical &': { - top: 'auto', - left: 26, - transform: 'translateY(50%)', - }, - '@media (pointer: coarse)': { - top: 40, - '$vertical &': { - left: 31, - }, - }, - }, - /* Styles applied to the mark label element if active (depending on the value). */ - markLabelActive: { - color: theme.palette.text.primary, - }, -}); + rail: getUtilityClass('rail'), + track: getUtilityClass('track'), + mark: getUtilityClass('mark'), + markLabel: getUtilityClass('markLabel'), + valueLabel: getUtilityClass('valueLabel'), + thumb: clsx(getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { + [getUtilityClass('disabled')]: disabled, + }), + }; + + return utilityClasses; +}; const Slider = React.forwardRef(function Slider(props, ref) { const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, 'aria-valuetext': ariaValuetext, - classes, + classes = {}, className, color = 'primary', component: Component = 'span', @@ -382,15 +192,16 @@ const Slider = React.forwardRef(function Slider(props, ref) { orientation = 'horizontal', scale = Identity, step = 1, - ThumbComponent = 'span', track = 'normal', value: valueProp, - ValueLabelComponent = ValueLabel, valueLabelDisplay = 'off', valueLabelFormat = Identity, + isRtl = false, + components = {}, + componentsProps = {}, ...other } = props; - const theme = useTheme(); + const touchId = React.useRef(); // We can't use the :active browser pseudo-classes. // - The active state isn't triggered when clicking on the rail. @@ -449,8 +260,6 @@ const Slider = React.forwardRef(function Slider(props, ref) { setOpen(-1); }); - const isRtl = theme.direction === 'rtl'; - const handleKeyDown = useEventCallback((event) => { const index = Number(event.currentTarget.getAttribute('data-index')); const value = values[index]; @@ -707,26 +516,65 @@ const Slider = React.forwardRef(function Slider(props, ref) { ...axisProps[axis].leap(trackLeap), }; + const Root = components.root || 'span'; + const rootProps = componentsProps.root || {}; + + const Rail = components.rail || 'span'; + const railProps = componentsProps.rail || {}; + + const Track = components.track || 'span'; + const trackProps = componentsProps.track || {}; + + const Thumb = components.thumb || 'span'; + const thumbProps = componentsProps.thumb || {}; + + const ValueLabel = components.valueLabel || ValueLabelComponent; + const valueLabelProps = componentsProps.valueLabel || {}; + + const Mark = components.mark || 'span'; + const markProps = componentsProps.mark || {}; + + const MarkLabel = components.markLabel || 'span'; + const markLabelProps = componentsProps.markLabel || {}; + + // all props with defaults + // consider extracting to hook an reusing the lint rule for the varints + const stateAndProps = { + ...props, + color, + disabled, + max, + min, + orientation, + scale, + step, + track, + valueLabelDisplay, + valueLabelFormat, + isRtl, + }; + + const utilityClasses = useSliderClasses({ + ...stateAndProps, + marked: marks.length > 0 && marks.some((mark) => mark.label), + }); + return ( - 0 && marks.some((mark) => mark.label), - [classes.vertical]: orientation === 'vertical', - [classes.trackInverted]: track === 'inverted', - [classes.trackFalse]: track === false, - }, - className, - )} + className={clsx(className, classes.root, utilityClasses.root)} onMouseDown={handleMouseDown} - {...other} + marked={marks.length > 0 && marks.some((mark) => mark.label)} + {...stateAndProps} + {...rootProps} > - - + + {marks.map((mark, index) => { const percent = valueToPercent(mark.value, min, max); @@ -749,24 +597,30 @@ const Slider = React.forwardRef(function Slider(props, ref) { return ( - {mark.label != null ? ( - {mark.label} - + ) : null} ); @@ -776,11 +630,11 @@ const Slider = React.forwardRef(function Slider(props, ref) { const style = axisProps[axis].offset(percent); return ( - - - + ); })} - + ); }); @@ -880,6 +739,19 @@ Slider.propTypes = { * Either a string to use a HTML element or a component. */ component: PropTypes.elementType, + /** + * The components used for each slot in the component. + * Either a string to use a HTML element or a component. + */ + components: PropTypes.shape({ + root: PropTypes.component, + rail: PropTypes.component, + track: PropTypes.component, + thumb: PropTypes.component, + valueLabel: PropTypes.component, + mark: PropTypes.component, + markLabel: PropTypes.component, + }), /** * The default element value. Use when the component is not controlled. */ @@ -903,6 +775,10 @@ Slider.propTypes = { * @returns {string} */ getAriaValueText: PropTypes.func, + /** + * Indicates whether the theme context has rtl direction. It is set automatically. + */ + isRtl: PropTypes.boolean, /** * Marks indicate predetermined values to which the user can move the slider. * If `true` the marks will be spaced according the value of the `step` prop. @@ -1005,4 +881,4 @@ Slider.propTypes = { valueLabelFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), }; -export default withStyles(styles, { name: 'MuiSlider' })(Slider); +export default Slider; diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js new file mode 100644 index 00000000000000..7f7abb582ad2a4 --- /dev/null +++ b/packages/material-ui/src/Slider/SliderStyled.js @@ -0,0 +1,261 @@ +import * as React from 'react'; +import styled from '@emotion/styled'; +import isPropValid from '@emotion/is-prop-valid'; +import useTheme from '../styles/useTheme'; +import { fade, lighten, darken } from '../styles/colorManipulator'; +import SliderBase from './Slider'; +import ValueLabel from './ValueLabel'; + +const shouldForwardProp = (prop) => + isPropValid(prop) && prop !== 'color' && prop !== 'orientation' && prop !== 'disabled'; + +const StyledComponent = styled('span', { shouldForwardProp })((props) => ({ + height: 2, + width: '100%', + boxSizing: 'content-box', + padding: '13px 0', + display: 'inline-block', + position: 'relative', + cursor: 'pointer', + touchAction: 'none', + color: props.theme.palette.primary.main, + WebkitTapHighlightColor: 'transparent', + ...(props.color === 'secondary' && { + color: props.theme.palette.secondary.main, + }), + ...(props.disabled && { + pointerEvents: 'none', + cursor: 'default', + color: props.theme.palette.grey[400], + }), + ...(props.orientation === 'vertical' && { + width: 2, + height: '100%', + padding: '0 13px', + }), + // The primary input mechanism of the device includes a pointing device of limited accuracy. + '@media (pointer: coarse)': { + // Reach 42px touch target, about ~8mm on screen. + padding: '20px 0', + ...(props.orientation === 'vertical' && { + padding: '0 20px', + }), + }, + '@media print': { + colorAdjust: 'exact', + }, + ...(props.marked && { + marginBottom: 20, + ...(props.orientation === 'vertical' && { + marginBottom: 'auto', + marginRight: 20, + }), + }), +})); + +const StyledRail = styled('span', { shouldForwardProp })((props) => ({ + display: 'block', + position: 'absolute', + width: '100%', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + opacity: 0.38, + ...(props.orientation === 'vertical' && { + height: '100%', + width: 2, + }), + ...(props.track === 'inverted' && { + opacity: 1, + }), +})); + +const StyledTrack = styled('span', { shouldForwardProp })((props) => ({ + display: 'block', + position: 'absolute', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + ...(props.orientation === 'vertical' && { + width: 2, + }), + ...(props.track === false && { + display: 'none', + }), + ...(props.track === 'inverted' && { + backgroundColor: + // Same logic as the LinearProgress track color + props.theme.palette.type === 'light' + ? lighten(props.theme.palette.primary.main, 0.62) + : darken(props.theme.palette.primary.main, 0.5), + }), +})); + +const StyledThumb = styled('span', { shouldForwardProp })((props) => ({ + position: 'absolute', + width: 12, + height: 12, + marginLeft: -6, + marginTop: -5, + boxSizing: 'border-box', + borderRadius: '50%', + outline: 0, + backgroundColor: 'currentColor', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: props.theme.transitions.create(['box-shadow'], { + duration: props.theme.transitions.duration.shortest, + }), + '::after': { + position: 'absolute', + content: '""', + borderRadius: '50%', + // reach 42px hit target (2 * 15 + thumb diameter) + left: -15, + top: -15, + right: -15, + bottom: -15, + }, + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, + }, + ...(props.focusVisible && { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, + }), + '&.MuiSlider--active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, + }, + ...(props.disabled && { + width: 8, + height: 8, + marginLeft: -4, + marginTop: -3, + ':hover': { + boxShadow: 'none', + }, + }), + ...(props.orientation === 'vertical' && { + marginLeft: -5, + marginBottom: -6, + }), + ...((props.orientation === 'vertical' || props.disabled) && { + marginLeft: -3, + marginBottom: -4, + }), + ...(props.color === 'secondary' && { + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + ...(props.focusVisible && { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }), + '&.MuiSlider--active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + }), +})); + +const StyledValueLabel = styled(ValueLabel)({ + // IE 11 centering bug, to remove from the customization demos once no longer supported + left: 'calc(-50% - 4px)', +}); + +const StyledMark = styled('span', { shouldForwardProp })((props) => ({ + position: 'absolute', + width: 2, + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + ...(props.markActive && { + backgroundColor: props.theme.palette.background.paper, + opacity: 0.8, + }), +})); + +const StyledMarkLabel = styled('span', { shouldForwardProp })((props) => ({ + ...props.theme.typography.body2, + color: props.theme.palette.text.secondary, + position: 'absolute', + top: 26, + transform: 'translateX(-50%)', + whiteSpace: 'nowrap', + ...(props.orientation === 'vertical' && { + top: 'auto', + left: 26, + transform: 'translateY(50%)', + }), + '@media (pointer: coarse)': { + top: 40, + ...(props.orientation === 'vertical' && { + left: 31, + }), + }, + ...(props.markLabelActive && { + color: props.theme.palette.text.primary, + }), +})); + +// This implementatino uses the ClassNames component https://emotion.sh/docs/class-names +const Slider = React.forwardRef(function Slider(props, ref) { + const { components = {}, componentsProps = {}, ...other } = props; + + const theme = useTheme(); + const isRtl = theme.direction === 'rtl'; + + return ( + + ); +}); + +export default Slider; diff --git a/packages/material-ui/src/Slider/ValueLabel.js b/packages/material-ui/src/Slider/ValueLabel.js index 528c9161d1c4fc..1e070928732602 100644 --- a/packages/material-ui/src/Slider/ValueLabel.js +++ b/packages/material-ui/src/Slider/ValueLabel.js @@ -43,6 +43,7 @@ const styles = (theme) => ({ /** * @ignore - internal component. */ +// TODO: convert to emotion function ValueLabel(props) { const { children, classes, className, open, value, valueLabelDisplay } = props; diff --git a/packages/material-ui/src/Slider/index.d.ts b/packages/material-ui/src/Slider/index.d.ts index 006f966fe2404f..444df65729b43f 100644 --- a/packages/material-ui/src/Slider/index.d.ts +++ b/packages/material-ui/src/Slider/index.d.ts @@ -1,2 +1,2 @@ -export { default } from './Slider'; -export * from './Slider'; +export { default } from './SliderStyled'; +export * from './SliderStyled'; diff --git a/packages/material-ui/src/Slider/index.js b/packages/material-ui/src/Slider/index.js index 9898d6a85d1d01..1df58e6268e679 100644 --- a/packages/material-ui/src/Slider/index.js +++ b/packages/material-ui/src/Slider/index.js @@ -1 +1 @@ -export { default } from './Slider'; +export { default } from './SliderStyled'; From 4c58672831594392d5e759b6a094a1c028cb1d72 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Sat, 29 Aug 2020 11:03:51 +0200 Subject: [PATCH 002/125] fix --- packages/material-ui/src/Slider/SliderStyled.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js index 7f7abb582ad2a4..ccbabe0c396232 100644 --- a/packages/material-ui/src/Slider/SliderStyled.js +++ b/packages/material-ui/src/Slider/SliderStyled.js @@ -225,31 +225,31 @@ const Slider = React.forwardRef(function Slider(props, ref) { }} componentsProps={{ root: { - as: props.components.root, + as: components.root, ...(componentsProps.root || {}), }, rail: { - as: props.components.rail, + as: components.rail, ...(componentsProps.rail || {}), }, track: { - as: props.components.track, + as: components.track, ...(componentsProps.track || {}), }, thumb: { - as: props.components.thumb, + as: components.thumb, ...(componentsProps.thumb || {}), }, valueLabel: { - as: props.components.valueLabel, + as: components.valueLabel, ...(componentsProps.valueLabel || {}), }, mark: { - as: props.components.mark, + as: components.mark, ...(componentsProps.mark || {}), }, markLabel: { - as: props.components.markLabel, + as: components.markLabel, ...(componentsProps.markLabel || {}), }, }} From 7fe38a0ac225dd0a6f619e9982e7f6b0dd40fd4c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 31 Aug 2020 08:28:09 +0200 Subject: [PATCH 003/125] implementet theme default props, implemented rtl --- packages/material-ui-styles/package.json | 5 +++- .../src/ThemeProvider/ThemeProvider.js | 19 +++++++++++- .../material-ui/src/Slider/SliderStyled.js | 29 +++++++++++++++---- yarn.lock | 12 ++++++++ 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/packages/material-ui-styles/package.json b/packages/material-ui-styles/package.json index 805224c2e7fc2d..d29c013fda0b9e 100644 --- a/packages/material-ui-styles/package.json +++ b/packages/material-ui-styles/package.json @@ -38,6 +38,7 @@ "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json" }, "peerDependencies": { + "@emotion/core": "^10.0.27", "@types/react": "^16.8.6", "react": "^16.8.0", "react-dom": "^16.8.0" @@ -49,6 +50,7 @@ }, "dependencies": { "@babel/runtime": "^7.4.4", + "@emotion/cache": "^10.0.27", "@emotion/hash": "^0.8.0", "@material-ui/types": "^5.1.0", "@material-ui/utils": "^5.0.0-alpha.1", @@ -63,7 +65,8 @@ "jss-plugin-props-sort": "^10.0.3", "jss-plugin-rule-value-function": "^10.0.3", "jss-plugin-vendor-prefixer": "^10.0.3", - "prop-types": "^15.7.2" + "prop-types": "^15.7.2", + "stylis-plugin-rtl": "^1.0.0" }, "sideEffects": false, "publishConfig": { diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 2a3093f36603a2..57ef204f87e747 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -1,6 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { exactProp } from '@material-ui/utils'; +import { CacheProvider } from "@emotion/core"; +import createCache from "@emotion/cache"; +import rtlPlugin from "stylis-plugin-rtl"; import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; @@ -61,7 +64,21 @@ function ThemeProvider(props) { return output; }, [localTheme, outerTheme]); - return {children}; + const cacheLtr = createCache({ + key: "mui", + stylisPlugins: [], + speedy: true + }); + + const cacheRtl = createCache({ + key: "muirtl", + stylisPlugins: [rtlPlugin], + speedy: true + }); + + const rtl = theme.direction === 'rtl'; + + return {children}; } ThemeProvider.propTypes = { diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js index ccbabe0c396232..e0e62abba2c6c5 100644 --- a/packages/material-ui/src/Slider/SliderStyled.js +++ b/packages/material-ui/src/Slider/SliderStyled.js @@ -1,10 +1,12 @@ import * as React from 'react'; import styled from '@emotion/styled'; import isPropValid from '@emotion/is-prop-valid'; +import { getThemeProps } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; import SliderBase from './Slider'; import ValueLabel from './ValueLabel'; +import defaultTheme from '../styles/defaultTheme'; const shouldForwardProp = (prop) => isPropValid(prop) && prop !== 'color' && prop !== 'orientation' && prop !== 'disabled'; @@ -202,17 +204,32 @@ const StyledMarkLabel = styled('span', { shouldForwardProp })((props) => ({ }), })); -// This implementatino uses the ClassNames component https://emotion.sh/docs/class-names -const Slider = React.forwardRef(function Slider(props, ref) { - const { components = {}, componentsProps = {}, ...other } = props; +const useThemeProps = (inputProps, ref, name) => { + const props = Object.assign({}, inputProps); + const { innerRef } = props; + + const contextTheme = useTheme() || defaultTheme; + + const more = getThemeProps({ theme: contextTheme, name, props }); - const theme = useTheme(); + const theme = more.theme || contextTheme; const isRtl = theme.direction === 'rtl'; + return { + ref: innerRef || ref, + theme, + isRtl, + ...more, + }; +}; + +// This implementatino uses the ClassNames component https://emotion.sh/docs/class-names +const Slider = React.forwardRef(function Slider(inputProps, inputRef) { + const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); + const { components = {}, componentsProps = {}, ref, ...other } = props; + return ( Date: Mon, 31 Aug 2020 09:59:50 +0200 Subject: [PATCH 004/125] wip overrides, needs refactor --- .../components/slider/ContinuousSlider.js | 60 ++++++---- packages/material-ui/src/Slider/Slider.js | 18 +-- .../material-ui/src/Slider/SliderStyled.js | 106 +++++++++++------- 3 files changed, 109 insertions(+), 75 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index a024382190fee6..aee248e8595a32 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -5,6 +5,7 @@ import Typography from '@material-ui/core/Typography'; import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; +import { ThemeProvider } from '@material-ui/styles'; const useStyles = makeStyles({ root: { @@ -21,29 +22,42 @@ export default function ContinuousSlider() { }; return ( -
- - Volume - - - - + +
+ + Volume + + + + + + + + + + + - - - - - - - - - Disabled slider - - -
+ + Disabled slider + + +
+ ); } diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index f14b3e966311b6..1fa83f797dc072 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -562,17 +562,17 @@ const Slider = React.forwardRef(function Slider(props, ref) { return ( 0 && marks.some((mark) => mark.label)} {...stateAndProps} {...rootProps} + className={clsx(className, classes.root, utilityClasses.root, rootProps.className)} > - + @@ -604,7 +604,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...markProps} className={clsx(classes.mark, utilityClasses.mark, { [getUtilityClass('markActive')]: markActive, - })} + }, markProps.className)} markActive={markActive} /> {mark.label != null ? ( @@ -616,7 +616,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...markLabelProps} className={clsx(classes.mark, utilityClasses.markLabel, { [getUtilityClass('markLabelActive')]: markActive, - })} + }, markLabelProps.className)} markLabelActive={markActive} > {mark.label} @@ -634,7 +634,6 @@ const Slider = React.forwardRef(function Slider(props, ref) { key={index} valueLabelFormat={valueLabelFormat} valueLabelDisplay={valueLabelDisplay} - className={clsx(classes.valueLabel, utilityClasses.valueLabel)} value={ typeof valueLabelFormat === 'function' ? valueLabelFormat(scale(value), index) @@ -645,14 +644,15 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} + className={clsx(classes.valueLabel, utilityClasses.valueLabel, valueLabelProps.className)} > { }; }; +// Stores a mapping between hashed string and cssified styles object +const stylesCache = {}; + +const useThemeOverrides = (name) => { + const theme = useTheme() || defaultTheme; + + let overrides = {}; + + if(theme && theme.components && theme.components[name] && theme.components[name].overrides) { + overrides = theme.components[name].overrides; + } + + return overrides; +}; + +const getComponentProps = (components, componentsProps, name) => { + return { + as: components[name], + ...(componentsProps[name] || {}), + }; +} + +const convertOverridesToClasses = (overrides, css) => { + const classes = {}; + + for(let key in overrides) { + classes[key] = css(overrides[key]); + } + + console.log(classes); + return classes; +} + // This implementatino uses the ClassNames component https://emotion.sh/docs/class-names const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); + const overrides = useThemeOverrides('MuiSlider'); const { components = {}, componentsProps = {}, ref, ...other } = props; return ( - + // TODO: move to ThemeProvider + + {({ css, cx }) => ( + + )} + ); }); From 6adbc8246a583134702318a8efae90d0bb061c83 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 08:42:16 +0200 Subject: [PATCH 005/125] converted CustomizedSlider to use components for overrides --- .../components/slider/ContinuousSlider.js | 26 +-- .../components/slider/CustomizedSlider.js | 193 ++++++++++-------- .../src/ThemeProvider/ThemeProvider.js | 24 ++- packages/material-ui/src/Slider/Slider.js | 47 +++-- .../material-ui/src/Slider/SliderStyled.js | 150 +++++++------- packages/material-ui/src/Slider/index.js | 9 + 6 files changed, 261 insertions(+), 188 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index aee248e8595a32..5696e14bf60c4d 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -22,18 +22,20 @@ export default function ContinuousSlider() { }; return ( - +
Volume diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 1ab7e7beecface..9038a67d6afa02 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -1,9 +1,18 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { withStyles, makeStyles } from '@material-ui/core/styles'; -import Slider from '@material-ui/core/Slider'; +import { makeStyles, useTheme } from '@material-ui/core/styles'; +import Slider, { + SliderRoot, + SliderMark, + SliderRail, + SliderTrack, + SliderThumb, + SliderValueLabel, +} from '@material-ui/core/Slider'; +import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; +import { ThemeProvider } from 'emotion-theming'; const useStyles = makeStyles((theme) => ({ root: { @@ -48,20 +57,20 @@ const marks = [ }, ]; -const IOSSlider = withStyles({ - root: { +const iosComponents = { + root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 28, width: 28, backgroundColor: '#fff', boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', // Reset on touch devices, it doesn't add specificity @@ -69,73 +78,82 @@ const IOSSlider = withStyles({ boxShadow: iOSBoxShadow, }, }, - }, - active: {}, - valueLabel: { + ...(props.active && { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, + }, + }), + })), + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { background: 'transparent', color: '#000', }, - }, - track: { + }), + track: styled(SliderTrack)({ height: 2, - }, - rail: { + }), + rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', - }, - mark: { + }), + mark: styled(SliderMark)((props) => ({ backgroundColor: '#bfbfbf', height: 8, width: 1, marginTop: -3, - }, - markActive: { - opacity: 1, - backgroundColor: 'currentColor', - }, -})(Slider); + ...(props.markActive && { + opacity: 1, + backgroundColor: 'currentColor', + }), + })), +}; -const PrettoSlider = withStyles({ - root: { +const prettoComponents = { + root: styled(SliderRoot)({ color: '#52af77', height: 8, - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 24, width: 24, backgroundColor: '#fff', border: '2px solid currentColor', marginTop: -8, marginLeft: -12, - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: 'inherit', }, - }, - active: {}, - valueLabel: { + ...(props.active && { + boxShadow: 'inherit', + }), + })), + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', - }, - track: { + }), + track: styled(SliderTrack)({ height: 8, borderRadius: 4, - }, - rail: { + }), + rail: styled(SliderRail)({ height: 8, borderRadius: 4, - }, -})(Slider); + }), +}; -const AirbnbSlider = withStyles({ - root: { +const airbnbComponents = { + root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 27, width: 27, backgroundColor: '#fff', @@ -143,9 +161,12 @@ const AirbnbSlider = withStyles({ marginTop: -12, marginLeft: -13, boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: '#ccc 0 2px 3px 1px', }, + ...(props.active && { + boxShadow: '#ccc 0 2px 3px 1px', + }), '& .bar': { // display: inline-block !important; height: 9, @@ -154,17 +175,16 @@ const AirbnbSlider = withStyles({ marginLeft: 1, marginRight: 1, }, - }, - active: {}, - track: { + })), + track: styled(SliderTrack)({ height: 3, - }, - rail: { + }), + rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, - }, -})(Slider); + }), +}; function AirbnbThumbComponent(props) { return ( @@ -178,39 +198,52 @@ function AirbnbThumbComponent(props) { export default function CustomizedSlider() { const classes = useStyles(); + const theme = useTheme(); return ( -
- iOS - -
- pretto.fr - -
- Tooltip value label - -
- Airbnb - - index === 0 ? 'Minimum price' : 'Maximum price' - } - defaultValue={[20, 40]} - /> -
+ +
+ iOS + +
+ pretto.fr + +
+ Tooltip value label + +
+ Airbnb + + index === 0 ? 'Minimum price' : 'Maximum price' + } + defaultValue={[20, 40]} + /> +
+ ); } diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 57ef204f87e747..2c707ce56ce02d 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { exactProp } from '@material-ui/utils'; -import { CacheProvider } from "@emotion/core"; -import createCache from "@emotion/cache"; -import rtlPlugin from "stylis-plugin-rtl"; +import { CacheProvider } from '@emotion/core'; +import createCache from '@emotion/cache'; +import rtlPlugin from 'stylis-plugin-rtl'; import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; @@ -65,20 +65,24 @@ function ThemeProvider(props) { }, [localTheme, outerTheme]); const cacheLtr = createCache({ - key: "mui", + key: 'mui', stylisPlugins: [], - speedy: true + speedy: true, }); - + const cacheRtl = createCache({ - key: "muirtl", + key: 'muirtl', stylisPlugins: [rtlPlugin], - speedy: true + speedy: true, }); - + const rtl = theme.direction === 'rtl'; - return {children}; + return ( + + {children} + + ); } ThemeProvider.propTypes = { diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 1fa83f797dc072..bb1a15adde77b9 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -568,7 +568,11 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...rootProps} className={clsx(className, classes.root, utilityClasses.root, rootProps.className)} > - + {mark.label != null ? ( @@ -614,9 +623,14 @@ const Slider = React.forwardRef(function Slider(props, ref) { style={style} {...stateAndProps} {...markLabelProps} - className={clsx(classes.mark, utilityClasses.markLabel, { - [getUtilityClass('markLabelActive')]: markActive, - }, markLabelProps.className)} + className={clsx( + classes.mark, + utilityClasses.markLabel, + { + [getUtilityClass('markLabelActive')]: markActive, + }, + markLabelProps.className, + )} markLabelActive={markActive} > {mark.label} @@ -644,15 +658,24 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} - className={clsx(classes.valueLabel, utilityClasses.valueLabel, valueLabelProps.className)} + className={clsx( + classes.valueLabel, + utilityClasses.valueLabel, + valueLabelProps.className, + )} > isPropValid(prop) && prop !== 'color' && prop !== 'orientation' && prop !== 'disabled'; -const StyledComponent = styled('span', { shouldForwardProp })((props) => ({ - height: 2, - width: '100%', - boxSizing: 'content-box', - padding: '13px 0', - display: 'inline-block', - position: 'relative', - cursor: 'pointer', - touchAction: 'none', - color: props.theme.palette.primary.main, - WebkitTapHighlightColor: 'transparent', - ...(props.color === 'secondary' && { - color: props.theme.palette.secondary.main, - }), - ...(props.disabled && { - pointerEvents: 'none', - cursor: 'default', - color: props.theme.palette.grey[400], - }), - ...(props.orientation === 'vertical' && { - width: 2, - height: '100%', - padding: '0 13px', - }), - // The primary input mechanism of the device includes a pointing device of limited accuracy. - '@media (pointer: coarse)': { - // Reach 42px touch target, about ~8mm on screen. - padding: '20px 0', - ...(props.orientation === 'vertical' && { - padding: '0 20px', +export const SliderRoot = styled('span', { shouldForwardProp })((props) => { + return { + height: 2, + width: '100%', + boxSizing: 'content-box', + padding: '13px 0', + display: 'inline-block', + position: 'relative', + cursor: 'pointer', + touchAction: 'none', + color: props.theme.palette.primary.main, + WebkitTapHighlightColor: 'transparent', + ...(props.color === 'secondary' && { + color: props.theme.palette.secondary.main, + }), + ...(props.disabled && { + pointerEvents: 'none', + cursor: 'default', + color: props.theme.palette.grey[400], }), - }, - '@media print': { - colorAdjust: 'exact', - }, - ...(props.marked && { - marginBottom: 20, ...(props.orientation === 'vertical' && { - marginBottom: 'auto', - marginRight: 20, + width: 2, + height: '100%', + padding: '0 13px', }), - }), -})); + // The primary input mechanism of the device includes a pointing device of limited accuracy. + '@media (pointer: coarse)': { + // Reach 42px touch target, about ~8mm on screen. + padding: '20px 0', + ...(props.orientation === 'vertical' && { + padding: '0 20px', + }), + }, + '@media print': { + colorAdjust: 'exact', + }, + ...(props.marked && { + marginBottom: 20, + ...(props.orientation === 'vertical' && { + marginBottom: 'auto', + marginRight: 20, + }), + }), + }; +}); -const StyledRail = styled('span', { shouldForwardProp })((props) => ({ +export const SliderRail = styled('span', { shouldForwardProp })((props) => ({ display: 'block', position: 'absolute', width: '100%', @@ -73,7 +75,7 @@ const StyledRail = styled('span', { shouldForwardProp })((props) => ({ }), })); -const StyledTrack = styled('span', { shouldForwardProp })((props) => ({ +export const SliderTrack = styled('span', { shouldForwardProp })((props) => ({ display: 'block', position: 'absolute', height: 2, @@ -94,7 +96,7 @@ const StyledTrack = styled('span', { shouldForwardProp })((props) => ({ }), })); -const StyledThumb = styled('span', { shouldForwardProp })((props) => ({ +export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ position: 'absolute', width: 12, height: 12, @@ -165,12 +167,12 @@ const StyledThumb = styled('span', { shouldForwardProp })((props) => ({ }), })); -const StyledValueLabel = styled(ValueLabel)({ +export const SliderValueLabel = styled(ValueLabel)({ // IE 11 centering bug, to remove from the customization demos once no longer supported left: 'calc(-50% - 4px)', }); -const StyledMark = styled('span', { shouldForwardProp })((props) => ({ +export const SliderMark = styled('span', { shouldForwardProp })((props) => ({ position: 'absolute', width: 2, height: 2, @@ -182,7 +184,7 @@ const StyledMark = styled('span', { shouldForwardProp })((props) => ({ }), })); -const StyledMarkLabel = styled('span', { shouldForwardProp })((props) => ({ +export const SliderMarkLabel = styled('span', { shouldForwardProp })((props) => ({ ...props.theme.typography.body2, color: props.theme.palette.text.secondary, position: 'absolute', @@ -232,7 +234,7 @@ const useThemeOverrides = (name) => { let overrides = {}; - if(theme && theme.components && theme.components[name] && theme.components[name].overrides) { + if (theme && theme.components && theme.components[name] && theme.components[name].overrides) { overrides = theme.components[name].overrides; } @@ -244,20 +246,19 @@ const getComponentProps = (components, componentsProps, name) => { as: components[name], ...(componentsProps[name] || {}), }; -} +}; const convertOverridesToClasses = (overrides, css) => { const classes = {}; - for(let key in overrides) { + // TODO: resolve dynamic styles if we want to support + for (let key in overrides) { classes[key] = css(overrides[key]); } - console.log(classes); return classes; -} +}; -// This implementatino uses the ClassNames component https://emotion.sh/docs/class-names const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); const overrides = useThemeOverrides('MuiSlider'); @@ -268,28 +269,29 @@ const Slider = React.forwardRef(function Slider(inputProps, inputRef) { {({ css, cx }) => ( + {...other} + classes={convertOverridesToClasses(overrides, css)} + components={{ + root: SliderRoot, + rail: SliderRail, + track: SliderTrack, + thumb: SliderThumb, + valueLabel: SliderValueLabel, + mark: SliderMark, + markLabel: SliderMarkLabel, + ...components, + }} + componentsProps={{ + root: getComponentProps(components, componentsProps, 'root'), + rail: getComponentProps(components, componentsProps, 'rail'), + track: getComponentProps(components, componentsProps, 'track'), + thumb: getComponentProps(components, componentsProps, 'thumb'), + valueLabel: getComponentProps(components, componentsProps, 'valueLabel'), + mark: getComponentProps(components, componentsProps, 'mark'), + markLabel: getComponentProps(components, componentsProps, 'markLabel'), + }} + ref={ref} + /> )} ); diff --git a/packages/material-ui/src/Slider/index.js b/packages/material-ui/src/Slider/index.js index 1df58e6268e679..bfd8260dccdc98 100644 --- a/packages/material-ui/src/Slider/index.js +++ b/packages/material-ui/src/Slider/index.js @@ -1 +1,10 @@ export { default } from './SliderStyled'; +export { + SliderRoot, + SliderMark, + SliderMarkLabel, + SliderRail, + SliderTrack, + SliderThumb, + SliderValueLabel, +} from './SliderStyled'; From 0c98292b63ee68cb2224aeabc7ecec7ef4909b28 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 09:04:10 +0200 Subject: [PATCH 006/125] cleanups --- packages/material-ui/package.json | 1 + packages/material-ui/src/Slider/Slider.d.ts | 47 ++----------- packages/material-ui/src/Slider/Slider.js | 69 +++++-------------- .../material-ui/src/Slider/SliderStyled.js | 62 ++++++++--------- 4 files changed, 52 insertions(+), 127 deletions(-) diff --git a/packages/material-ui/package.json b/packages/material-ui/package.json index f27eb7191e0d8a..f6c8ab3b9ff7dd 100644 --- a/packages/material-ui/package.json +++ b/packages/material-ui/package.json @@ -42,6 +42,7 @@ "@emotion/core": "^10.0.27", "@emotion/styled": "^10.0.27", "@types/react": "^16.8.6", + "emotion": "^10.0.27", "emotion-theming": "^10.0.27", "react": "^16.8.0", "react-dom": "^16.8.0" diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index a4d8ac67e1e964..6d3b453563e269 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -30,48 +30,7 @@ export interface SliderTypeMap

{ /** * Override or extend the styles applied to the component. */ - classes?: { - /** Styles applied to the root element. */ - root?: string; - /** Styles applied to the root element if `color="primary"`. */ - colorPrimary?: string; - /** Styles applied to the root element if `color="secondary"`. */ - colorSecondary?: string; - /** Styles applied to the root element if `marks` is provided with at least one label. */ - marked?: string; - /** Pseudo-class applied to the root element if `orientation="vertical"`. */ - vertical?: string; - /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ - disabled?: string; - /** Styles applied to the rail element. */ - rail?: string; - /** Styles applied to the track element. */ - track?: string; - /** Styles applied to the track element if `track={false}`. */ - trackFalse?: string; - /** Styles applied to the track element if `track="inverted"`. */ - trackInverted?: string; - /** Styles applied to the thumb element. */ - thumb?: string; - /** Styles applied to the thumb element if `color="primary"`. */ - thumbColorPrimary?: string; - /** Styles applied to the thumb element if `color="secondary"`. */ - thumbColorSecondary?: string; - /** Pseudo-class applied to the thumb element if it's active. */ - active?: string; - /** Pseudo-class applied to the thumb element if keyboard focused. */ - focusVisible?: string; - /** Styles applied to the thumb label element. */ - valueLabel?: string; - /** Styles applied to the mark element. */ - mark?: string; - /** Styles applied to the mark element if active (depending on the value). */ - markActive?: string; - /** Styles applied to the mark label element. */ - markLabel?: string; - /** Styles applied to the mark label element if active (depending on the value). */ - markLabelActive?: string; - }; + classes?: {}; /** * The color of the component. It supports those theme colors that make sense for this component. */ @@ -99,6 +58,10 @@ export interface SliderTypeMap

{ * @returns {string} */ getAriaValueText?: (value: number, index: number) => string; + /** + * Indicates whether the theme context has rtl direction. It is set automatically. + */ + isRtl?: boolean; /** * Marks indicate predetermined values to which the user can move the slider. * If `true` the marks will be spaced according the value of the `step` prop. diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index bb1a15adde77b9..efa1c0f6533551 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,6 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import clsx from 'clsx'; +import { cx } from 'emotion'; import { chainPropTypes } from '@material-ui/utils'; import useIsFocusVisible from '../utils/useIsFocusVisible'; import ownerDocument from '../utils/ownerDocument'; @@ -149,7 +149,7 @@ const useSliderClasses = (props) => { const { color, disabled, marked, orientation, track } = props; const utilityClasses = { - root: clsx(getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { + root: cx(getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { [getUtilityClass('disabled')]: disabled, [getUtilityClass('marked')]: marked, [getUtilityClass('vertical')]: orientation === 'vertical', @@ -161,7 +161,7 @@ const useSliderClasses = (props) => { mark: getUtilityClass('mark'), markLabel: getUtilityClass('markLabel'), valueLabel: getUtilityClass('valueLabel'), - thumb: clsx(getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { + thumb: cx(getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { [getUtilityClass('disabled')]: disabled, }), }; @@ -541,6 +541,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { // consider extracting to hook an reusing the lint rule for the varints const stateAndProps = { ...props, + classes: undefined, // we do not want to override other components classes color, disabled, max, @@ -566,17 +567,17 @@ const Slider = React.forwardRef(function Slider(props, ref) { marked={marks.length > 0 && marks.some((mark) => mark.label)} {...stateAndProps} {...rootProps} - className={clsx(className, classes.root, utilityClasses.root, rootProps.className)} + className={cx(rootProps.className, classes.root, className, utilityClasses.root)} > @@ -606,14 +607,9 @@ const Slider = React.forwardRef(function Slider(props, ref) { data-index={index} {...stateAndProps} {...markProps} - className={clsx( - classes.mark, - utilityClasses.mark, - { - [getUtilityClass('markActive')]: markActive, - }, - markProps.className, - )} + className={cx(markProps.className, classes.mark, utilityClasses.mark, { + [getUtilityClass('markActive')]: markActive, + })} markActive={markActive} /> {mark.label != null ? ( @@ -623,14 +619,9 @@ const Slider = React.forwardRef(function Slider(props, ref) { style={style} {...stateAndProps} {...markLabelProps} - className={clsx( - classes.mark, - utilityClasses.markLabel, - { - [getUtilityClass('markLabelActive')]: markActive, - }, - markLabelProps.className, - )} + className={cx(markLabelProps.className, classes.mark, utilityClasses.markLabel, { + [getUtilityClass('markLabelActive')]: markActive, + })} markLabelActive={markActive} > {mark.label} @@ -658,24 +649,15 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} - className={clsx( - classes.valueLabel, - utilityClasses.valueLabel, - valueLabelProps.className, - )} + className={cx(valueLabelProps.className, classes.valueLabel, utilityClasses.valueLabel)} > - isPropValid(prop) && prop !== 'color' && prop !== 'orientation' && prop !== 'disabled'; + isPropValid(prop) && prop !== 'color' && prop !== 'scale' && prop !== 'orientation' && prop !== 'disabled'; export const SliderRoot = styled('span', { shouldForwardProp })((props) => { return { @@ -226,9 +226,6 @@ const useThemeProps = (inputProps, ref, name) => { }; }; -// Stores a mapping between hashed string and cssified styles object -const stylesCache = {}; - const useThemeOverrides = (name) => { const theme = useTheme() || defaultTheme; @@ -248,7 +245,7 @@ const getComponentProps = (components, componentsProps, name) => { }; }; -const convertOverridesToClasses = (overrides, css) => { +const convertOverridesToClasses = (overrides) => { const classes = {}; // TODO: resolve dynamic styles if we want to support @@ -265,35 +262,30 @@ const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const { components = {}, componentsProps = {}, ref, ...other } = props; return ( - // TODO: move to ThemeProvider - - {({ css, cx }) => ( - - )} - + ); }); From 99499b645a33cefb69a6f1e10e20da3cb7228009 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 09:30:12 +0200 Subject: [PATCH 007/125] overrides fixed --- packages/material-ui/src/Slider/Slider.js | 73 ++++++++++++------- .../material-ui/src/Slider/SliderStyled.js | 1 - 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index efa1c0f6533551..c41f27238380a9 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -146,27 +146,45 @@ const getUtilityClass = (name) => { }; const useSliderClasses = (props) => { - const { color, disabled, marked, orientation, track } = props; - - const utilityClasses = { - root: cx(getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { - [getUtilityClass('disabled')]: disabled, - [getUtilityClass('marked')]: marked, - [getUtilityClass('vertical')]: orientation === 'vertical', - [getUtilityClass('trackInverted')]: track === 'inverted', - [getUtilityClass('trackFalse')]: track === false, - }), - rail: getUtilityClass('rail'), - track: getUtilityClass('track'), - mark: getUtilityClass('mark'), - markLabel: getUtilityClass('markLabel'), - valueLabel: getUtilityClass('valueLabel'), - thumb: cx(getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { - [getUtilityClass('disabled')]: disabled, - }), + const { color, disabled, marked, orientation, track, classes } = props; + + const overridesClasses = { + root: cx( + getUtilityClass('root'), + classes.root, + getUtilityClass(`color${capitalize(color)}`), + classes[`color${capitalize(color)}`], + { + [getUtilityClass('disabled')]: disabled, + [classes.disabled]: disabled, + [getUtilityClass('marked')]: marked, + [classes.marked]: marked, + [getUtilityClass('vertical')]: orientation === 'vertical', + [classes.vertical]: orientation === 'vertical', + [getUtilityClass('trackInverted')]: track === 'inverted', + [classes.trackInverted]: track === 'inverted', + [getUtilityClass('trackFalse')]: track === false, + [classes.trackFalse]: track === false, + } + ), + rail: cx(getUtilityClass('rail'), classes.rail), + track: cx(getUtilityClass('track'), classes.track), + mark: cx(getUtilityClass('mark'), classes.mark), + markLabel: cx(getUtilityClass('markLabel'), classes.markLabel), + valueLabel: cx(getUtilityClass('valueLabel'), classes.valueLabel), + thumb: cx( + getUtilityClass('thumb'), + classes.thumb, + getUtilityClass(`thumbColor${capitalize(color)}`), + classes[`thumbColor${capitalize(color)}`], + { + [getUtilityClass('disabled')]: disabled, + [classes.disabled]: disabled + } + ), }; - return utilityClasses; + return overridesClasses; }; const Slider = React.forwardRef(function Slider(props, ref) { @@ -555,8 +573,9 @@ const Slider = React.forwardRef(function Slider(props, ref) { isRtl, }; - const utilityClasses = useSliderClasses({ + const overridesClasses = useSliderClasses({ ...stateAndProps, + classes, marked: marks.length > 0 && marks.some((mark) => mark.label), }); @@ -567,17 +586,17 @@ const Slider = React.forwardRef(function Slider(props, ref) { marked={marks.length > 0 && marks.some((mark) => mark.label)} {...stateAndProps} {...rootProps} - className={cx(rootProps.className, classes.root, className, utilityClasses.root)} + className={cx(rootProps.className, className, overridesClasses.root)} > @@ -607,7 +626,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { data-index={index} {...stateAndProps} {...markProps} - className={cx(markProps.className, classes.mark, utilityClasses.mark, { + className={cx(markProps.className, overridesClasses.mark, { [getUtilityClass('markActive')]: markActive, })} markActive={markActive} @@ -619,7 +638,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { style={style} {...stateAndProps} {...markLabelProps} - className={cx(markLabelProps.className, classes.mark, utilityClasses.markLabel, { + className={cx(markLabelProps.className, overridesClasses.markLabel, { [getUtilityClass('markLabelActive')]: markActive, })} markLabelActive={markActive} @@ -649,12 +668,12 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} - className={cx(valueLabelProps.className, classes.valueLabel, utilityClasses.valueLabel)} + className={cx(valueLabelProps.className, overridesClasses.valueLabel)} > { const convertOverridesToClasses = (overrides) => { const classes = {}; - // TODO: resolve dynamic styles if we want to support for (let key in overrides) { classes[key] = css(overrides[key]); } From d375e3dc0fb61dc1e05ab240b24148fc383dd17a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 09:35:11 +0200 Subject: [PATCH 008/125] reverted changes in continious slider --- .../components/slider/ContinuousSlider.js | 62 +++++++------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index 5696e14bf60c4d..a024382190fee6 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -5,7 +5,6 @@ import Typography from '@material-ui/core/Typography'; import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; -import { ThemeProvider } from '@material-ui/styles'; const useStyles = makeStyles({ root: { @@ -22,44 +21,29 @@ export default function ContinuousSlider() { }; return ( - -

- - Volume - - - - - - - - - - - +
+ + Volume + + + + - - Disabled slider - - -
- + + + + + + +
+ + Disabled slider + + +
); } From 4777a558295b4f832db4f9fe7d12b37274d35546 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 10:08:43 +0200 Subject: [PATCH 009/125] reverted some changes --- packages/material-ui/src/Slider/Slider.d.ts | 43 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 6d3b453563e269..6c3da15a8e0dec 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -30,7 +30,48 @@ export interface SliderTypeMap

{ /** * Override or extend the styles applied to the component. */ - classes?: {}; + classes?: { + /** Styles applied to the root element. */ + root?: string; + /** Styles applied to the root element if `color="primary"`. */ + colorPrimary?: string; + /** Styles applied to the root element if `color="secondary"`. */ + colorSecondary?: string; + /** Styles applied to the root element if `marks` is provided with at least one label. */ + marked?: string; + /** Pseudo-class applied to the root element if `orientation="vertical"`. */ + vertical?: string; + /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ + disabled?: string; + /** Styles applied to the rail element. */ + rail?: string; + /** Styles applied to the track element. */ + track?: string; + /** Styles applied to the track element if `track={false}`. */ + trackFalse?: string; + /** Styles applied to the track element if `track="inverted"`. */ + trackInverted?: string; + /** Styles applied to the thumb element. */ + thumb?: string; + /** Styles applied to the thumb element if `color="primary"`. */ + thumbColorPrimary?: string; + /** Styles applied to the thumb element if `color="secondary"`. */ + thumbColorSecondary?: string; + /** Pseudo-class applied to the thumb element if it's active. */ + active?: string; + /** Pseudo-class applied to the thumb element if keyboard focused. */ + focusVisible?: string; + /** Styles applied to the thumb label element. */ + valueLabel?: string; + /** Styles applied to the mark element. */ + mark?: string; + /** Styles applied to the mark element if active (depending on the value). */ + markActive?: string; + /** Styles applied to the mark label element. */ + markLabel?: string; + /** Styles applied to the mark label element if active (depending on the value). */ + markLabelActive?: string; + }; /** * The color of the component. It supports those theme colors that make sense for this component. */ From f89164797edae03e04f6a1397f2a6c2b3a6d4f0c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 1 Sep 2020 21:33:02 +0200 Subject: [PATCH 010/125] implemented variants --- packages/material-ui-styles/src/index.d.ts | 3 ++ packages/material-ui-styles/src/index.js | 3 ++ .../material-ui/src/Slider/SliderStyled.js | 50 ++++++++++++------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/packages/material-ui-styles/src/index.d.ts b/packages/material-ui-styles/src/index.d.ts index 65d11adec915fe..baf467943fe9f6 100644 --- a/packages/material-ui-styles/src/index.d.ts +++ b/packages/material-ui-styles/src/index.d.ts @@ -34,6 +34,9 @@ export * from './useTheme'; export { default as useThemeVariants } from './useThemeVariants'; export * from './useThemeVariants'; +export { default as propsToClassKey } from './propsToClassKey'; +export * from './propsToClassKey'; + export { default as withStyles } from './withStyles'; export * from './withStyles'; diff --git a/packages/material-ui-styles/src/index.js b/packages/material-ui-styles/src/index.js index dd9aac3207d387..c390bed604f19a 100644 --- a/packages/material-ui-styles/src/index.js +++ b/packages/material-ui-styles/src/index.js @@ -61,6 +61,9 @@ export * from './useTheme'; export { default as useThemeVariants } from './useThemeVariants'; export * from './useThemeVariants'; +export { default as propsToClassKey } from './propsToClassKey'; +export * from './propsToClassKey'; + export { default as withStyles } from './withStyles'; export * from './withStyles'; diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js index 2a6b98c3c10c68..d67ddf9ed60508 100644 --- a/packages/material-ui/src/Slider/SliderStyled.js +++ b/packages/material-ui/src/Slider/SliderStyled.js @@ -1,8 +1,8 @@ import * as React from 'react'; -import { css } from 'emotion'; +import { css, cx } from 'emotion'; import styled from '@emotion/styled'; import isPropValid from '@emotion/is-prop-valid'; -import { getThemeProps } from '@material-ui/styles'; +import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; import SliderBase from './Slider'; @@ -226,16 +226,36 @@ const useThemeProps = (inputProps, ref, name) => { }; }; -const useThemeOverrides = (name) => { +const useThemeClasses = (name) => { const theme = useTheme() || defaultTheme; - let overrides = {}; + let styleOverrides = {}; + let variants = []; - if (theme && theme.components && theme.components[name] && theme.components[name].overrides) { - overrides = theme.components[name].overrides; + if (theme && theme.components && theme.components[name] && theme.components[name].styleOverrides) { + styleOverrides = theme.components[name].styleOverrides; } - return overrides; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + variants = theme.components[name].variants; + } + + const classes = {}; + + Object.keys(styleOverrides).forEach(key => { + classes[key] = css(styleOverrides[key]); + }); + + variants.forEach((definition) => { + const key = propsToClassKey(definition.props); + if(classes[key]) { + classes[key] = cx(classes[key], css(definition.style)) + } else { + classes[key] = css(definition.style); + } + }); + + return classes; }; const getComponentProps = (components, componentsProps, name) => { @@ -245,25 +265,17 @@ const getComponentProps = (components, componentsProps, name) => { }; }; -const convertOverridesToClasses = (overrides) => { - const classes = {}; - - for (let key in overrides) { - classes[key] = css(overrides[key]); - } - - return classes; -}; - const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); - const overrides = useThemeOverrides('MuiSlider'); + const classes = useThemeClasses('MuiSlider'); + const themeVariantsClasses = useThemeVariants({ ...props, classes }, 'MuiSlider'); const { components = {}, componentsProps = {}, ref, ...other } = props; return ( Date: Tue, 1 Sep 2020 21:39:27 +0200 Subject: [PATCH 011/125] fixed variants presendance over overrides --- .../components/slider/ContinuousSlider.js | 73 +++++++++++++------ packages/material-ui/src/Slider/Slider.js | 14 ++-- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index a024382190fee6..1b8a32ce314d79 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -5,6 +5,7 @@ import Typography from '@material-ui/core/Typography'; import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; +import { ThemeProvider } from '@material-ui/styles'; const useStyles = makeStyles({ root: { @@ -20,30 +21,56 @@ export default function ContinuousSlider() { setValue(newValue); }; + const theme = { + components: { + MuiSlider: { + variants: [ + { + props: { color: 'primary', orientation: 'vertical'}, + style: { + backgroundColor: 'green' + } + }, + ], + styleOverrides: { + root: { + background: 'red' + } + } + } + }, + }; + return ( -

- - Volume - - - - - - - - - - + +
+ + Volume + + + + + + + + + + + - - - Disabled slider - - -
+ + Disabled slider + + + + Vertical primary slider + + +
+ ); } diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 1daf83cd45239d..0ecc6262b9165c 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -613,17 +613,17 @@ const Slider = React.forwardRef(function Slider(props, ref) { marked={marks.length > 0 && marks.some((mark) => mark.label)} {...stateAndProps} {...rootProps} - className={cx(rootProps.className, className, overridesClasses.root)} + className={cx(overridesClasses.root, rootProps.className, className)} > @@ -653,7 +653,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { data-index={index} {...stateAndProps} {...markProps} - className={cx(markProps.className, overridesClasses.mark, { + className={cx(overridesClasses.mark, markProps.className, { [getUtilityClass('markActive')]: markActive, })} markActive={markActive} @@ -665,7 +665,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { style={style} {...stateAndProps} {...markLabelProps} - className={cx(markLabelProps.className, overridesClasses.markLabel, { + className={cx(overridesClasses.markLabel, markLabelProps.className, { [getUtilityClass('markLabelActive')]: markActive, })} markLabelActive={markActive} @@ -695,12 +695,12 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} - className={cx(valueLabelProps.className, overridesClasses.valueLabel)} + className={cx(overridesClasses.valueLabel, valueLabelProps.className)} > Date: Tue, 1 Sep 2020 21:56:09 +0200 Subject: [PATCH 012/125] prettier + docs:formatted --- CHANGELOG.md | 2 +- .../components/slider/ContinuousSlider.js | 15 +- .../components/slider/ContinuousSlider.tsx | 76 ++++--- .../components/slider/CustomizedSlider.js | 6 +- .../components/slider/CustomizedSlider.tsx | 197 +++++++++++------- packages/material-ui/src/Slider/Slider.js | 8 +- .../material-ui/src/Slider/SliderStyled.js | 19 +- packages/material-ui/src/Slider/index.d.ts | 9 + 8 files changed, 210 insertions(+), 122 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a1e9688e26726..a8981b39ac0f62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -127,7 +127,7 @@ const theme = createMuiTheme({ - [ButtonBase] Reset box-sizing to border-box (#22316) @su8ru - [Dialog] Fix unexpected close when releasing click on backdrop (#22310) @danbrud - [Divider] Add text in divider (#22285) @ShehryarShoukat96 -- [Slider] Respect disabled property when already focused (#22247) @pireads +- [Slider] Respect disabled property when already focused (#22247) @pireads - [Tabs] Don't fire onChange if current value (#22381) @jjoselv - [Tabs] Improve focus management on list with no active tabs (#22377) @alexmotoc - [theme] Add theme.mixins.gutters() in adaptV4Theme (#22396) @mnajdova diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index 1b8a32ce314d79..c6b78ab830f55e 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -24,20 +24,21 @@ export default function ContinuousSlider() { const theme = { components: { MuiSlider: { + // @ts-ignore MuiSlider does not support variants, this is added just for testing variants: [ { - props: { color: 'primary', orientation: 'vertical'}, + props: { color: 'primary', orientation: 'vertical' }, style: { - backgroundColor: 'green' - } + backgroundColor: 'green', + }, }, ], styleOverrides: { root: { - background: 'red' - } - } - } + background: 'red', + }, + }, + }, }, }; diff --git a/docs/src/pages/components/slider/ContinuousSlider.tsx b/docs/src/pages/components/slider/ContinuousSlider.tsx index 66234230619d29..2fc325d720de12 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.tsx +++ b/docs/src/pages/components/slider/ContinuousSlider.tsx @@ -1,10 +1,11 @@ import * as React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; +import { makeStyles, Theme } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; +import { ThemeProvider } from '@material-ui/styles'; const useStyles = makeStyles({ root: { @@ -23,30 +24,57 @@ export default function ContinuousSlider() { setValue(newValue as number); }; + const theme: Theme = { + components: { + MuiSlider: { + // @ts-ignore MuiSlider does not support variants, this is added just for testing + variants: [ + { + props: { color: 'primary', orientation: 'vertical' }, + style: { + backgroundColor: 'green', + }, + }, + ], + styleOverrides: { + root: { + background: 'red', + }, + }, + }, + }, + }; + return ( -
- - Volume - - - - - - - - - - + +
+ + Volume + + + + + + + + + + + - - - Disabled slider - - -
+ + Disabled slider + + + + Vertical primary slider + + +
+ ); } diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 9038a67d6afa02..b2336fdb5b71b0 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -1,6 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { makeStyles, useTheme } from '@material-ui/core/styles'; +import { useTheme, makeStyles } from '@material-ui/core/styles'; import Slider, { SliderRoot, SliderMark, @@ -67,6 +67,7 @@ const iosComponents = { height: 28, width: 28, backgroundColor: '#fff', + // @ts-ignore boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, @@ -104,6 +105,7 @@ const iosComponents = { backgroundColor: '#bfbfbf', }), mark: styled(SliderMark)((props) => ({ + // @ts-ignore backgroundColor: '#bfbfbf', height: 8, width: 1, @@ -160,6 +162,7 @@ const airbnbComponents = { border: '1px solid currentColor', marginTop: -12, marginLeft: -13, + // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', '&:focus, &:hover': { boxShadow: '#ccc 0 2px 3px 1px', @@ -198,6 +201,7 @@ function AirbnbThumbComponent(props) { export default function CustomizedSlider() { const classes = useStyles(); + // For some reason the theme when styled used twice is coming from emotion, not our defulat theme const theme = useTheme(); return ( diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index 08c6a0dc968908..d49f9cd4745f25 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -1,13 +1,22 @@ import * as React from 'react'; import { - withStyles, + useTheme, makeStyles, Theme, createStyles, } from '@material-ui/core/styles'; -import Slider from '@material-ui/core/Slider'; +import Slider, { + SliderRoot, + SliderMark, + SliderRail, + SliderTrack, + SliderThumb, + SliderValueLabel, +} from '@material-ui/core/Slider'; +import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; +import { ThemeProvider } from 'emotion-theming'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -54,20 +63,21 @@ const marks = [ }, ]; -const IOSSlider = withStyles({ - root: { +const iosComponents = { + root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 28, width: 28, backgroundColor: '#fff', + // @ts-ignore boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', // Reset on touch devices, it doesn't add specificity @@ -75,83 +85,97 @@ const IOSSlider = withStyles({ boxShadow: iOSBoxShadow, }, }, - }, - active: {}, - valueLabel: { + ...(props.active && { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, + }, + }), + })), + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { background: 'transparent', color: '#000', }, - }, - track: { + }), + track: styled(SliderTrack)({ height: 2, - }, - rail: { + }), + rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', - }, - mark: { + }), + mark: styled(SliderMark)((props) => ({ + // @ts-ignore backgroundColor: '#bfbfbf', height: 8, width: 1, marginTop: -3, - }, - markActive: { - opacity: 1, - backgroundColor: 'currentColor', - }, -})(Slider); + ...(props.markActive && { + opacity: 1, + backgroundColor: 'currentColor', + }), + })), +}; -const PrettoSlider = withStyles({ - root: { +const prettoComponents = { + root: styled(SliderRoot)({ color: '#52af77', height: 8, - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 24, width: 24, backgroundColor: '#fff', border: '2px solid currentColor', marginTop: -8, marginLeft: -12, - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: 'inherit', }, - }, - active: {}, - valueLabel: { + ...(props.active && { + boxShadow: 'inherit', + }), + })), + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', - }, - track: { + }), + track: styled(SliderTrack)({ height: 8, borderRadius: 4, - }, - rail: { + }), + rail: styled(SliderRail)({ height: 8, borderRadius: 4, - }, -})(Slider); + }), +}; -const AirbnbSlider = withStyles({ - root: { +const airbnbComponents = { + root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', - }, - thumb: { + }), + thumb: styled(SliderThumb)((props) => ({ height: 27, width: 27, backgroundColor: '#fff', border: '1px solid currentColor', marginTop: -12, marginLeft: -13, + // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &$active': { + '&:focus, &:hover': { boxShadow: '#ccc 0 2px 3px 1px', }, + ...(props.active && { + boxShadow: '#ccc 0 2px 3px 1px', + }), '& .bar': { // display: inline-block !important; height: 9, @@ -160,17 +184,16 @@ const AirbnbSlider = withStyles({ marginLeft: 1, marginRight: 1, }, - }, - active: {}, - track: { + })), + track: styled(SliderTrack)({ height: 3, - }, - rail: { + }), + rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, - }, -})(Slider); + }), +}; function AirbnbThumbComponent(props: any) { return ( @@ -184,39 +207,53 @@ function AirbnbThumbComponent(props: any) { export default function CustomizedSlider() { const classes = useStyles(); + // For some reason the theme when styled used twice is coming from emotion, not our defulat theme + const theme = useTheme(); return ( -
- iOS - -
- pretto.fr - -
- Tooltip value label - -
- Airbnb - - index === 0 ? 'Minimum price' : 'Maximum price' - } - defaultValue={[20, 40]} - /> -
+ +
+ iOS + +
+ pretto.fr + +
+ Tooltip value label + +
+ Airbnb + + index === 0 ? 'Minimum price' : 'Maximum price' + } + defaultValue={[20, 40]} + /> +
+ ); } diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 0ecc6262b9165c..d44b8b674cd3f2 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -166,7 +166,7 @@ const useSliderClasses = (props) => { [classes.trackInverted]: track === 'inverted', [getUtilityClass('trackFalse')]: track === false, [classes.trackFalse]: track === false, - } + }, ), rail: cx(getUtilityClass('rail'), classes.rail), track: cx(getUtilityClass('track'), classes.track), @@ -176,12 +176,12 @@ const useSliderClasses = (props) => { thumb: cx( getUtilityClass('thumb'), classes.thumb, - getUtilityClass(`thumbColor${capitalize(color)}`), + getUtilityClass(`thumbColor${capitalize(color)}`), classes[`thumbColor${capitalize(color)}`], { [getUtilityClass('disabled')]: disabled, - [classes.disabled]: disabled - } + [classes.disabled]: disabled, + }, ), }; diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js index d67ddf9ed60508..f292cfec1d1ad8 100644 --- a/packages/material-ui/src/Slider/SliderStyled.js +++ b/packages/material-ui/src/Slider/SliderStyled.js @@ -10,7 +10,11 @@ import ValueLabel from './ValueLabel'; import defaultTheme from '../styles/defaultTheme'; const shouldForwardProp = (prop) => - isPropValid(prop) && prop !== 'color' && prop !== 'scale' && prop !== 'orientation' && prop !== 'disabled'; + isPropValid(prop) && + prop !== 'color' && + prop !== 'scale' && + prop !== 'orientation' && + prop !== 'disabled'; export const SliderRoot = styled('span', { shouldForwardProp })((props) => { return { @@ -232,7 +236,12 @@ const useThemeClasses = (name) => { let styleOverrides = {}; let variants = []; - if (theme && theme.components && theme.components[name] && theme.components[name].styleOverrides) { + if ( + theme && + theme.components && + theme.components[name] && + theme.components[name].styleOverrides + ) { styleOverrides = theme.components[name].styleOverrides; } @@ -242,14 +251,14 @@ const useThemeClasses = (name) => { const classes = {}; - Object.keys(styleOverrides).forEach(key => { + Object.keys(styleOverrides).forEach((key) => { classes[key] = css(styleOverrides[key]); }); variants.forEach((definition) => { const key = propsToClassKey(definition.props); - if(classes[key]) { - classes[key] = cx(classes[key], css(definition.style)) + if (classes[key]) { + classes[key] = cx(classes[key], css(definition.style)); } else { classes[key] = css(definition.style); } diff --git a/packages/material-ui/src/Slider/index.d.ts b/packages/material-ui/src/Slider/index.d.ts index 444df65729b43f..1c804c88525ee3 100644 --- a/packages/material-ui/src/Slider/index.d.ts +++ b/packages/material-ui/src/Slider/index.d.ts @@ -1,2 +1,11 @@ export { default } from './SliderStyled'; +export { + SliderRoot, + SliderMark, + SliderMarkLabel, + SliderRail, + SliderTrack, + SliderThumb, + SliderValueLabel, +} from './SliderStyled'; export * from './SliderStyled'; From 940f6d7ccf2b6d436b8572cd1593bf1ab3dd3dbe Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 2 Sep 2020 05:14:51 +0200 Subject: [PATCH 013/125] renamed components --- packages/material-ui/src/Slider/Slider.d.ts | 220 +--- packages/material-ui/src/Slider/Slider.js | 1162 ++++------------- .../material-ui/src/Slider/SliderBase.d.ts | 199 +++ packages/material-ui/src/Slider/SliderBase.js | 922 +++++++++++++ .../material-ui/src/Slider/SliderStyled.js | 312 ----- packages/material-ui/src/Slider/index.d.ts | 8 +- packages/material-ui/src/Slider/index.js | 5 +- 7 files changed, 1432 insertions(+), 1396 deletions(-) create mode 100644 packages/material-ui/src/Slider/SliderBase.d.ts create mode 100644 packages/material-ui/src/Slider/SliderBase.js delete mode 100644 packages/material-ui/src/Slider/SliderStyled.js diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 6c3da15a8e0dec..1a35d801530ada 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -1,199 +1,7 @@ import * as React from 'react'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; +import { SliderTypeMap } from './SliderBase'; -export interface Mark { - value: number; - label?: React.ReactNode; -} - -export interface ValueLabelProps extends React.HTMLAttributes { - children: React.ReactElement; - index: number; - open: boolean; - value: number; -} - -export interface SliderTypeMap

{ - props: P & { - /** - * The label of the slider. - */ - 'aria-label'?: string; - /** - * The id of the element containing a label for the slider. - */ - 'aria-labelledby'?: string; - /** - * A string value that provides a user-friendly name for the current value of the slider. - */ - 'aria-valuetext'?: string; - /** - * Override or extend the styles applied to the component. - */ - classes?: { - /** Styles applied to the root element. */ - root?: string; - /** Styles applied to the root element if `color="primary"`. */ - colorPrimary?: string; - /** Styles applied to the root element if `color="secondary"`. */ - colorSecondary?: string; - /** Styles applied to the root element if `marks` is provided with at least one label. */ - marked?: string; - /** Pseudo-class applied to the root element if `orientation="vertical"`. */ - vertical?: string; - /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ - disabled?: string; - /** Styles applied to the rail element. */ - rail?: string; - /** Styles applied to the track element. */ - track?: string; - /** Styles applied to the track element if `track={false}`. */ - trackFalse?: string; - /** Styles applied to the track element if `track="inverted"`. */ - trackInverted?: string; - /** Styles applied to the thumb element. */ - thumb?: string; - /** Styles applied to the thumb element if `color="primary"`. */ - thumbColorPrimary?: string; - /** Styles applied to the thumb element if `color="secondary"`. */ - thumbColorSecondary?: string; - /** Pseudo-class applied to the thumb element if it's active. */ - active?: string; - /** Pseudo-class applied to the thumb element if keyboard focused. */ - focusVisible?: string; - /** Styles applied to the thumb label element. */ - valueLabel?: string; - /** Styles applied to the mark element. */ - mark?: string; - /** Styles applied to the mark element if active (depending on the value). */ - markActive?: string; - /** Styles applied to the mark label element. */ - markLabel?: string; - /** Styles applied to the mark label element if active (depending on the value). */ - markLabelActive?: string; - }; - /** - * The color of the component. It supports those theme colors that make sense for this component. - */ - color?: 'primary' | 'secondary'; - /** - * The default element value. Use when the component is not controlled. - */ - defaultValue?: number | number[]; - /** - * If `true`, the slider will be disabled. - */ - disabled?: boolean; - /** - * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. - * - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaLabel?: (index: number) => string; - /** - * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. - * - * @param {number} value The thumb label's value to format. - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaValueText?: (value: number, index: number) => string; - /** - * Indicates whether the theme context has rtl direction. It is set automatically. - */ - isRtl?: boolean; - /** - * Marks indicate predetermined values to which the user can move the slider. - * If `true` the marks will be spaced according the value of the `step` prop. - * If an array, it should contain objects with `value` and an optional `label` keys. - */ - marks?: boolean | Mark[]; - /** - * The maximum allowed value of the slider. - * Should not be equal to min. - */ - max?: number; - /** - * The minimum allowed value of the slider. - * Should not be equal to max. - */ - min?: number; - /** - * Name attribute of the hidden `input` element. - */ - name?: string; - /** - * Callback function that is fired when the slider's value changed. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChange?: (event: React.SyntheticEvent, value: number | number[]) => void; - /** - * Callback function that is fired when the `mouseup` is triggered. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChangeCommitted?: (event: React.SyntheticEvent, value: number | number[]) => void; - /** - * The slider orientation. - */ - orientation?: 'horizontal' | 'vertical'; - /** - * A transformation function, to change the scale of the slider. - */ - scale?: (value: number) => number; - /** - * The granularity with which the slider can step through values. (A "discrete" slider.) - * The `min` prop serves as the origin for the valid values. - * We recommend (max - min) to be evenly divisible by the step. - * - * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. - */ - step?: number | null; - /** - * The component used to display the value label. - */ - ThumbComponent?: React.ElementType>; - /** - * The track presentation: - * - * - `normal` the track will render a bar representing the slider value. - * - `inverted` the track will render a bar representing the remaining slider value. - * - `false` the track will render without a bar. - */ - track?: 'normal' | false | 'inverted'; - /** - * The value of the slider. - * For ranged sliders, provide an array with two values. - */ - value?: number | number[]; - /** - * The value label component. - */ - ValueLabelComponent?: React.ElementType; - /** - * Controls when the value label is displayed: - * - * - `auto` the value label will display when the thumb is hovered or focused. - * - `on` will display persistently. - * - `off` will never display. - */ - valueLabelDisplay?: 'on' | 'auto' | 'off'; - /** - * The format function the value label's value. - * - * When a function is provided, it should have the following signature: - * - * - {number} value The value label's value to format - * - {number} index The value label's index to format - */ - valueLabelFormat?: string | ((value: number, index: number) => React.ReactNode); - }; - defaultComponent: D; -} /** * * Demos: @@ -213,4 +21,30 @@ export type SliderProps< P = {} > = OverrideProps, D>; +export const SliderRoot: React.FC; +export const SliderMark: React.FC< + SliderProps & { + markActive?: boolean; + } +>; +export const SliderMarkLabel: React.FC< + SliderProps & { + markLabelActive?: boolean; + } +>; +export const SliderRail: React.FC; +export const SliderTrack: React.FC; +export const SliderThumb: React.FC< + SliderProps & { + active?: boolean; + focusVisible?: boolean; + } +>; +export const SliderValueLabel: React.FC< + SliderProps & { + index?: number; + open?: boolean; + } +>; + export default Slider; diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index d44b8b674cd3f2..9723719ea8ccdd 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,922 +1,312 @@ import * as React from 'react'; -import PropTypes from 'prop-types'; -import { cx } from 'emotion'; -import { chainPropTypes } from '@material-ui/utils'; -import useIsFocusVisible from '../utils/useIsFocusVisible'; -import useEnhancedEffect from '../utils/useEnhancedEffect'; -import ownerDocument from '../utils/ownerDocument'; -import useEventCallback from '../utils/useEventCallback'; -import useForkRef from '../utils/useForkRef'; -import capitalize from '../utils/capitalize'; -import useControlled from '../utils/useControlled'; -import ValueLabelComponent from './ValueLabel'; - -function asc(a, b) { - return a - b; -} - -function clamp(value, min, max) { - return Math.min(Math.max(min, value), max); -} - -function findClosest(values, currentValue) { - const { index: closestIndex } = values.reduce((acc, value, index) => { - const distance = Math.abs(currentValue - value); - - if (acc === null || distance < acc.distance || distance === acc.distance) { - return { - distance, - index, - }; - } - - return acc; - }, null); - return closestIndex; -} - -function trackFinger(event, touchId) { - if (touchId.current !== undefined && event.changedTouches) { - for (let i = 0; i < event.changedTouches.length; i += 1) { - const touch = event.changedTouches[i]; - if (touch.identifier === touchId.current) { - return { - x: touch.clientX, - y: touch.clientY, - }; - } - } - - return false; - } - +import { css, cx } from 'emotion'; +import styled from '@emotion/styled'; +import isPropValid from '@emotion/is-prop-valid'; +import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; +import useTheme from '../styles/useTheme'; +import { fade, lighten, darken } from '../styles/colorManipulator'; +import SliderBase from './SliderBase'; +import ValueLabel from './ValueLabel'; +import defaultTheme from '../styles/defaultTheme'; + +const shouldForwardProp = (prop) => + isPropValid(prop) && + prop !== 'color' && + prop !== 'scale' && + prop !== 'orientation' && + prop !== 'disabled'; + +export const SliderRoot = styled('span', { shouldForwardProp })((props) => { return { - x: event.clientX, - y: event.clientY, + height: 2, + width: '100%', + boxSizing: 'content-box', + padding: '13px 0', + display: 'inline-block', + position: 'relative', + cursor: 'pointer', + touchAction: 'none', + color: props.theme.palette.primary.main, + WebkitTapHighlightColor: 'transparent', + ...(props.color === 'secondary' && { + color: props.theme.palette.secondary.main, + }), + ...(props.disabled && { + pointerEvents: 'none', + cursor: 'default', + color: props.theme.palette.grey[400], + }), + ...(props.orientation === 'vertical' && { + width: 2, + height: '100%', + padding: '0 13px', + }), + // The primary input mechanism of the device includes a pointing device of limited accuracy. + '@media (pointer: coarse)': { + // Reach 42px touch target, about ~8mm on screen. + padding: '20px 0', + ...(props.orientation === 'vertical' && { + padding: '0 20px', + }), + }, + '@media print': { + colorAdjust: 'exact', + }, + ...(props.marked && { + marginBottom: 20, + ...(props.orientation === 'vertical' && { + marginBottom: 'auto', + marginRight: 20, + }), + }), }; -} - -function valueToPercent(value, min, max) { - return ((value - min) * 100) / (max - min); -} - -function percentToValue(percent, min, max) { - return (max - min) * percent + min; -} - -function getDecimalPrecision(num) { - // This handles the case when num is very small (0.00000001), js will turn this into 1e-8. - // When num is bigger than 1 or less than -1 it won't get converted to this notation so it's fine. - if (Math.abs(num) < 1) { - const parts = num.toExponential().split('e-'); - const matissaDecimalPart = parts[0].split('.')[1]; - return (matissaDecimalPart ? matissaDecimalPart.length : 0) + parseInt(parts[1], 10); - } - - const decimalPart = num.toString().split('.')[1]; - return decimalPart ? decimalPart.length : 0; -} - -function roundValueToStep(value, step, min) { - const nearest = Math.round((value - min) / step) * step + min; - return Number(nearest.toFixed(getDecimalPrecision(step))); -} - -function setValueIndex({ values, source, newValue, index }) { - // Performance shortcut - if (source[index] === newValue) { - return source; - } - - const output = values.slice(); - output[index] = newValue; - return output; -} - -function focusThumb({ sliderRef, activeIndex, setActive }) { - const doc = ownerDocument(sliderRef.current); - if ( - !sliderRef.current.contains(doc.activeElement) || - Number(doc.activeElement.getAttribute('data-index')) !== activeIndex - ) { - sliderRef.current.querySelector(`[role="slider"][data-index="${activeIndex}"]`).focus(); - } - - if (setActive) { - setActive(activeIndex); - } -} +}); -const axisProps = { - horizontal: { - offset: (percent) => ({ left: `${percent}%` }), - leap: (percent) => ({ width: `${percent}%` }), +export const SliderRail = styled('span', { shouldForwardProp })((props) => ({ + display: 'block', + position: 'absolute', + width: '100%', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + opacity: 0.38, + ...(props.orientation === 'vertical' && { + height: '100%', + width: 2, + }), + ...(props.track === 'inverted' && { + opacity: 1, + }), +})); + +export const SliderTrack = styled('span', { shouldForwardProp })((props) => ({ + display: 'block', + position: 'absolute', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + ...(props.orientation === 'vertical' && { + width: 2, + }), + ...(props.track === false && { + display: 'none', + }), + ...(props.track === 'inverted' && { + backgroundColor: + // Same logic as the LinearProgress track color + props.theme.palette.type === 'light' + ? lighten(props.theme.palette.primary.main, 0.62) + : darken(props.theme.palette.primary.main, 0.5), + }), +})); + +export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ + position: 'absolute', + width: 12, + height: 12, + marginLeft: -6, + marginTop: -5, + boxSizing: 'border-box', + borderRadius: '50%', + outline: 0, + backgroundColor: 'currentColor', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: props.theme.transitions.create(['box-shadow'], { + duration: props.theme.transitions.duration.shortest, + }), + '::after': { + position: 'absolute', + content: '""', + borderRadius: '50%', + // reach 42px hit target (2 * 15 + thumb diameter) + left: -15, + top: -15, + right: -15, + bottom: -15, }, - 'horizontal-reverse': { - offset: (percent) => ({ right: `${percent}%` }), - leap: (percent) => ({ width: `${percent}%` }), + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, }, - vertical: { - offset: (percent) => ({ bottom: `${percent}%` }), - leap: (percent) => ({ height: `${percent}%` }), + ...(props.focusVisible && { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, + }), + '&.MuiSlider--active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, }, -}; - -const Identity = (x) => x; - -// TODO: remove support for Safari < 13. -// https://caniuse.com/#search=touch-action -// -// Safari, on iOS, supports touch action since v13. -// Over 80% of the iOS phones are compatible -// in August 2020. -let cachedSupportsTouchActionNone; -function doesSupportTouchActionNone() { - if (cachedSupportsTouchActionNone === undefined) { - const element = document.createElement('div'); - element.style.touchAction = 'none'; - document.body.appendChild(element); - cachedSupportsTouchActionNone = window.getComputedStyle(element).touchAction === 'none'; - element.parentElement.removeChild(element); - } - return cachedSupportsTouchActionNone; -} - -const getUtilityClass = (name) => { - return `MuiSlider-${name}`; -}; + ...(props.disabled && { + width: 8, + height: 8, + marginLeft: -4, + marginTop: -3, + ':hover': { + boxShadow: 'none', + }, + }), + ...(props.orientation === 'vertical' && { + marginLeft: -5, + marginBottom: -6, + }), + ...((props.orientation === 'vertical' || props.disabled) && { + marginLeft: -3, + marginBottom: -4, + }), + ...(props.color === 'secondary' && { + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + ...(props.focusVisible && { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }), + '&.MuiSlider--active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + }), +})); -const useSliderClasses = (props) => { - const { color, disabled, marked, orientation, track, classes } = props; +export const SliderValueLabel = styled(ValueLabel)({ + // IE 11 centering bug, to remove from the customization demos once no longer supported + left: 'calc(-50% - 4px)', +}); - const overridesClasses = { - root: cx( - getUtilityClass('root'), - classes.root, - getUtilityClass(`color${capitalize(color)}`), - classes[`color${capitalize(color)}`], - { - [getUtilityClass('disabled')]: disabled, - [classes.disabled]: disabled, - [getUtilityClass('marked')]: marked, - [classes.marked]: marked, - [getUtilityClass('vertical')]: orientation === 'vertical', - [classes.vertical]: orientation === 'vertical', - [getUtilityClass('trackInverted')]: track === 'inverted', - [classes.trackInverted]: track === 'inverted', - [getUtilityClass('trackFalse')]: track === false, - [classes.trackFalse]: track === false, - }, - ), - rail: cx(getUtilityClass('rail'), classes.rail), - track: cx(getUtilityClass('track'), classes.track), - mark: cx(getUtilityClass('mark'), classes.mark), - markLabel: cx(getUtilityClass('markLabel'), classes.markLabel), - valueLabel: cx(getUtilityClass('valueLabel'), classes.valueLabel), - thumb: cx( - getUtilityClass('thumb'), - classes.thumb, - getUtilityClass(`thumbColor${capitalize(color)}`), - classes[`thumbColor${capitalize(color)}`], - { - [getUtilityClass('disabled')]: disabled, - [classes.disabled]: disabled, - }, - ), - }; +export const SliderMark = styled('span', { shouldForwardProp })((props) => ({ + position: 'absolute', + width: 2, + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + ...(props.markActive && { + backgroundColor: props.theme.palette.background.paper, + opacity: 0.8, + }), +})); + +export const SliderMarkLabel = styled('span', { shouldForwardProp })((props) => ({ + ...props.theme.typography.body2, + color: props.theme.palette.text.secondary, + position: 'absolute', + top: 26, + transform: 'translateX(-50%)', + whiteSpace: 'nowrap', + ...(props.orientation === 'vertical' && { + top: 'auto', + left: 26, + transform: 'translateY(50%)', + }), + '@media (pointer: coarse)': { + top: 40, + ...(props.orientation === 'vertical' && { + left: 31, + }), + }, + ...(props.markLabelActive && { + color: props.theme.palette.text.primary, + }), +})); - return overridesClasses; -}; +const useThemeProps = (inputProps, ref, name) => { + const props = Object.assign({}, inputProps); + const { innerRef } = props; -const Slider = React.forwardRef(function Slider(props, ref) { - const { - 'aria-label': ariaLabel, - 'aria-labelledby': ariaLabelledby, - 'aria-valuetext': ariaValuetext, - classes = {}, - className, - color = 'primary', - component: Component = 'span', - defaultValue, - disabled = false, - getAriaLabel, - getAriaValueText, - marks: marksProp = false, - max = 100, - min = 0, - name, - onChange, - onChangeCommitted, - onMouseDown, - orientation = 'horizontal', - scale = Identity, - step = 1, - track = 'normal', - value: valueProp, - valueLabelDisplay = 'off', - valueLabelFormat = Identity, - isRtl = false, - components = {}, - componentsProps = {}, - ...other - } = props; + const contextTheme = useTheme() || defaultTheme; - const touchId = React.useRef(); - // We can't use the :active browser pseudo-classes. - // - The active state isn't triggered when clicking on the rail. - // - The active state isn't transfered when inversing a range slider. - const [active, setActive] = React.useState(-1); - const [open, setOpen] = React.useState(-1); + const more = getThemeProps({ theme: contextTheme, name, props }); - const [valueDerived, setValueState] = useControlled({ - controlled: valueProp, - default: defaultValue, - name: 'Slider', - }); + const theme = more.theme || contextTheme; + const isRtl = theme.direction === 'rtl'; - const range = Array.isArray(valueDerived); - let values = range ? valueDerived.slice().sort(asc) : [valueDerived]; - values = values.map((value) => clamp(value, min, max)); - const marks = - marksProp === true && step !== null - ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ - value: min + step * index, - })) - : marksProp || []; + return { + ref: innerRef || ref, + theme, + isRtl, + ...more, + }; +}; - const { - isFocusVisibleRef, - onBlur: handleBlurVisible, - onFocus: handleFocusVisible, - ref: focusVisibleRef, - } = useIsFocusVisible(); - const [focusVisible, setFocusVisible] = React.useState(-1); +const useThemeClasses = (name) => { + const theme = useTheme() || defaultTheme; - const sliderRef = React.useRef(); - const handleFocusRef = useForkRef(focusVisibleRef, sliderRef); - const handleRef = useForkRef(ref, handleFocusRef); + let styleOverrides = {}; + let variants = []; - const handleFocus = useEventCallback((event) => { - const index = Number(event.currentTarget.getAttribute('data-index')); - handleFocusVisible(event); - if (isFocusVisibleRef.current === true) { - setFocusVisible(index); - } - setOpen(index); - }); - const handleBlur = useEventCallback((event) => { - handleBlurVisible(event); - if (isFocusVisibleRef.current === false) { - setFocusVisible(-1); - } - setOpen(-1); - }); - const handleMouseOver = useEventCallback((event) => { - const index = Number(event.currentTarget.getAttribute('data-index')); - setOpen(index); - }); - const handleMouseLeave = useEventCallback(() => { - setOpen(-1); - }); - - useEnhancedEffect(() => { - if (disabled && sliderRef.current.contains(document.activeElement)) { - // This is necessary because Firefox and Safari will keep focus - // on a disabled element: - // https://codesandbox.io/s/mui-pr-22247-forked-h151h?file=/src/App.js - document.activeElement.blur(); - } - }, [disabled]); - - if (disabled && active !== -1) { - setActive(-1); - } - if (disabled && focusVisible !== -1) { - setFocusVisible(-1); + if ( + theme && + theme.components && + theme.components[name] && + theme.components[name].styleOverrides + ) { + styleOverrides = theme.components[name].styleOverrides; } - const handleKeyDown = useEventCallback((event) => { - const index = Number(event.currentTarget.getAttribute('data-index')); - const value = values[index]; - const tenPercents = (max - min) / 10; - const marksValues = marks.map((mark) => mark.value); - const marksIndex = marksValues.indexOf(value); - let newValue; - const increaseKey = isRtl ? 'ArrowLeft' : 'ArrowRight'; - const decreaseKey = isRtl ? 'ArrowRight' : 'ArrowLeft'; - - switch (event.key) { - case 'Home': - newValue = min; - break; - case 'End': - newValue = max; - break; - case 'PageUp': - if (step) { - newValue = value + tenPercents; - } - break; - case 'PageDown': - if (step) { - newValue = value - tenPercents; - } - break; - case increaseKey: - case 'ArrowUp': - if (step) { - newValue = value + step; - } else { - newValue = marksValues[marksIndex + 1] || marksValues[marksValues.length - 1]; - } - break; - case decreaseKey: - case 'ArrowDown': - if (step) { - newValue = value - step; - } else { - newValue = marksValues[marksIndex - 1] || marksValues[0]; - } - break; - default: - return; - } - - // Prevent scroll of the page - event.preventDefault(); - - if (step) { - newValue = roundValueToStep(newValue, step, min); - } - - newValue = clamp(newValue, min, max); - - if (range) { - const previousValue = newValue; - newValue = setValueIndex({ - values, - source: valueDerived, - newValue, - index, - }).sort(asc); - focusThumb({ sliderRef, activeIndex: newValue.indexOf(previousValue) }); - } - - setValueState(newValue); - setFocusVisible(index); - - if (onChange) { - onChange(event, newValue); - } - if (onChangeCommitted) { - onChangeCommitted(event, newValue); - } - }); - - const previousIndex = React.useRef(); - let axis = orientation; - if (isRtl && orientation === 'horizontal') { - axis += '-reverse'; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + variants = theme.components[name].variants; } - const getFingerNewValue = ({ finger, move = false, values: values2, source }) => { - const { current: slider } = sliderRef; - const { width, height, bottom, left } = slider.getBoundingClientRect(); - let percent; - - if (axis.indexOf('vertical') === 0) { - percent = (bottom - finger.y) / height; - } else { - percent = (finger.x - left) / width; - } - - if (axis.indexOf('-reverse') !== -1) { - percent = 1 - percent; - } - - let newValue; - newValue = percentToValue(percent, min, max); - if (step) { - newValue = roundValueToStep(newValue, step, min); - } else { - const marksValues = marks.map((mark) => mark.value); - const closestIndex = findClosest(marksValues, newValue); - newValue = marksValues[closestIndex]; - } - - newValue = clamp(newValue, min, max); - let activeIndex = 0; - - if (range) { - if (!move) { - activeIndex = findClosest(values2, newValue); - } else { - activeIndex = previousIndex.current; - } - - const previousValue = newValue; - newValue = setValueIndex({ - values: values2, - source, - newValue, - index: activeIndex, - }).sort(asc); - activeIndex = newValue.indexOf(previousValue); - previousIndex.current = activeIndex; - } - - return { newValue, activeIndex }; - }; - - const handleTouchMove = useEventCallback((nativeEvent) => { - const finger = trackFinger(nativeEvent, touchId); - - if (!finger) { - return; - } - - const { newValue, activeIndex } = getFingerNewValue({ - finger, - move: true, - values, - source: valueDerived, - }); - - focusThumb({ sliderRef, activeIndex, setActive }); - setValueState(newValue); + const classes = {}; - if (onChange) { - onChange(nativeEvent, newValue); - } - }); - - const handleTouchEnd = useEventCallback((nativeEvent) => { - const finger = trackFinger(nativeEvent, touchId); - - if (!finger) { - return; - } - - const { newValue } = getFingerNewValue({ finger, values, source: valueDerived }); - - setActive(-1); - if (nativeEvent.type === 'touchend') { - setOpen(-1); - } - - if (onChangeCommitted) { - onChangeCommitted(nativeEvent, newValue); - } - - touchId.current = undefined; - - const doc = ownerDocument(sliderRef.current); - doc.removeEventListener('mousemove', handleTouchMove); - doc.removeEventListener('mouseup', handleTouchEnd); - doc.removeEventListener('touchmove', handleTouchMove); - doc.removeEventListener('touchend', handleTouchEnd); + Object.keys(styleOverrides).forEach((key) => { + classes[key] = css(styleOverrides[key]); }); - const handleTouchStart = useEventCallback((event) => { - // If touch-action: none; is not supported we need to prevent the scroll manually. - if (!doesSupportTouchActionNone()) { - event.preventDefault(); - } - - const touch = event.changedTouches[0]; - if (touch != null) { - // A number that uniquely identifies the current finger in the touch session. - touchId.current = touch.identifier; - } - const finger = trackFinger(event, touchId); - const { newValue, activeIndex } = getFingerNewValue({ finger, values, source: valueDerived }); - focusThumb({ sliderRef, activeIndex, setActive }); - - setValueState(newValue); - - if (onChange) { - onChange(event, newValue); - } - - const doc = ownerDocument(sliderRef.current); - doc.addEventListener('touchmove', handleTouchMove); - doc.addEventListener('touchend', handleTouchEnd); - }); - - React.useEffect(() => { - const { current: slider } = sliderRef; - slider.addEventListener('touchstart', handleTouchStart, { - passive: doesSupportTouchActionNone(), - }); - - const doc = ownerDocument(slider); - - return () => { - slider.removeEventListener('touchstart', handleTouchStart, { - passive: doesSupportTouchActionNone(), - }); - - doc.removeEventListener('mousemove', handleTouchMove); - doc.removeEventListener('mouseup', handleTouchEnd); - doc.removeEventListener('touchmove', handleTouchMove); - doc.removeEventListener('touchend', handleTouchEnd); - }; - }, [handleTouchEnd, handleTouchMove, handleTouchStart]); - - React.useEffect(() => { - if (disabled) { - const doc = ownerDocument(sliderRef.current); - doc.removeEventListener('mousemove', handleTouchMove); - doc.removeEventListener('mouseup', handleTouchEnd); - doc.removeEventListener('touchmove', handleTouchMove); - doc.removeEventListener('touchend', handleTouchEnd); - } - }, [disabled, handleTouchEnd, handleTouchMove]); - - const handleMouseDown = useEventCallback((event) => { - if (onMouseDown) { - onMouseDown(event); - } - - event.preventDefault(); - const finger = trackFinger(event, touchId); - const { newValue, activeIndex } = getFingerNewValue({ finger, values, source: valueDerived }); - focusThumb({ sliderRef, activeIndex, setActive }); - - setValueState(newValue); - - if (onChange) { - onChange(event, newValue); + variants.forEach((definition) => { + const key = propsToClassKey(definition.props); + if (classes[key]) { + classes[key] = cx(classes[key], css(definition.style)); + } else { + classes[key] = css(definition.style); } - - const doc = ownerDocument(sliderRef.current); - doc.addEventListener('mousemove', handleTouchMove); - doc.addEventListener('mouseup', handleTouchEnd); }); - const trackOffset = valueToPercent(range ? values[0] : min, min, max); - const trackLeap = valueToPercent(values[values.length - 1], min, max) - trackOffset; - const trackStyle = { - ...axisProps[axis].offset(trackOffset), - ...axisProps[axis].leap(trackLeap), - }; - - const Root = components.root || 'span'; - const rootProps = componentsProps.root || {}; - - const Rail = components.rail || 'span'; - const railProps = componentsProps.rail || {}; - - const Track = components.track || 'span'; - const trackProps = componentsProps.track || {}; - - const Thumb = components.thumb || 'span'; - const thumbProps = componentsProps.thumb || {}; - - const ValueLabel = components.valueLabel || ValueLabelComponent; - const valueLabelProps = componentsProps.valueLabel || {}; - - const Mark = components.mark || 'span'; - const markProps = componentsProps.mark || {}; - - const MarkLabel = components.markLabel || 'span'; - const markLabelProps = componentsProps.markLabel || {}; + return classes; +}; - // all props with defaults - // consider extracting to hook an reusing the lint rule for the varints - const stateAndProps = { - ...props, - classes: undefined, // we do not want to override other components classes - color, - disabled, - max, - min, - orientation, - scale, - step, - track, - valueLabelDisplay, - valueLabelFormat, - isRtl, +const getComponentProps = (components, componentsProps, name) => { + return { + as: components[name], + ...(componentsProps[name] || {}), }; +}; - const overridesClasses = useSliderClasses({ - ...stateAndProps, - classes, - marked: marks.length > 0 && marks.some((mark) => mark.label), - }); +const Slider = React.forwardRef(function Slider(inputProps, inputRef) { + const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); + const classes = useThemeClasses('MuiSlider'); + const themeVariantsClasses = useThemeVariants({ ...props, classes }, 'MuiSlider'); + const { components = {}, componentsProps = {}, ref, ...other } = props; return ( - 0 && marks.some((mark) => mark.label)} - {...stateAndProps} - {...rootProps} - className={cx(overridesClasses.root, rootProps.className, className)} - > - - - - {marks.map((mark, index) => { - const percent = valueToPercent(mark.value, min, max); - const style = axisProps[axis].offset(percent); - - let markActive; - if (track === false) { - markActive = values.indexOf(mark.value) !== -1; - } else { - 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])); - } - - return ( - - - {mark.label != null ? ( - - {mark.label} - - ) : null} - - ); - })} - {values.map((value, index) => { - const percent = valueToPercent(value, min, max); - const style = axisProps[axis].offset(percent); - - return ( - - - - ); - })} - + ); }); -Slider.propTypes = { - // ----------------------------- Warning -------------------------------- - // | These PropTypes are generated from the TypeScript type definitions | - // | To update them edit the d.ts file and run "yarn proptypes" | - // ---------------------------------------------------------------------- - /** - * The label of the slider. - */ - 'aria-label': chainPropTypes(PropTypes.string, (props) => { - const range = Array.isArray(props.value || props.defaultValue); - - if (range && props['aria-label'] != null) { - return new Error( - 'Material-UI: You need to use the `getAriaLabel` prop instead of `aria-label` when using a range slider.', - ); - } - - return null; - }), - /** - * The id of the element containing a label for the slider. - */ - 'aria-labelledby': PropTypes.string, - /** - * A string value that provides a user-friendly name for the current value of the slider. - */ - 'aria-valuetext': chainPropTypes(PropTypes.string, (props) => { - const range = Array.isArray(props.value || props.defaultValue); - - if (range && props['aria-valuetext'] != null) { - return new Error( - 'Material-UI: You need to use the `getAriaValueText` prop instead of `aria-valuetext` when using a range slider.', - ); - } - - return null; - }), - /** - * @ignore - */ - children: PropTypes.node, - /** - * Override or extend the styles applied to the component. - */ - classes: PropTypes.object, - /** - * @ignore - */ - className: PropTypes.string, - /** - * The color of the component. It supports those theme colors that make sense for this component. - */ - color: PropTypes.oneOf(['primary', 'secondary']), - /** - * The component used for the root node. - * Either a string to use a HTML element or a component. - */ - component: PropTypes.elementType, - /** - * The default element value. Use when the component is not controlled. - */ - defaultValue: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), - /** - * If `true`, the slider will be disabled. - */ - disabled: PropTypes.bool, - /** - * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. - * - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaLabel: PropTypes.func, - /** - * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. - * - * @param {number} value The thumb label's value to format. - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaValueText: PropTypes.func, - /** - * Indicates whether the theme context has rtl direction. It is set automatically. - */ - isRtl: PropTypes.bool, - /** - * Marks indicate predetermined values to which the user can move the slider. - * If `true` the marks will be spaced according the value of the `step` prop. - * If an array, it should contain objects with `value` and an optional `label` keys. - */ - marks: PropTypes.oneOfType([ - PropTypes.arrayOf( - PropTypes.shape({ - label: PropTypes.node, - value: PropTypes.number.isRequired, - }), - ), - PropTypes.bool, - ]), - /** - * The maximum allowed value of the slider. - * Should not be equal to min. - */ - max: PropTypes.number, - /** - * The minimum allowed value of the slider. - * Should not be equal to max. - */ - min: PropTypes.number, - /** - * Name attribute of the hidden `input` element. - */ - name: PropTypes.string, - /** - * Callback function that is fired when the slider's value changed. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChange: PropTypes.func, - /** - * Callback function that is fired when the `mouseup` is triggered. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChangeCommitted: PropTypes.func, - /** - * @ignore - */ - onMouseDown: PropTypes.func, - /** - * The slider orientation. - */ - orientation: PropTypes.oneOf(['horizontal', 'vertical']), - /** - * A transformation function, to change the scale of the slider. - */ - scale: PropTypes.func, - /** - * The granularity with which the slider can step through values. (A "discrete" slider.) - * The `min` prop serves as the origin for the valid values. - * We recommend (max - min) to be evenly divisible by the step. - * - * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. - */ - step: PropTypes.number, - /** - * The component used to display the value label. - */ - ThumbComponent: PropTypes.elementType, - /** - * The track presentation: - * - * - `normal` the track will render a bar representing the slider value. - * - `inverted` the track will render a bar representing the remaining slider value. - * - `false` the track will render without a bar. - */ - track: PropTypes.oneOf(['inverted', 'normal', false]), - /** - * The value of the slider. - * For ranged sliders, provide an array with two values. - */ - value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), - /** - * The value label component. - */ - ValueLabelComponent: PropTypes.elementType, - /** - * Controls when the value label is displayed: - * - * - `auto` the value label will display when the thumb is hovered or focused. - * - `on` will display persistently. - * - `off` will never display. - */ - valueLabelDisplay: PropTypes.oneOf(['auto', 'off', 'on']), - /** - * The format function the value label's value. - * - * When a function is provided, it should have the following signature: - * - * - {number} value The value label's value to format - * - {number} index The value label's index to format - */ - valueLabelFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), -}; - export default Slider; diff --git a/packages/material-ui/src/Slider/SliderBase.d.ts b/packages/material-ui/src/Slider/SliderBase.d.ts new file mode 100644 index 00000000000000..5a6426360144cd --- /dev/null +++ b/packages/material-ui/src/Slider/SliderBase.d.ts @@ -0,0 +1,199 @@ +import { OverridableComponent } from '../OverridableComponent'; + +export interface Mark { + value: number; + label?: React.ReactNode; +} + +export interface ValueLabelProps extends React.HTMLAttributes { + children: React.ReactElement; + index: number; + open: boolean; + value: number; +} + +export interface SliderTypeMap

{ + props: P & { + /** + * The label of the slider. + */ + 'aria-label'?: string; + /** + * The id of the element containing a label for the slider. + */ + 'aria-labelledby'?: string; + /** + * A string value that provides a user-friendly name for the current value of the slider. + */ + 'aria-valuetext'?: string; + /** + * Override or extend the styles applied to the component. + */ + classes?: { + /** Styles applied to the root element. */ + root?: string; + /** Styles applied to the root element if `color="primary"`. */ + colorPrimary?: string; + /** Styles applied to the root element if `color="secondary"`. */ + colorSecondary?: string; + /** Styles applied to the root element if `marks` is provided with at least one label. */ + marked?: string; + /** Pseudo-class applied to the root element if `orientation="vertical"`. */ + vertical?: string; + /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ + disabled?: string; + /** Styles applied to the rail element. */ + rail?: string; + /** Styles applied to the track element. */ + track?: string; + /** Styles applied to the track element if `track={false}`. */ + trackFalse?: string; + /** Styles applied to the track element if `track="inverted"`. */ + trackInverted?: string; + /** Styles applied to the thumb element. */ + thumb?: string; + /** Styles applied to the thumb element if `color="primary"`. */ + thumbColorPrimary?: string; + /** Styles applied to the thumb element if `color="secondary"`. */ + thumbColorSecondary?: string; + /** Pseudo-class applied to the thumb element if it's active. */ + active?: string; + /** Pseudo-class applied to the thumb element if keyboard focused. */ + focusVisible?: string; + /** Styles applied to the thumb label element. */ + valueLabel?: string; + /** Styles applied to the mark element. */ + mark?: string; + /** Styles applied to the mark element if active (depending on the value). */ + markActive?: string; + /** Styles applied to the mark label element. */ + markLabel?: string; + /** Styles applied to the mark label element if active (depending on the value). */ + markLabelActive?: string; + }; + /** + * The color of the component. It supports those theme colors that make sense for this component. + */ + color?: 'primary' | 'secondary'; + /** + * The default element value. Use when the component is not controlled. + */ + defaultValue?: number | number[]; + /** + * If `true`, the slider will be disabled. + */ + disabled?: boolean; + /** + * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. + * + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaLabel?: (index: number) => string; + /** + * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. + * + * @param {number} value The thumb label's value to format. + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaValueText?: (value: number, index: number) => string; + /** + * Indicates whether the theme context has rtl direction. It is set automatically. + */ + isRtl?: boolean; + /** + * Marks indicate predetermined values to which the user can move the slider. + * If `true` the marks will be spaced according the value of the `step` prop. + * If an array, it should contain objects with `value` and an optional `label` keys. + */ + marks?: boolean | Mark[]; + /** + * The maximum allowed value of the slider. + * Should not be equal to min. + */ + max?: number; + /** + * The minimum allowed value of the slider. + * Should not be equal to max. + */ + min?: number; + /** + * Name attribute of the hidden `input` element. + */ + name?: string; + /** + * Callback function that is fired when the slider's value changed. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChange?: (event: React.SyntheticEvent, value: number | number[]) => void; + /** + * Callback function that is fired when the `mouseup` is triggered. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChangeCommitted?: (event: React.SyntheticEvent, value: number | number[]) => void; + /** + * The slider orientation. + */ + orientation?: 'horizontal' | 'vertical'; + /** + * A transformation function, to change the scale of the slider. + */ + scale?: (value: number) => number; + /** + * The granularity with which the slider can step through values. (A "discrete" slider.) + * The `min` prop serves as the origin for the valid values. + * We recommend (max - min) to be evenly divisible by the step. + * + * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. + */ + step?: number | null; + /** + * The component used to display the value label. + */ + ThumbComponent?: React.ElementType>; + /** + * The track presentation: + * + * - `normal` the track will render a bar representing the slider value. + * - `inverted` the track will render a bar representing the remaining slider value. + * - `false` the track will render without a bar. + */ + track?: 'normal' | false | 'inverted'; + /** + * The value of the slider. + * For ranged sliders, provide an array with two values. + */ + value?: number | number[]; + /** + * The value label component. + */ + ValueLabelComponent?: React.ElementType; + /** + * Controls when the value label is displayed: + * + * - `auto` the value label will display when the thumb is hovered or focused. + * - `on` will display persistently. + * - `off` will never display. + */ + valueLabelDisplay?: 'on' | 'auto' | 'off'; + /** + * The format function the value label's value. + * + * When a function is provided, it should have the following signature: + * + * - {number} value The value label's value to format + * - {number} index The value label's index to format + */ + valueLabelFormat?: string | ((value: number, index: number) => React.ReactNode); + }; + defaultComponent: D; +} + +declare const SliderBase: OverridableComponent; + +export default SliderBase; diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js new file mode 100644 index 00000000000000..d44b8b674cd3f2 --- /dev/null +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -0,0 +1,922 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { cx } from 'emotion'; +import { chainPropTypes } from '@material-ui/utils'; +import useIsFocusVisible from '../utils/useIsFocusVisible'; +import useEnhancedEffect from '../utils/useEnhancedEffect'; +import ownerDocument from '../utils/ownerDocument'; +import useEventCallback from '../utils/useEventCallback'; +import useForkRef from '../utils/useForkRef'; +import capitalize from '../utils/capitalize'; +import useControlled from '../utils/useControlled'; +import ValueLabelComponent from './ValueLabel'; + +function asc(a, b) { + return a - b; +} + +function clamp(value, min, max) { + return Math.min(Math.max(min, value), max); +} + +function findClosest(values, currentValue) { + const { index: closestIndex } = values.reduce((acc, value, index) => { + const distance = Math.abs(currentValue - value); + + if (acc === null || distance < acc.distance || distance === acc.distance) { + return { + distance, + index, + }; + } + + return acc; + }, null); + return closestIndex; +} + +function trackFinger(event, touchId) { + if (touchId.current !== undefined && event.changedTouches) { + for (let i = 0; i < event.changedTouches.length; i += 1) { + const touch = event.changedTouches[i]; + if (touch.identifier === touchId.current) { + return { + x: touch.clientX, + y: touch.clientY, + }; + } + } + + return false; + } + + return { + x: event.clientX, + y: event.clientY, + }; +} + +function valueToPercent(value, min, max) { + return ((value - min) * 100) / (max - min); +} + +function percentToValue(percent, min, max) { + return (max - min) * percent + min; +} + +function getDecimalPrecision(num) { + // This handles the case when num is very small (0.00000001), js will turn this into 1e-8. + // When num is bigger than 1 or less than -1 it won't get converted to this notation so it's fine. + if (Math.abs(num) < 1) { + const parts = num.toExponential().split('e-'); + const matissaDecimalPart = parts[0].split('.')[1]; + return (matissaDecimalPart ? matissaDecimalPart.length : 0) + parseInt(parts[1], 10); + } + + const decimalPart = num.toString().split('.')[1]; + return decimalPart ? decimalPart.length : 0; +} + +function roundValueToStep(value, step, min) { + const nearest = Math.round((value - min) / step) * step + min; + return Number(nearest.toFixed(getDecimalPrecision(step))); +} + +function setValueIndex({ values, source, newValue, index }) { + // Performance shortcut + if (source[index] === newValue) { + return source; + } + + const output = values.slice(); + output[index] = newValue; + return output; +} + +function focusThumb({ sliderRef, activeIndex, setActive }) { + const doc = ownerDocument(sliderRef.current); + if ( + !sliderRef.current.contains(doc.activeElement) || + Number(doc.activeElement.getAttribute('data-index')) !== activeIndex + ) { + sliderRef.current.querySelector(`[role="slider"][data-index="${activeIndex}"]`).focus(); + } + + if (setActive) { + setActive(activeIndex); + } +} + +const axisProps = { + horizontal: { + offset: (percent) => ({ left: `${percent}%` }), + leap: (percent) => ({ width: `${percent}%` }), + }, + 'horizontal-reverse': { + offset: (percent) => ({ right: `${percent}%` }), + leap: (percent) => ({ width: `${percent}%` }), + }, + vertical: { + offset: (percent) => ({ bottom: `${percent}%` }), + leap: (percent) => ({ height: `${percent}%` }), + }, +}; + +const Identity = (x) => x; + +// TODO: remove support for Safari < 13. +// https://caniuse.com/#search=touch-action +// +// Safari, on iOS, supports touch action since v13. +// Over 80% of the iOS phones are compatible +// in August 2020. +let cachedSupportsTouchActionNone; +function doesSupportTouchActionNone() { + if (cachedSupportsTouchActionNone === undefined) { + const element = document.createElement('div'); + element.style.touchAction = 'none'; + document.body.appendChild(element); + cachedSupportsTouchActionNone = window.getComputedStyle(element).touchAction === 'none'; + element.parentElement.removeChild(element); + } + return cachedSupportsTouchActionNone; +} + +const getUtilityClass = (name) => { + return `MuiSlider-${name}`; +}; + +const useSliderClasses = (props) => { + const { color, disabled, marked, orientation, track, classes } = props; + + const overridesClasses = { + root: cx( + getUtilityClass('root'), + classes.root, + getUtilityClass(`color${capitalize(color)}`), + classes[`color${capitalize(color)}`], + { + [getUtilityClass('disabled')]: disabled, + [classes.disabled]: disabled, + [getUtilityClass('marked')]: marked, + [classes.marked]: marked, + [getUtilityClass('vertical')]: orientation === 'vertical', + [classes.vertical]: orientation === 'vertical', + [getUtilityClass('trackInverted')]: track === 'inverted', + [classes.trackInverted]: track === 'inverted', + [getUtilityClass('trackFalse')]: track === false, + [classes.trackFalse]: track === false, + }, + ), + rail: cx(getUtilityClass('rail'), classes.rail), + track: cx(getUtilityClass('track'), classes.track), + mark: cx(getUtilityClass('mark'), classes.mark), + markLabel: cx(getUtilityClass('markLabel'), classes.markLabel), + valueLabel: cx(getUtilityClass('valueLabel'), classes.valueLabel), + thumb: cx( + getUtilityClass('thumb'), + classes.thumb, + getUtilityClass(`thumbColor${capitalize(color)}`), + classes[`thumbColor${capitalize(color)}`], + { + [getUtilityClass('disabled')]: disabled, + [classes.disabled]: disabled, + }, + ), + }; + + return overridesClasses; +}; + +const Slider = React.forwardRef(function Slider(props, ref) { + const { + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledby, + 'aria-valuetext': ariaValuetext, + classes = {}, + className, + color = 'primary', + component: Component = 'span', + defaultValue, + disabled = false, + getAriaLabel, + getAriaValueText, + marks: marksProp = false, + max = 100, + min = 0, + name, + onChange, + onChangeCommitted, + onMouseDown, + orientation = 'horizontal', + scale = Identity, + step = 1, + track = 'normal', + value: valueProp, + valueLabelDisplay = 'off', + valueLabelFormat = Identity, + isRtl = false, + components = {}, + componentsProps = {}, + ...other + } = props; + + const touchId = React.useRef(); + // We can't use the :active browser pseudo-classes. + // - The active state isn't triggered when clicking on the rail. + // - The active state isn't transfered when inversing a range slider. + const [active, setActive] = React.useState(-1); + const [open, setOpen] = React.useState(-1); + + const [valueDerived, setValueState] = useControlled({ + controlled: valueProp, + default: defaultValue, + name: 'Slider', + }); + + const range = Array.isArray(valueDerived); + let values = range ? valueDerived.slice().sort(asc) : [valueDerived]; + values = values.map((value) => clamp(value, min, max)); + const marks = + marksProp === true && step !== null + ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ + value: min + step * index, + })) + : marksProp || []; + + const { + isFocusVisibleRef, + onBlur: handleBlurVisible, + onFocus: handleFocusVisible, + ref: focusVisibleRef, + } = useIsFocusVisible(); + const [focusVisible, setFocusVisible] = React.useState(-1); + + const sliderRef = React.useRef(); + const handleFocusRef = useForkRef(focusVisibleRef, sliderRef); + const handleRef = useForkRef(ref, handleFocusRef); + + const handleFocus = useEventCallback((event) => { + const index = Number(event.currentTarget.getAttribute('data-index')); + handleFocusVisible(event); + if (isFocusVisibleRef.current === true) { + setFocusVisible(index); + } + setOpen(index); + }); + const handleBlur = useEventCallback((event) => { + handleBlurVisible(event); + if (isFocusVisibleRef.current === false) { + setFocusVisible(-1); + } + setOpen(-1); + }); + const handleMouseOver = useEventCallback((event) => { + const index = Number(event.currentTarget.getAttribute('data-index')); + setOpen(index); + }); + const handleMouseLeave = useEventCallback(() => { + setOpen(-1); + }); + + useEnhancedEffect(() => { + if (disabled && sliderRef.current.contains(document.activeElement)) { + // This is necessary because Firefox and Safari will keep focus + // on a disabled element: + // https://codesandbox.io/s/mui-pr-22247-forked-h151h?file=/src/App.js + document.activeElement.blur(); + } + }, [disabled]); + + if (disabled && active !== -1) { + setActive(-1); + } + if (disabled && focusVisible !== -1) { + setFocusVisible(-1); + } + + const handleKeyDown = useEventCallback((event) => { + const index = Number(event.currentTarget.getAttribute('data-index')); + const value = values[index]; + const tenPercents = (max - min) / 10; + const marksValues = marks.map((mark) => mark.value); + const marksIndex = marksValues.indexOf(value); + let newValue; + const increaseKey = isRtl ? 'ArrowLeft' : 'ArrowRight'; + const decreaseKey = isRtl ? 'ArrowRight' : 'ArrowLeft'; + + switch (event.key) { + case 'Home': + newValue = min; + break; + case 'End': + newValue = max; + break; + case 'PageUp': + if (step) { + newValue = value + tenPercents; + } + break; + case 'PageDown': + if (step) { + newValue = value - tenPercents; + } + break; + case increaseKey: + case 'ArrowUp': + if (step) { + newValue = value + step; + } else { + newValue = marksValues[marksIndex + 1] || marksValues[marksValues.length - 1]; + } + break; + case decreaseKey: + case 'ArrowDown': + if (step) { + newValue = value - step; + } else { + newValue = marksValues[marksIndex - 1] || marksValues[0]; + } + break; + default: + return; + } + + // Prevent scroll of the page + event.preventDefault(); + + if (step) { + newValue = roundValueToStep(newValue, step, min); + } + + newValue = clamp(newValue, min, max); + + if (range) { + const previousValue = newValue; + newValue = setValueIndex({ + values, + source: valueDerived, + newValue, + index, + }).sort(asc); + focusThumb({ sliderRef, activeIndex: newValue.indexOf(previousValue) }); + } + + setValueState(newValue); + setFocusVisible(index); + + if (onChange) { + onChange(event, newValue); + } + if (onChangeCommitted) { + onChangeCommitted(event, newValue); + } + }); + + const previousIndex = React.useRef(); + let axis = orientation; + if (isRtl && orientation === 'horizontal') { + axis += '-reverse'; + } + + const getFingerNewValue = ({ finger, move = false, values: values2, source }) => { + const { current: slider } = sliderRef; + const { width, height, bottom, left } = slider.getBoundingClientRect(); + let percent; + + if (axis.indexOf('vertical') === 0) { + percent = (bottom - finger.y) / height; + } else { + percent = (finger.x - left) / width; + } + + if (axis.indexOf('-reverse') !== -1) { + percent = 1 - percent; + } + + let newValue; + newValue = percentToValue(percent, min, max); + if (step) { + newValue = roundValueToStep(newValue, step, min); + } else { + const marksValues = marks.map((mark) => mark.value); + const closestIndex = findClosest(marksValues, newValue); + newValue = marksValues[closestIndex]; + } + + newValue = clamp(newValue, min, max); + let activeIndex = 0; + + if (range) { + if (!move) { + activeIndex = findClosest(values2, newValue); + } else { + activeIndex = previousIndex.current; + } + + const previousValue = newValue; + newValue = setValueIndex({ + values: values2, + source, + newValue, + index: activeIndex, + }).sort(asc); + activeIndex = newValue.indexOf(previousValue); + previousIndex.current = activeIndex; + } + + return { newValue, activeIndex }; + }; + + const handleTouchMove = useEventCallback((nativeEvent) => { + const finger = trackFinger(nativeEvent, touchId); + + if (!finger) { + return; + } + + const { newValue, activeIndex } = getFingerNewValue({ + finger, + move: true, + values, + source: valueDerived, + }); + + focusThumb({ sliderRef, activeIndex, setActive }); + setValueState(newValue); + + if (onChange) { + onChange(nativeEvent, newValue); + } + }); + + const handleTouchEnd = useEventCallback((nativeEvent) => { + const finger = trackFinger(nativeEvent, touchId); + + if (!finger) { + return; + } + + const { newValue } = getFingerNewValue({ finger, values, source: valueDerived }); + + setActive(-1); + if (nativeEvent.type === 'touchend') { + setOpen(-1); + } + + if (onChangeCommitted) { + onChangeCommitted(nativeEvent, newValue); + } + + touchId.current = undefined; + + const doc = ownerDocument(sliderRef.current); + doc.removeEventListener('mousemove', handleTouchMove); + doc.removeEventListener('mouseup', handleTouchEnd); + doc.removeEventListener('touchmove', handleTouchMove); + doc.removeEventListener('touchend', handleTouchEnd); + }); + + const handleTouchStart = useEventCallback((event) => { + // If touch-action: none; is not supported we need to prevent the scroll manually. + if (!doesSupportTouchActionNone()) { + event.preventDefault(); + } + + const touch = event.changedTouches[0]; + if (touch != null) { + // A number that uniquely identifies the current finger in the touch session. + touchId.current = touch.identifier; + } + const finger = trackFinger(event, touchId); + const { newValue, activeIndex } = getFingerNewValue({ finger, values, source: valueDerived }); + focusThumb({ sliderRef, activeIndex, setActive }); + + setValueState(newValue); + + if (onChange) { + onChange(event, newValue); + } + + const doc = ownerDocument(sliderRef.current); + doc.addEventListener('touchmove', handleTouchMove); + doc.addEventListener('touchend', handleTouchEnd); + }); + + React.useEffect(() => { + const { current: slider } = sliderRef; + slider.addEventListener('touchstart', handleTouchStart, { + passive: doesSupportTouchActionNone(), + }); + + const doc = ownerDocument(slider); + + return () => { + slider.removeEventListener('touchstart', handleTouchStart, { + passive: doesSupportTouchActionNone(), + }); + + doc.removeEventListener('mousemove', handleTouchMove); + doc.removeEventListener('mouseup', handleTouchEnd); + doc.removeEventListener('touchmove', handleTouchMove); + doc.removeEventListener('touchend', handleTouchEnd); + }; + }, [handleTouchEnd, handleTouchMove, handleTouchStart]); + + React.useEffect(() => { + if (disabled) { + const doc = ownerDocument(sliderRef.current); + doc.removeEventListener('mousemove', handleTouchMove); + doc.removeEventListener('mouseup', handleTouchEnd); + doc.removeEventListener('touchmove', handleTouchMove); + doc.removeEventListener('touchend', handleTouchEnd); + } + }, [disabled, handleTouchEnd, handleTouchMove]); + + const handleMouseDown = useEventCallback((event) => { + if (onMouseDown) { + onMouseDown(event); + } + + event.preventDefault(); + const finger = trackFinger(event, touchId); + const { newValue, activeIndex } = getFingerNewValue({ finger, values, source: valueDerived }); + focusThumb({ sliderRef, activeIndex, setActive }); + + setValueState(newValue); + + if (onChange) { + onChange(event, newValue); + } + + const doc = ownerDocument(sliderRef.current); + doc.addEventListener('mousemove', handleTouchMove); + doc.addEventListener('mouseup', handleTouchEnd); + }); + + const trackOffset = valueToPercent(range ? values[0] : min, min, max); + const trackLeap = valueToPercent(values[values.length - 1], min, max) - trackOffset; + const trackStyle = { + ...axisProps[axis].offset(trackOffset), + ...axisProps[axis].leap(trackLeap), + }; + + const Root = components.root || 'span'; + const rootProps = componentsProps.root || {}; + + const Rail = components.rail || 'span'; + const railProps = componentsProps.rail || {}; + + const Track = components.track || 'span'; + const trackProps = componentsProps.track || {}; + + const Thumb = components.thumb || 'span'; + const thumbProps = componentsProps.thumb || {}; + + const ValueLabel = components.valueLabel || ValueLabelComponent; + const valueLabelProps = componentsProps.valueLabel || {}; + + const Mark = components.mark || 'span'; + const markProps = componentsProps.mark || {}; + + const MarkLabel = components.markLabel || 'span'; + const markLabelProps = componentsProps.markLabel || {}; + + // all props with defaults + // consider extracting to hook an reusing the lint rule for the varints + const stateAndProps = { + ...props, + classes: undefined, // we do not want to override other components classes + color, + disabled, + max, + min, + orientation, + scale, + step, + track, + valueLabelDisplay, + valueLabelFormat, + isRtl, + }; + + const overridesClasses = useSliderClasses({ + ...stateAndProps, + classes, + marked: marks.length > 0 && marks.some((mark) => mark.label), + }); + + return ( + 0 && marks.some((mark) => mark.label)} + {...stateAndProps} + {...rootProps} + className={cx(overridesClasses.root, rootProps.className, className)} + > + + + + {marks.map((mark, index) => { + const percent = valueToPercent(mark.value, min, max); + const style = axisProps[axis].offset(percent); + + let markActive; + if (track === false) { + markActive = values.indexOf(mark.value) !== -1; + } else { + 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])); + } + + return ( + + + {mark.label != null ? ( + + {mark.label} + + ) : null} + + ); + })} + {values.map((value, index) => { + const percent = valueToPercent(value, min, max); + const style = axisProps[axis].offset(percent); + + return ( + + + + ); + })} + + ); +}); + +Slider.propTypes = { + // ----------------------------- Warning -------------------------------- + // | These PropTypes are generated from the TypeScript type definitions | + // | To update them edit the d.ts file and run "yarn proptypes" | + // ---------------------------------------------------------------------- + /** + * The label of the slider. + */ + 'aria-label': chainPropTypes(PropTypes.string, (props) => { + const range = Array.isArray(props.value || props.defaultValue); + + if (range && props['aria-label'] != null) { + return new Error( + 'Material-UI: You need to use the `getAriaLabel` prop instead of `aria-label` when using a range slider.', + ); + } + + return null; + }), + /** + * The id of the element containing a label for the slider. + */ + 'aria-labelledby': PropTypes.string, + /** + * A string value that provides a user-friendly name for the current value of the slider. + */ + 'aria-valuetext': chainPropTypes(PropTypes.string, (props) => { + const range = Array.isArray(props.value || props.defaultValue); + + if (range && props['aria-valuetext'] != null) { + return new Error( + 'Material-UI: You need to use the `getAriaValueText` prop instead of `aria-valuetext` when using a range slider.', + ); + } + + return null; + }), + /** + * @ignore + */ + children: PropTypes.node, + /** + * Override or extend the styles applied to the component. + */ + classes: PropTypes.object, + /** + * @ignore + */ + className: PropTypes.string, + /** + * The color of the component. It supports those theme colors that make sense for this component. + */ + color: PropTypes.oneOf(['primary', 'secondary']), + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: PropTypes.elementType, + /** + * The default element value. Use when the component is not controlled. + */ + defaultValue: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), + /** + * If `true`, the slider will be disabled. + */ + disabled: PropTypes.bool, + /** + * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. + * + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaLabel: PropTypes.func, + /** + * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. + * + * @param {number} value The thumb label's value to format. + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaValueText: PropTypes.func, + /** + * Indicates whether the theme context has rtl direction. It is set automatically. + */ + isRtl: PropTypes.bool, + /** + * Marks indicate predetermined values to which the user can move the slider. + * If `true` the marks will be spaced according the value of the `step` prop. + * If an array, it should contain objects with `value` and an optional `label` keys. + */ + marks: PropTypes.oneOfType([ + PropTypes.arrayOf( + PropTypes.shape({ + label: PropTypes.node, + value: PropTypes.number.isRequired, + }), + ), + PropTypes.bool, + ]), + /** + * The maximum allowed value of the slider. + * Should not be equal to min. + */ + max: PropTypes.number, + /** + * The minimum allowed value of the slider. + * Should not be equal to max. + */ + min: PropTypes.number, + /** + * Name attribute of the hidden `input` element. + */ + name: PropTypes.string, + /** + * Callback function that is fired when the slider's value changed. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChange: PropTypes.func, + /** + * Callback function that is fired when the `mouseup` is triggered. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChangeCommitted: PropTypes.func, + /** + * @ignore + */ + onMouseDown: PropTypes.func, + /** + * The slider orientation. + */ + orientation: PropTypes.oneOf(['horizontal', 'vertical']), + /** + * A transformation function, to change the scale of the slider. + */ + scale: PropTypes.func, + /** + * The granularity with which the slider can step through values. (A "discrete" slider.) + * The `min` prop serves as the origin for the valid values. + * We recommend (max - min) to be evenly divisible by the step. + * + * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. + */ + step: PropTypes.number, + /** + * The component used to display the value label. + */ + ThumbComponent: PropTypes.elementType, + /** + * The track presentation: + * + * - `normal` the track will render a bar representing the slider value. + * - `inverted` the track will render a bar representing the remaining slider value. + * - `false` the track will render without a bar. + */ + track: PropTypes.oneOf(['inverted', 'normal', false]), + /** + * The value of the slider. + * For ranged sliders, provide an array with two values. + */ + value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), + /** + * The value label component. + */ + ValueLabelComponent: PropTypes.elementType, + /** + * Controls when the value label is displayed: + * + * - `auto` the value label will display when the thumb is hovered or focused. + * - `on` will display persistently. + * - `off` will never display. + */ + valueLabelDisplay: PropTypes.oneOf(['auto', 'off', 'on']), + /** + * The format function the value label's value. + * + * When a function is provided, it should have the following signature: + * + * - {number} value The value label's value to format + * - {number} index The value label's index to format + */ + valueLabelFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), +}; + +export default Slider; diff --git a/packages/material-ui/src/Slider/SliderStyled.js b/packages/material-ui/src/Slider/SliderStyled.js deleted file mode 100644 index f292cfec1d1ad8..00000000000000 --- a/packages/material-ui/src/Slider/SliderStyled.js +++ /dev/null @@ -1,312 +0,0 @@ -import * as React from 'react'; -import { css, cx } from 'emotion'; -import styled from '@emotion/styled'; -import isPropValid from '@emotion/is-prop-valid'; -import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; -import useTheme from '../styles/useTheme'; -import { fade, lighten, darken } from '../styles/colorManipulator'; -import SliderBase from './Slider'; -import ValueLabel from './ValueLabel'; -import defaultTheme from '../styles/defaultTheme'; - -const shouldForwardProp = (prop) => - isPropValid(prop) && - prop !== 'color' && - prop !== 'scale' && - prop !== 'orientation' && - prop !== 'disabled'; - -export const SliderRoot = styled('span', { shouldForwardProp })((props) => { - return { - height: 2, - width: '100%', - boxSizing: 'content-box', - padding: '13px 0', - display: 'inline-block', - position: 'relative', - cursor: 'pointer', - touchAction: 'none', - color: props.theme.palette.primary.main, - WebkitTapHighlightColor: 'transparent', - ...(props.color === 'secondary' && { - color: props.theme.palette.secondary.main, - }), - ...(props.disabled && { - pointerEvents: 'none', - cursor: 'default', - color: props.theme.palette.grey[400], - }), - ...(props.orientation === 'vertical' && { - width: 2, - height: '100%', - padding: '0 13px', - }), - // The primary input mechanism of the device includes a pointing device of limited accuracy. - '@media (pointer: coarse)': { - // Reach 42px touch target, about ~8mm on screen. - padding: '20px 0', - ...(props.orientation === 'vertical' && { - padding: '0 20px', - }), - }, - '@media print': { - colorAdjust: 'exact', - }, - ...(props.marked && { - marginBottom: 20, - ...(props.orientation === 'vertical' && { - marginBottom: 'auto', - marginRight: 20, - }), - }), - }; -}); - -export const SliderRail = styled('span', { shouldForwardProp })((props) => ({ - display: 'block', - position: 'absolute', - width: '100%', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - opacity: 0.38, - ...(props.orientation === 'vertical' && { - height: '100%', - width: 2, - }), - ...(props.track === 'inverted' && { - opacity: 1, - }), -})); - -export const SliderTrack = styled('span', { shouldForwardProp })((props) => ({ - display: 'block', - position: 'absolute', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - ...(props.orientation === 'vertical' && { - width: 2, - }), - ...(props.track === false && { - display: 'none', - }), - ...(props.track === 'inverted' && { - backgroundColor: - // Same logic as the LinearProgress track color - props.theme.palette.type === 'light' - ? lighten(props.theme.palette.primary.main, 0.62) - : darken(props.theme.palette.primary.main, 0.5), - }), -})); - -export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ - position: 'absolute', - width: 12, - height: 12, - marginLeft: -6, - marginTop: -5, - boxSizing: 'border-box', - borderRadius: '50%', - outline: 0, - backgroundColor: 'currentColor', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - transition: props.theme.transitions.create(['box-shadow'], { - duration: props.theme.transitions.duration.shortest, - }), - '::after': { - position: 'absolute', - content: '""', - borderRadius: '50%', - // reach 42px hit target (2 * 15 + thumb diameter) - left: -15, - top: -15, - right: -15, - bottom: -15, - }, - ':hover': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, - '@media (hover: none)': { - boxShadow: 'none', - }, - }, - ...(props.focusVisible && { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, - '@media (hover: none)': { - boxShadow: 'none', - }, - }), - '&.MuiSlider--active': { - boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, - }, - ...(props.disabled && { - width: 8, - height: 8, - marginLeft: -4, - marginTop: -3, - ':hover': { - boxShadow: 'none', - }, - }), - ...(props.orientation === 'vertical' && { - marginLeft: -5, - marginBottom: -6, - }), - ...((props.orientation === 'vertical' || props.disabled) && { - marginLeft: -3, - marginBottom: -4, - }), - ...(props.color === 'secondary' && { - ':hover': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, - }, - ...(props.focusVisible && { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, - }), - '&.MuiSlider--active': { - boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, - }, - }), -})); - -export const SliderValueLabel = styled(ValueLabel)({ - // IE 11 centering bug, to remove from the customization demos once no longer supported - left: 'calc(-50% - 4px)', -}); - -export const SliderMark = styled('span', { shouldForwardProp })((props) => ({ - position: 'absolute', - width: 2, - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - ...(props.markActive && { - backgroundColor: props.theme.palette.background.paper, - opacity: 0.8, - }), -})); - -export const SliderMarkLabel = styled('span', { shouldForwardProp })((props) => ({ - ...props.theme.typography.body2, - color: props.theme.palette.text.secondary, - position: 'absolute', - top: 26, - transform: 'translateX(-50%)', - whiteSpace: 'nowrap', - ...(props.orientation === 'vertical' && { - top: 'auto', - left: 26, - transform: 'translateY(50%)', - }), - '@media (pointer: coarse)': { - top: 40, - ...(props.orientation === 'vertical' && { - left: 31, - }), - }, - ...(props.markLabelActive && { - color: props.theme.palette.text.primary, - }), -})); - -const useThemeProps = (inputProps, ref, name) => { - const props = Object.assign({}, inputProps); - const { innerRef } = props; - - const contextTheme = useTheme() || defaultTheme; - - const more = getThemeProps({ theme: contextTheme, name, props }); - - const theme = more.theme || contextTheme; - const isRtl = theme.direction === 'rtl'; - - return { - ref: innerRef || ref, - theme, - isRtl, - ...more, - }; -}; - -const useThemeClasses = (name) => { - const theme = useTheme() || defaultTheme; - - let styleOverrides = {}; - let variants = []; - - if ( - theme && - theme.components && - theme.components[name] && - theme.components[name].styleOverrides - ) { - styleOverrides = theme.components[name].styleOverrides; - } - - if (theme && theme.components && theme.components[name] && theme.components[name].variants) { - variants = theme.components[name].variants; - } - - const classes = {}; - - Object.keys(styleOverrides).forEach((key) => { - classes[key] = css(styleOverrides[key]); - }); - - variants.forEach((definition) => { - const key = propsToClassKey(definition.props); - if (classes[key]) { - classes[key] = cx(classes[key], css(definition.style)); - } else { - classes[key] = css(definition.style); - } - }); - - return classes; -}; - -const getComponentProps = (components, componentsProps, name) => { - return { - as: components[name], - ...(componentsProps[name] || {}), - }; -}; - -const Slider = React.forwardRef(function Slider(inputProps, inputRef) { - const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); - const classes = useThemeClasses('MuiSlider'); - const themeVariantsClasses = useThemeVariants({ ...props, classes }, 'MuiSlider'); - const { components = {}, componentsProps = {}, ref, ...other } = props; - - return ( - - ); -}); - -export default Slider; diff --git a/packages/material-ui/src/Slider/index.d.ts b/packages/material-ui/src/Slider/index.d.ts index 1c804c88525ee3..e81742056288f6 100644 --- a/packages/material-ui/src/Slider/index.d.ts +++ b/packages/material-ui/src/Slider/index.d.ts @@ -1,4 +1,5 @@ -export { default } from './SliderStyled'; +export { default } from './Slider'; +export { default as SliderBase } from './SliderBase'; export { SliderRoot, SliderMark, @@ -7,5 +8,6 @@ export { SliderTrack, SliderThumb, SliderValueLabel, -} from './SliderStyled'; -export * from './SliderStyled'; +} from './Slider'; +export * from './Slider'; +export * from './SliderBase'; diff --git a/packages/material-ui/src/Slider/index.js b/packages/material-ui/src/Slider/index.js index bfd8260dccdc98..76bef8511bce76 100644 --- a/packages/material-ui/src/Slider/index.js +++ b/packages/material-ui/src/Slider/index.js @@ -1,4 +1,5 @@ -export { default } from './SliderStyled'; +export { default } from './Slider'; +export { default as SliderBase } from './SliderBase'; export { SliderRoot, SliderMark, @@ -7,4 +8,4 @@ export { SliderTrack, SliderThumb, SliderValueLabel, -} from './SliderStyled'; +} from './Slider'; From 3a80cdaa8ab80e641d63a7ae27a35e4337d98bc6 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 09:15:40 +0200 Subject: [PATCH 014/125] Update packages/material-ui/src/Slider/Slider.js Co-authored-by: Olivier Tassinari --- packages/material-ui/src/Slider/Slider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 9723719ea8ccdd..4891a4197d12f3 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -138,7 +138,7 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ boxShadow: 'none', }, }), - '&.MuiSlider--active': { + '&.Mui-active': { boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, }, ...(props.disabled && { From 27e7286a503ec208a08fa31202fe9197ef45f7a5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 09:22:39 +0200 Subject: [PATCH 015/125] components names fixed --- .../components/slider/CustomizedSlider.js | 32 +- packages/material-ui/src/Slider/Slider.d.ts | 276 ++++++++++++++++-- packages/material-ui/src/Slider/Slider.js | 14 +- .../material-ui/src/Slider/SliderBase.d.ts | 195 +------------ packages/material-ui/src/Slider/SliderBase.js | 14 +- 5 files changed, 281 insertions(+), 250 deletions(-) diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index b2336fdb5b71b0..66c47b69e0e455 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -58,12 +58,12 @@ const marks = [ ]; const iosComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)((props) => ({ height: 28, width: 28, backgroundColor: '#fff', @@ -88,7 +88,7 @@ const iosComponents = { }, }), })), - valueLabel: styled(SliderValueLabel)({ + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { @@ -96,15 +96,15 @@ const iosComponents = { color: '#000', }, }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 2, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', }), - mark: styled(SliderMark)((props) => ({ + Mark: styled(SliderMark)((props) => ({ // @ts-ignore backgroundColor: '#bfbfbf', height: 8, @@ -118,11 +118,11 @@ const iosComponents = { }; const prettoComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#52af77', height: 8, }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)((props) => ({ height: 24, width: 24, backgroundColor: '#fff', @@ -136,26 +136,26 @@ const prettoComponents = { boxShadow: 'inherit', }), })), - valueLabel: styled(SliderValueLabel)({ + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 8, borderRadius: 4, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 8, borderRadius: 4, }), }; const airbnbComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)((props) => ({ height: 27, width: 27, backgroundColor: '#fff', @@ -179,10 +179,10 @@ const airbnbComponents = { marginRight: 1, }, })), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 3, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, @@ -227,7 +227,7 @@ export default function CustomizedSlider() { Tooltip value label { + children: React.ReactElement; + index: number; + open: boolean; + value: number; +} + +export interface SliderTypeMap

{ + props: P & { + /** + * The label of the slider. + */ + 'aria-label'?: string; + /** + * The id of the element containing a label for the slider. + */ + 'aria-labelledby'?: string; + /** + * A string value that provides a user-friendly name for the current value of the slider. + */ + 'aria-valuetext'?: string; + /** + * Override or extend the styles applied to the component. + */ + classes?: { + /** Styles applied to the root element. */ + root?: string; + /** Styles applied to the root element if `color="primary"`. */ + colorPrimary?: string; + /** Styles applied to the root element if `color="secondary"`. */ + colorSecondary?: string; + /** Styles applied to the root element if `marks` is provided with at least one label. */ + marked?: string; + /** Pseudo-class applied to the root element if `orientation="vertical"`. */ + vertical?: string; + /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ + disabled?: string; + /** Styles applied to the rail element. */ + rail?: string; + /** Styles applied to the track element. */ + track?: string; + /** Styles applied to the track element if `track={false}`. */ + trackFalse?: string; + /** Styles applied to the track element if `track="inverted"`. */ + trackInverted?: string; + /** Styles applied to the thumb element. */ + thumb?: string; + /** Styles applied to the thumb element if `color="primary"`. */ + thumbColorPrimary?: string; + /** Styles applied to the thumb element if `color="secondary"`. */ + thumbColorSecondary?: string; + /** Pseudo-class applied to the thumb element if it's active. */ + active?: string; + /** Pseudo-class applied to the thumb element if keyboard focused. */ + focusVisible?: string; + /** Styles applied to the thumb label element. */ + valueLabel?: string; + /** Styles applied to the mark element. */ + mark?: string; + /** Styles applied to the mark element if active (depending on the value). */ + markActive?: string; + /** Styles applied to the mark label element. */ + markLabel?: string; + /** Styles applied to the mark label element if active (depending on the value). */ + markLabelActive?: string; + }; + /** + * The color of the component. It supports those theme colors that make sense for this component. + */ + color?: 'primary' | 'secondary'; + /** + * The components used for each slot inside the Slider. + * Either a string to use a HTML element or a component. + */ + components?: { + Root?: React.ElementType['props'], 'components' | 'componentsProps'>>; + Track?: React.ElementType; + Rail?: React.ElementType; + Thumb?: React.ElementType; + Mark?: React.ElementType; + MarkLabel?: React.ElementType; + ValueLabel?: React.ElementType; + }; + /** + * The props used for each slot inside the Slider. + */ + componentsProps?: { + root?: Omit['props'], 'components' | 'componentsProps'>; + track?: Omit['props'], 'components' | 'componentsProps'>; + rail?: Omit['props'], 'components' | 'componentsProps'>; + thumb?: Omit['props'], 'components' | 'componentsProps'> & { + active?: boolean; + focusVisible?: boolean; + }; + mark?: Omit['props'], 'components' | 'componentsProps'> & { markActive?: boolean; }; + markLabel?: Omit['props'], 'components' | 'componentsProps'> & { markLabelActive?: boolean; }; + valueLabel?: Omit['props'], 'components' | 'componentsProps'> & { + index?: number; + open?: boolean; + }; + } + /** + * The default element value. Use when the component is not controlled. + */ + defaultValue?: number | number[]; + /** + * If `true`, the slider will be disabled. + */ + disabled?: boolean; + /** + * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. + * + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaLabel?: (index: number) => string; + /** + * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. + * + * @param {number} value The thumb label's value to format. + * @param {number} index The thumb label's index to format. + * @returns {string} + */ + getAriaValueText?: (value: number, index: number) => string; + /** + * Indicates whether the theme context has rtl direction. It is set automatically. + */ + isRtl?: boolean; + /** + * Marks indicate predetermined values to which the user can move the slider. + * If `true` the marks will be spaced according the value of the `step` prop. + * If an array, it should contain objects with `value` and an optional `label` keys. + */ + marks?: boolean | Mark[]; + /** + * The maximum allowed value of the slider. + * Should not be equal to min. + */ + max?: number; + /** + * The minimum allowed value of the slider. + * Should not be equal to max. + */ + min?: number; + /** + * Name attribute of the hidden `input` element. + */ + name?: string; + /** + * Callback function that is fired when the slider's value changed. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChange?: (event: React.SyntheticEvent, value: number | number[]) => void; + /** + * Callback function that is fired when the `mouseup` is triggered. + * + * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. + * @param {number | number[]} value The new value. + */ + onChangeCommitted?: (event: React.SyntheticEvent, value: number | number[]) => void; + /** + * The slider orientation. + */ + orientation?: 'horizontal' | 'vertical'; + /** + * A transformation function, to change the scale of the slider. + */ + scale?: (value: number) => number; + /** + * The granularity with which the slider can step through values. (A "discrete" slider.) + * The `min` prop serves as the origin for the valid values. + * We recommend (max - min) to be evenly divisible by the step. + * + * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. + */ + step?: number | null; + /** + * The component used to display the value label. + */ + ThumbComponent?: React.ElementType>; + /** + * The track presentation: + * + * - `normal` the track will render a bar representing the slider value. + * - `inverted` the track will render a bar representing the remaining slider value. + * - `false` the track will render without a bar. + */ + track?: 'normal' | false | 'inverted'; + /** + * The value of the slider. + * For ranged sliders, provide an array with two values. + */ + value?: number | number[]; + /** + * The value label component. + */ + ValueLabelComponent?: React.ElementType; + /** + * Controls when the value label is displayed: + * + * - `auto` the value label will display when the thumb is hovered or focused. + * - `on` will display persistently. + * - `off` will never display. + */ + valueLabelDisplay?: 'on' | 'auto' | 'off'; + /** + * The format function the value label's value. + * + * When a function is provided, it should have the following signature: + * + * - {number} value The value label's value to format + * - {number} index The value label's index to format + */ + valueLabelFormat?: string | ((value: number, index: number) => React.ReactNode); + }; + defaultComponent: D; +} /** * @@ -21,30 +245,30 @@ export type SliderProps< P = {} > = OverrideProps, D>; -export const SliderRoot: React.FC; -export const SliderMark: React.FC< - SliderProps & { - markActive?: boolean; - } ->; -export const SliderMarkLabel: React.FC< - SliderProps & { - markLabelActive?: boolean; - } ->; -export const SliderRail: React.FC; -export const SliderTrack: React.FC; -export const SliderThumb: React.FC< - SliderProps & { - active?: boolean; - focusVisible?: boolean; - } ->; -export const SliderValueLabel: React.FC< - SliderProps & { - index?: number; - open?: boolean; - } ->; +type SliderRootProps = Omit; +type SliderMarkProps = SliderRootProps & { + markActive?: boolean; +}; +type SliderMarkLabelProps = SliderRootProps & { + markLabelActive?: boolean; +}; +type SliderRailProps = SliderRootProps; +type SliderTrackProps = SliderRootProps; +type SliderThumbProps = SliderRootProps & { + active?: boolean; + focusVisible?: boolean; +}; +type SliderValueLabel = SliderRootProps & { + index?: number; + open?: boolean; +}; + +export const SliderRoot: React.FC; +export const SliderMark: React.FC; +export const SliderMarkLabel: React.FC; +export const SliderRail: React.FC; +export const SliderTrack: React.FC; +export const SliderThumb: React.FC; +export const SliderValueLabel: React.FC; export default Slider; diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 4891a4197d12f3..6613e3ed3b0d40 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -286,13 +286,13 @@ const Slider = React.forwardRef(function Slider(inputProps, inputRef) { classes={classes} className={cx(themeVariantsClasses, props.className)} components={{ - root: SliderRoot, - rail: SliderRail, - track: SliderTrack, - thumb: SliderThumb, - valueLabel: SliderValueLabel, - mark: SliderMark, - markLabel: SliderMarkLabel, + Root: SliderRoot, + Rail: SliderRail, + Track: SliderTrack, + Thumb: SliderThumb, + ValueLabel: SliderValueLabel, + Mark: SliderMark, + MarkLabel: SliderMarkLabel, ...components, }} componentsProps={{ diff --git a/packages/material-ui/src/Slider/SliderBase.d.ts b/packages/material-ui/src/Slider/SliderBase.d.ts index 5a6426360144cd..e823b9f45ab642 100644 --- a/packages/material-ui/src/Slider/SliderBase.d.ts +++ b/packages/material-ui/src/Slider/SliderBase.d.ts @@ -1,198 +1,5 @@ import { OverridableComponent } from '../OverridableComponent'; - -export interface Mark { - value: number; - label?: React.ReactNode; -} - -export interface ValueLabelProps extends React.HTMLAttributes { - children: React.ReactElement; - index: number; - open: boolean; - value: number; -} - -export interface SliderTypeMap

{ - props: P & { - /** - * The label of the slider. - */ - 'aria-label'?: string; - /** - * The id of the element containing a label for the slider. - */ - 'aria-labelledby'?: string; - /** - * A string value that provides a user-friendly name for the current value of the slider. - */ - 'aria-valuetext'?: string; - /** - * Override or extend the styles applied to the component. - */ - classes?: { - /** Styles applied to the root element. */ - root?: string; - /** Styles applied to the root element if `color="primary"`. */ - colorPrimary?: string; - /** Styles applied to the root element if `color="secondary"`. */ - colorSecondary?: string; - /** Styles applied to the root element if `marks` is provided with at least one label. */ - marked?: string; - /** Pseudo-class applied to the root element if `orientation="vertical"`. */ - vertical?: string; - /** Pseudo-class applied to the root and thumb element if `disabled={true}`. */ - disabled?: string; - /** Styles applied to the rail element. */ - rail?: string; - /** Styles applied to the track element. */ - track?: string; - /** Styles applied to the track element if `track={false}`. */ - trackFalse?: string; - /** Styles applied to the track element if `track="inverted"`. */ - trackInverted?: string; - /** Styles applied to the thumb element. */ - thumb?: string; - /** Styles applied to the thumb element if `color="primary"`. */ - thumbColorPrimary?: string; - /** Styles applied to the thumb element if `color="secondary"`. */ - thumbColorSecondary?: string; - /** Pseudo-class applied to the thumb element if it's active. */ - active?: string; - /** Pseudo-class applied to the thumb element if keyboard focused. */ - focusVisible?: string; - /** Styles applied to the thumb label element. */ - valueLabel?: string; - /** Styles applied to the mark element. */ - mark?: string; - /** Styles applied to the mark element if active (depending on the value). */ - markActive?: string; - /** Styles applied to the mark label element. */ - markLabel?: string; - /** Styles applied to the mark label element if active (depending on the value). */ - markLabelActive?: string; - }; - /** - * The color of the component. It supports those theme colors that make sense for this component. - */ - color?: 'primary' | 'secondary'; - /** - * The default element value. Use when the component is not controlled. - */ - defaultValue?: number | number[]; - /** - * If `true`, the slider will be disabled. - */ - disabled?: boolean; - /** - * Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider. - * - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaLabel?: (index: number) => string; - /** - * Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider. - * - * @param {number} value The thumb label's value to format. - * @param {number} index The thumb label's index to format. - * @returns {string} - */ - getAriaValueText?: (value: number, index: number) => string; - /** - * Indicates whether the theme context has rtl direction. It is set automatically. - */ - isRtl?: boolean; - /** - * Marks indicate predetermined values to which the user can move the slider. - * If `true` the marks will be spaced according the value of the `step` prop. - * If an array, it should contain objects with `value` and an optional `label` keys. - */ - marks?: boolean | Mark[]; - /** - * The maximum allowed value of the slider. - * Should not be equal to min. - */ - max?: number; - /** - * The minimum allowed value of the slider. - * Should not be equal to max. - */ - min?: number; - /** - * Name attribute of the hidden `input` element. - */ - name?: string; - /** - * Callback function that is fired when the slider's value changed. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChange?: (event: React.SyntheticEvent, value: number | number[]) => void; - /** - * Callback function that is fired when the `mouseup` is triggered. - * - * @param {object} event The event source of the callback. **Warning**: This is a generic event not a change event. - * @param {number | number[]} value The new value. - */ - onChangeCommitted?: (event: React.SyntheticEvent, value: number | number[]) => void; - /** - * The slider orientation. - */ - orientation?: 'horizontal' | 'vertical'; - /** - * A transformation function, to change the scale of the slider. - */ - scale?: (value: number) => number; - /** - * The granularity with which the slider can step through values. (A "discrete" slider.) - * The `min` prop serves as the origin for the valid values. - * We recommend (max - min) to be evenly divisible by the step. - * - * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. - */ - step?: number | null; - /** - * The component used to display the value label. - */ - ThumbComponent?: React.ElementType>; - /** - * The track presentation: - * - * - `normal` the track will render a bar representing the slider value. - * - `inverted` the track will render a bar representing the remaining slider value. - * - `false` the track will render without a bar. - */ - track?: 'normal' | false | 'inverted'; - /** - * The value of the slider. - * For ranged sliders, provide an array with two values. - */ - value?: number | number[]; - /** - * The value label component. - */ - ValueLabelComponent?: React.ElementType; - /** - * Controls when the value label is displayed: - * - * - `auto` the value label will display when the thumb is hovered or focused. - * - `on` will display persistently. - * - `off` will never display. - */ - valueLabelDisplay?: 'on' | 'auto' | 'off'; - /** - * The format function the value label's value. - * - * When a function is provided, it should have the following signature: - * - * - {number} value The value label's value to format - * - {number} index The value label's index to format - */ - valueLabelFormat?: string | ((value: number, index: number) => React.ReactNode); - }; - defaultComponent: D; -} +import { SliderTypeMap } from './Slider'; declare const SliderBase: OverridableComponent; diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index d44b8b674cd3f2..0a711b5daa102e 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -561,25 +561,25 @@ const Slider = React.forwardRef(function Slider(props, ref) { ...axisProps[axis].leap(trackLeap), }; - const Root = components.root || 'span'; + const Root = components.Root || 'span'; const rootProps = componentsProps.root || {}; - const Rail = components.rail || 'span'; + const Rail = components.Rail || 'span'; const railProps = componentsProps.rail || {}; - const Track = components.track || 'span'; + const Track = components.Track || 'span'; const trackProps = componentsProps.track || {}; - const Thumb = components.thumb || 'span'; + const Thumb = components.Thumb || 'span'; const thumbProps = componentsProps.thumb || {}; - const ValueLabel = components.valueLabel || ValueLabelComponent; + const ValueLabel = components.ValueLabel || ValueLabelComponent; const valueLabelProps = componentsProps.valueLabel || {}; - const Mark = components.mark || 'span'; + const Mark = components.Mark || 'span'; const markProps = componentsProps.mark || {}; - const MarkLabel = components.markLabel || 'span'; + const MarkLabel = components.MarkLabel || 'span'; const markLabelProps = componentsProps.markLabel || {}; // all props with defaults From 2946ee188f70edfb2189f930c33ba476a71de622 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 09:55:43 +0200 Subject: [PATCH 016/125] fixed used cx in base --- .../components/slider/ContinuousSlider.js | 14 +++- packages/material-ui/src/Slider/Slider.js | 79 ++++++++++++++++--- packages/material-ui/src/Slider/SliderBase.js | 46 +++++------ 3 files changed, 100 insertions(+), 39 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index c6b78ab830f55e..ee6829d99d5b7c 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -2,10 +2,12 @@ import * as React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import Slider from '@material-ui/core/Slider'; +import Slider, { SliderRoot } from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; import { ThemeProvider } from '@material-ui/styles'; +import styled from '@emotion/styled'; + const useStyles = makeStyles({ root: { @@ -42,6 +44,10 @@ export default function ContinuousSlider() { }, }; + const Root = styled(SliderRoot)({ + backgroundColor: 'grey', + }) + return (

@@ -57,6 +63,9 @@ export default function ContinuousSlider() { value={value} onChange={handleChange} aria-labelledby="continuous-slider" + components={{ + Root, + }} /> @@ -71,6 +80,9 @@ export default function ContinuousSlider() { Vertical primary slider +
); diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 6613e3ed3b0d40..fd16b0de00be52 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -5,6 +5,7 @@ import isPropValid from '@emotion/is-prop-valid'; import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; +import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; import ValueLabel from './ValueLabel'; import defaultTheme from '../styles/defaultTheme'; @@ -267,24 +268,82 @@ const useThemeClasses = (name) => { return classes; }; -const getComponentProps = (components, componentsProps, name) => { +const getComponentProps = (components, componentsProps, themeOverridesClassesPerComponent, name) => { + const slotProps = componentsProps[name] || {}; return { as: components[name], - ...(componentsProps[name] || {}), + ...slotProps, + ...(name !== 'root' && { + className: cx(themeOverridesClassesPerComponent, slotProps.className), + }) }; }; +const useSliderClasses = (props) => { + const { + color = 'primary', + disabled = false, + marks: marksProp = false, + max = 100, + min = 0, + orientation = 'horizontal', + step = 1, + track = 'normal', + classes, + } = props; + + + const marks = + marksProp === true && step !== null + ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ + value: min + step * index, + })) + : marksProp || []; + + + const marked = marks.length > 0 && marks.some((mark) => mark.label); + + const overridesClasses = { + root: cx( + classes.root, + classes[`color${capitalize(color)}`], + { + [classes.disabled]: disabled, + [classes.marked]: marked, + [classes.vertical]: orientation === 'vertical', + [classes.trackInverted]: track === 'inverted', + [classes.trackFalse]: track === false, + }, + ), + rail: classes.rail, + track: classes.track, + mark: classes.mark, + markLabel: classes.markLabel, + valueLabel: classes.valueLabel, + thumb: cx( + classes.thumb, + classes[`thumbColor${capitalize(color)}`], + { + [classes.disabled]: disabled, + }, + ), + }; + + return overridesClasses; +}; + const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); const classes = useThemeClasses('MuiSlider'); const themeVariantsClasses = useThemeVariants({ ...props, classes }, 'MuiSlider'); + const themeOverridesClassesPerComponent = useSliderClasses({ ...props, classes }); const { components = {}, componentsProps = {}, ref, ...other } = props; return ( diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index 0a711b5daa102e..592a580d4df959 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -1,6 +1,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { cx } from 'emotion'; +import clsx from 'clsx'; import { chainPropTypes } from '@material-ui/utils'; import useIsFocusVisible from '../utils/useIsFocusVisible'; import useEnhancedEffect from '../utils/useEnhancedEffect'; @@ -149,43 +149,33 @@ const getUtilityClass = (name) => { const useSliderClasses = (props) => { const { color, disabled, marked, orientation, track, classes } = props; - const overridesClasses = { - root: cx( + const utilityClasses = { + root: clsx( getUtilityClass('root'), - classes.root, getUtilityClass(`color${capitalize(color)}`), - classes[`color${capitalize(color)}`], { [getUtilityClass('disabled')]: disabled, - [classes.disabled]: disabled, [getUtilityClass('marked')]: marked, - [classes.marked]: marked, [getUtilityClass('vertical')]: orientation === 'vertical', - [classes.vertical]: orientation === 'vertical', [getUtilityClass('trackInverted')]: track === 'inverted', - [classes.trackInverted]: track === 'inverted', [getUtilityClass('trackFalse')]: track === false, - [classes.trackFalse]: track === false, }, ), - rail: cx(getUtilityClass('rail'), classes.rail), - track: cx(getUtilityClass('track'), classes.track), - mark: cx(getUtilityClass('mark'), classes.mark), - markLabel: cx(getUtilityClass('markLabel'), classes.markLabel), - valueLabel: cx(getUtilityClass('valueLabel'), classes.valueLabel), - thumb: cx( + rail: getUtilityClass('rail'), + track: getUtilityClass('track'), + mark: getUtilityClass('mark'), + markLabel: getUtilityClass('markLabel'), + valueLabel: getUtilityClass('valueLabel'), + thumb: clsx( getUtilityClass('thumb'), - classes.thumb, getUtilityClass(`thumbColor${capitalize(color)}`), - classes[`thumbColor${capitalize(color)}`], { [getUtilityClass('disabled')]: disabled, - [classes.disabled]: disabled, }, ), }; - return overridesClasses; + return utilityClasses; }; const Slider = React.forwardRef(function Slider(props, ref) { @@ -600,7 +590,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { isRtl, }; - const overridesClasses = useSliderClasses({ + const utilityClasses = useSliderClasses({ ...stateAndProps, classes, marked: marks.length > 0 && marks.some((mark) => mark.label), @@ -613,17 +603,17 @@ const Slider = React.forwardRef(function Slider(props, ref) { marked={marks.length > 0 && marks.some((mark) => mark.label)} {...stateAndProps} {...rootProps} - className={cx(overridesClasses.root, rootProps.className, className)} + className={clsx(utilityClasses.root, rootProps.className, className)} > @@ -653,7 +643,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { data-index={index} {...stateAndProps} {...markProps} - className={cx(overridesClasses.mark, markProps.className, { + className={clsx(utilityClasses.mark, markProps.className, { [getUtilityClass('markActive')]: markActive, })} markActive={markActive} @@ -665,7 +655,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { style={style} {...stateAndProps} {...markLabelProps} - className={cx(overridesClasses.markLabel, markLabelProps.className, { + className={clsx(utilityClasses.markLabel, markLabelProps.className, { [getUtilityClass('markLabelActive')]: markActive, })} markLabelActive={markActive} @@ -695,12 +685,12 @@ const Slider = React.forwardRef(function Slider(props, ref) { disabled={disabled} {...stateAndProps} {...valueLabelProps} - className={cx(overridesClasses.valueLabel, valueLabelProps.className)} + className={clsx(utilityClasses.valueLabel, valueLabelProps.className)} > Date: Thu, 3 Sep 2020 10:07:45 +0200 Subject: [PATCH 017/125] export * --- packages/material-ui/src/Slider/index.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/material-ui/src/Slider/index.js b/packages/material-ui/src/Slider/index.js index 76bef8511bce76..f7405315520e87 100644 --- a/packages/material-ui/src/Slider/index.js +++ b/packages/material-ui/src/Slider/index.js @@ -1,11 +1,3 @@ export { default } from './Slider'; export { default as SliderBase } from './SliderBase'; -export { - SliderRoot, - SliderMark, - SliderMarkLabel, - SliderRail, - SliderTrack, - SliderThumb, - SliderValueLabel, -} from './Slider'; +export * from './Slider'; From b05a8e7aaf48fe2e78abed2f186221c5a8f293ee Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 10:10:38 +0200 Subject: [PATCH 018/125] reverted some changes --- .../pages/components/slider/ContinuousSlider.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index ee6829d99d5b7c..c6b78ab830f55e 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -2,12 +2,10 @@ import * as React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import Slider, { SliderRoot } from '@material-ui/core/Slider'; +import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; import { ThemeProvider } from '@material-ui/styles'; -import styled from '@emotion/styled'; - const useStyles = makeStyles({ root: { @@ -44,10 +42,6 @@ export default function ContinuousSlider() { }, }; - const Root = styled(SliderRoot)({ - backgroundColor: 'grey', - }) - return (
@@ -63,9 +57,6 @@ export default function ContinuousSlider() { value={value} onChange={handleChange} aria-labelledby="continuous-slider" - components={{ - Root, - }} /> @@ -80,9 +71,6 @@ export default function ContinuousSlider() { Vertical primary slider -
); From a21e19911d995e113946c759e00aa683498c787e Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 10:21:45 +0200 Subject: [PATCH 019/125] fixed disabled and active class selectors --- packages/material-ui/src/Slider/Slider.js | 16 +++++++++------- packages/material-ui/src/Slider/SliderBase.js | 8 ++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index fd16b0de00be52..f1442ff1f4c092 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -32,11 +32,11 @@ export const SliderRoot = styled('span', { shouldForwardProp })((props) => { ...(props.color === 'secondary' && { color: props.theme.palette.secondary.main, }), - ...(props.disabled && { + '&.Mui-disabled': { pointerEvents: 'none', cursor: 'default', color: props.theme.palette.grey[400], - }), + }, ...(props.orientation === 'vertical' && { width: 2, height: '100%', @@ -142,7 +142,7 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ '&.Mui-active': { boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, }, - ...(props.disabled && { + '&.Mui-disabled': { width: 8, height: 8, marginLeft: -4, @@ -150,14 +150,16 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ ':hover': { boxShadow: 'none', }, - }), + }, ...(props.orientation === 'vertical' && { marginLeft: -5, marginBottom: -6, }), - ...((props.orientation === 'vertical' || props.disabled) && { - marginLeft: -3, - marginBottom: -4, + ...(props.orientation === 'vertical' && { + '&.Mui-disabled': { + marginLeft: -3, + marginBottom: -4, + } }), ...(props.color === 'secondary' && { ':hover': { diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index 592a580d4df959..dab92dd8b99f1c 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -147,14 +147,14 @@ const getUtilityClass = (name) => { }; const useSliderClasses = (props) => { - const { color, disabled, marked, orientation, track, classes } = props; + const { color, disabled, marked, orientation, track } = props; const utilityClasses = { root: clsx( getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { - [getUtilityClass('disabled')]: disabled, + ['Mui-disabled']: disabled, [getUtilityClass('marked')]: marked, [getUtilityClass('vertical')]: orientation === 'vertical', [getUtilityClass('trackInverted')]: track === 'inverted', @@ -170,7 +170,7 @@ const useSliderClasses = (props) => { getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { - [getUtilityClass('disabled')]: disabled, + ['Mui-disabled']: disabled, }, ), }; @@ -691,7 +691,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...stateAndProps} {...thumbProps} className={clsx(utilityClasses.thumb, thumbProps.className, { - [getUtilityClass('active')]: active === index, + ['Mui-active']: active === index, [getUtilityClass('focusVisible')]: focusVisible === index, })} active={active === index} From ff8af15f0632c6aa3ac4f238d619c56f5c6fa037 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 3 Sep 2020 12:42:35 +0200 Subject: [PATCH 020/125] Update packages/material-ui/src/Slider/Slider.d.ts Co-authored-by: Umidbek Karimov --- packages/material-ui/src/Slider/Slider.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 7b3e13cde4da4d..86ea628c97eaef 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -245,7 +245,7 @@ export type SliderProps< P = {} > = OverrideProps, D>; -type SliderRootProps = Omit; +type SliderRootProps = Omit; type SliderMarkProps = SliderRootProps & { markActive?: boolean; }; From fa0b76f2cb3bceb32b5ec6d2d524cc093d21e341 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 3 Sep 2020 16:42:04 +0200 Subject: [PATCH 021/125] try to style the unstyled component --- .../components/slider/CustomizedSlider.js | 32 +++--- .../pages/components/slider/UnstyledSlider.js | 62 +++++++++++ .../components/slider/UnstyledSlider.tsx | 62 +++++++++++ docs/src/pages/components/slider/slider.md | 4 + packages/material-ui/src/Slider/Slider.d.ts | 14 ++- packages/material-ui/src/Slider/Slider.js | 100 ++++++++++++------ packages/material-ui/src/Slider/SliderBase.js | 28 ++--- 7 files changed, 229 insertions(+), 73 deletions(-) create mode 100644 docs/src/pages/components/slider/UnstyledSlider.js create mode 100644 docs/src/pages/components/slider/UnstyledSlider.tsx diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 66c47b69e0e455..b2336fdb5b71b0 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -58,12 +58,12 @@ const marks = [ ]; const iosComponents = { - Root: styled(SliderRoot)({ + root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', }), - Thumb: styled(SliderThumb)((props) => ({ + thumb: styled(SliderThumb)((props) => ({ height: 28, width: 28, backgroundColor: '#fff', @@ -88,7 +88,7 @@ const iosComponents = { }, }), })), - ValueLabel: styled(SliderValueLabel)({ + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { @@ -96,15 +96,15 @@ const iosComponents = { color: '#000', }, }), - Track: styled(SliderTrack)({ + track: styled(SliderTrack)({ height: 2, }), - Rail: styled(SliderRail)({ + rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', }), - Mark: styled(SliderMark)((props) => ({ + mark: styled(SliderMark)((props) => ({ // @ts-ignore backgroundColor: '#bfbfbf', height: 8, @@ -118,11 +118,11 @@ const iosComponents = { }; const prettoComponents = { - Root: styled(SliderRoot)({ + root: styled(SliderRoot)({ color: '#52af77', height: 8, }), - Thumb: styled(SliderThumb)((props) => ({ + thumb: styled(SliderThumb)((props) => ({ height: 24, width: 24, backgroundColor: '#fff', @@ -136,26 +136,26 @@ const prettoComponents = { boxShadow: 'inherit', }), })), - ValueLabel: styled(SliderValueLabel)({ + valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', }), - Track: styled(SliderTrack)({ + track: styled(SliderTrack)({ height: 8, borderRadius: 4, }), - Rail: styled(SliderRail)({ + rail: styled(SliderRail)({ height: 8, borderRadius: 4, }), }; const airbnbComponents = { - Root: styled(SliderRoot)({ + root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', }), - Thumb: styled(SliderThumb)((props) => ({ + thumb: styled(SliderThumb)((props) => ({ height: 27, width: 27, backgroundColor: '#fff', @@ -179,10 +179,10 @@ const airbnbComponents = { marginRight: 1, }, })), - Track: styled(SliderTrack)({ + track: styled(SliderTrack)({ height: 3, }), - Rail: styled(SliderRail)({ + rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, @@ -227,7 +227,7 @@ export default function CustomizedSlider() { Tooltip value label ; +} diff --git a/docs/src/pages/components/slider/UnstyledSlider.tsx b/docs/src/pages/components/slider/UnstyledSlider.tsx new file mode 100644 index 00000000000000..eb478301cbb82d --- /dev/null +++ b/docs/src/pages/components/slider/UnstyledSlider.tsx @@ -0,0 +1,62 @@ +import * as React from 'react'; +import styled from '@emotion/styled'; +import { SliderBase } from '@material-ui/core/Slider'; + +const StyledSlider = styled(SliderBase)` + height: 2px; + width: 100%; + padding: 13px 0; + display: inline-block; + position: relative; + cursor: pointer; + touch-action: none; + -webkit-tap-highlight-color: transparent; + + & .MuiSlider-rail { + display: block; + position: absolute; + width: 100%; + height: 2px; + border-radius: 1px; + background-color: currentColor; + opacity: 0.38; + } + + & .MuiSlider-track { + display: block; + position: absolute; + height: 2px; + border-radius: 1px; + background-color: currentColor; + } + + & .MuiSlider-thumb { + position: absolute; + width: 12px; + height: 12px; + margin-left: -6px; + margin-top: -5px; + box-sizing: border-box; + border-radius: 50%; + outline: 0; + background-color: currentColor; + display: flex; + align-items: center; + justify-content: center; + transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + + &::after { + position: absolute; + content: ''; + border-radius: 50%; + left: -15px; + top: -15px; + right: -15px; + bottom: -15px; + } + } +`; + +export default function UnstyledSlider() { + return ; +} diff --git a/docs/src/pages/components/slider/slider.md b/docs/src/pages/components/slider/slider.md index 5676fd903787bd..2a8d78f72500ef 100644 --- a/docs/src/pages/components/slider/slider.md +++ b/docs/src/pages/components/slider/slider.md @@ -100,6 +100,10 @@ For instance, in the following demo, the value _x_ represents the power of _10^x {{"demo": "pages/components/slider/NonLinearSlider.js"}} +## Unstyled slider + +{{"demo": "pages/components/slider/UnstyledSlider.js"}} + ## Accessibility (WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#slider) diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 86ea628c97eaef..558b38cd181076 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -81,7 +81,9 @@ export interface SliderTypeMap

{ * Either a string to use a HTML element or a component. */ components?: { - Root?: React.ElementType['props'], 'components' | 'componentsProps'>>; + Root?: React.ElementType< + Omit['props'], 'components' | 'componentsProps'> + >; Track?: React.ElementType; Rail?: React.ElementType; Thumb?: React.ElementType; @@ -100,13 +102,17 @@ export interface SliderTypeMap

{ active?: boolean; focusVisible?: boolean; }; - mark?: Omit['props'], 'components' | 'componentsProps'> & { markActive?: boolean; }; - markLabel?: Omit['props'], 'components' | 'componentsProps'> & { markLabelActive?: boolean; }; + mark?: Omit['props'], 'components' | 'componentsProps'> & { + markActive?: boolean; + }; + markLabel?: Omit['props'], 'components' | 'componentsProps'> & { + markLabelActive?: boolean; + }; valueLabel?: Omit['props'], 'components' | 'componentsProps'> & { index?: number; open?: boolean; }; - } + }; /** * The default element value. Use when the component is not controlled. */ diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index f1442ff1f4c092..c78a29ba047321 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -159,7 +159,7 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ '&.Mui-disabled': { marginLeft: -3, marginBottom: -4, - } + }, }), ...(props.color === 'secondary' && { ':hover': { @@ -270,14 +270,19 @@ const useThemeClasses = (name) => { return classes; }; -const getComponentProps = (components, componentsProps, themeOverridesClassesPerComponent, name) => { +const getComponentProps = ( + components, + componentsProps, + themeOverridesClassesPerComponent, + name, +) => { const slotProps = componentsProps[name] || {}; return { as: components[name], ...slotProps, ...(name !== 'root' && { className: cx(themeOverridesClassesPerComponent, slotProps.className), - }) + }), }; }; @@ -294,41 +299,31 @@ const useSliderClasses = (props) => { classes, } = props; - const marks = - marksProp === true && step !== null - ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ - value: min + step * index, - })) - : marksProp || []; - + marksProp === true && step !== null + ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ + value: min + step * index, + })) + : marksProp || []; const marked = marks.length > 0 && marks.some((mark) => mark.label); const overridesClasses = { - root: cx( - classes.root, - classes[`color${capitalize(color)}`], - { - [classes.disabled]: disabled, - [classes.marked]: marked, - [classes.vertical]: orientation === 'vertical', - [classes.trackInverted]: track === 'inverted', - [classes.trackFalse]: track === false, - }, - ), + root: cx(classes.root, classes[`color${capitalize(color)}`], { + [classes.disabled]: disabled, + [classes.marked]: marked, + [classes.vertical]: orientation === 'vertical', + [classes.trackInverted]: track === 'inverted', + [classes.trackFalse]: track === false, + }), rail: classes.rail, track: classes.track, mark: classes.mark, markLabel: classes.markLabel, valueLabel: classes.valueLabel, - thumb: cx( - classes.thumb, - classes[`thumbColor${capitalize(color)}`], - { - [classes.disabled]: disabled, - }, - ), + thumb: cx(classes.thumb, classes[`thumbColor${capitalize(color)}`], { + [classes.disabled]: disabled, + }), }; return overridesClasses; @@ -357,13 +352,48 @@ const Slider = React.forwardRef(function Slider(inputProps, inputRef) { ...components, }} componentsProps={{ - root: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'root'), - rail: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'rail'), - track: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'track'), - thumb: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'thumb'), - valueLabel: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'valueLabel'), - mark: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'mark'), - markLabel: getComponentProps(components, componentsProps, themeOverridesClassesPerComponent, 'markLabel'), + root: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'root', + ), + rail: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'rail', + ), + track: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'track', + ), + thumb: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'thumb', + ), + valueLabel: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'valueLabel', + ), + mark: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'mark', + ), + markLabel: getComponentProps( + components, + componentsProps, + themeOverridesClassesPerComponent, + 'markLabel', + ), }} ref={ref} /> diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index dab92dd8b99f1c..5eb0fd7606164b 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -150,29 +150,21 @@ const useSliderClasses = (props) => { const { color, disabled, marked, orientation, track } = props; const utilityClasses = { - root: clsx( - getUtilityClass('root'), - getUtilityClass(`color${capitalize(color)}`), - { - ['Mui-disabled']: disabled, - [getUtilityClass('marked')]: marked, - [getUtilityClass('vertical')]: orientation === 'vertical', - [getUtilityClass('trackInverted')]: track === 'inverted', - [getUtilityClass('trackFalse')]: track === false, - }, - ), + root: clsx(getUtilityClass('root'), getUtilityClass(`color${capitalize(color)}`), { + ['Mui-disabled']: disabled, + [getUtilityClass('marked')]: marked, + [getUtilityClass('vertical')]: orientation === 'vertical', + [getUtilityClass('trackInverted')]: track === 'inverted', + [getUtilityClass('trackFalse')]: track === false, + }), rail: getUtilityClass('rail'), track: getUtilityClass('track'), mark: getUtilityClass('mark'), markLabel: getUtilityClass('markLabel'), valueLabel: getUtilityClass('valueLabel'), - thumb: clsx( - getUtilityClass('thumb'), - getUtilityClass(`thumbColor${capitalize(color)}`), - { - ['Mui-disabled']: disabled, - }, - ), + thumb: clsx(getUtilityClass('thumb'), getUtilityClass(`thumbColor${capitalize(color)}`), { + ['Mui-disabled']: disabled, + }), }; return utilityClasses; From 8f2284058124c57fcfb7972a93308008d9cdeba3 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 3 Sep 2020 17:20:42 +0200 Subject: [PATCH 022/125] have the demo interactive --- docs/src/pages/components/slider/UnstyledSlider.js | 2 +- docs/src/pages/components/slider/UnstyledSlider.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/components/slider/UnstyledSlider.js b/docs/src/pages/components/slider/UnstyledSlider.js index eb478301cbb82d..f54d71fc5d492e 100644 --- a/docs/src/pages/components/slider/UnstyledSlider.js +++ b/docs/src/pages/components/slider/UnstyledSlider.js @@ -58,5 +58,5 @@ const StyledSlider = styled(SliderBase)` `; export default function UnstyledSlider() { - return ; + return ; } diff --git a/docs/src/pages/components/slider/UnstyledSlider.tsx b/docs/src/pages/components/slider/UnstyledSlider.tsx index eb478301cbb82d..f54d71fc5d492e 100644 --- a/docs/src/pages/components/slider/UnstyledSlider.tsx +++ b/docs/src/pages/components/slider/UnstyledSlider.tsx @@ -58,5 +58,5 @@ const StyledSlider = styled(SliderBase)` `; export default function UnstyledSlider() { - return ; + return ; } From c448969a4d740703c946968d58fc35732e92ff96 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 7 Sep 2020 07:53:39 +0200 Subject: [PATCH 023/125] fixed style, fixed classnames --- .../components/slider/CustomizedSlider.js | 20 +++---------------- .../components/slider/CustomizedSlider.tsx | 20 +++---------------- packages/material-ui/src/Slider/Slider.js | 10 +++++----- packages/material-ui/src/Slider/SliderBase.js | 10 +++++----- 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index b2336fdb5b71b0..9f9e4649e4bad6 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -71,7 +71,7 @@ const iosComponents = { boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', // Reset on touch devices, it doesn't add specificity @@ -79,14 +79,6 @@ const iosComponents = { boxShadow: iOSBoxShadow, }, }, - ...(props.active && { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, - }, - }), })), valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', @@ -129,12 +121,9 @@ const prettoComponents = { border: '2px solid currentColor', marginTop: -8, marginLeft: -12, - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: 'inherit', }, - ...(props.active && { - boxShadow: 'inherit', - }), })), valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', @@ -164,12 +153,9 @@ const airbnbComponents = { marginLeft: -13, // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: '#ccc 0 2px 3px 1px', }, - ...(props.active && { - boxShadow: '#ccc 0 2px 3px 1px', - }), '& .bar': { // display: inline-block !important; height: 9, diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index d49f9cd4745f25..69ef6eb86806f3 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -77,7 +77,7 @@ const iosComponents = { boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', // Reset on touch devices, it doesn't add specificity @@ -85,14 +85,6 @@ const iosComponents = { boxShadow: iOSBoxShadow, }, }, - ...(props.active && { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, - }, - }), })), valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', @@ -135,12 +127,9 @@ const prettoComponents = { border: '2px solid currentColor', marginTop: -8, marginLeft: -12, - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: 'inherit', }, - ...(props.active && { - boxShadow: 'inherit', - }), })), valueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', @@ -170,12 +159,9 @@ const airbnbComponents = { marginLeft: -13, // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover': { + '&:focus, &:hover, &.Mui-active': { boxShadow: '#ccc 0 2px 3px 1px', }, - ...(props.active && { - boxShadow: '#ccc 0 2px 3px 1px', - }), '& .bar': { // display: inline-block !important; height: 9, diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index c78a29ba047321..487b68643565ff 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -133,12 +133,12 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ boxShadow: 'none', }, }, - ...(props.focusVisible && { + '&.Mui-focusVisible': { boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, '@media (hover: none)': { boxShadow: 'none', }, - }), + }, '&.Mui-active': { boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, }, @@ -165,10 +165,10 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ ':hover': { boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, }, - ...(props.focusVisible && { + '&.Mui-focusVisible': { boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, - }), - '&.MuiSlider--active': { + }, + '&.Mui-active': { boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, }, }), diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index 5eb0fd7606164b..9ceff0b0b11e3b 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -606,7 +606,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...stateAndProps} {...trackProps} className={clsx(utilityClasses.track, trackProps.className)} - style={trackStyle} + style={{ ...trackStyle, ...trackProps.style }} /> {marks.map((mark, index) => { @@ -631,10 +631,10 @@ const Slider = React.forwardRef(function Slider(props, ref) { return ( Date: Mon, 7 Sep 2020 08:03:22 +0200 Subject: [PATCH 024/125] merge conflicts --- packages/material-ui/src/Slider/SliderBase.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index 9ceff0b0b11e3b..c70bf27e392dfe 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -417,6 +417,13 @@ const Slider = React.forwardRef(function Slider(props, ref) { return; } + // Cancel move in case some other element consumed a mouseup event and it was not fired. + if (nativeEvent.type === 'mousemove' && nativeEvent.buttons === 0) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + handleTouchEnd(nativeEvent); + return; + } + const { newValue, activeIndex } = getFingerNewValue({ finger, move: true, @@ -765,6 +772,7 @@ Slider.propTypes = { className: PropTypes.string, /** * The color of the component. It supports those theme colors that make sense for this component. + * @default 'primary' */ color: PropTypes.oneOf(['primary', 'secondary']), /** @@ -778,6 +786,7 @@ Slider.propTypes = { defaultValue: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), /** * If `true`, the slider will be disabled. + * @default false */ disabled: PropTypes.bool, /** @@ -803,6 +812,7 @@ Slider.propTypes = { * Marks indicate predetermined values to which the user can move the slider. * If `true` the marks will be spaced according the value of the `step` prop. * If an array, it should contain objects with `value` and an optional `label` keys. + * @default false */ marks: PropTypes.oneOfType([ PropTypes.arrayOf( @@ -816,11 +826,13 @@ Slider.propTypes = { /** * The maximum allowed value of the slider. * Should not be equal to min. + * @default 100 */ max: PropTypes.number, /** * The minimum allowed value of the slider. * Should not be equal to max. + * @default 0 */ min: PropTypes.number, /** @@ -847,10 +859,12 @@ Slider.propTypes = { onMouseDown: PropTypes.func, /** * The slider orientation. + * @default 'horizontal' */ orientation: PropTypes.oneOf(['horizontal', 'vertical']), /** * A transformation function, to change the scale of the slider. + * @default (x) => x */ scale: PropTypes.func, /** @@ -859,10 +873,12 @@ Slider.propTypes = { * We recommend (max - min) to be evenly divisible by the step. * * When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. + * @default 1 */ step: PropTypes.number, /** * The component used to display the value label. + * @default 'span' */ ThumbComponent: PropTypes.elementType, /** @@ -871,6 +887,7 @@ Slider.propTypes = { * - `normal` the track will render a bar representing the slider value. * - `inverted` the track will render a bar representing the remaining slider value. * - `false` the track will render without a bar. + * @default 'normal' */ track: PropTypes.oneOf(['inverted', 'normal', false]), /** @@ -880,6 +897,7 @@ Slider.propTypes = { value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.number), PropTypes.number]), /** * The value label component. + * @default ValueLabel */ ValueLabelComponent: PropTypes.elementType, /** @@ -888,6 +906,7 @@ Slider.propTypes = { * - `auto` the value label will display when the thumb is hovered or focused. * - `on` will display persistently. * - `off` will never display. + * @default 'off' */ valueLabelDisplay: PropTypes.oneOf(['auto', 'off', 'on']), /** @@ -897,6 +916,7 @@ Slider.propTypes = { * * - {number} value The value label's value to format * - {number} index The value label's index to format + * @default (x) => x */ valueLabelFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), }; From 79b8a269e1827dfb55eacc0dbc6826712b1d491a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 7 Sep 2020 08:08:10 +0200 Subject: [PATCH 025/125] moved cache creation --- .../src/ThemeProvider/ThemeProvider.js | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 2c707ce56ce02d..73c06169b26f04 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -30,6 +30,20 @@ function mergeOuterLocalTheme(outerTheme, localTheme) { return { ...outerTheme, ...localTheme }; } +// Cache for the ltr version of the styles +const cacheLtr = createCache({ + key: 'mui', + stylisPlugins: [], + speedy: true, +}); + +// Cache for the rtl version of the styles +const cacheRtl = createCache({ + key: 'muirtl', + stylisPlugins: [rtlPlugin], + speedy: true, +}); + /** * This component takes a `theme` prop. * It makes the `theme` available down the React tree thanks to React context. @@ -64,18 +78,6 @@ function ThemeProvider(props) { return output; }, [localTheme, outerTheme]); - const cacheLtr = createCache({ - key: 'mui', - stylisPlugins: [], - speedy: true, - }); - - const cacheRtl = createCache({ - key: 'muirtl', - stylisPlugins: [rtlPlugin], - speedy: true, - }); - const rtl = theme.direction === 'rtl'; return ( From 0780a157409018d59117bb724459a0e0e8d7939e Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 7 Sep 2020 08:12:18 +0200 Subject: [PATCH 026/125] improved typings --- packages/material-ui/src/Slider/Slider.d.ts | 24 ++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index b5cb67f27af81f..2026a067d11e0f 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -264,23 +264,13 @@ export type SliderProps< P = {} > = OverrideProps, D>; -type SliderRootProps = Omit; -type SliderMarkProps = SliderRootProps & { - markActive?: boolean; -}; -type SliderMarkLabelProps = SliderRootProps & { - markLabelActive?: boolean; -}; -type SliderRailProps = SliderRootProps; -type SliderTrackProps = SliderRootProps; -type SliderThumbProps = SliderRootProps & { - active?: boolean; - focusVisible?: boolean; -}; -type SliderValueLabel = SliderRootProps & { - index?: number; - open?: boolean; -}; +type SliderRootProps = NonNullable["root"]; +type SliderMarkProps = NonNullable["mark"]; +type SliderMarkLabelProps = NonNullable["markLabel"]; +type SliderRailProps = NonNullable["rail"]; +type SliderTrackProps = NonNullable["track"]; +type SliderThumbProps = NonNullable["thumb"]; +type SliderValueLabel = NonNullable["valueLabel"]; export const SliderRoot: React.FC; export const SliderMark: React.FC; From 530b79f27757eb678991ae9e34321f6c57e62f96 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 7 Sep 2020 09:18:30 +0200 Subject: [PATCH 027/125] fixed overrides & extracted state --- .../components/slider/CustomizedSlider.js | 41 ++++++++-------- .../components/slider/CustomizedSlider.tsx | 38 +++++++-------- packages/material-ui/src/Slider/Slider.d.ts | 48 +++++++++++-------- packages/material-ui/src/Slider/Slider.js | 44 ++++++++--------- packages/material-ui/src/Slider/SliderBase.js | 42 ++++++++++------ 5 files changed, 114 insertions(+), 99 deletions(-) diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 9f9e4649e4bad6..2b1d5d941c90a4 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -58,12 +58,12 @@ const marks = [ ]; const iosComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 28, width: 28, backgroundColor: '#fff', @@ -79,8 +79,8 @@ const iosComponents = { boxShadow: iOSBoxShadow, }, }, - })), - valueLabel: styled(SliderValueLabel)({ + }), + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { @@ -88,21 +88,21 @@ const iosComponents = { color: '#000', }, }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 2, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', }), - mark: styled(SliderMark)((props) => ({ + Mark: styled(SliderMark)((props) => ({ // @ts-ignore backgroundColor: '#bfbfbf', height: 8, width: 1, marginTop: -3, - ...(props.markActive && { + ...(props.state.markActive && { opacity: 1, backgroundColor: 'currentColor', }), @@ -110,11 +110,11 @@ const iosComponents = { }; const prettoComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#52af77', height: 8, }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 24, width: 24, backgroundColor: '#fff', @@ -124,27 +124,27 @@ const prettoComponents = { '&:focus, &:hover, &.Mui-active': { boxShadow: 'inherit', }, - })), - valueLabel: styled(SliderValueLabel)({ + }), + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 8, borderRadius: 4, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 8, borderRadius: 4, }), }; const airbnbComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 27, width: 27, backgroundColor: '#fff', @@ -164,11 +164,11 @@ const airbnbComponents = { marginLeft: 1, marginRight: 1, }, - })), - track: styled(SliderTrack)({ + }), + Track: styled(SliderTrack)({ height: 3, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, @@ -213,7 +213,7 @@ export default function CustomizedSlider() { Tooltip value label index === 0 ? 'Minimum price' : 'Maximum price' } diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index 69ef6eb86806f3..2daab0bca482c1 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -64,12 +64,12 @@ const marks = [ ]; const iosComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3880ff', height: 2, padding: '15px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 28, width: 28, backgroundColor: '#fff', @@ -85,8 +85,8 @@ const iosComponents = { boxShadow: iOSBoxShadow, }, }, - })), - valueLabel: styled(SliderValueLabel)({ + }), + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 12px)', top: -22, '& *': { @@ -94,21 +94,21 @@ const iosComponents = { color: '#000', }, }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 2, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 2, opacity: 0.5, backgroundColor: '#bfbfbf', }), - mark: styled(SliderMark)((props) => ({ + Mark: styled(SliderMark)((props) => ({ // @ts-ignore backgroundColor: '#bfbfbf', height: 8, width: 1, marginTop: -3, - ...(props.markActive && { + ...(props.state.markActive && { opacity: 1, backgroundColor: 'currentColor', }), @@ -116,11 +116,11 @@ const iosComponents = { }; const prettoComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#52af77', height: 8, }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 24, width: 24, backgroundColor: '#fff', @@ -130,27 +130,27 @@ const prettoComponents = { '&:focus, &:hover, &.Mui-active': { boxShadow: 'inherit', }, - })), - valueLabel: styled(SliderValueLabel)({ + }), + ValueLabel: styled(SliderValueLabel)({ left: 'calc(-50% + 4px)', }), - track: styled(SliderTrack)({ + Track: styled(SliderTrack)({ height: 8, borderRadius: 4, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ height: 8, borderRadius: 4, }), }; const airbnbComponents = { - root: styled(SliderRoot)({ + Root: styled(SliderRoot)({ color: '#3a8589', height: 3, padding: '13px 0', }), - thumb: styled(SliderThumb)((props) => ({ + Thumb: styled(SliderThumb)({ height: 27, width: 27, backgroundColor: '#fff', @@ -170,11 +170,11 @@ const airbnbComponents = { marginLeft: 1, marginRight: 1, }, - })), - track: styled(SliderTrack)({ + }), + Track: styled(SliderTrack)({ height: 3, }), - rail: styled(SliderRail)({ + Rail: styled(SliderRail)({ color: '#d8d8d8', opacity: 1, height: 3, diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 2026a067d11e0f..5f34370e60bb3e 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -96,22 +96,30 @@ export interface SliderTypeMap

{ * The props used for each slot inside the Slider. */ componentsProps?: { - root?: Omit['props'], 'components' | 'componentsProps'>; - track?: Omit['props'], 'components' | 'componentsProps'>; - rail?: Omit['props'], 'components' | 'componentsProps'>; - thumb?: Omit['props'], 'components' | 'componentsProps'> & { - active?: boolean; - focusVisible?: boolean; + root?: { state: Omit['props'], 'components' | 'componentsProps'> }; + track?: { state: Omit['props'], 'components' | 'componentsProps'> }; + rail?: { state: Omit['props'], 'components' | 'componentsProps'> }; + thumb?: { + state: Omit['props'], 'components' | 'componentsProps'> & { + active?: boolean; + focusVisible?: boolean; + }; }; - mark?: Omit['props'], 'components' | 'componentsProps'> & { - markActive?: boolean; + mark?: { + state: Omit['props'], 'components' | 'componentsProps'> & { + markActive?: boolean; + }; }; - markLabel?: Omit['props'], 'components' | 'componentsProps'> & { - markLabelActive?: boolean; + markLabel?: { + state: Omit['props'], 'components' | 'componentsProps'> & { + markLabelActive?: boolean; + }; }; - valueLabel?: Omit['props'], 'components' | 'componentsProps'> & { - index?: number; - open?: boolean; + valueLabel?: { + state: Omit['props'], 'components' | 'componentsProps'> & { + index?: number; + open?: boolean; + }; }; }; /** @@ -264,13 +272,13 @@ export type SliderProps< P = {} > = OverrideProps, D>; -type SliderRootProps = NonNullable["root"]; -type SliderMarkProps = NonNullable["mark"]; -type SliderMarkLabelProps = NonNullable["markLabel"]; -type SliderRailProps = NonNullable["rail"]; -type SliderTrackProps = NonNullable["track"]; -type SliderThumbProps = NonNullable["thumb"]; -type SliderValueLabel = NonNullable["valueLabel"]; +type SliderRootProps = NonNullable['root']; +type SliderMarkProps = NonNullable['mark']; +type SliderMarkLabelProps = NonNullable['markLabel']; +type SliderRailProps = NonNullable['rail']; +type SliderTrackProps = NonNullable['track']; +type SliderThumbProps = NonNullable['thumb']; +type SliderValueLabel = NonNullable['valueLabel']; export const SliderRoot: React.FC; export const SliderMark: React.FC; diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 6a7b1df39ec78a..41b653536ff2a8 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,7 +1,6 @@ import * as React from 'react'; import { css, cx } from 'emotion'; import styled from '@emotion/styled'; -import isPropValid from '@emotion/is-prop-valid'; import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; @@ -10,12 +9,7 @@ import SliderBase from './SliderBase'; import ValueLabel from './ValueLabel'; import defaultTheme from '../styles/defaultTheme'; -const shouldForwardProp = (prop) => - isPropValid(prop) && - prop !== 'color' && - prop !== 'scale' && - prop !== 'orientation' && - prop !== 'disabled'; +const shouldForwardProp = (prop) => prop !== 'state' && prop != 'as'; export const SliderRoot = styled('span', { shouldForwardProp })((props) => { return { @@ -29,7 +23,7 @@ export const SliderRoot = styled('span', { shouldForwardProp })((props) => { touchAction: 'none', color: props.theme.palette.primary.main, WebkitTapHighlightColor: 'transparent', - ...(props.color === 'secondary' && { + ...(props.state.color === 'secondary' && { color: props.theme.palette.secondary.main, }), '&.Mui-disabled': { @@ -37,7 +31,7 @@ export const SliderRoot = styled('span', { shouldForwardProp })((props) => { cursor: 'default', color: props.theme.palette.grey[400], }, - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { width: 2, height: '100%', padding: '0 13px', @@ -46,16 +40,16 @@ export const SliderRoot = styled('span', { shouldForwardProp })((props) => { '@media (pointer: coarse)': { // Reach 42px touch target, about ~8mm on screen. padding: '20px 0', - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { padding: '0 20px', }), }, '@media print': { colorAdjust: 'exact', }, - ...(props.marked && { + ...(props.state.marked && { marginBottom: 20, - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { marginBottom: 'auto', marginRight: 20, }), @@ -71,11 +65,11 @@ export const SliderRail = styled('span', { shouldForwardProp })((props) => ({ borderRadius: 1, backgroundColor: 'currentColor', opacity: 0.38, - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { height: '100%', width: 2, }), - ...(props.track === 'inverted' && { + ...(props.state.track === 'inverted' && { opacity: 1, }), })); @@ -86,13 +80,13 @@ export const SliderTrack = styled('span', { shouldForwardProp })((props) => ({ height: 2, borderRadius: 1, backgroundColor: 'currentColor', - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { width: 2, }), - ...(props.track === false && { + ...(props.state.track === false && { display: 'none', }), - ...(props.track === 'inverted' && { + ...(props.state.track === 'inverted' && { backgroundColor: // Same logic as the LinearProgress track color props.theme.palette.type === 'light' @@ -151,17 +145,17 @@ export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ boxShadow: 'none', }, }, - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { marginLeft: -5, marginBottom: -6, }), - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { '&.Mui-disabled': { marginLeft: -3, marginBottom: -4, }, }), - ...(props.color === 'secondary' && { + ...(props.state.color === 'secondary' && { ':hover': { boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, }, @@ -185,7 +179,7 @@ export const SliderMark = styled('span', { shouldForwardProp })((props) => ({ height: 2, borderRadius: 1, backgroundColor: 'currentColor', - ...(props.markActive && { + ...(props.state.markActive && { backgroundColor: props.theme.palette.background.paper, opacity: 0.8, }), @@ -198,18 +192,18 @@ export const SliderMarkLabel = styled('span', { shouldForwardProp })((props) => top: 26, transform: 'translateX(-50%)', whiteSpace: 'nowrap', - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { top: 'auto', left: 26, transform: 'translateY(50%)', }), '@media (pointer: coarse)': { top: 40, - ...(props.orientation === 'vertical' && { + ...(props.state.orientation === 'vertical' && { left: 31, }), }, - ...(props.markLabelActive && { + ...(props.state.markLabelActive && { color: props.theme.palette.text.primary, }), })); @@ -400,4 +394,4 @@ const Slider = React.forwardRef(function Slider(inputProps, inputRef) { ); }); -export default Slider; \ No newline at end of file +export default Slider; diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index c70bf27e392dfe..7ea296b7ab90c2 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -170,6 +170,8 @@ const useSliderClasses = (props) => { return utilityClasses; }; +const isTag = (element) => typeof element === 'string'; + const Slider = React.forwardRef(function Slider(props, ref) { const { 'aria-label': ariaLabel, @@ -575,7 +577,6 @@ const Slider = React.forwardRef(function Slider(props, ref) { // consider extracting to hook an reusing the lint rule for the varints const stateAndProps = { ...props, - classes: undefined, // we do not want to override other components classes color, disabled, max, @@ -587,31 +588,34 @@ const Slider = React.forwardRef(function Slider(props, ref) { valueLabelDisplay, valueLabelFormat, isRtl, + marked: marks.length > 0 && marks.some((mark) => mark.label), }; const utilityClasses = useSliderClasses({ ...stateAndProps, classes, - marked: marks.length > 0 && marks.some((mark) => mark.label), }); return ( 0 && marks.some((mark) => mark.label)} - {...stateAndProps} + state={!isTag(Root) ? stateAndProps : undefined} + theme={!isTag(Root) ? props.theme : undefined} {...rootProps} + {...other} className={clsx(utilityClasses.root, rootProps.className, className)} > @@ -639,25 +643,27 @@ const Slider = React.forwardRef(function Slider(props, ref) { {mark.label != null ? ( {mark.label} @@ -682,19 +688,27 @@ const Slider = React.forwardRef(function Slider(props, ref) { index={index} open={open === index || active === index || valueLabelDisplay === 'on'} disabled={disabled} - {...stateAndProps} {...valueLabelProps} + state={!isTag(ValueLabel) ? stateAndProps : undefined} + theme={!isTag(ValueLabel) ? props.theme : undefined} className={clsx(utilityClasses.valueLabel, valueLabelProps.className)} > Date: Mon, 7 Sep 2020 09:23:49 +0200 Subject: [PATCH 028/125] fixed ts --- .../components/slider/CustomizedSlider.tsx | 2 +- packages/material-ui/src/Slider/Slider.d.ts | 22 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index 2daab0bca482c1..876608a1345762 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -219,7 +219,7 @@ export default function CustomizedSlider() { Tooltip value label { * Either a string to use a HTML element or a component. */ components?: { - Root?: React.ElementType< - Omit['props'], 'components' | 'componentsProps'> - >; + Root?: React.ElementType; Track?: React.ElementType; Rail?: React.ElementType; Thumb?: React.ElementType; @@ -96,30 +94,34 @@ export interface SliderTypeMap

{ * The props used for each slot inside the Slider. */ componentsProps?: { - root?: { state: Omit['props'], 'components' | 'componentsProps'> }; - track?: { state: Omit['props'], 'components' | 'componentsProps'> }; - rail?: { state: Omit['props'], 'components' | 'componentsProps'> }; + root?: { state?: Omit['props'], 'components' | 'componentsProps'>; as: React.ElementType }; + track?: { state?: Omit['props'], 'components' | 'componentsProps'>; as?: React.ElementType; }; + rail?: { state?: Omit['props'], 'components' | 'componentsProps'>; as?: React.ElementType; }; thumb?: { - state: Omit['props'], 'components' | 'componentsProps'> & { + state?: Omit['props'], 'components' | 'componentsProps'> & { active?: boolean; focusVisible?: boolean; }; + as?: React.ElementType; }; mark?: { - state: Omit['props'], 'components' | 'componentsProps'> & { + state?: Omit['props'], 'components' | 'componentsProps'> & { markActive?: boolean; }; + as?: React.ElementType; }; markLabel?: { - state: Omit['props'], 'components' | 'componentsProps'> & { + state?: Omit['props'], 'components' | 'componentsProps'> & { markLabelActive?: boolean; }; + as?: React.ElementType; }; valueLabel?: { - state: Omit['props'], 'components' | 'componentsProps'> & { + state?: Omit['props'], 'components' | 'componentsProps'> & { index?: number; open?: boolean; }; + as?: React.ElementType; }; }; /** From 9ec7c654f7300c7f7c373085d6432fc529e1a9f4 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 9 Sep 2020 10:57:40 +0200 Subject: [PATCH 029/125] wip --- .../components/slider/ContinuousSlider.js | 14 +- .../components/slider/ContinuousSlider.tsx | 1 + .../components/slider/CustomizedSlider.js | 201 +++--- .../components/slider/CustomizedSlider.tsx | 192 +++--- packages/material-ui/src/Slider/Slider.js | 578 +++++++++--------- packages/material-ui/src/Slider/SliderBase.js | 29 +- 6 files changed, 494 insertions(+), 521 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index c6b78ab830f55e..d128a88a822061 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -2,10 +2,11 @@ import * as React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import Slider from '@material-ui/core/Slider'; +import Slider, { SliderRoot } from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; import { ThemeProvider } from '@material-ui/styles'; +import styled from '@emotion/styled'; const useStyles = makeStyles({ root: { @@ -13,6 +14,14 @@ const useStyles = makeStyles({ }, }); + +const componentOverrides = { + Root: styled(SliderRoot)` + background-color: pink; + border-color: green; + ` +} + export default function ContinuousSlider() { const classes = useStyles(); const [value, setValue] = React.useState(30); @@ -30,6 +39,7 @@ export default function ContinuousSlider() { props: { color: 'primary', orientation: 'vertical' }, style: { backgroundColor: 'green', + border: '3px solid orange', }, }, ], @@ -70,7 +80,7 @@ export default function ContinuousSlider() { Vertical primary slider - +

); diff --git a/docs/src/pages/components/slider/ContinuousSlider.tsx b/docs/src/pages/components/slider/ContinuousSlider.tsx index 2fc325d720de12..26731c48af848a 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.tsx +++ b/docs/src/pages/components/slider/ContinuousSlider.tsx @@ -33,6 +33,7 @@ export default function ContinuousSlider() { props: { color: 'primary', orientation: 'vertical' }, style: { backgroundColor: 'green', + border: '3px solid orange', }, }, ], diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 2b1d5d941c90a4..c7824cd9c4c62c 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -3,16 +3,10 @@ import PropTypes from 'prop-types'; import { useTheme, makeStyles } from '@material-ui/core/styles'; import Slider, { SliderRoot, - SliderMark, - SliderRail, - SliderTrack, - SliderThumb, - SliderValueLabel, } from '@material-ui/core/Slider'; import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; -import { ThemeProvider } from 'emotion-theming'; const useStyles = makeStyles((theme) => ({ root: { @@ -62,79 +56,84 @@ const iosComponents = { color: '#3880ff', height: 2, padding: '15px 0', - }), - Thumb: styled(SliderThumb)({ - height: 28, - width: 28, - backgroundColor: '#fff', - // @ts-ignore - boxShadow: iOSBoxShadow, - marginTop: -14, - marginLeft: -14, - '&:focus, &:hover, &.Mui-active': { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, + '& .MuiSlider-thumb': { + height: 28, + width: 28, + backgroundColor: '#fff', + // @ts-ignore + boxShadow: iOSBoxShadow, + marginTop: -14, + marginLeft: -14, + '&:focus, &:hover, &.Mui-active': { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, + }, }, }, - }), - ValueLabel: styled(SliderValueLabel)({ - left: 'calc(-50% + 12px)', - top: -22, - '& *': { - background: 'transparent', - color: '#000', + + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 12px)', + top: -22, + '& *': { + background: 'transparent', + color: '#000', + }, }, + + '& .MuiSlider-track': { + height: 2, + }, + + '& .MuiSlider-rail': { + height: 2, + opacity: 0.5, + backgroundColor: '#bfbfbf', + }, + + '& .MuiSlider-mark': { + backgroundColor: '#bfbfbf', + height: 8, + width: 1, + marginTop: -3, + '&.MuiSlider-markActive': { + opacity: 1, + backgroundColor: 'currentColor', + }, + } }), - Track: styled(SliderTrack)({ - height: 2, - }), - Rail: styled(SliderRail)({ - height: 2, - opacity: 0.5, - backgroundColor: '#bfbfbf', - }), - Mark: styled(SliderMark)((props) => ({ - // @ts-ignore - backgroundColor: '#bfbfbf', - height: 8, - width: 1, - marginTop: -3, - ...(props.state.markActive && { - opacity: 1, - backgroundColor: 'currentColor', - }), - })), }; const prettoComponents = { Root: styled(SliderRoot)({ color: '#52af77', height: 8, - }), - Thumb: styled(SliderThumb)({ - height: 24, - width: 24, - backgroundColor: '#fff', - border: '2px solid currentColor', - marginTop: -8, - marginLeft: -12, - '&:focus, &:hover, &.Mui-active': { - boxShadow: 'inherit', + '& .MuiSlider-thumb': { + height: 24, + width: 24, + backgroundColor: '#fff', + border: '2px solid currentColor', + marginTop: -8, + marginLeft: -12, + '&:focus, &:hover, &.Mui-active': { + boxShadow: 'inherit', + }, }, - }), - ValueLabel: styled(SliderValueLabel)({ - left: 'calc(-50% + 4px)', - }), - Track: styled(SliderTrack)({ - height: 8, - borderRadius: 4, - }), - Rail: styled(SliderRail)({ - height: 8, - borderRadius: 4, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 4px)', + }, + + '& .MuiSlider-track': { + height: 8, + borderRadius: 4, + }, + + '& .MuiSlider-rail': { + height: 8, + borderRadius: 4, + } }), }; @@ -143,35 +142,38 @@ const airbnbComponents = { color: '#3a8589', height: 3, padding: '13px 0', - }), - Thumb: styled(SliderThumb)({ - height: 27, - width: 27, - backgroundColor: '#fff', - border: '1px solid currentColor', - marginTop: -12, - marginLeft: -13, - // @ts-ignore - boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &.Mui-active': { - boxShadow: '#ccc 0 2px 3px 1px', + + '& .MuiSlider-thumb': { + height: 27, + width: 27, + backgroundColor: '#fff', + border: '1px solid currentColor', + marginTop: -12, + marginLeft: -13, + // @ts-ignore + boxShadow: '#ebebeb 0 2px 2px', + '&:focus, &:hover, &.Mui-active': { + boxShadow: '#ccc 0 2px 3px 1px', + }, + '& .bar': { + // display: inline-block !important; + height: 9, + width: 1, + backgroundColor: 'currentColor', + marginLeft: 1, + marginRight: 1, + }, }, - '& .bar': { - // display: inline-block !important; - height: 9, - width: 1, - backgroundColor: 'currentColor', - marginLeft: 1, - marginRight: 1, + + '& .MuiSlider-track': { + height: 3, }, - }), - Track: styled(SliderTrack)({ - height: 3, - }), - Rail: styled(SliderRail)({ - color: '#d8d8d8', - opacity: 1, - height: 3, + + '& .MuiSlider-rail': { + color: '#d8d8d8', + opacity: 1, + height: 3, + } }), }; @@ -191,7 +193,6 @@ export default function CustomizedSlider() { const theme = useTheme(); return ( -
iOS Airbnb index === 0 ? 'Minimum price' : 'Maximum price' } defaultValue={[20, 40]} />
-
); } diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index 876608a1345762..38e05997090a7e 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -7,11 +7,6 @@ import { } from '@material-ui/core/styles'; import Slider, { SliderRoot, - SliderMark, - SliderRail, - SliderTrack, - SliderThumb, - SliderValueLabel, } from '@material-ui/core/Slider'; import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; @@ -68,79 +63,84 @@ const iosComponents = { color: '#3880ff', height: 2, padding: '15px 0', - }), - Thumb: styled(SliderThumb)({ - height: 28, - width: 28, - backgroundColor: '#fff', - // @ts-ignore - boxShadow: iOSBoxShadow, - marginTop: -14, - marginLeft: -14, - '&:focus, &:hover, &.Mui-active': { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, + '& .MuiSlider-thumb': { + height: 28, + width: 28, + backgroundColor: '#fff', + // @ts-ignore + boxShadow: iOSBoxShadow, + marginTop: -14, + marginLeft: -14, + '&:focus, &:hover, &.Mui-active': { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, + }, }, }, - }), - ValueLabel: styled(SliderValueLabel)({ - left: 'calc(-50% + 12px)', - top: -22, - '& *': { - background: 'transparent', - color: '#000', + + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 12px)', + top: -22, + '& *': { + background: 'transparent', + color: '#000', + }, }, + + '& .MuiSlider-track': { + height: 2, + }, + + '& .MuiSlider-rail': { + height: 2, + opacity: 0.5, + backgroundColor: '#bfbfbf', + }, + + '& .MuiSlider-mark': { + backgroundColor: '#bfbfbf', + height: 8, + width: 1, + marginTop: -3, + '&.MuiSlider-markActive': { + opacity: 1, + backgroundColor: 'currentColor', + }, + } }), - Track: styled(SliderTrack)({ - height: 2, - }), - Rail: styled(SliderRail)({ - height: 2, - opacity: 0.5, - backgroundColor: '#bfbfbf', - }), - Mark: styled(SliderMark)((props) => ({ - // @ts-ignore - backgroundColor: '#bfbfbf', - height: 8, - width: 1, - marginTop: -3, - ...(props.state.markActive && { - opacity: 1, - backgroundColor: 'currentColor', - }), - })), }; const prettoComponents = { Root: styled(SliderRoot)({ color: '#52af77', height: 8, - }), - Thumb: styled(SliderThumb)({ - height: 24, - width: 24, - backgroundColor: '#fff', - border: '2px solid currentColor', - marginTop: -8, - marginLeft: -12, - '&:focus, &:hover, &.Mui-active': { - boxShadow: 'inherit', + '& .MuiSlider-thumb': { + height: 24, + width: 24, + backgroundColor: '#fff', + border: '2px solid currentColor', + marginTop: -8, + marginLeft: -12, + '&:focus, &:hover, &.Mui-active': { + boxShadow: 'inherit', + }, }, - }), - ValueLabel: styled(SliderValueLabel)({ - left: 'calc(-50% + 4px)', - }), - Track: styled(SliderTrack)({ - height: 8, - borderRadius: 4, - }), - Rail: styled(SliderRail)({ - height: 8, - borderRadius: 4, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 4px)', + }, + + '& .MuiSlider-track': { + height: 8, + borderRadius: 4, + }, + + '& .MuiSlider-rail': { + height: 8, + borderRadius: 4, + } }), }; @@ -149,35 +149,38 @@ const airbnbComponents = { color: '#3a8589', height: 3, padding: '13px 0', - }), - Thumb: styled(SliderThumb)({ - height: 27, - width: 27, - backgroundColor: '#fff', - border: '1px solid currentColor', - marginTop: -12, - marginLeft: -13, - // @ts-ignore - boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &.Mui-active': { - boxShadow: '#ccc 0 2px 3px 1px', + + '& .MuiSlider-thumb': { + height: 27, + width: 27, + backgroundColor: '#fff', + border: '1px solid currentColor', + marginTop: -12, + marginLeft: -13, + // @ts-ignore + boxShadow: '#ebebeb 0 2px 2px', + '&:focus, &:hover, &.Mui-active': { + boxShadow: '#ccc 0 2px 3px 1px', + }, + '& .bar': { + // display: inline-block !important; + height: 9, + width: 1, + backgroundColor: 'currentColor', + marginLeft: 1, + marginRight: 1, + }, }, - '& .bar': { - // display: inline-block !important; - height: 9, - width: 1, - backgroundColor: 'currentColor', - marginLeft: 1, - marginRight: 1, + + '& .MuiSlider-track': { + height: 3, }, - }), - Track: styled(SliderTrack)({ - height: 3, - }), - Rail: styled(SliderRail)({ - color: '#d8d8d8', - opacity: 1, - height: 3, + + '& .MuiSlider-rail': { + color: '#d8d8d8', + opacity: 1, + height: 3, + } }), }; @@ -233,7 +236,6 @@ export default function CustomizedSlider() { as: AirbnbThumbComponent, }, }} - ThumbComponent={AirbnbThumbComponent} getAriaLabel={(index) => index === 0 ? 'Minimum price' : 'Maximum price' } diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 41b653536ff2a8..65ed3e2b71ebac 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,17 +1,138 @@ import * as React from 'react'; -import { css, cx } from 'emotion'; import styled from '@emotion/styled'; -import { getThemeProps, useThemeVariants, propsToClassKey } from '@material-ui/styles'; +import { getThemeProps, propsToClassKey } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; -import ValueLabel from './ValueLabel'; import defaultTheme from '../styles/defaultTheme'; const shouldForwardProp = (prop) => prop !== 'state' && prop != 'as'; -export const SliderRoot = styled('span', { shouldForwardProp })((props) => { +const getStyleOverrides = (name, theme) => { + let styleOverrides = {}; + + if ( + theme && + theme.components && + theme.components[name] && + theme.components[name].styleOverrides + ) { + styleOverrides = theme.components[name].styleOverrides; + } + + return styleOverrides; +}; + +const getVariantStyles = (name, theme) => { + let variants = []; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + variants = theme.components[name].variants; + } + + const variantsStyles = {}; + + variants.forEach((definition) => { + const key = propsToClassKey(definition.props); + variantsStyles[key] = definition.style; + }); + + return variantsStyles; +}; + +const overridesResolver = (props, styles, name) => { + const { + color = 'primary', + disabled = false, + marks: marksProp = false, + max = 100, + min = 0, + orientation = 'horizontal', + step = 1, + track = 'normal', + } = props; + + const marks = + marksProp === true && step !== null + ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ + value: min + step * index, + })) + : marksProp || []; + + const marked = marks.length > 0 && marks.some((mark) => mark.label); + + const styleOverrides = { + ...styles.root, + ...styles[`color${capitalize(color)}`], + '&.Mui-disabled': styles.disabled, + ...(marked && styles.marked), + ...(orientation === 'vertical' && styles.vertical), + ...(track === 'inverted' && styles.trackInverted), + ...(track === false && styles.trackFalse), + [`.& ${name}-rail`]: styles.rail, + [`.& ${name}-track`]: styles.track, + [`.& ${name}-mark`]: styles.mark, + [`.& ${name}-markLabel`]: styles.markLabel, + [`.& ${name}-valueLabel`]: styles.valueLabel, + [`.& ${name}-thumb`]: { + ...styles.thumb, + ...styles[`thumbColor${capitalize(color)}`], + '&.Mui-disabled': styles.disabled, + }, + }; + + return styleOverrides; +} + +const variantsResolver = (props, styles, theme, name) => { + const { state = {} } = props; + let variantsStyles = {}; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + const themeVariants = theme.components[name].variants; + themeVariants.forEach((themeVariant) => { + let isMatch = true; + Object.keys(themeVariant.props).forEach((key) => { + if (state[key] !== themeVariant.props[key]) { + isMatch = false; + } + }); + if (isMatch) { + variantsStyles = {...variantsStyles, ...styles[propsToClassKey(themeVariant.props)]}; + } + }); + } + + return variantsStyles; +}; + +const muiStyled = (el, params, muiConfig) => { + const result = styled(el, params); + const muiFunc = (...params) => { + const newParams = params; + + newParams.unshift(props => { + const theme = props.theme || defaultTheme; + const name = muiConfig.muiName; + const variantsResolver = muiConfig.variantsResolver; + const variantsStylesByKeys = getVariantStyles(name, theme); + const result = variantsResolver(props, variantsStylesByKeys, theme, name); + return result; + }); + + newParams.unshift(props => { + const theme = props.theme || defaultTheme; + const name = muiConfig.muiName; + const overridesResolver = muiConfig.overridesResolver; + const styleOverridesByKeys = getStyleOverrides(name, theme); + return overridesResolver(props, styleOverridesByKeys, name); + }); + + return result(newParams); + } + return muiFunc; +} + +export const SliderRoot = muiStyled('div', { shouldForwardProp }, { muiName: 'MuiSlider', overridesResolver, variantsResolver })((props) => { return { height: 2, width: '100%', @@ -54,159 +175,171 @@ export const SliderRoot = styled('span', { shouldForwardProp })((props) => { marginRight: 20, }), }), - }; -}); -export const SliderRail = styled('span', { shouldForwardProp })((props) => ({ - display: 'block', - position: 'absolute', - width: '100%', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - opacity: 0.38, - ...(props.state.orientation === 'vertical' && { - height: '100%', - width: 2, - }), - ...(props.state.track === 'inverted' && { - opacity: 1, - }), -})); - -export const SliderTrack = styled('span', { shouldForwardProp })((props) => ({ - display: 'block', - position: 'absolute', - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - ...(props.state.orientation === 'vertical' && { - width: 2, - }), - ...(props.state.track === false && { - display: 'none', - }), - ...(props.state.track === 'inverted' && { - backgroundColor: - // Same logic as the LinearProgress track color - props.theme.palette.type === 'light' - ? lighten(props.theme.palette.primary.main, 0.62) - : darken(props.theme.palette.primary.main, 0.5), - }), -})); - -export const SliderThumb = styled('span', { shouldForwardProp })((props) => ({ - position: 'absolute', - width: 12, - height: 12, - marginLeft: -6, - marginTop: -5, - boxSizing: 'border-box', - borderRadius: '50%', - outline: 0, - backgroundColor: 'currentColor', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - transition: props.theme.transitions.create(['box-shadow'], { - duration: props.theme.transitions.duration.shortest, - }), - '::after': { - position: 'absolute', - content: '""', - borderRadius: '50%', - // reach 42px hit target (2 * 15 + thumb diameter) - left: -15, - top: -15, - right: -15, - bottom: -15, - }, - ':hover': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, - '@media (hover: none)': { - boxShadow: 'none', - }, - }, - '&.Mui-focusVisible': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, - '@media (hover: none)': { - boxShadow: 'none', - }, - }, - '&.Mui-active': { - boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, - }, - '&.Mui-disabled': { - width: 8, - height: 8, - marginLeft: -4, - marginTop: -3, - ':hover': { - boxShadow: 'none', + '& .MuiSlider-rail': { + display: 'block', + position: 'absolute', + width: '100%', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + opacity: 0.38, + ...(props.state.orientation === 'vertical' && { + height: '100%', + width: 2, + }), + ...(props.state.track === 'inverted' && { + opacity: 1, + }), }, - }, - ...(props.state.orientation === 'vertical' && { - marginLeft: -5, - marginBottom: -6, - }), - ...(props.state.orientation === 'vertical' && { - '&.Mui-disabled': { - marginLeft: -3, - marginBottom: -4, + + '& .MuiSlider-track': { + display: 'block', + position: 'absolute', + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + ...(props.state.orientation === 'vertical' && { + width: 2, + }), + ...(props.state.track === false && { + display: 'none', + }), + ...(props.state.track === 'inverted' && { + backgroundColor: + // Same logic as the LinearProgress track color + props.theme.palette.type === 'light' + ? lighten(props.theme.palette.primary.main, 0.62) + : darken(props.theme.palette.primary.main, 0.5), + }), }, - }), - ...(props.state.color === 'secondary' && { - ':hover': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + + '& .MuiSlider-thumb': { + position: 'absolute', + width: 12, + height: 12, + marginLeft: -6, + marginTop: -5, + boxSizing: 'border-box', + borderRadius: '50%', + outline: 0, + backgroundColor: 'currentColor', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: props.theme.transitions.create(['box-shadow'], { + duration: props.theme.transitions.duration.shortest, + }), + '::after': { + position: 'absolute', + content: '""', + borderRadius: '50%', + // reach 42px hit target (2 * 15 + thumb diameter) + left: -15, + top: -15, + right: -15, + bottom: -15, + }, + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, + }, + '&.Mui-focusVisible': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.primary.main, 0.16)}`, + '@media (hover: none)': { + boxShadow: 'none', + }, + }, + '&.Mui-active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.primary.main, 0.16)}`, + }, + '&.Mui-disabled': { + width: 8, + height: 8, + marginLeft: -4, + marginTop: -3, + ':hover': { + boxShadow: 'none', + }, + }, + ...(props.state.orientation === 'vertical' && { + marginLeft: -5, + marginBottom: -6, + }), + ...(props.state.orientation === 'vertical' && { + '&.Mui-disabled': { + marginLeft: -3, + marginBottom: -4, + }, + }), + ...(props.state.color === 'secondary' && { + ':hover': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + '&.Mui-focusVisible': { + boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + '&.Mui-active': { + boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, + }, + }), }, - '&.Mui-focusVisible': { - boxShadow: `0px 0px 0px 8px ${fade(props.theme.palette.secondary.main, 0.16)}`, + + '& .MuiSlider-valueLabel': { + // IE 11 centering bug, to remove from the customization demos once no longer supported + left: 'calc(-50% - 4px)', }, - '&.Mui-active': { - boxShadow: `0px 0px 0px 14px ${fade(props.theme.palette.secondary.main, 0.16)}`, + + '& .MuiSlider-mark': { + position: 'absolute', + width: 2, + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + '&.MuiSlider-markActive': { + backgroundColor: props.theme.palette.background.paper, + opacity: 0.8, + }, }, - }), -})); -export const SliderValueLabel = styled(ValueLabel)({ - // IE 11 centering bug, to remove from the customization demos once no longer supported - left: 'calc(-50% - 4px)', + '& .MuiSlider-markLabel': { + ...props.theme.typography.body2, + color: props.theme.palette.text.secondary, + position: 'absolute', + top: 26, + transform: 'translateX(-50%)', + whiteSpace: 'nowrap', + ...(props.state.orientation === 'vertical' && { + top: 'auto', + left: 26, + transform: 'translateY(50%)', + }), + '@media (pointer: coarse)': { + top: 40, + ...(props.state.orientation === 'vertical' && { + left: 31, + }), + }, + '&.MuiSlider-markLabelActive': { + color: props.theme.palette.text.primary, + } + } + }; }); -export const SliderMark = styled('span', { shouldForwardProp })((props) => ({ - position: 'absolute', - width: 2, - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - ...(props.state.markActive && { - backgroundColor: props.theme.palette.background.paper, - opacity: 0.8, - }), -})); - -export const SliderMarkLabel = styled('span', { shouldForwardProp })((props) => ({ - ...props.theme.typography.body2, - color: props.theme.palette.text.secondary, - position: 'absolute', - top: 26, - transform: 'translateX(-50%)', - whiteSpace: 'nowrap', - ...(props.state.orientation === 'vertical' && { - top: 'auto', - left: 26, - transform: 'translateY(50%)', - }), - '@media (pointer: coarse)': { - top: 40, - ...(props.state.orientation === 'vertical' && { - left: 31, - }), - }, - ...(props.state.markLabelActive && { - color: props.theme.palette.text.primary, - }), -})); +const getComponentProps = ( + components, + componentsProps, + name, +) => { + const slotProps = componentsProps[name] || {}; + return { + as: components[name], + ...slotProps, + }; +}; const useThemeProps = (inputProps, ref, name) => { const props = Object.assign({}, inputProps); @@ -227,171 +360,24 @@ const useThemeProps = (inputProps, ref, name) => { }; }; -const useThemeClasses = (name) => { - const theme = useTheme() || defaultTheme; - - let styleOverrides = {}; - let variants = []; - - if ( - theme && - theme.components && - theme.components[name] && - theme.components[name].styleOverrides - ) { - styleOverrides = theme.components[name].styleOverrides; - } - - if (theme && theme.components && theme.components[name] && theme.components[name].variants) { - variants = theme.components[name].variants; - } - - const classes = {}; - - Object.keys(styleOverrides).forEach((key) => { - classes[key] = css(styleOverrides[key]); - }); - - variants.forEach((definition) => { - const key = propsToClassKey(definition.props); - if (classes[key]) { - classes[key] = cx(classes[key], css(definition.style)); - } else { - classes[key] = css(definition.style); - } - }); - - return classes; -}; - -const getComponentProps = ( - components, - componentsProps, - themeOverridesClassesPerComponent, - name, -) => { - const slotProps = componentsProps[name] || {}; - return { - as: components[name], - ...slotProps, - ...(name !== 'root' && { - className: cx(themeOverridesClassesPerComponent, slotProps.className), - }), - }; -}; - -const useSliderClasses = (props) => { - const { - color = 'primary', - disabled = false, - marks: marksProp = false, - max = 100, - min = 0, - orientation = 'horizontal', - step = 1, - track = 'normal', - classes, - } = props; - - const marks = - marksProp === true && step !== null - ? [...Array(Math.floor((max - min) / step) + 1)].map((_, index) => ({ - value: min + step * index, - })) - : marksProp || []; - - const marked = marks.length > 0 && marks.some((mark) => mark.label); - - const overridesClasses = { - root: cx(classes.root, classes[`color${capitalize(color)}`], { - [classes.disabled]: disabled, - [classes.marked]: marked, - [classes.vertical]: orientation === 'vertical', - [classes.trackInverted]: track === 'inverted', - [classes.trackFalse]: track === false, - }), - rail: classes.rail, - track: classes.track, - mark: classes.mark, - markLabel: classes.markLabel, - valueLabel: classes.valueLabel, - thumb: cx(classes.thumb, classes[`thumbColor${capitalize(color)}`], { - [classes.disabled]: disabled, - }), - }; - - return overridesClasses; -}; - const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); - const classes = useThemeClasses('MuiSlider'); - const themeVariantsClasses = useThemeVariants({ ...props, classes }, 'MuiSlider'); - const themeOverridesClassesPerComponent = useSliderClasses({ ...props, classes }); const { components = {}, componentsProps = {}, ref, ...other } = props; - - return ( - - ); }); export default Slider; diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index 7ea296b7ab90c2..b8b4b170de1695 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -170,7 +170,7 @@ const useSliderClasses = (props) => { return utilityClasses; }; -const isTag = (element) => typeof element === 'string'; +const isComponent = (element) => typeof element !== 'string'; const Slider = React.forwardRef(function Slider(props, ref) { const { @@ -600,22 +600,18 @@ const Slider = React.forwardRef(function Slider(props, ref) { @@ -648,8 +644,6 @@ const Slider = React.forwardRef(function Slider(props, ref) { className={clsx(utilityClasses.mark, markProps.className, { [getUtilityClass('markActive')]: markActive, })} - state={!isTag(Mark) ? { ...stateAndProps, markActive } : undefined} - theme={!isTag(Mark) ? props.theme : undefined} /> {mark.label != null ? ( {mark.label} @@ -689,24 +679,13 @@ const Slider = React.forwardRef(function Slider(props, ref) { open={open === index || active === index || valueLabelDisplay === 'on'} disabled={disabled} {...valueLabelProps} - state={!isTag(ValueLabel) ? stateAndProps : undefined} - theme={!isTag(ValueLabel) ? props.theme : undefined} className={clsx(utilityClasses.valueLabel, valueLabelProps.className)} > Date: Wed, 9 Sep 2020 11:16:03 +0200 Subject: [PATCH 030/125] extracted muiStyled wip --- packages/material-ui/src/Slider/Slider.js | 60 +----------------- packages/material-ui/src/styles/index.d.ts | 1 + packages/material-ui/src/styles/index.js | 1 + .../material-ui/src/styles/muiStyled.d.ts | 8 +++ packages/material-ui/src/styles/muiStyled.js | 62 +++++++++++++++++++ 5 files changed, 73 insertions(+), 59 deletions(-) create mode 100644 packages/material-ui/src/styles/muiStyled.d.ts create mode 100644 packages/material-ui/src/styles/muiStyled.js diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 65ed3e2b71ebac..6a4ae926a2cfcd 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,45 +1,14 @@ import * as React from 'react'; -import styled from '@emotion/styled'; import { getThemeProps, propsToClassKey } from '@material-ui/styles'; import useTheme from '../styles/useTheme'; import { fade, lighten, darken } from '../styles/colorManipulator'; import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; import defaultTheme from '../styles/defaultTheme'; +import muiStyled from '../styles/muiStyled'; const shouldForwardProp = (prop) => prop !== 'state' && prop != 'as'; -const getStyleOverrides = (name, theme) => { - let styleOverrides = {}; - - if ( - theme && - theme.components && - theme.components[name] && - theme.components[name].styleOverrides - ) { - styleOverrides = theme.components[name].styleOverrides; - } - - return styleOverrides; -}; - -const getVariantStyles = (name, theme) => { - let variants = []; - if (theme && theme.components && theme.components[name] && theme.components[name].variants) { - variants = theme.components[name].variants; - } - - const variantsStyles = {}; - - variants.forEach((definition) => { - const key = propsToClassKey(definition.props); - variantsStyles[key] = definition.style; - }); - - return variantsStyles; -}; - const overridesResolver = (props, styles, name) => { const { color = 'primary', @@ -105,33 +74,6 @@ const variantsResolver = (props, styles, theme, name) => { return variantsStyles; }; -const muiStyled = (el, params, muiConfig) => { - const result = styled(el, params); - const muiFunc = (...params) => { - const newParams = params; - - newParams.unshift(props => { - const theme = props.theme || defaultTheme; - const name = muiConfig.muiName; - const variantsResolver = muiConfig.variantsResolver; - const variantsStylesByKeys = getVariantStyles(name, theme); - const result = variantsResolver(props, variantsStylesByKeys, theme, name); - return result; - }); - - newParams.unshift(props => { - const theme = props.theme || defaultTheme; - const name = muiConfig.muiName; - const overridesResolver = muiConfig.overridesResolver; - const styleOverridesByKeys = getStyleOverrides(name, theme); - return overridesResolver(props, styleOverridesByKeys, name); - }); - - return result(newParams); - } - return muiFunc; -} - export const SliderRoot = muiStyled('div', { shouldForwardProp }, { muiName: 'MuiSlider', overridesResolver, variantsResolver })((props) => { return { height: 2, diff --git a/packages/material-ui/src/styles/index.d.ts b/packages/material-ui/src/styles/index.d.ts index 812f80e6b4e30a..ad3c474e1a2188 100644 --- a/packages/material-ui/src/styles/index.d.ts +++ b/packages/material-ui/src/styles/index.d.ts @@ -23,6 +23,7 @@ export { StyledComponentProps, } from './withStyles'; export { default as withTheme, WithTheme } from './withTheme'; +export { default as muiStyled } from './muiStyled'; export { default as styled, ComponentCreator, StyledProps } from './styled'; export { createGenerateClassName, diff --git a/packages/material-ui/src/styles/index.js b/packages/material-ui/src/styles/index.js index 2fb7099da2caaf..8d0f9ef14407bc 100644 --- a/packages/material-ui/src/styles/index.js +++ b/packages/material-ui/src/styles/index.js @@ -10,6 +10,7 @@ export * from './transitions'; export { default as useTheme } from './useTheme'; export { default as withStyles } from './withStyles'; export { default as withTheme } from './withTheme'; +export { default as muiStyled } from './muiStyled'; export { createGenerateClassName, jssPreset, diff --git a/packages/material-ui/src/styles/muiStyled.d.ts b/packages/material-ui/src/styles/muiStyled.d.ts new file mode 100644 index 00000000000000..b5a49f0cfb7f2b --- /dev/null +++ b/packages/material-ui/src/styles/muiStyled.d.ts @@ -0,0 +1,8 @@ +/** + * Cutom styled functionality that support mui specific config. + * + * @param options Takes an incomplete theme object and adds the missing parts. + * @returns A complete, ready to use theme object. + */ +// TODO: fix typings +export default function adaptV4Theme(component: any, config: any, muiConfig: any): React.Component; diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js new file mode 100644 index 00000000000000..ae6d8a3e254bf8 --- /dev/null +++ b/packages/material-ui/src/styles/muiStyled.js @@ -0,0 +1,62 @@ +import styled from '@emotion/styled'; +import { propsToClassKey } from '@material-ui/styles' + +const getStyleOverrides = (name, theme) => { + let styleOverrides = {}; + + if ( + theme && + theme.components && + theme.components[name] && + theme.components[name].styleOverrides + ) { + styleOverrides = theme.components[name].styleOverrides; + } + + return styleOverrides; +}; + +const getVariantStyles = (name, theme) => { + let variants = []; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + variants = theme.components[name].variants; + } + + const variantsStyles = {}; + + variants.forEach((definition) => { + const key = propsToClassKey(definition.props); + variantsStyles[key] = definition.style; + }); + + return variantsStyles; +}; + +const muiStyled = (el, params, muiConfig) => { + const result = styled(el, params); + const muiFunc = (...params) => { + const newParams = params; + + newParams.unshift(props => { + const theme = props.theme || defaultTheme; + const name = muiConfig.muiName; + const variantsResolver = muiConfig.variantsResolver; + const variantsStylesByKeys = getVariantStyles(name, theme); + const result = variantsResolver(props, variantsStylesByKeys, theme, name); + return result; + }); + + newParams.unshift(props => { + const theme = props.theme || defaultTheme; + const name = muiConfig.muiName; + const overridesResolver = muiConfig.overridesResolver; + const styleOverridesByKeys = getStyleOverrides(name, theme); + return overridesResolver(props, styleOverridesByKeys, name); + }); + + return result(newParams); + } + return muiFunc; +} + +export default muiStyled; \ No newline at end of file From 4cdb02c2de4b47cdb824ed9442bac8932cffda66 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 9 Sep 2020 11:33:51 +0200 Subject: [PATCH 031/125] removed dependency + cleanup --- .../components/slider/ContinuousSlider.js | 12 +- .../components/slider/CustomizedSlider.js | 234 ++++++++---------- .../components/slider/CustomizedSlider.tsx | 232 ++++++++--------- packages/material-ui/package.json | 1 - packages/material-ui/src/Slider/Slider.d.ts | 15 +- packages/material-ui/src/Slider/Slider.js | 30 ++- packages/material-ui/src/Slider/SliderBase.js | 5 +- packages/material-ui/src/styles/muiStyled.js | 12 +- 8 files changed, 258 insertions(+), 283 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index d128a88a822061..6cde55f69dfc87 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -14,13 +14,12 @@ const useStyles = makeStyles({ }, }); - const componentOverrides = { Root: styled(SliderRoot)` background-color: pink; border-color: green; - ` -} + `, +}; export default function ContinuousSlider() { const classes = useStyles(); @@ -80,7 +79,12 @@ export default function ContinuousSlider() { Vertical primary slider - +
); diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index c7824cd9c4c62c..2bda386bb08fcb 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -1,12 +1,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useTheme, makeStyles } from '@material-ui/core/styles'; -import Slider, { - SliderRoot, -} from '@material-ui/core/Slider'; +import Slider from '@material-ui/core/Slider'; import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; +import { ThemeProvider } from 'emotion-theming'; const useStyles = makeStyles((theme) => ({ root: { @@ -51,131 +50,116 @@ const marks = [ }, ]; -const iosComponents = { - Root: styled(SliderRoot)({ - color: '#3880ff', - height: 2, - padding: '15px 0', - '& .MuiSlider-thumb': { - height: 28, - width: 28, - backgroundColor: '#fff', - // @ts-ignore - boxShadow: iOSBoxShadow, - marginTop: -14, - marginLeft: -14, - '&:focus, &:hover, &.Mui-active': { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, - }, +const IosSlider = styled(Slider)({ + color: '#3880ff', + height: 2, + padding: '15px 0', + '& .MuiSlider-thumb': { + height: 28, + width: 28, + backgroundColor: '#fff', + // @ts-ignore + boxShadow: iOSBoxShadow, + marginTop: -14, + marginLeft: -14, + '&:focus, &:hover, &.Mui-active': { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, }, }, - - '& .MuiSlider-valueLabel': { - left: 'calc(-50% + 12px)', - top: -22, - '& *': { - background: 'transparent', - color: '#000', - }, + }, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 12px)', + top: -22, + '& *': { + background: 'transparent', + color: '#000', }, - - '& .MuiSlider-track': { - height: 2, + }, + '& .MuiSlider-track': { + height: 2, + }, + '& .MuiSlider-rail': { + height: 2, + opacity: 0.5, + backgroundColor: '#bfbfbf', + }, + '& .MuiSlider-mark': { + backgroundColor: '#bfbfbf', + height: 8, + width: 1, + marginTop: -3, + '&.MuiSlider-markActive': { + opacity: 1, + backgroundColor: 'currentColor', }, - - '& .MuiSlider-rail': { - height: 2, - opacity: 0.5, - backgroundColor: '#bfbfbf', + }, +}); + +const PrettoSlider = styled(Slider)({ + color: '#52af77', + height: 8, + '& .MuiSlider-thumb': { + height: 24, + width: 24, + backgroundColor: '#fff', + border: '2px solid currentColor', + marginTop: -8, + marginLeft: -12, + '&:focus, &:hover, &.Mui-active': { + boxShadow: 'inherit', }, - - '& .MuiSlider-mark': { - backgroundColor: '#bfbfbf', - height: 8, - width: 1, - marginTop: -3, - '&.MuiSlider-markActive': { - opacity: 1, - backgroundColor: 'currentColor', - }, - } - }), -}; - -const prettoComponents = { - Root: styled(SliderRoot)({ - color: '#52af77', + }, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 4px)', + }, + '& .MuiSlider-track': { height: 8, - '& .MuiSlider-thumb': { - height: 24, - width: 24, - backgroundColor: '#fff', - border: '2px solid currentColor', - marginTop: -8, - marginLeft: -12, - '&:focus, &:hover, &.Mui-active': { - boxShadow: 'inherit', - }, - }, - '& .MuiSlider-valueLabel': { - left: 'calc(-50% + 4px)', + borderRadius: 4, + }, + '& .MuiSlider-rail': { + height: 8, + borderRadius: 4, + }, +}); + +const AirbnbSlider = styled(Slider)({ + color: '#3a8589', + height: 3, + padding: '13px 0', + '& .MuiSlider-thumb': { + height: 27, + width: 27, + backgroundColor: '#fff', + border: '1px solid currentColor', + marginTop: -12, + marginLeft: -13, + // @ts-ignore + boxShadow: '#ebebeb 0 2px 2px', + '&:focus, &:hover, &.Mui-active': { + boxShadow: '#ccc 0 2px 3px 1px', }, - - '& .MuiSlider-track': { - height: 8, - borderRadius: 4, + '& .bar': { + // display: inline-block !important; + height: 9, + width: 1, + backgroundColor: 'currentColor', + marginLeft: 1, + marginRight: 1, }, - - '& .MuiSlider-rail': { - height: 8, - borderRadius: 4, - } - }), -}; - -const airbnbComponents = { - Root: styled(SliderRoot)({ - color: '#3a8589', + }, + '& .MuiSlider-track': { height: 3, - padding: '13px 0', - - '& .MuiSlider-thumb': { - height: 27, - width: 27, - backgroundColor: '#fff', - border: '1px solid currentColor', - marginTop: -12, - marginLeft: -13, - // @ts-ignore - boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &.Mui-active': { - boxShadow: '#ccc 0 2px 3px 1px', - }, - '& .bar': { - // display: inline-block !important; - height: 9, - width: 1, - backgroundColor: 'currentColor', - marginLeft: 1, - marginRight: 1, - }, - }, - - '& .MuiSlider-track': { - height: 3, - }, - - '& .MuiSlider-rail': { - color: '#d8d8d8', - opacity: 1, - height: 3, - } - }), -}; + }, + '& .MuiSlider-rail': { + color: '#d8d8d8', + opacity: 1, + height: 3, + }, +}); function AirbnbThumbComponent(props) { return ( @@ -193,22 +177,21 @@ export default function CustomizedSlider() { const theme = useTheme(); return ( +
iOS -
pretto.fr -
Tooltip value label @@ -221,13 +204,14 @@ export default function CustomizedSlider() { />
Airbnb - index === 0 ? 'Minimum price' : 'Maximum price' } defaultValue={[20, 40]} />
+ ); } diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index 38e05997090a7e..be33c7a35de9f5 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -5,9 +5,7 @@ import { Theme, createStyles, } from '@material-ui/core/styles'; -import Slider, { - SliderRoot, -} from '@material-ui/core/Slider'; +import Slider from '@material-ui/core/Slider'; import styled from '@emotion/styled'; import Typography from '@material-ui/core/Typography'; import Tooltip from '@material-ui/core/Tooltip'; @@ -58,132 +56,125 @@ const marks = [ }, ]; -const iosComponents = { - Root: styled(SliderRoot)({ - color: '#3880ff', - height: 2, - padding: '15px 0', - '& .MuiSlider-thumb': { - height: 28, - width: 28, - backgroundColor: '#fff', - // @ts-ignore - boxShadow: iOSBoxShadow, - marginTop: -14, - marginLeft: -14, - '&:focus, &:hover, &.Mui-active': { - boxShadow: - '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: iOSBoxShadow, - }, - }, - }, - - '& .MuiSlider-valueLabel': { - left: 'calc(-50% + 12px)', - top: -22, - '& *': { - background: 'transparent', - color: '#000', +const IosSlider = styled(Slider)({ + color: '#3880ff', + height: 2, + padding: '15px 0', + '& .MuiSlider-thumb': { + height: 28, + width: 28, + backgroundColor: '#fff', + // @ts-ignore + boxShadow: iOSBoxShadow, + marginTop: -14, + marginLeft: -14, + '&:focus, &:hover, &.Mui-active': { + boxShadow: + '0 3px 1px rgba(0,0,0,0.1),0 4px 8px rgba(0,0,0,0.3),0 0 0 1px rgba(0,0,0,0.02)', + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: iOSBoxShadow, }, }, + }, - '& .MuiSlider-track': { - height: 2, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 12px)', + top: -22, + '& *': { + background: 'transparent', + color: '#000', }, + }, - '& .MuiSlider-rail': { - height: 2, - opacity: 0.5, - backgroundColor: '#bfbfbf', - }, + '& .MuiSlider-track': { + height: 2, + }, - '& .MuiSlider-mark': { - backgroundColor: '#bfbfbf', - height: 8, - width: 1, - marginTop: -3, - '&.MuiSlider-markActive': { - opacity: 1, - backgroundColor: 'currentColor', - }, - } - }), -}; + '& .MuiSlider-rail': { + height: 2, + opacity: 0.5, + backgroundColor: '#bfbfbf', + }, -const prettoComponents = { - Root: styled(SliderRoot)({ - color: '#52af77', + '& .MuiSlider-mark': { + backgroundColor: '#bfbfbf', height: 8, - '& .MuiSlider-thumb': { - height: 24, - width: 24, - backgroundColor: '#fff', - border: '2px solid currentColor', - marginTop: -8, - marginLeft: -12, - '&:focus, &:hover, &.Mui-active': { - boxShadow: 'inherit', - }, - }, - '& .MuiSlider-valueLabel': { - left: 'calc(-50% + 4px)', + width: 1, + marginTop: -3, + '&.MuiSlider-markActive': { + opacity: 1, + backgroundColor: 'currentColor', }, - - '& .MuiSlider-track': { - height: 8, - borderRadius: 4, + }, +}); + +const PrettoSlider = styled(Slider)({ + color: '#52af77', + height: 8, + '& .MuiSlider-thumb': { + height: 24, + width: 24, + backgroundColor: '#fff', + border: '2px solid currentColor', + marginTop: -8, + marginLeft: -12, + '&:focus, &:hover, &.Mui-active': { + boxShadow: 'inherit', }, + }, + '& .MuiSlider-valueLabel': { + left: 'calc(-50% + 4px)', + }, - '& .MuiSlider-rail': { - height: 8, - borderRadius: 4, - } - }), -}; + '& .MuiSlider-track': { + height: 8, + borderRadius: 4, + }, -const airbnbComponents = { - Root: styled(SliderRoot)({ - color: '#3a8589', - height: 3, - padding: '13px 0', - - '& .MuiSlider-thumb': { - height: 27, - width: 27, - backgroundColor: '#fff', - border: '1px solid currentColor', - marginTop: -12, - marginLeft: -13, - // @ts-ignore - boxShadow: '#ebebeb 0 2px 2px', - '&:focus, &:hover, &.Mui-active': { - boxShadow: '#ccc 0 2px 3px 1px', - }, - '& .bar': { - // display: inline-block !important; - height: 9, - width: 1, - backgroundColor: 'currentColor', - marginLeft: 1, - marginRight: 1, - }, + '& .MuiSlider-rail': { + height: 8, + borderRadius: 4, + }, +}); + +const AirbnbSlider = styled(Slider)({ + color: '#3a8589', + height: 3, + padding: '13px 0', + + '& .MuiSlider-thumb': { + height: 27, + width: 27, + backgroundColor: '#fff', + border: '1px solid currentColor', + marginTop: -12, + marginLeft: -13, + // @ts-ignore + boxShadow: '#ebebeb 0 2px 2px', + '&:focus, &:hover, &.Mui-active': { + boxShadow: '#ccc 0 2px 3px 1px', }, - - '& .MuiSlider-track': { - height: 3, + '& .bar': { + // display: inline-block !important; + height: 9, + width: 1, + backgroundColor: 'currentColor', + marginLeft: 1, + marginRight: 1, }, + }, - '& .MuiSlider-rail': { - color: '#d8d8d8', - opacity: 1, - height: 3, - } - }), -}; + '& .MuiSlider-track': { + height: 3, + }, + '& .MuiSlider-rail': { + color: '#d8d8d8', + opacity: 1, + height: 3, + }, +}); function AirbnbThumbComponent(props: any) { return ( @@ -203,20 +194,18 @@ export default function CustomizedSlider() {
iOS -
pretto.fr -
Tooltip value label @@ -229,13 +218,8 @@ export default function CustomizedSlider() { />
Airbnb - index === 0 ? 'Minimum price' : 'Maximum price' } diff --git a/packages/material-ui/package.json b/packages/material-ui/package.json index 08d0ddb4ec7065..5715943c27d172 100644 --- a/packages/material-ui/package.json +++ b/packages/material-ui/package.json @@ -42,7 +42,6 @@ "@emotion/core": "^10.0.27", "@emotion/styled": "^10.0.27", "@types/react": "^16.8.6", - "emotion": "^10.0.27", "emotion-theming": "^10.0.27", "react": "^16.8.0", "react-dom": "^16.8.0" diff --git a/packages/material-ui/src/Slider/Slider.d.ts b/packages/material-ui/src/Slider/Slider.d.ts index 7d798fecaffc78..98db442971517b 100644 --- a/packages/material-ui/src/Slider/Slider.d.ts +++ b/packages/material-ui/src/Slider/Slider.d.ts @@ -94,9 +94,18 @@ export interface SliderTypeMap

{ * The props used for each slot inside the Slider. */ componentsProps?: { - root?: { state?: Omit['props'], 'components' | 'componentsProps'>; as: React.ElementType }; - track?: { state?: Omit['props'], 'components' | 'componentsProps'>; as?: React.ElementType; }; - rail?: { state?: Omit['props'], 'components' | 'componentsProps'>; as?: React.ElementType; }; + root?: { + state?: Omit['props'], 'components' | 'componentsProps'>; + as: React.ElementType; + }; + track?: { + state?: Omit['props'], 'components' | 'componentsProps'>; + as?: React.ElementType; + }; + rail?: { + state?: Omit['props'], 'components' | 'componentsProps'>; + as?: React.ElementType; + }; thumb?: { state?: Omit['props'], 'components' | 'componentsProps'> & { active?: boolean; diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 6a4ae926a2cfcd..88f7d366603b42 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -51,7 +51,7 @@ const overridesResolver = (props, styles, name) => { }; return styleOverrides; -} +}; const variantsResolver = (props, styles, theme, name) => { const { state = {} } = props; @@ -66,7 +66,7 @@ const variantsResolver = (props, styles, theme, name) => { } }); if (isMatch) { - variantsStyles = {...variantsStyles, ...styles[propsToClassKey(themeVariant.props)]}; + variantsStyles = { ...variantsStyles, ...styles[propsToClassKey(themeVariant.props)] }; } }); } @@ -74,7 +74,11 @@ const variantsResolver = (props, styles, theme, name) => { return variantsStyles; }; -export const SliderRoot = muiStyled('div', { shouldForwardProp }, { muiName: 'MuiSlider', overridesResolver, variantsResolver })((props) => { +export const SliderRoot = muiStyled( + 'div', + { shouldForwardProp }, + { muiName: 'MuiSlider', overridesResolver, variantsResolver }, +)((props) => { return { height: 2, width: '100%', @@ -266,16 +270,12 @@ export const SliderRoot = muiStyled('div', { shouldForwardProp }, { muiName: 'Mu }, '&.MuiSlider-markLabelActive': { color: props.theme.palette.text.primary, - } - } + }, + }, }; }); -const getComponentProps = ( - components, - componentsProps, - name, -) => { +const getComponentProps = (components, componentsProps, name) => { const slotProps = componentsProps[name] || {}; return { as: components[name], @@ -305,21 +305,19 @@ const useThemeProps = (inputProps, ref, name) => { const Slider = React.forwardRef(function Slider(inputProps, inputRef) { const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); const { components = {}, componentsProps = {}, ref, ...other } = props; - return + ); }); export default Slider; diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index b8b4b170de1695..bd3d9d2ff71db3 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -606,10 +606,7 @@ const Slider = React.forwardRef(function Slider(props, ref) { {...other} className={clsx(utilityClasses.root, rootProps.className, className)} > - + { let styleOverrides = {}; @@ -37,7 +37,7 @@ const muiStyled = (el, params, muiConfig) => { const muiFunc = (...params) => { const newParams = params; - newParams.unshift(props => { + newParams.unshift((props) => { const theme = props.theme || defaultTheme; const name = muiConfig.muiName; const variantsResolver = muiConfig.variantsResolver; @@ -46,7 +46,7 @@ const muiStyled = (el, params, muiConfig) => { return result; }); - newParams.unshift(props => { + newParams.unshift((props) => { const theme = props.theme || defaultTheme; const name = muiConfig.muiName; const overridesResolver = muiConfig.overridesResolver; @@ -55,8 +55,8 @@ const muiStyled = (el, params, muiConfig) => { }); return result(newParams); - } + }; return muiFunc; -} +}; -export default muiStyled; \ No newline at end of file +export default muiStyled; From 551e2f929c5720f510933ea558798615204fd8e7 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 9 Sep 2020 12:03:49 +0200 Subject: [PATCH 032/125] cleanups --- .../components/slider/ContinuousSlider.js | 16 ++++----- .../components/slider/ContinuousSlider.tsx | 11 ++++++ packages/material-ui/src/styles/muiStyled.js | 36 +++++++++---------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/docs/src/pages/components/slider/ContinuousSlider.js b/docs/src/pages/components/slider/ContinuousSlider.js index 6cde55f69dfc87..3056c6ff9dcd6c 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.js +++ b/docs/src/pages/components/slider/ContinuousSlider.js @@ -2,7 +2,7 @@ import * as React from 'react'; import { makeStyles } from '@material-ui/core/styles'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import Slider, { SliderRoot } from '@material-ui/core/Slider'; +import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; import { ThemeProvider } from '@material-ui/styles'; @@ -14,12 +14,10 @@ const useStyles = makeStyles({ }, }); -const componentOverrides = { - Root: styled(SliderRoot)` - background-color: pink; - border-color: green; - `, -}; +const CustomSlider = styled(Slider)` + background-color: pink; + border-color: green; +`; export default function ContinuousSlider() { const classes = useStyles(); @@ -79,11 +77,11 @@ export default function ContinuousSlider() { Vertical primary slider - +

diff --git a/docs/src/pages/components/slider/ContinuousSlider.tsx b/docs/src/pages/components/slider/ContinuousSlider.tsx index 26731c48af848a..72b8a94018dfef 100644 --- a/docs/src/pages/components/slider/ContinuousSlider.tsx +++ b/docs/src/pages/components/slider/ContinuousSlider.tsx @@ -6,6 +6,7 @@ import Slider from '@material-ui/core/Slider'; import VolumeDown from '@material-ui/icons/VolumeDown'; import VolumeUp from '@material-ui/icons/VolumeUp'; import { ThemeProvider } from '@material-ui/styles'; +import styled from '@emotion/styled'; const useStyles = makeStyles({ root: { @@ -13,6 +14,11 @@ const useStyles = makeStyles({ }, }); +const CustomSlider = styled(Slider)` + background-color: pink; + border-color: green; +`; + export default function ContinuousSlider() { const classes = useStyles(); const [value, setValue] = React.useState(30); @@ -75,6 +81,11 @@ export default function ContinuousSlider() { Vertical primary slider +
); diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index 72df55a3cdd18d..4b198933d225ae 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -35,26 +35,22 @@ const getVariantStyles = (name, theme) => { const muiStyled = (el, params, muiConfig) => { const result = styled(el, params); const muiFunc = (...params) => { - const newParams = params; - - newParams.unshift((props) => { - const theme = props.theme || defaultTheme; - const name = muiConfig.muiName; - const variantsResolver = muiConfig.variantsResolver; - const variantsStylesByKeys = getVariantStyles(name, theme); - const result = variantsResolver(props, variantsStylesByKeys, theme, name); - return result; - }); - - newParams.unshift((props) => { - const theme = props.theme || defaultTheme; - const name = muiConfig.muiName; - const overridesResolver = muiConfig.overridesResolver; - const styleOverridesByKeys = getStyleOverrides(name, theme); - return overridesResolver(props, styleOverridesByKeys, name); - }); - - return result(newParams); + const theme = props.theme || defaultTheme; + const name = muiConfig.muiName; + + if (muiConfig.overridesResolver) { + params.push((props) => + muiConfig.overridesResolver(props, getStyleOverrides(name, theme), name), + ); + } + + if (muiConfig.variantsResolver) { + params.push((props) => + muiConfig.variantsResolver(props, getVariantStyles(name, theme), theme, name), + ); + } + + return result(params); }; return muiFunc; }; From bb0e95955006a698a95b6141a4b7a5d101675dd5 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 9 Sep 2020 13:16:17 +0200 Subject: [PATCH 033/125] refactors --- packages/material-ui/src/styles/muiStyled.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index 4b198933d225ae..ab3d38b1a52ac0 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -35,19 +35,20 @@ const getVariantStyles = (name, theme) => { const muiStyled = (el, params, muiConfig) => { const result = styled(el, params); const muiFunc = (...params) => { - const theme = props.theme || defaultTheme; const name = muiConfig.muiName; if (muiConfig.overridesResolver) { - params.push((props) => - muiConfig.overridesResolver(props, getStyleOverrides(name, theme), name), - ); + params.push((props) => { + const theme = props.theme || defaultTheme; + return muiConfig.overridesResolver(props, getStyleOverrides(name, theme), name); + }); } if (muiConfig.variantsResolver) { - params.push((props) => - muiConfig.variantsResolver(props, getVariantStyles(name, theme), theme, name), - ); + params.push((props) => { + const theme = props.theme || defaultTheme; + return muiConfig.variantsResolver(props, getVariantStyles(name, theme), theme, name); + }); } return result(params); From 0fbd75e34d565d988d3897d2f53c5a0e5908105a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 10 Sep 2020 14:01:09 +0200 Subject: [PATCH 034/125] refactors and comments addressed --- packages/material-ui/src/Slider/Slider.js | 30 ++++--------------- .../material-ui/src/styles/useThemeProps.d.ts | 15 ++++++++++ .../material-ui/src/styles/useThemeProps.js | 20 +++++++++++++ 3 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 packages/material-ui/src/styles/useThemeProps.d.ts create mode 100644 packages/material-ui/src/styles/useThemeProps.js diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index 88f7d366603b42..dcb39448e6b512 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -1,6 +1,6 @@ import * as React from 'react'; -import { getThemeProps, propsToClassKey } from '@material-ui/styles'; -import useTheme from '../styles/useTheme'; +import { propsToClassKey } from '@material-ui/styles'; +import useThemeProps from '../styles/useThemeProps'; import { fade, lighten, darken } from '../styles/colorManipulator'; import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; @@ -12,7 +12,6 @@ const shouldForwardProp = (prop) => prop !== 'state' && prop != 'as'; const overridesResolver = (props, styles, name) => { const { color = 'primary', - disabled = false, marks: marksProp = false, max = 100, min = 0, @@ -283,28 +282,9 @@ const getComponentProps = (components, componentsProps, name) => { }; }; -const useThemeProps = (inputProps, ref, name) => { - const props = Object.assign({}, inputProps); - const { innerRef } = props; - - const contextTheme = useTheme() || defaultTheme; - - const more = getThemeProps({ theme: contextTheme, name, props }); - - const theme = more.theme || contextTheme; - const isRtl = theme.direction === 'rtl'; - - return { - ref: innerRef || ref, - theme, - isRtl, - ...more, - }; -}; - -const Slider = React.forwardRef(function Slider(inputProps, inputRef) { - const props = useThemeProps(inputProps, inputRef, 'MuiSlider'); - const { components = {}, componentsProps = {}, ref, ...other } = props; +const Slider = React.forwardRef(function Slider(inputProps, ref) { + const props = useThemeProps({ props: inputProps, name: 'MuiSlider' }); + const { components = {}, componentsProps = {}, ...other } = props; return ( { + components?: { [K in keyof Components]: { defaultProps?: Partial } }; +} + +type ThemedProps = Theme extends { + components: Record; +} + ? Props + : {}; + +export default function useThemeProps< + Theme extends ThemeWithProps, + Props, + Name extends keyof any +>(params: { props: Props; name: Name; }): Props & ThemedProps; diff --git a/packages/material-ui/src/styles/useThemeProps.js b/packages/material-ui/src/styles/useThemeProps.js new file mode 100644 index 00000000000000..3a204d062ee78b --- /dev/null +++ b/packages/material-ui/src/styles/useThemeProps.js @@ -0,0 +1,20 @@ +import useTheme from './useTheme'; +import { getThemeProps } from '@material-ui/styles'; +import defaultTheme from './defaultTheme'; + +export default function useThemeProps({ props: inputProps, name }) { + const props = Object.assign({}, inputProps); + + const contextTheme = useTheme() || defaultTheme; + + const more = getThemeProps({ theme: contextTheme, name, props }); + + const theme = more.theme || contextTheme; + const isRtl = theme.direction === 'rtl'; + + return { + theme, + isRtl, + ...more, + }; +}; \ No newline at end of file From 1da5ffe9cb21311c66546b5db083c08fabebccd4 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 10 Sep 2020 17:07:45 +0200 Subject: [PATCH 035/125] extracted muiStyled default params --- packages/material-ui/src/Slider/Slider.js | 5 +---- packages/material-ui/src/styles/muiStyled.js | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index dcb39448e6b512..7087170000936b 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -4,11 +4,8 @@ import useThemeProps from '../styles/useThemeProps'; import { fade, lighten, darken } from '../styles/colorManipulator'; import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; -import defaultTheme from '../styles/defaultTheme'; import muiStyled from '../styles/muiStyled'; -const shouldForwardProp = (prop) => prop !== 'state' && prop != 'as'; - const overridesResolver = (props, styles, name) => { const { color = 'primary', @@ -75,7 +72,7 @@ const variantsResolver = (props, styles, theme, name) => { export const SliderRoot = muiStyled( 'div', - { shouldForwardProp }, + {}, { muiName: 'MuiSlider', overridesResolver, variantsResolver }, )((props) => { return { diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index ab3d38b1a52ac0..24249e1936b75f 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -32,8 +32,10 @@ const getVariantStyles = (name, theme) => { return variantsStyles; }; +const shouldForwardProp = (prop) => prop !== 'state' && prop !== 'theme'; + const muiStyled = (el, params, muiConfig) => { - const result = styled(el, params); + const result = styled(el, { shouldForwardProp, ...params }); const muiFunc = (...params) => { const name = muiConfig.muiName; From d249d8367260903bae2193872465befb453ed124 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 11 Sep 2020 13:40:16 +0200 Subject: [PATCH 036/125] prettier + fixes --- packages/material-ui/src/Slider/Slider.js | 1 + packages/material-ui/src/styles/useThemeProps.d.ts | 2 +- packages/material-ui/src/styles/useThemeProps.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index b28b4b7e686b6d..acb9efcf9cf198 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -284,6 +284,7 @@ const Slider = React.forwardRef(function Slider(inputProps, ref) { ...components, }} componentsProps={{ + ...componentsProps, root: getComponentProps(components, componentsProps, 'root'), }} ref={ref} diff --git a/packages/material-ui/src/styles/useThemeProps.d.ts b/packages/material-ui/src/styles/useThemeProps.d.ts index 3326c8b117818d..8e3d653ea86826 100644 --- a/packages/material-ui/src/styles/useThemeProps.d.ts +++ b/packages/material-ui/src/styles/useThemeProps.d.ts @@ -12,4 +12,4 @@ export default function useThemeProps< Theme extends ThemeWithProps, Props, Name extends keyof any ->(params: { props: Props; name: Name; }): Props & ThemedProps; +>(params: { props: Props; name: Name }): Props & ThemedProps; diff --git a/packages/material-ui/src/styles/useThemeProps.js b/packages/material-ui/src/styles/useThemeProps.js index 3a204d062ee78b..89bb9b9a26e4a1 100644 --- a/packages/material-ui/src/styles/useThemeProps.js +++ b/packages/material-ui/src/styles/useThemeProps.js @@ -17,4 +17,4 @@ export default function useThemeProps({ props: inputProps, name }) { isRtl, ...more, }; -}; \ No newline at end of file +} From 47911ac01bda312e7be2a28112e9f99095afac43 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 14 Sep 2020 14:11:26 +0200 Subject: [PATCH 037/125] added @material-ui/styled --- docs/babel.config.js | 1 + docs/package.json | 1 + packages/material-ui-styled/README.md | 1 + packages/material-ui-styled/package.json | 49 ++++++++++++++++++++ packages/material-ui-styled/src/index.d.ts | 4 ++ packages/material-ui-styled/src/index.js | 4 ++ packages/material-ui-styled/src/styled.d.ts | 3 ++ packages/material-ui-styled/src/styled.js | 3 ++ packages/material-ui-styled/tsconfig.json | 4 ++ packages/material-ui/src/styles/muiStyled.js | 2 +- 10 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 packages/material-ui-styled/README.md create mode 100644 packages/material-ui-styled/package.json create mode 100644 packages/material-ui-styled/src/index.d.ts create mode 100644 packages/material-ui-styled/src/index.js create mode 100644 packages/material-ui-styled/src/styled.d.ts create mode 100644 packages/material-ui-styled/src/styled.js create mode 100644 packages/material-ui-styled/tsconfig.json diff --git a/docs/babel.config.js b/docs/babel.config.js index 5b3c1a4a066b8c..ddabe769da2601 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -19,6 +19,7 @@ const alias = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', + '@material-ui/styled': '@emotion/styled', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', docs: './', diff --git a/docs/package.json b/docs/package.json index f8e7c53a71a70e..460c8b8d06d4da 100644 --- a/docs/package.json +++ b/docs/package.json @@ -33,6 +33,7 @@ "@material-ui/lab": "^5.0.0-alpha.1", "@material-ui/pickers": "^4.0.0-alpha.11", "@material-ui/styles": "^5.0.0-alpha.1", + "@material-ui/styled": "^5.0.0-alpha.1", "@material-ui/system": "^5.0.0-alpha.1", "@material-ui/types": "^5.0.0", "@trendmicro/react-interpolate": "^0.5.5", diff --git a/packages/material-ui-styled/README.md b/packages/material-ui-styled/README.md new file mode 100644 index 00000000000000..282917cff1ceef --- /dev/null +++ b/packages/material-ui-styled/README.md @@ -0,0 +1 @@ +# @material-ui/styled diff --git a/packages/material-ui-styled/package.json b/packages/material-ui-styled/package.json new file mode 100644 index 00000000000000..e67e15d8e50144 --- /dev/null +++ b/packages/material-ui-styled/package.json @@ -0,0 +1,49 @@ +{ + "name": "@material-ui/styled", + "version": "5.0.0-alpha.8", + "private": false, + "author": "Material-UI Team", + "description": "Material-UI Styled - Wrapper package for styled utility.", + "main": "./src/index.js", + "keywords": [ + "react", + "react-component", + "material design", + "material-ui", + "styled" + ], + "repository": { + "type": "git", + "url": "https://github.com/mui-org/material-ui.git", + "directory": "packages/material-ui-styled" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/mui-org/material-ui/issues" + }, + "homepage": "https://material-ui.com/styled/basics/", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "scripts": { + "build": "yarn build:cjs && yarn build:esm && yarn build:es && yarn build:copy-files", + "build:cjs": "node ../../scripts/build cjs", + "build:esm": "node ../../scripts/build esm", + "build:es": "node ../../scripts/build es", + "build:copy-files": "node ../../scripts/copy-files.js", + "prebuild": "rimraf build", + "release": "yarn build && npm publish build --tag next", + "test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/material-ui-styles/**/*.test.{js,ts,tsx}' --exclude '**/node_modules/**'", + "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json" + }, + "dependencies": { + }, + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=8.0.0" + } +} diff --git a/packages/material-ui-styled/src/index.d.ts b/packages/material-ui-styled/src/index.d.ts new file mode 100644 index 00000000000000..e6843aae94605b --- /dev/null +++ b/packages/material-ui-styled/src/index.d.ts @@ -0,0 +1,4 @@ +import styled from './styled'; +export * from './styled'; + +export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled/src/index.js b/packages/material-ui-styled/src/index.js new file mode 100644 index 00000000000000..e6843aae94605b --- /dev/null +++ b/packages/material-ui-styled/src/index.js @@ -0,0 +1,4 @@ +import styled from './styled'; +export * from './styled'; + +export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled/src/styled.d.ts b/packages/material-ui-styled/src/styled.d.ts new file mode 100644 index 00000000000000..87b79ead56126b --- /dev/null +++ b/packages/material-ui-styled/src/styled.d.ts @@ -0,0 +1,3 @@ +declare function styled(params: any): (styles: any) => any; + +export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled/src/styled.js b/packages/material-ui-styled/src/styled.js new file mode 100644 index 00000000000000..f4bbf52cbbe090 --- /dev/null +++ b/packages/material-ui-styled/src/styled.js @@ -0,0 +1,3 @@ +const styled = () => () => null; + +export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled/tsconfig.json b/packages/material-ui-styled/tsconfig.json new file mode 100644 index 00000000000000..57220954971e1e --- /dev/null +++ b/packages/material-ui-styled/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig", + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index 24249e1936b75f..2e25fa3946b403 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import styled from '@material-ui/styled'; import { propsToClassKey } from '@material-ui/styles'; const getStyleOverrides = (name, theme) => { From 4f71ad6309cd14fc46e1e91fd54d3dd83ff4e98a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 14 Sep 2020 16:13:47 +0200 Subject: [PATCH 038/125] renamed package --- docs/babel.config.js | 2 +- docs/package.json | 2 +- packages/material-ui-styled-engine/README.md | 1 + .../package.json | 2 +- .../src/index.d.ts | 0 .../src/index.js | 0 .../src/styled.d.ts | 0 .../src/styled.js | 0 .../tsconfig.json | 0 packages/material-ui-styled/README.md | 1 - packages/material-ui/src/styles/muiStyled.js | 2 +- 11 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 packages/material-ui-styled-engine/README.md rename packages/{material-ui-styled => material-ui-styled-engine}/package.json (97%) rename packages/{material-ui-styled => material-ui-styled-engine}/src/index.d.ts (100%) rename packages/{material-ui-styled => material-ui-styled-engine}/src/index.js (100%) rename packages/{material-ui-styled => material-ui-styled-engine}/src/styled.d.ts (100%) rename packages/{material-ui-styled => material-ui-styled-engine}/src/styled.js (100%) rename packages/{material-ui-styled => material-ui-styled-engine}/tsconfig.json (100%) delete mode 100644 packages/material-ui-styled/README.md diff --git a/docs/babel.config.js b/docs/babel.config.js index ddabe769da2601..539629c95a2e72 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -19,7 +19,7 @@ const alias = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', - '@material-ui/styled': '@emotion/styled', + '@material-ui/styled-engine': '@emotion/styled', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', docs: './', diff --git a/docs/package.json b/docs/package.json index 460c8b8d06d4da..93df717fee0126 100644 --- a/docs/package.json +++ b/docs/package.json @@ -33,7 +33,7 @@ "@material-ui/lab": "^5.0.0-alpha.1", "@material-ui/pickers": "^4.0.0-alpha.11", "@material-ui/styles": "^5.0.0-alpha.1", - "@material-ui/styled": "^5.0.0-alpha.1", + "@material-ui/styled-engine": "^5.0.0-alpha.1", "@material-ui/system": "^5.0.0-alpha.1", "@material-ui/types": "^5.0.0", "@trendmicro/react-interpolate": "^0.5.5", diff --git a/packages/material-ui-styled-engine/README.md b/packages/material-ui-styled-engine/README.md new file mode 100644 index 00000000000000..98650f0745314b --- /dev/null +++ b/packages/material-ui-styled-engine/README.md @@ -0,0 +1 @@ +# @material-ui/styled-engine diff --git a/packages/material-ui-styled/package.json b/packages/material-ui-styled-engine/package.json similarity index 97% rename from packages/material-ui-styled/package.json rename to packages/material-ui-styled-engine/package.json index e67e15d8e50144..d0402fda319e38 100644 --- a/packages/material-ui-styled/package.json +++ b/packages/material-ui-styled-engine/package.json @@ -1,5 +1,5 @@ { - "name": "@material-ui/styled", + "name": "@material-ui/styled-engine", "version": "5.0.0-alpha.8", "private": false, "author": "Material-UI Team", diff --git a/packages/material-ui-styled/src/index.d.ts b/packages/material-ui-styled-engine/src/index.d.ts similarity index 100% rename from packages/material-ui-styled/src/index.d.ts rename to packages/material-ui-styled-engine/src/index.d.ts diff --git a/packages/material-ui-styled/src/index.js b/packages/material-ui-styled-engine/src/index.js similarity index 100% rename from packages/material-ui-styled/src/index.js rename to packages/material-ui-styled-engine/src/index.js diff --git a/packages/material-ui-styled/src/styled.d.ts b/packages/material-ui-styled-engine/src/styled.d.ts similarity index 100% rename from packages/material-ui-styled/src/styled.d.ts rename to packages/material-ui-styled-engine/src/styled.d.ts diff --git a/packages/material-ui-styled/src/styled.js b/packages/material-ui-styled-engine/src/styled.js similarity index 100% rename from packages/material-ui-styled/src/styled.js rename to packages/material-ui-styled-engine/src/styled.js diff --git a/packages/material-ui-styled/tsconfig.json b/packages/material-ui-styled-engine/tsconfig.json similarity index 100% rename from packages/material-ui-styled/tsconfig.json rename to packages/material-ui-styled-engine/tsconfig.json diff --git a/packages/material-ui-styled/README.md b/packages/material-ui-styled/README.md deleted file mode 100644 index 282917cff1ceef..00000000000000 --- a/packages/material-ui-styled/README.md +++ /dev/null @@ -1 +0,0 @@ -# @material-ui/styled diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index 2e25fa3946b403..30954d39e070f9 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -1,4 +1,4 @@ -import styled from '@material-ui/styled'; +import styled from '@material-ui/styled-engine'; import { propsToClassKey } from '@material-ui/styles'; const getStyleOverrides = (name, theme) => { From 983f4474bb558fb168172793a4f9157a9eea8b14 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 09:22:09 +0200 Subject: [PATCH 039/125] merge conflicts --- packages/material-ui/src/Slider/SliderBase.js | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index bd3d9d2ff71db3..a10b9ec3327a6d 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -199,12 +199,9 @@ const Slider = React.forwardRef(function Slider(props, ref) { value: valueProp, valueLabelDisplay = 'off', valueLabelFormat = Identity, - isRtl = false, - components = {}, - componentsProps = {}, ...other } = props; - + const theme = useTheme(); const touchId = React.useRef(); // We can't use the :active browser pseudo-classes. // - The active state isn't triggered when clicking on the rail. @@ -218,6 +215,22 @@ const Slider = React.forwardRef(function Slider(props, ref) { name: 'Slider', }); + const handleChange = + onChange && + ((event, value) => { + if (!(event instanceof Event)) event.persist(); + + // Redefine target to allow name and value to be read. + // This allows seamless integration with the most popular form libraries. + // https://github.com/mui-org/material-ui/issues/13485#issuecomment-676048492 + Object.defineProperty(event, 'target', { + writable: true, + value: { value, name }, + }); + + onChange(event, value); + }); + const range = Array.isArray(valueDerived); let values = range ? valueDerived.slice().sort(asc) : [valueDerived]; values = values.map((value) => clamp(value, min, max)); @@ -349,8 +362,8 @@ const Slider = React.forwardRef(function Slider(props, ref) { setValueState(newValue); setFocusVisible(index); - if (onChange) { - onChange(event, newValue); + if (handleChange) { + handleChange(event, newValue); } if (onChangeCommitted) { onChangeCommitted(event, newValue); @@ -436,8 +449,8 @@ const Slider = React.forwardRef(function Slider(props, ref) { focusThumb({ sliderRef, activeIndex, setActive }); setValueState(newValue); - if (onChange) { - onChange(nativeEvent, newValue); + if (handleChange) { + handleChange(nativeEvent, newValue); } }); @@ -485,8 +498,8 @@ const Slider = React.forwardRef(function Slider(props, ref) { setValueState(newValue); - if (onChange) { - onChange(event, newValue); + if (handleChange) { + handleChange(event, newValue); } const doc = ownerDocument(sliderRef.current); @@ -536,8 +549,8 @@ const Slider = React.forwardRef(function Slider(props, ref) { setValueState(newValue); - if (onChange) { - onChange(event, newValue); + if (handleChange) { + handleChange(event, newValue); } const doc = ownerDocument(sliderRef.current); From bd51f798ed0fac88b98692411f575357e875d431 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 10:13:20 +0200 Subject: [PATCH 040/125] fixed after merge --- packages/material-ui/src/Slider/SliderBase.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/material-ui/src/Slider/SliderBase.js b/packages/material-ui/src/Slider/SliderBase.js index a10b9ec3327a6d..96e03d5c09dd6b 100644 --- a/packages/material-ui/src/Slider/SliderBase.js +++ b/packages/material-ui/src/Slider/SliderBase.js @@ -199,9 +199,12 @@ const Slider = React.forwardRef(function Slider(props, ref) { value: valueProp, valueLabelDisplay = 'off', valueLabelFormat = Identity, + isRtl = false, + components = {}, + componentsProps = {}, ...other } = props; - const theme = useTheme(); + const touchId = React.useRef(); // We can't use the :active browser pseudo-classes. // - The active state isn't triggered when clicking on the rail. From 5a42c9f325c9620deb45e495c1e5f135d5eb02af Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 10:29:18 +0200 Subject: [PATCH 041/125] cleanup --- docs/src/pages/components/slider/CustomizedSlider.js | 2 -- docs/src/pages/components/slider/CustomizedSlider.tsx | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/src/pages/components/slider/CustomizedSlider.js b/docs/src/pages/components/slider/CustomizedSlider.js index 0c011e995eb086..74fcf752e0bc37 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.js +++ b/docs/src/pages/components/slider/CustomizedSlider.js @@ -58,7 +58,6 @@ const IosSlider = styled(Slider)({ height: 28, width: 28, backgroundColor: '#fff', - // @ts-ignore boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, @@ -137,7 +136,6 @@ const AirbnbSlider = styled(Slider)({ border: '1px solid currentColor', marginTop: -12, marginLeft: -13, - // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', '&:focus, &:hover, &.Mui-active': { boxShadow: '#ccc 0 2px 3px 1px', diff --git a/docs/src/pages/components/slider/CustomizedSlider.tsx b/docs/src/pages/components/slider/CustomizedSlider.tsx index e9871dd4dfb41d..cab7ab041f6c1f 100644 --- a/docs/src/pages/components/slider/CustomizedSlider.tsx +++ b/docs/src/pages/components/slider/CustomizedSlider.tsx @@ -64,7 +64,6 @@ const IosSlider = styled(Slider)({ height: 28, width: 28, backgroundColor: '#fff', - // @ts-ignore boxShadow: iOSBoxShadow, marginTop: -14, marginLeft: -14, @@ -150,7 +149,6 @@ const AirbnbSlider = styled(Slider)({ border: '1px solid currentColor', marginTop: -12, marginLeft: -13, - // @ts-ignore boxShadow: '#ebebeb 0 2px 2px', '&:focus, &:hover, &.Mui-active': { boxShadow: '#ccc 0 2px 3px 1px', From 396cee890c8435a351e8d128fe93ea0b9850a847 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 11:44:13 +0200 Subject: [PATCH 042/125] implemented rtl on the docs --- docs/package.json | 2 + docs/pages/_app.js | 35 ++++++-- docs/pages/guides/right-to-left-v5.js | 20 +++++ docs/src/modules/components/AppFrame.js | 4 + docs/src/modules/utils/RtlContext.js | 8 ++ .../guides/right-to-left-v5/Direction.js | 18 +++++ .../guides/right-to-left-v5/Direction.tsx | 18 +++++ .../guides/right-to-left-v5/RtlOptOut.js | 28 +++++++ .../guides/right-to-left-v5/RtlOptOut.tsx | 40 +++++++++ .../right-to-left-v5/right-to-left-v5.md | 81 +++++++++++++++++++ packages/material-ui-styles/package.json | 5 +- .../src/ThemeProvider/ThemeProvider.js | 25 +----- 12 files changed, 251 insertions(+), 33 deletions(-) create mode 100644 docs/pages/guides/right-to-left-v5.js create mode 100644 docs/src/modules/utils/RtlContext.js create mode 100644 docs/src/pages/guides/right-to-left-v5/Direction.js create mode 100644 docs/src/pages/guides/right-to-left-v5/Direction.tsx create mode 100644 docs/src/pages/guides/right-to-left-v5/RtlOptOut.js create mode 100644 docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx create mode 100644 docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md diff --git a/docs/package.json b/docs/package.json index 8dc56140c824a0..5748b82d1c050f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,6 +22,7 @@ "@babel/plugin-transform-object-assign": "^7.10.1", "@babel/runtime-corejs2": "^7.10.2", "@date-io/core": "^1.3.9", + "@emotion/cache": "^10.0.27", "@emotion/core": "^10.0.27", "@emotion/styled": "^10.0.27", "@fortawesome/fontawesome-svg-core": "^1.2.30", @@ -112,6 +113,7 @@ "redux-logger": "^3.0.6", "rimraf": "^3.0.0", "styled-components": "^5.0.0", + "stylis-plugin-rtl": "^1.0.0", "webfontloader": "^1.6.28", "webpack": "^4.41.0", "webpack-bundle-analyzer": "^3.5.1" diff --git a/docs/pages/_app.js b/docs/pages/_app.js index afb3aa4578fbdb..d0048a46fa992d 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -9,6 +9,9 @@ import PropTypes from 'prop-types'; import acceptLanguage from 'accept-language'; import { create } from 'jss'; import rtl from 'jss-rtl'; +import { CacheProvider } from '@emotion/core'; +import createCache from '@emotion/cache'; +import rtlPlugin from 'stylis-plugin-rtl'; import { useRouter } from 'next/router'; import { StylesProvider, jssPreset } from '@material-ui/styles'; import pages from 'docs/src/pages'; @@ -16,6 +19,7 @@ import initRedux from 'docs/src/modules/redux/initRedux'; import PageContext from 'docs/src/modules/components/PageContext'; import GoogleAnalytics from 'docs/src/modules/components/GoogleAnalytics'; import loadScript from 'docs/src/modules/utils/loadScript'; +import RtlContext from 'docs/src/modules/utils/RtlContext'; import { ThemeProvider } from 'docs/src/modules/components/ThemeContext'; import { pathnameToLanguage, getCookie } from 'docs/src/modules/utils/helpers'; import { ACTION_TYPES, CODE_VARIANTS } from 'docs/src/modules/constants'; @@ -275,6 +279,20 @@ function findActivePage(currentPages, pathname) { return activePage; } +// Cache for the ltr version of the styles +const cacheLtr = createCache({ + key: 'mui', + stylisPlugins: [], + speedy: true, +}); + +// Cache for the rtl version of the styles +const cacheRtl = createCache({ + key: 'muirtl', + stylisPlugins: [rtlPlugin], + speedy: true, +}); + function AppWrapper(props) { const { children, pageProps } = props; @@ -283,6 +301,9 @@ function AppWrapper(props) { initRedux({ options: { userLanguage: pageProps.userLanguage } }), ); + const [setl, setRtl] = React.useState(false); + const rtlContextValue = { rtl, setRtl }; + React.useEffect(() => { loadDependencies(); registerServiceWorker(); @@ -311,11 +332,15 @@ function AppWrapper(props) { ))} - - - {children} - - + + + + + {children} + + + + diff --git a/docs/pages/guides/right-to-left-v5.js b/docs/pages/guides/right-to-left-v5.js new file mode 100644 index 00000000000000..975c17055ddba6 --- /dev/null +++ b/docs/pages/guides/right-to-left-v5.js @@ -0,0 +1,20 @@ +import React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; + +const pageFilename = 'guides/right-to-left-v5'; +const requireDemo = require.context('docs/src/pages/guides/right-to-left-v5', false, /\.(js|tsx)$/); +const requireRaw = require.context( + '!raw-loader!../../src/pages/guides/right-to-left-v5', + false, + /\.(js|md|tsx)$/, +); + +export default function Page({ demos, docs }) { + return ; +} + +Page.getInitialProps = () => { + const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); + return { demos, docs }; +}; diff --git a/docs/src/modules/components/AppFrame.js b/docs/src/modules/components/AppFrame.js index 87a96eab50f2f0..d513876112ebdc 100644 --- a/docs/src/modules/components/AppFrame.js +++ b/docs/src/modules/components/AppFrame.js @@ -32,6 +32,7 @@ import Notifications from 'docs/src/modules/components/Notifications'; import MarkdownLinks from 'docs/src/modules/components/MarkdownLinks'; import { LANGUAGES_LABEL } from 'docs/src/modules/constants'; import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; +import RtlContext from 'docs/src/modules/utils/RtlContext'; import { useChangeTheme } from 'docs/src/modules/components/ThemeContext'; import PageContext from 'docs/src/modules/components/PageContext'; @@ -147,6 +148,7 @@ function AppFrame(props) { const theme = useTheme(); const t = useSelector((state) => state.options.t); const userLanguage = useSelector((state) => state.options.userLanguage); + const { rtl, setRtl } = React.useContext(RtlContext); const crowdInLocale = LOCALES[userLanguage] || userLanguage; @@ -176,6 +178,8 @@ function AppFrame(props) { changeTheme({ paletteType }); }; const handleToggleDirection = () => { + setRtl(!rtl); + // TODO: remove in v5 after the style engine is oved to emotion changeTheme({ direction: theme.direction === 'ltr' ? 'rtl' : 'ltr' }); }; diff --git a/docs/src/modules/utils/RtlContext.js b/docs/src/modules/utils/RtlContext.js new file mode 100644 index 00000000000000..465ef058b5ec2f --- /dev/null +++ b/docs/src/modules/utils/RtlContext.js @@ -0,0 +1,8 @@ +import React from "react"; + +const RltContext = React.createContext({ + rtl: false, + setRtl: () => {} +}); + +export default RltContext; diff --git a/docs/src/pages/guides/right-to-left-v5/Direction.js b/docs/src/pages/guides/right-to-left-v5/Direction.js new file mode 100644 index 00000000000000..f272ea15f62957 --- /dev/null +++ b/docs/src/pages/guides/right-to-left-v5/Direction.js @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; +import TextField from '@material-ui/core/TextField'; + +const theme = createMuiTheme({ + direction: 'rtl', // Both here and +}); + +export default function Direction() { + return ( + +
+ + +
+
+ ); +} diff --git a/docs/src/pages/guides/right-to-left-v5/Direction.tsx b/docs/src/pages/guides/right-to-left-v5/Direction.tsx new file mode 100644 index 00000000000000..f272ea15f62957 --- /dev/null +++ b/docs/src/pages/guides/right-to-left-v5/Direction.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; +import TextField from '@material-ui/core/TextField'; + +const theme = createMuiTheme({ + direction: 'rtl', // Both here and +}); + +export default function Direction() { + return ( + +
+ + +
+
+ ); +} diff --git a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js new file mode 100644 index 00000000000000..f45eead8a359fb --- /dev/null +++ b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + root: { + width: '100%', + marginTop: theme.spacing(4), + marginRight: theme.spacing(2), + }, + affected: { + textAlign: 'right', + }, + unaffected: { + flip: false, + textAlign: 'right', + }, +})); + +export default function RtlOptOut() { + const classes = useStyles(); + + return ( +
+
Affected
+
Unaffected
+
+ ); +} diff --git a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx new file mode 100644 index 00000000000000..f7e3fea1061b42 --- /dev/null +++ b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; + +declare module '@material-ui/core/styles/withStyles' { + // Augment the BaseCSSProperties so that we can control jss-rtl + interface BaseCSSProperties { + /** + * Used to control if the rule-set should be affected by rtl transformation + */ + flip?: boolean; + } +} + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + marginTop: theme.spacing(4), + marginRight: theme.spacing(2), + }, + affected: { + textAlign: 'right', + }, + unaffected: { + flip: false, + textAlign: 'right', + }, + }), +); + +export default function RtlOptOut() { + const classes = useStyles(); + + return ( +
+
Affected
+
Unaffected
+
+ ); +} diff --git a/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md b/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md new file mode 100644 index 00000000000000..bf585f96db9cc7 --- /dev/null +++ b/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md @@ -0,0 +1,81 @@ +# Right-to-left + +

Right-to-left languages such as Arabic, Persian, or Hebrew are supported. To change the direction of Material-UI components you must follow the following steps.

+ +## Steps + +### 1. HTML + +Make sure the `dir` attribute is set on the body, otherwise native components will break: + +```html + +``` + +### 2. stylis-plugin-rtl + +You need this stylis plugin to flip the styles: [stylis-plugin-rtl](https://github.com/styled-components/stylis-plugin-rtl). + +```sh +npm install stylis-plugin-rtl@^1 +``` + +Note: both emotion and styled-components currently work with the v1 of the plugin. + +Having installed the plugin in your project, Material-UI components still require it to be loaded by the style engine instance that you use. Find bellow guides on how you can configure it for `@emotion` and `styled-components` + +#### 2.1. configuring @emotion to use the stylis-plugin-rtl + +If you use emotion as your style engine, you should create new cache instance that uses the `stylis-plugin-rtl` and provide that on the top of your application tree. The [CacheProvider](https://emotion.sh/docs/cache-provider) component enables this: + +```jsx +import rtlPlugin from 'stylis-plugin-rtl'; +import { CacheProvider } from '@emotion/core'; +import createCache from '@emotion/cache'; + +// Create rtl cache +const cacheRtl = createCache({ + key: 'muirtl', + stylisPlugins: [rtlPlugin], + speedy: true, +}); + +function RTL(props) { + return {props.children}; +} +``` + +#### 2.2. configuring styled-components to use the stylis-plugin-rtl + +If you use `styled-components` as your style engine, you can use the [StyleSheetManager](https://styled-components.com/docs/api#stylesheetmanager) and provide the stylis-plugin-rtl as an item in the `stylisPlugins` property: + +```jsx +import { StyleSheetManager } from "styled-components"; +import rtlPlugin from "stylis-plugin-rtl"; + +function RTL(props) { + return ( + + {props.children} + + ); +} +``` + +## Demo + +TODO + +_Use the direction toggle button on the top right corner to flip the whole documentation_ + +{{"demo": "pages/guides/right-to-left/Direction.js"}} + +## Opting out of rtl transformation + +TODO + +If you want to prevent a specific rule-set from being affected by the `rtl` transformation you can add `flip: false` at the beginning. + +_Use the direction toggle button on the top right corner to see the effect._ + +{{"demo": "pages/guides/right-to-left/RtlOptOut.js", "hideEditButton": true}} diff --git a/packages/material-ui-styles/package.json b/packages/material-ui-styles/package.json index 8380c01dff8783..4e0d51e3854a8f 100644 --- a/packages/material-ui-styles/package.json +++ b/packages/material-ui-styles/package.json @@ -38,7 +38,6 @@ "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json" }, "peerDependencies": { - "@emotion/core": "^10.0.27", "@types/react": "^16.8.6", "react": "^16.8.0", "react-dom": "^16.8.0" @@ -50,7 +49,6 @@ }, "dependencies": { "@babel/runtime": "^7.4.4", - "@emotion/cache": "^10.0.27", "@emotion/hash": "^0.8.0", "@material-ui/types": "^5.1.0", "@material-ui/utils": "^5.0.0-alpha.8", @@ -65,8 +63,7 @@ "jss-plugin-props-sort": "^10.0.3", "jss-plugin-rule-value-function": "^10.0.3", "jss-plugin-vendor-prefixer": "^10.0.3", - "prop-types": "^15.7.2", - "stylis-plugin-rtl": "^1.0.0" + "prop-types": "^15.7.2" }, "sideEffects": false, "publishConfig": { diff --git a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js index 73c06169b26f04..2a3093f36603a2 100644 --- a/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js +++ b/packages/material-ui-styles/src/ThemeProvider/ThemeProvider.js @@ -1,9 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { exactProp } from '@material-ui/utils'; -import { CacheProvider } from '@emotion/core'; -import createCache from '@emotion/cache'; -import rtlPlugin from 'stylis-plugin-rtl'; import ThemeContext from '../useTheme/ThemeContext'; import useTheme from '../useTheme'; import nested from './nested'; @@ -30,20 +27,6 @@ function mergeOuterLocalTheme(outerTheme, localTheme) { return { ...outerTheme, ...localTheme }; } -// Cache for the ltr version of the styles -const cacheLtr = createCache({ - key: 'mui', - stylisPlugins: [], - speedy: true, -}); - -// Cache for the rtl version of the styles -const cacheRtl = createCache({ - key: 'muirtl', - stylisPlugins: [rtlPlugin], - speedy: true, -}); - /** * This component takes a `theme` prop. * It makes the `theme` available down the React tree thanks to React context. @@ -78,13 +61,7 @@ function ThemeProvider(props) { return output; }, [localTheme, outerTheme]); - const rtl = theme.direction === 'rtl'; - - return ( - - {children} - - ); + return {children}; } ThemeProvider.propTypes = { From a5569b5293847502ca4759bcdae687fede2667cc Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 14:38:57 +0200 Subject: [PATCH 043/125] fixed rtl usage --- docs/pages/_app.js | 6 +-- docs/src/pages.js | 1 + .../guides/right-to-left-v5/RtlOptOut.js | 44 ++++++++++--------- .../right-to-left-v5/right-to-left-v5.md | 12 +---- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/docs/pages/_app.js b/docs/pages/_app.js index d0048a46fa992d..1ee98c38848271 100644 --- a/docs/pages/_app.js +++ b/docs/pages/_app.js @@ -8,7 +8,7 @@ import NextHead from 'next/head'; import PropTypes from 'prop-types'; import acceptLanguage from 'accept-language'; import { create } from 'jss'; -import rtl from 'jss-rtl'; +import jssRtl from 'jss-rtl'; import { CacheProvider } from '@emotion/core'; import createCache from '@emotion/cache'; import rtlPlugin from 'stylis-plugin-rtl'; @@ -26,7 +26,7 @@ import { ACTION_TYPES, CODE_VARIANTS } from 'docs/src/modules/constants'; // Configure JSS const jss = create({ - plugins: [...jssPreset().plugins, rtl()], + plugins: [...jssPreset().plugins, jssRtl()], insertionPoint: process.browser ? document.querySelector('#insertion-point-jss') : null, }); @@ -301,7 +301,7 @@ function AppWrapper(props) { initRedux({ options: { userLanguage: pageProps.userLanguage } }), ); - const [setl, setRtl] = React.useState(false); + const [rtl, setRtl] = React.useState(false); const rtlContextValue = { rtl, setRtl }; React.useEffect(() => { diff --git a/docs/src/pages.js b/docs/src/pages.js index 957a7ac317e045..2cd42946b71aa8 100644 --- a/docs/src/pages.js +++ b/docs/src/pages.js @@ -196,6 +196,7 @@ const pages = [ { pathname: '/guides/localization' }, { pathname: '/guides/content-security-policy', title: 'Content Security Policy' }, { pathname: '/guides/right-to-left', title: 'Right-to-left' }, + { pathname: '/guides/right-to-left-v5', title: 'Right-to-left v5' }, { pathname: '/guides/flow' }, ], }, diff --git a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js index f45eead8a359fb..a98fd405890698 100644 --- a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js +++ b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.js @@ -1,28 +1,32 @@ import * as React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; +import { createMuiTheme } from '@material-ui/core/styles'; +import styled from '@emotion/styled'; +import { ThemeProvider } from 'emotion-theming'; -const useStyles = makeStyles((theme) => ({ - root: { - width: '100%', - marginTop: theme.spacing(4), - marginRight: theme.spacing(2), - }, - affected: { - textAlign: 'right', - }, - unaffected: { - flip: false, - textAlign: 'right', - }, +const Root = styled('div')(props => ({ + width: '100%', + marginTop: props.theme.spacing(4), + marginRight: props.theme.spacing(2), })); -export default function RtlOptOut() { - const classes = useStyles(); +const AffectedText = styled('div')({ + textAlign: 'right', +}); + +const UnaffectedText = styled('div')({ + /* @noflip */ + textAlign: 'right', +}); +const theme = createMuiTheme(); + +export default function RtlOptOut() { return ( -
-
Affected
-
Unaffected
-
+ + + Affected + Unaffected + + ); } diff --git a/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md b/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md index bf585f96db9cc7..b3a769b81e39e1 100644 --- a/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md +++ b/docs/src/pages/guides/right-to-left-v5/right-to-left-v5.md @@ -62,20 +62,12 @@ function RTL(props) { } ``` -## Demo - -TODO - -_Use the direction toggle button on the top right corner to flip the whole documentation_ - -{{"demo": "pages/guides/right-to-left/Direction.js"}} - ## Opting out of rtl transformation -TODO +TODO: does not work :( If you want to prevent a specific rule-set from being affected by the `rtl` transformation you can add `flip: false` at the beginning. _Use the direction toggle button on the top right corner to see the effect._ -{{"demo": "pages/guides/right-to-left/RtlOptOut.js", "hideEditButton": true}} +{{"demo": "pages/guides/right-to-left-v5/RtlOptOut.js", "hideEditButton": true}} From 61673cd643c7d5d2ff0a9263046786af36135958 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 17:10:16 +0200 Subject: [PATCH 044/125] updated ts example --- .../guides/right-to-left-v5/RtlOptOut.tsx | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx index f7e3fea1061b42..403485b92d703f 100644 --- a/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx +++ b/docs/src/pages/guides/right-to-left-v5/RtlOptOut.tsx @@ -1,40 +1,32 @@ import * as React from 'react'; -import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; +import { createMuiTheme, Theme } from '@material-ui/core/styles'; +import styled from '@emotion/styled'; +import { ThemeProvider } from 'emotion-theming'; -declare module '@material-ui/core/styles/withStyles' { - // Augment the BaseCSSProperties so that we can control jss-rtl - interface BaseCSSProperties { - /** - * Used to control if the rule-set should be affected by rtl transformation - */ - flip?: boolean; - } -} +const Root = styled('div')((props: { theme?: Theme }) => ({ + width: '100%', + marginTop: props.theme?.spacing(4), + marginRight: props.theme?.spacing(2), +})); -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - width: '100%', - marginTop: theme.spacing(4), - marginRight: theme.spacing(2), - }, - affected: { - textAlign: 'right', - }, - unaffected: { - flip: false, - textAlign: 'right', - }, - }), -); +const AffectedText = styled('div')({ + textAlign: 'right', +}); -export default function RtlOptOut() { - const classes = useStyles(); +const UnaffectedText = styled('div')({ + /* @noflip */ + textAlign: 'right', +}); +const theme = createMuiTheme(); + +export default function RtlOptOut() { return ( -
-
Affected
-
Unaffected
-
+ + + Affected + Unaffected + + ); } From 47c4105b1e0a14d604e316bc25419f727e8fe2d7 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 17:39:25 +0200 Subject: [PATCH 045/125] wip --- docs/babel.config.js | 3 ++- docs/package.json | 2 +- packages/material-ui-styled-engine/README.md | 2 ++ packages/material-ui-styled-engine/package.json | 5 +++++ packages/material-ui-styled-engine/src/index.d.ts | 5 +++-- packages/material-ui-styled-engine/src/index.js | 2 +- packages/material-ui-styled-engine/src/styled.d.ts | 3 --- packages/material-ui-styled-engine/src/styled.js | 2 +- packages/material-ui/package.json | 4 ---- 9 files changed, 15 insertions(+), 13 deletions(-) delete mode 100644 packages/material-ui-styled-engine/src/styled.d.ts diff --git a/docs/babel.config.js b/docs/babel.config.js index 539629c95a2e72..3373c74218b80a 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -19,7 +19,8 @@ const alias = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', - '@material-ui/styled-engine': '@emotion/styled', + // Uncomment next line for using the styled-components as style engine + // '@material-ui/styled-engine': '@material-ui/styled-engine-sc', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', docs: './', diff --git a/docs/package.json b/docs/package.json index 5748b82d1c050f..cfc218913e5364 100644 --- a/docs/package.json +++ b/docs/package.json @@ -34,7 +34,6 @@ "@material-ui/lab": "^5.0.0-alpha.1", "@material-ui/pickers": "^4.0.0-alpha.11", "@material-ui/styles": "^5.0.0-alpha.1", - "@material-ui/styled-engine": "^5.0.0-alpha.1", "@material-ui/system": "^5.0.0-alpha.1", "@material-ui/types": "^5.0.0", "@trendmicro/react-interpolate": "^0.5.5", @@ -121,6 +120,7 @@ "devDependencies": { "@babel/plugin-transform-react-constant-elements": "^7.8.3", "@babel/preset-typescript": "^7.7.4", + "@material-ui/styled-engine": "^5.0.0-alpha.1", "@types/recharts": "^1.8.14", "babel-plugin-unwrap-createstyles": "^4.1.0", "cpy-cli": "^3.0.0", diff --git a/packages/material-ui-styled-engine/README.md b/packages/material-ui-styled-engine/README.md index 98650f0745314b..3f1a9dd5a4b33a 100644 --- a/packages/material-ui-styled-engine/README.md +++ b/packages/material-ui-styled-engine/README.md @@ -1 +1,3 @@ # @material-ui/styled-engine + +This package is a simlple wrapper around the `@emotion/styled` package. It is used internally in the `@material-ui/core` package. If you wish to use `styled-components` instead please use an alias to replace this package with `@material-ui/styled-engine-sc`. \ No newline at end of file diff --git a/packages/material-ui-styled-engine/package.json b/packages/material-ui-styled-engine/package.json index d0402fda319e38..86b76f232899b1 100644 --- a/packages/material-ui-styled-engine/package.json +++ b/packages/material-ui-styled-engine/package.json @@ -39,6 +39,11 @@ }, "dependencies": { }, + "peerDependencies": { + "@emotion/core": "^10.0.27", + "@emotion/styled": "^10.0.27", + "emotion-theming": "^10.0.27" + }, "sideEffects": false, "publishConfig": { "access": "public" diff --git a/packages/material-ui-styled-engine/src/index.d.ts b/packages/material-ui-styled-engine/src/index.d.ts index e6843aae94605b..26fe41b0fb354a 100644 --- a/packages/material-ui-styled-engine/src/index.d.ts +++ b/packages/material-ui-styled-engine/src/index.d.ts @@ -1,4 +1,5 @@ -import styled from './styled'; -export * from './styled'; +import { CreateStyled } from '@emotion/styled'; + +declare const styled: CreateStyled; export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled-engine/src/index.js b/packages/material-ui-styled-engine/src/index.js index e6843aae94605b..4980e3052eac4a 100644 --- a/packages/material-ui-styled-engine/src/index.js +++ b/packages/material-ui-styled-engine/src/index.js @@ -1,4 +1,4 @@ -import styled from './styled'; +import styled from '@emotion/styled'; export * from './styled'; export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled-engine/src/styled.d.ts b/packages/material-ui-styled-engine/src/styled.d.ts deleted file mode 100644 index 87b79ead56126b..00000000000000 --- a/packages/material-ui-styled-engine/src/styled.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare function styled(params: any): (styles: any) => any; - -export default styled; \ No newline at end of file diff --git a/packages/material-ui-styled-engine/src/styled.js b/packages/material-ui-styled-engine/src/styled.js index f4bbf52cbbe090..3651b939a048b0 100644 --- a/packages/material-ui-styled-engine/src/styled.js +++ b/packages/material-ui-styled-engine/src/styled.js @@ -1,3 +1,3 @@ -const styled = () => () => null; +import styled from '@emotion/styled'; export default styled; \ No newline at end of file diff --git a/packages/material-ui/package.json b/packages/material-ui/package.json index 5715943c27d172..f7aa648cc15225 100644 --- a/packages/material-ui/package.json +++ b/packages/material-ui/package.json @@ -39,10 +39,7 @@ "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json && tsc -p tsconfig.build.json" }, "peerDependencies": { - "@emotion/core": "^10.0.27", - "@emotion/styled": "^10.0.27", "@types/react": "^16.8.6", - "emotion-theming": "^10.0.27", "react": "^16.8.0", "react-dom": "^16.8.0" }, @@ -53,7 +50,6 @@ }, "dependencies": { "@babel/runtime": "^7.4.4", - "@emotion/is-prop-valid": "^0.8.8", "@material-ui/styles": "^5.0.0-alpha.8", "@material-ui/system": "^5.0.0-alpha.6", "@material-ui/types": "^5.1.0", From dc7a03efbe8e45828074d9fed3f5c954b14b791f Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 17:44:54 +0200 Subject: [PATCH 046/125] added @material-ui/styled-engine as peerDependeny --- packages/material-ui/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/material-ui/package.json b/packages/material-ui/package.json index f7aa648cc15225..6c5c3eea015df7 100644 --- a/packages/material-ui/package.json +++ b/packages/material-ui/package.json @@ -39,6 +39,7 @@ "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json && tsc -p tsconfig.build.json" }, "peerDependencies": { + "@material-ui/styled-engine": "^5.0.0-alpha.1", "@types/react": "^16.8.6", "react": "^16.8.0", "react-dom": "^16.8.0" From e39ab3bc61c76f056946bd35b7d77d9e1bf0a8ce Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 18:06:43 +0200 Subject: [PATCH 047/125] fixed build --- .codesandbox/ci.json | 1 + babel.config.js | 1 + docs/babel.config.js | 3 ++- docs/next.config.js | 1 + docs/src/modules/utils/helpers.js | 1 + packages/material-ui-styled-engine/src/index.d.ts | 7 ++----- packages/material-ui-styled-engine/src/index.js | 6 ++---- packages/material-ui-styled-engine/src/styled.js | 3 --- scripts/sizeSnapshot/webpack.config.js | 1 + tsconfig.json | 2 ++ webpackBaseConfig.js | 1 + 11 files changed, 14 insertions(+), 13 deletions(-) delete mode 100644 packages/material-ui-styled-engine/src/styled.js diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index f1f80be03d4c90..ca95b32945c2ee 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -14,6 +14,7 @@ "@material-ui/icons": "packages/material-ui-icons/build", "@material-ui/lab": "packages/material-ui-lab/build", "@material-ui/styles": "packages/material-ui-styles/build", + "@material-ui/styled-engine": "packages/material-ui-styled-engine/build", "@material-ui/system": "packages/material-ui-system/build", "@material-ui/types": "packages/material-ui-types", "@material-ui/utils": "packages/material-ui-utils/build" diff --git a/babel.config.js b/babel.config.js index 162d469804993a..3edd4b000adf94 100644 --- a/babel.config.js +++ b/babel.config.js @@ -27,6 +27,7 @@ const defaultAlias = { '@material-ui/docs': './packages/material-ui-docs/src', '@material-ui/icons': './packages/material-ui-icons/src', '@material-ui/lab': './packages/material-ui-lab/src', + '@material-ui/styled-engine': './packages/material-ui-styled-engine/src', '@material-ui/styles': './packages/material-ui-styles/src', '@material-ui/system': './packages/material-ui-system/src', '@material-ui/utils': './packages/material-ui-utils/src', diff --git a/docs/babel.config.js b/docs/babel.config.js index 3373c74218b80a..42760b68442bed 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -19,8 +19,9 @@ const alias = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', + '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', // Uncomment next line for using the styled-components as style engine - // '@material-ui/styled-engine': '@material-ui/styled-engine-sc', + // '@material-ui/styled-engine': '../packages/material-ui-styled-engine-sc/src', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', docs: './', diff --git a/docs/next.config.js b/docs/next.config.js index cc49ae80f838ff..922b524996343e 100644 --- a/docs/next.config.js +++ b/docs/next.config.js @@ -115,6 +115,7 @@ module.exports = { '@material-ui/docs': '../packages/material-ui-docs/src', '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', + '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', '@material-ui/styles': '../packages/material-ui-styles/src', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', diff --git a/docs/src/modules/utils/helpers.js b/docs/src/modules/utils/helpers.js index b292a29e6ee945..7e2cd03da9388a 100644 --- a/docs/src/modules/utils/helpers.js +++ b/docs/src/modules/utils/helpers.js @@ -120,6 +120,7 @@ function getDependencies(raw, options = {}) { '@material-ui/core': 'next', '@material-ui/icons': 'next', '@material-ui/lab': 'next', + '@material-ui/styled-engine': 'next', '@material-ui/styles': 'next', '@material-ui/system': 'next', '@material-ui/utils': 'next', diff --git a/packages/material-ui-styled-engine/src/index.d.ts b/packages/material-ui-styled-engine/src/index.d.ts index 26fe41b0fb354a..53bc27a1a267b7 100644 --- a/packages/material-ui-styled-engine/src/index.d.ts +++ b/packages/material-ui-styled-engine/src/index.d.ts @@ -1,5 +1,2 @@ -import { CreateStyled } from '@emotion/styled'; - -declare const styled: CreateStyled; - -export default styled; \ No newline at end of file +export * from '@emotion/styled'; +export { default } from '@emotion/styled'; diff --git a/packages/material-ui-styled-engine/src/index.js b/packages/material-ui-styled-engine/src/index.js index 4980e3052eac4a..53bc27a1a267b7 100644 --- a/packages/material-ui-styled-engine/src/index.js +++ b/packages/material-ui-styled-engine/src/index.js @@ -1,4 +1,2 @@ -import styled from '@emotion/styled'; -export * from './styled'; - -export default styled; \ No newline at end of file +export * from '@emotion/styled'; +export { default } from '@emotion/styled'; diff --git a/packages/material-ui-styled-engine/src/styled.js b/packages/material-ui-styled-engine/src/styled.js deleted file mode 100644 index 3651b939a048b0..00000000000000 --- a/packages/material-ui-styled-engine/src/styled.js +++ /dev/null @@ -1,3 +0,0 @@ -import styled from '@emotion/styled'; - -export default styled; \ No newline at end of file diff --git a/scripts/sizeSnapshot/webpack.config.js b/scripts/sizeSnapshot/webpack.config.js index 1f988a2937601a..ab31104eb9ad61 100644 --- a/scripts/sizeSnapshot/webpack.config.js +++ b/scripts/sizeSnapshot/webpack.config.js @@ -116,6 +116,7 @@ module.exports = async function webpackConfig() { alias: { '@material-ui/core': path.join(workspaceRoot, 'packages/material-ui/build'), '@material-ui/lab': path.join(workspaceRoot, 'packages/material-ui-lab/build'), + '@material-ui/styled-engine': path.join(workspaceRoot, 'packages/material-ui-styles/build'), '@material-ui/styles': path.join(workspaceRoot, 'packages/material-ui-styles/build'), '@material-ui/system': path.join(workspaceRoot, 'packages/material-ui-system/build'), '@material-ui/utils': path.join(workspaceRoot, 'packages/material-ui-utils/build'), diff --git a/tsconfig.json b/tsconfig.json index 08eef2acb1c91a..a94fb73c04012e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,8 @@ "@material-ui/icons": ["./packages/material-ui-icons/src"], "@material-ui/lab": ["./packages/material-ui-lab/src"], "@material-ui/lab/*": ["./packages/material-ui-lab/src/*"], + "@material-ui/styled-engine": ["./packages/material-ui-styled-engine/src"], + "@material-ui/styled-engine/*": ["./packages/material-ui-styled-engine/src/*"], "@material-ui/styles": ["./packages/material-ui-styles/src"], "@material-ui/styles/*": ["./packages/material-ui-styles/src/*"], "@material-ui/system": ["./packages/material-ui-system/src"], diff --git a/webpackBaseConfig.js b/webpackBaseConfig.js index 331edf3ba2df71..c9439541dbcc73 100644 --- a/webpackBaseConfig.js +++ b/webpackBaseConfig.js @@ -11,6 +11,7 @@ module.exports = { '@material-ui/docs': path.resolve(__dirname, './packages/material-ui-docs/src'), '@material-ui/icons': path.resolve(__dirname, './packages/material-ui-icons/src'), '@material-ui/lab': path.resolve(__dirname, './packages/material-ui-lab/src'), + '@material-ui/styled-engine': path.resolve(__dirname, './packages/material-ui-styled-engine/src'), '@material-ui/styles': path.resolve(__dirname, './packages/material-ui-styles/src'), '@material-ui/system': path.resolve(__dirname, './packages/material-ui-system/src'), '@material-ui/utils': path.resolve(__dirname, './packages/material-ui-utils/src'), From b02c56b7b5e3a7222ebef9a70ef5ee4ad1518cb7 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 15 Sep 2020 18:50:11 +0200 Subject: [PATCH 048/125] added styled-engine-sc package --- .codesandbox/ci.json | 1 + babel.config.js | 1 + docs/babel.config.js | 3 +- docs/next.config.js | 1 + docs/package.json | 3 +- docs/src/modules/utils/helpers.js | 1 + .../material-ui-styled-engine-sc/README.md | 3 ++ .../material-ui-styled-engine-sc/package.json | 53 +++++++++++++++++++ .../src/index.d.ts | 2 + .../material-ui-styled-engine-sc/src/index.js | 2 + .../tsconfig.json | 4 ++ packages/material-ui-styled-engine/README.md | 2 +- scripts/sizeSnapshot/webpack.config.js | 3 +- tsconfig.json | 2 + webpackBaseConfig.js | 1 + 15 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 packages/material-ui-styled-engine-sc/README.md create mode 100644 packages/material-ui-styled-engine-sc/package.json create mode 100644 packages/material-ui-styled-engine-sc/src/index.d.ts create mode 100644 packages/material-ui-styled-engine-sc/src/index.js create mode 100644 packages/material-ui-styled-engine-sc/tsconfig.json diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index ca95b32945c2ee..1aa0ebc5aea4fd 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -15,6 +15,7 @@ "@material-ui/lab": "packages/material-ui-lab/build", "@material-ui/styles": "packages/material-ui-styles/build", "@material-ui/styled-engine": "packages/material-ui-styled-engine/build", + "@material-ui/styled-engine-sc": "packages/material-ui-styled-engine-sc/build", "@material-ui/system": "packages/material-ui-system/build", "@material-ui/types": "packages/material-ui-types", "@material-ui/utils": "packages/material-ui-utils/build" diff --git a/babel.config.js b/babel.config.js index 3edd4b000adf94..30bfea34532466 100644 --- a/babel.config.js +++ b/babel.config.js @@ -28,6 +28,7 @@ const defaultAlias = { '@material-ui/icons': './packages/material-ui-icons/src', '@material-ui/lab': './packages/material-ui-lab/src', '@material-ui/styled-engine': './packages/material-ui-styled-engine/src', + '@material-ui/styled-engine-sc': './packages/material-ui-styled-engine-sc/src', '@material-ui/styles': './packages/material-ui-styles/src', '@material-ui/system': './packages/material-ui-system/src', '@material-ui/utils': './packages/material-ui-utils/src', diff --git a/docs/babel.config.js b/docs/babel.config.js index 42760b68442bed..5127369fdaa3fa 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -19,8 +19,9 @@ const alias = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', + '@material-ui/styled-engine-sc': '../packages/material-ui-styled-engine-sc/src', + // Swap the comments on the next two lines for using styled-components as style engine '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', - // Uncomment next line for using the styled-components as style engine // '@material-ui/styled-engine': '../packages/material-ui-styled-engine-sc/src', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', diff --git a/docs/next.config.js b/docs/next.config.js index 922b524996343e..2debd62fd0040a 100644 --- a/docs/next.config.js +++ b/docs/next.config.js @@ -116,6 +116,7 @@ module.exports = { '@material-ui/icons': '../packages/material-ui-icons/src', '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', + '@material-ui/styled-engine-sc': '../packages/material-ui-styled-engine-sc/src', '@material-ui/styles': '../packages/material-ui-styles/src', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', diff --git a/docs/package.json b/docs/package.json index cfc218913e5364..9e71116f8183e8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -34,6 +34,8 @@ "@material-ui/lab": "^5.0.0-alpha.1", "@material-ui/pickers": "^4.0.0-alpha.11", "@material-ui/styles": "^5.0.0-alpha.1", + "@material-ui/styled-engine": "^5.0.0-alpha.1", + "@material-ui/styled-engine-sc": "^5.0.0-alpha.1", "@material-ui/system": "^5.0.0-alpha.1", "@material-ui/types": "^5.0.0", "@trendmicro/react-interpolate": "^0.5.5", @@ -120,7 +122,6 @@ "devDependencies": { "@babel/plugin-transform-react-constant-elements": "^7.8.3", "@babel/preset-typescript": "^7.7.4", - "@material-ui/styled-engine": "^5.0.0-alpha.1", "@types/recharts": "^1.8.14", "babel-plugin-unwrap-createstyles": "^4.1.0", "cpy-cli": "^3.0.0", diff --git a/docs/src/modules/utils/helpers.js b/docs/src/modules/utils/helpers.js index 7e2cd03da9388a..6b2fd4ab1ec561 100644 --- a/docs/src/modules/utils/helpers.js +++ b/docs/src/modules/utils/helpers.js @@ -121,6 +121,7 @@ function getDependencies(raw, options = {}) { '@material-ui/icons': 'next', '@material-ui/lab': 'next', '@material-ui/styled-engine': 'next', + '@material-ui/styled-engine-sc': 'next', '@material-ui/styles': 'next', '@material-ui/system': 'next', '@material-ui/utils': 'next', diff --git a/packages/material-ui-styled-engine-sc/README.md b/packages/material-ui-styled-engine-sc/README.md new file mode 100644 index 00000000000000..ac71c89edc46be --- /dev/null +++ b/packages/material-ui-styled-engine-sc/README.md @@ -0,0 +1,3 @@ +# @material-ui/styled-engine-sc + +This package is a simple wrapper around the `styled-components` package. It is created to be used as alias for the `@material-ui/styled-engine` package, for the developers who would like to use `styled-components` as a styled engine instead of `@emotion/styled`. \ No newline at end of file diff --git a/packages/material-ui-styled-engine-sc/package.json b/packages/material-ui-styled-engine-sc/package.json new file mode 100644 index 00000000000000..833c98c565d923 --- /dev/null +++ b/packages/material-ui-styled-engine-sc/package.json @@ -0,0 +1,53 @@ +{ + "name": "@material-ui/styled-engine-sc", + "version": "5.0.0-alpha.8", + "private": false, + "author": "Material-UI Team", + "description": "Material-UI Styled - Wrapper package for styled utility.", + "main": "./src/index.js", + "keywords": [ + "react", + "react-component", + "material design", + "material-ui", + "styled" + ], + "repository": { + "type": "git", + "url": "https://github.com/mui-org/material-ui.git", + "directory": "packages/material-ui-styled" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/mui-org/material-ui/issues" + }, + "homepage": "https://material-ui.com/styled/basics/", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "scripts": { + "build": "yarn build:cjs && yarn build:esm && yarn build:es && yarn build:copy-files", + "build:cjs": "node ../../scripts/build cjs", + "build:esm": "node ../../scripts/build esm", + "build:es": "node ../../scripts/build es", + "build:copy-files": "node ../../scripts/copy-files.js", + "prebuild": "rimraf build", + "release": "yarn build && npm publish build --tag next", + "test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/material-ui-styles/**/*.test.{js,ts,tsx}' --exclude '**/node_modules/**'", + "typescript": "tslint -p tsconfig.json \"{src,test}/**/*.{spec,d}.{ts,tsx}\" && tsc -p tsconfig.json" + }, + "dependencies": { + }, + "peerDependencies": { + "@types/styled-components": "5.1.3", + "styled-components": "^5.0.0" + }, + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=8.0.0" + } +} diff --git a/packages/material-ui-styled-engine-sc/src/index.d.ts b/packages/material-ui-styled-engine-sc/src/index.d.ts new file mode 100644 index 00000000000000..b023957e85fe10 --- /dev/null +++ b/packages/material-ui-styled-engine-sc/src/index.d.ts @@ -0,0 +1,2 @@ +export * from 'styled-components'; +export { default } from 'styled-components'; diff --git a/packages/material-ui-styled-engine-sc/src/index.js b/packages/material-ui-styled-engine-sc/src/index.js new file mode 100644 index 00000000000000..b023957e85fe10 --- /dev/null +++ b/packages/material-ui-styled-engine-sc/src/index.js @@ -0,0 +1,2 @@ +export * from 'styled-components'; +export { default } from 'styled-components'; diff --git a/packages/material-ui-styled-engine-sc/tsconfig.json b/packages/material-ui-styled-engine-sc/tsconfig.json new file mode 100644 index 00000000000000..57220954971e1e --- /dev/null +++ b/packages/material-ui-styled-engine-sc/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig", + "include": ["src/**/*", "test/**/*"] +} diff --git a/packages/material-ui-styled-engine/README.md b/packages/material-ui-styled-engine/README.md index 3f1a9dd5a4b33a..d87c11b0955d6e 100644 --- a/packages/material-ui-styled-engine/README.md +++ b/packages/material-ui-styled-engine/README.md @@ -1,3 +1,3 @@ # @material-ui/styled-engine -This package is a simlple wrapper around the `@emotion/styled` package. It is used internally in the `@material-ui/core` package. If you wish to use `styled-components` instead please use an alias to replace this package with `@material-ui/styled-engine-sc`. \ No newline at end of file +This package is a simple wrapper around the `@emotion/styled` package. It is used internally in the `@material-ui/core` package. If you wish to use `styled-components` instead please use an alias to replace this package with `@material-ui/styled-engine-sc`. \ No newline at end of file diff --git a/scripts/sizeSnapshot/webpack.config.js b/scripts/sizeSnapshot/webpack.config.js index ab31104eb9ad61..3b4c1bab1081d6 100644 --- a/scripts/sizeSnapshot/webpack.config.js +++ b/scripts/sizeSnapshot/webpack.config.js @@ -116,7 +116,8 @@ module.exports = async function webpackConfig() { alias: { '@material-ui/core': path.join(workspaceRoot, 'packages/material-ui/build'), '@material-ui/lab': path.join(workspaceRoot, 'packages/material-ui-lab/build'), - '@material-ui/styled-engine': path.join(workspaceRoot, 'packages/material-ui-styles/build'), + '@material-ui/styled-engine': path.join(workspaceRoot, 'packages/material-ui-styled-engine/build'), + '@material-ui/styled-engine-sc': path.join(workspaceRoot, 'packages/material-ui-styles-sc/build'), '@material-ui/styles': path.join(workspaceRoot, 'packages/material-ui-styles/build'), '@material-ui/system': path.join(workspaceRoot, 'packages/material-ui-system/build'), '@material-ui/utils': path.join(workspaceRoot, 'packages/material-ui-utils/build'), diff --git a/tsconfig.json b/tsconfig.json index a94fb73c04012e..63439ca95da593 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,8 @@ "@material-ui/lab/*": ["./packages/material-ui-lab/src/*"], "@material-ui/styled-engine": ["./packages/material-ui-styled-engine/src"], "@material-ui/styled-engine/*": ["./packages/material-ui-styled-engine/src/*"], + "@material-ui/styled-engine-sc": ["./packages/material-ui-styled-engine-sc/src"], + "@material-ui/styled-engine-sc/*": ["./packages/material-ui-styled-engine-sc/src/*"], "@material-ui/styles": ["./packages/material-ui-styles/src"], "@material-ui/styles/*": ["./packages/material-ui-styles/src/*"], "@material-ui/system": ["./packages/material-ui-system/src"], diff --git a/webpackBaseConfig.js b/webpackBaseConfig.js index c9439541dbcc73..33c617cb471f04 100644 --- a/webpackBaseConfig.js +++ b/webpackBaseConfig.js @@ -12,6 +12,7 @@ module.exports = { '@material-ui/icons': path.resolve(__dirname, './packages/material-ui-icons/src'), '@material-ui/lab': path.resolve(__dirname, './packages/material-ui-lab/src'), '@material-ui/styled-engine': path.resolve(__dirname, './packages/material-ui-styled-engine/src'), + '@material-ui/styled-engine-sc': path.resolve(__dirname, './packages/material-ui-styled-engine-sc/src'), '@material-ui/styles': path.resolve(__dirname, './packages/material-ui-styles/src'), '@material-ui/system': path.resolve(__dirname, './packages/material-ui-system/src'), '@material-ui/utils': path.resolve(__dirname, './packages/material-ui-utils/src'), From 1c9e41daadc3ff8ff6934c7dd6c7c76270df5859 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 16 Sep 2020 09:24:13 +0200 Subject: [PATCH 049/125] fixed refresh issues with sc --- docs/babel.config.js | 18 +++++-- docs/package.json | 3 +- yarn.lock | 125 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 125 insertions(+), 21 deletions(-) diff --git a/docs/babel.config.js b/docs/babel.config.js index 5127369fdaa3fa..e364fd469ffb2d 100644 --- a/docs/babel.config.js +++ b/docs/babel.config.js @@ -20,9 +20,9 @@ const alias = { '@material-ui/lab': '../packages/material-ui-lab/src', '@material-ui/styles': '../packages/material-ui-styles/src', '@material-ui/styled-engine-sc': '../packages/material-ui-styled-engine-sc/src', - // Swap the comments on the next two lines for using styled-components as style engine - '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', - // '@material-ui/styled-engine': '../packages/material-ui-styled-engine-sc/src', + // Swap the comments on the next two lines for using the styled-components as style engine + // '@material-ui/styled-engine': '../packages/material-ui-styled-engine/src', + '@material-ui/styled-engine': '../packages/material-ui-styled-engine-sc/src', '@material-ui/system': '../packages/material-ui-system/src', '@material-ui/utils': '../packages/material-ui-utils/src', docs: './', @@ -60,6 +60,10 @@ module.exports = { resolvePath, }, ], + [ + "babel-plugin-styled-components", + { "ssr": true, "displayName": true, "preprocess": false } + ] ], ignore: [/@babel[\\|/]runtime/], // Fix a Windows issue. env: { @@ -71,5 +75,13 @@ module.exports = { ['babel-plugin-transform-react-remove-prop-types', { mode: 'remove' }], ], }, + development: { + plugins: [ + [ + "babel-plugin-styled-components", + { "ssr": true, "displayName": true, "preprocess": false } + ], + ], + }, }, }; diff --git a/docs/package.json b/docs/package.json index 9e71116f8183e8..78bed1692e3a5f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -33,9 +33,9 @@ "@material-ui/icons": "^5.0.0-alpha.1", "@material-ui/lab": "^5.0.0-alpha.1", "@material-ui/pickers": "^4.0.0-alpha.11", - "@material-ui/styles": "^5.0.0-alpha.1", "@material-ui/styled-engine": "^5.0.0-alpha.1", "@material-ui/styled-engine-sc": "^5.0.0-alpha.1", + "@material-ui/styles": "^5.0.0-alpha.1", "@material-ui/system": "^5.0.0-alpha.1", "@material-ui/types": "^5.0.0", "@trendmicro/react-interpolate": "^0.5.5", @@ -123,6 +123,7 @@ "@babel/plugin-transform-react-constant-elements": "^7.8.3", "@babel/preset-typescript": "^7.7.4", "@types/recharts": "^1.8.14", + "babel-plugin-styled-components": "^1.11.1", "babel-plugin-unwrap-createstyles": "^4.1.0", "cpy-cli": "^3.0.0", "cross-fetch": "^3.0.5", diff --git a/yarn.lock b/yarn.lock index b744cfc1e47b6c..8eab8db4ee3246 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,7 +69,7 @@ optionalDependencies: chokidar "^2.1.8" -"@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": +"@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== @@ -85,7 +85,27 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@7.7.7", "@babel/core@^7.1.6", "@babel/core@^7.10.2", "@babel/core@^7.4.5", "@babel/core@^7.5.4", "@babel/core@^7.7.5": +"@babel/core@7.7.7": + version "7.7.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.7.tgz#ee155d2e12300bcc0cff6a8ad46f2af5063803e9" + integrity sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.7.7" + "@babel/helpers" "^7.7.4" + "@babel/parser" "^7.7.7" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@babel/types" "^7.7.4" + convert-source-map "^1.7.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/core@^7.1.6", "@babel/core@^7.10.2", "@babel/core@^7.4.5", "@babel/core@^7.5.4", "@babel/core@^7.7.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.4.tgz#780e8b83e496152f8dd7df63892b2e052bf1d51d" integrity sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA== @@ -117,6 +137,15 @@ lodash "^4.17.13" source-map "^0.5.0" +"@babel/generator@^7.7.7": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" + integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== + dependencies: + "@babel/types" "^7.11.5" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" @@ -325,7 +354,7 @@ "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helpers@^7.10.4": +"@babel/helpers@^7.10.4", "@babel/helpers@^7.7.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== @@ -357,11 +386,16 @@ resolve "^1.13.1" v8flags "^3.1.1" -"@babel/parser@7.10.5", "@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.10.4", "@babel/parser@^7.7.5": +"@babel/parser@^7.1.0", "@babel/parser@^7.1.6", "@babel/parser@^7.10.4", "@babel/parser@^7.7.5": version "7.10.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.5.tgz#e7c6bf5a7deff957cec9f04b551e2762909d826b" integrity sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ== +"@babel/parser@^7.7.7": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== + "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz#4b65abb3d9bacc6c657aaa413e56696f9f170fc6" @@ -411,7 +445,7 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": +"@babel/plugin-proposal-nullish-coalescing-operator@7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== @@ -444,7 +478,7 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@7.11.0", "@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.10.1", "@babel/plugin-proposal-optional-chaining@^7.11.0": +"@babel/plugin-proposal-optional-chaining@7.11.0", "@babel/plugin-proposal-optional-chaining@^7.1.0", "@babel/plugin-proposal-optional-chaining@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== @@ -633,12 +667,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.10.4", "@babel/plugin-transform-destructuring@npm:@minh.nguyen/plugin-transform-destructuring@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@minh.nguyen/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.2.tgz#49de3e25c373fadd11471a2fc99ec0ce07d92f19" - integrity sha512-DIzWFKl5nzSk9Hj9ZsEXAvvgHiyuAsw52queJMuKqfZOk1BOr9u1i2h0tc6tPF3rQieubP+eX4DPLTKSMpbyMg== +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.10.4" @@ -1038,7 +1072,7 @@ "@babel/plugin-transform-react-jsx-source" "^7.10.4" "@babel/plugin-transform-react-pure-annotations" "^7.10.4" -"@babel/preset-typescript@7.10.4", "@babel/preset-typescript@^7.1.0", "@babel/preset-typescript@^7.10.4", "@babel/preset-typescript@^7.7.4": +"@babel/preset-typescript@7.10.4", "@babel/preset-typescript@^7.1.0", "@babel/preset-typescript@^7.7.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.10.4.tgz#7d5d052e52a682480d6e2cc5aa31be61c8c25e36" integrity sha512-SdYnvGPv+bLlwkF2VkJnaX/ni1sMNetcGI1+nThF1gyv6Ph8Qucc4ZZAjM5yZcE/AKRXIOTZz7eSRDWOEjPyRQ== @@ -1073,7 +1107,14 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.0.0", "@babel/runtime@7.11.2", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.1.5", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" + integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@7.11.2", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.1.5", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.11.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== @@ -1104,7 +1145,7 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@7.11.5", "@babel/types@7.8.3", "@babel/types@^7.0.0", "@babel/types@^7.10.2", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0", "@babel/types@^7.6.1": +"@babel/types@7.11.5", "@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.5.0", "@babel/types@^7.6.1", "@babel/types@^7.7.4": version "7.11.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== @@ -1113,6 +1154,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + "@date-io/core@1.x", "@date-io/core@^1.3.13", "@date-io/core@^1.3.9": version "1.3.13" resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" @@ -4026,6 +4076,16 @@ babel-plugin-react-remove-properties@^0.3.0: babel-plugin-syntax-jsx "^6.18.0" lodash "^4.17.10" +babel-plugin-styled-components@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.11.1.tgz#5296a9e557d736c3186be079fff27c6665d63d76" + integrity sha512-YwrInHyKUk1PU3avIRdiLyCpM++18Rs1NgyMXEAQC33rIXs/vro0A+stf4sT0Gf22Got+xRWB8Cm0tw+qkRzBA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-module-imports" "^7.0.0" + babel-plugin-syntax-jsx "^6.18.0" + lodash "^4.17.11" + babel-plugin-syntax-jsx@6.18.0, babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -5621,7 +5681,14 @@ cross-env@^7.0.0: dependencies: cross-spawn "^7.0.1" -cross-fetch@3.0.5, cross-fetch@^3.0.5: +cross-fetch@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.5.tgz#2739d2981892e7ab488a7ad03b92df2816e03f4c" + integrity sha512-FFLcLtraisj5eteosnX1gf01qYDCOc4fDy0+euOt8Kn9YBY2NtXL/pCoYPavw24NIQkQqm5ZOLsGD5Zzj0gyew== + dependencies: + node-fetch "2.6.0" + +cross-fetch@^3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== @@ -6607,7 +6674,21 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" -dot-prop@^3.0.0, dot-prop@^4.1.1, dot-prop@^4.2.0, dot-prop@^5.2.0: +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.1.1, dot-prop@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" + integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== + dependencies: + is-obj "^1.0.0" + +dot-prop@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== @@ -9286,6 +9367,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -13921,6 +14007,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + regenerator-runtime@^0.13.4: version "0.13.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" @@ -16744,7 +16835,7 @@ webpack-sources@1.4.3, webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-s source-list-map "^2.0.0" source-map "~0.6.1" -webpack@4.44.1, webpack@^4.28.2, webpack@^4.41.0, webpack@^4.43.0, webpack@^4.44.1: +webpack@4.44.1, webpack@^4.28.2, webpack@^4.41.0, webpack@^4.43.0: version "4.44.1" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21" integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ== From 8f2feddba7a082bc4fc11a7760fdbe86b09f208b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 16 Sep 2020 09:52:51 +0200 Subject: [PATCH 050/125] moved overrides & variants definition --- packages/material-ui/src/Slider/Slider.js | 38 ++++++++++++++++++-- packages/material-ui/src/styles/index.d.ts | 1 + packages/material-ui/src/styles/index.js | 1 + packages/material-ui/src/styles/muiStyled.js | 4 +-- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/material-ui/src/Slider/Slider.js b/packages/material-ui/src/Slider/Slider.js index acb9efcf9cf198..55206d042f3c15 100644 --- a/packages/material-ui/src/Slider/Slider.js +++ b/packages/material-ui/src/Slider/Slider.js @@ -4,7 +4,38 @@ import useThemeProps from '../styles/useThemeProps'; import { fade, lighten, darken } from '../styles/colorManipulator'; import capitalize from '../utils/capitalize'; import SliderBase from './SliderBase'; -import muiStyled from '../styles/muiStyled'; +import styled from '@material-ui/styled-engine'; + +const getStyleOverrides = (name, theme) => { + let styleOverrides = {}; + + if ( + theme && + theme.components && + theme.components[name] && + theme.components[name].styleOverrides + ) { + styleOverrides = theme.components[name].styleOverrides; + } + + return styleOverrides; +}; + +const getVariantStyles = (name, theme) => { + let variants = []; + if (theme && theme.components && theme.components[name] && theme.components[name].variants) { + variants = theme.components[name].variants; + } + + const variantsStyles = {}; + + variants.forEach((definition) => { + const key = propsToClassKey(definition.props); + variantsStyles[key] = definition.style; + }); + + return variantsStyles; +}; const overridesResolver = (props, styles, name) => { const { @@ -70,7 +101,7 @@ const variantsResolver = (props, styles, theme, name) => { return variantsStyles; }; -export const SliderRoot = muiStyled( +export const SliderRoot = styled( 'div', {}, { muiName: 'MuiSlider', overridesResolver, variantsResolver }, @@ -262,6 +293,9 @@ export const SliderRoot = muiStyled( color: props.theme.palette.text.primary, }, }, + + ...overridesResolver(props, getStyleOverrides('MuiSlider', props.theme), 'MuiSlider'), + ...variantsResolver(props, getVariantStyles('MuiSlider', props.theme), props.theme, 'MuiSlider'), }; }); diff --git a/packages/material-ui/src/styles/index.d.ts b/packages/material-ui/src/styles/index.d.ts index 667a455d42e858..40e044a1d2af0f 100644 --- a/packages/material-ui/src/styles/index.d.ts +++ b/packages/material-ui/src/styles/index.d.ts @@ -24,6 +24,7 @@ export { } from './withStyles'; export { default as withTheme, WithTheme } from './withTheme'; export { default as muiStyled } from './muiStyled'; +export * from './muiStyled'; export { default as styled, ComponentCreator, StyledProps } from './styled'; export { createGenerateClassName, diff --git a/packages/material-ui/src/styles/index.js b/packages/material-ui/src/styles/index.js index fbf40a2af86190..3c893f7e3ee054 100644 --- a/packages/material-ui/src/styles/index.js +++ b/packages/material-ui/src/styles/index.js @@ -12,6 +12,7 @@ export { default as useTheme } from './useTheme'; export { default as withStyles } from './withStyles'; export { default as withTheme } from './withTheme'; export { default as muiStyled } from './muiStyled'; +export * from './muiStyled'; export { createGenerateClassName, jssPreset, diff --git a/packages/material-ui/src/styles/muiStyled.js b/packages/material-ui/src/styles/muiStyled.js index 30954d39e070f9..997d17044c5b1b 100644 --- a/packages/material-ui/src/styles/muiStyled.js +++ b/packages/material-ui/src/styles/muiStyled.js @@ -1,7 +1,7 @@ import styled from '@material-ui/styled-engine'; import { propsToClassKey } from '@material-ui/styles'; -const getStyleOverrides = (name, theme) => { +export const getStyleOverrides = (name, theme) => { let styleOverrides = {}; if ( @@ -16,7 +16,7 @@ const getStyleOverrides = (name, theme) => { return styleOverrides; }; -const getVariantStyles = (name, theme) => { +export const getVariantStyles = (name, theme) => { let variants = []; if (theme && theme.components && theme.components[name] && theme.components[name].variants) { variants = theme.components[name].variants; From dc4caeef5fdf31b002907a19c6e0d51e4a9e0b53 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 16 Sep 2020 09:53:44 +0200 Subject: [PATCH 051/125] nextjs _document update --- docs/pages/_document.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/pages/_document.js b/docs/pages/_document.js index 84aa2b00839faa..03655f26855cc3 100644 --- a/docs/pages/_document.js +++ b/docs/pages/_document.js @@ -92,23 +92,30 @@ export default class MyDocument extends Document { } } +// `getInitialProps` belongs to `_document` (instead of `_app`), +// it's compatible with static-site generation (SSG). MyDocument.getInitialProps = async (ctx) => { // Resolution order // // On the server: - // 1. page.getInitialProps - // 2. document.getInitialProps - // 3. page.render - // 4. document.render + // 1. app.getInitialProps + // 2. page.getInitialProps + // 3. document.getInitialProps + // 4. app.render + // 5. page.render + // 6. document.render // // On the server with error: - // 2. document.getInitialProps + // 1. document.getInitialProps + // 2. app.render // 3. page.render // 4. document.render // // On the client - // 1. page.getInitialProps - // 3. page.render + // 1. app.getInitialProps + // 2. page.getInitialProps + // 3. app.render + // 4. page.render // Render app and page and get the context of the page with collected side effects. const sheets = new ServerStyleSheets(); @@ -133,8 +140,10 @@ MyDocument.getInitialProps = async (ctx) => { ...initialProps, canonical: pathnameToLanguage(ctx.req.url).canonical, userLanguage: ctx.query.userLanguage || 'en', + // Styles fragment is rendered after the app and page rendering finish. styles: [ ...React.Children.toArray(initialProps.styles), + sheets.getStyleElement(),