From 5901bdabbb547598eac0036b6824cda564e07f6a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 26 Oct 2020 10:48:44 +0100 Subject: [PATCH 01/34] move core/utils to utils --- .../src}/capitalize.test.js | 0 packages/material-ui-utils/src/capitalize.ts | 13 ++ .../src/createChainedFunction.ts | 37 ++++ .../src}/debounce.test.js | 0 packages/material-ui-utils/src/debounce.ts | 26 +++ .../src/deprecatedPropType.test.ts} | 0 .../src/deprecatedPropType.ts | 20 ++ .../material-ui-utils/src/getScrollbarSize.ts | 16 ++ packages/material-ui-utils/src/index.ts | 18 ++ .../material-ui-utils/src/isMuiElement.ts | 40 ++++ .../material-ui-utils/src/ownerDocument.ts | 3 + packages/material-ui-utils/src/ownerWindow.ts | 6 + .../src}/requirePropFactory.test.js | 0 .../src/requirePropFactory.ts | 25 +++ packages/material-ui-utils/src/scrollLeft.ts | 77 ++++++++ .../src}/setRef.spec.tsx | 0 packages/material-ui-utils/src/setRef.ts | 25 +++ .../src/unsupportedProp.d.ts | 7 + .../src}/unsupportedProp.test.js | 0 .../material-ui-utils/src/unsupportedProp.ts | 19 ++ .../src}/useControlled.test.js | 0 .../material-ui-utils/src/useControlled.ts | 73 +++++++ .../src/useEnhancedEffect.d.ts | 6 + .../src/useEnhancedEffect.js | 8 + .../material-ui-utils/src/useEventCallback.ts | 16 ++ packages/material-ui-utils/src/useForkRef.ts | 19 ++ .../src}/useId.test.js | 0 packages/material-ui-utils/src/useId.ts | 18 ++ .../src/useIsFocusVisible.d.ts | 8 + .../src}/useIsFocusVisible.test.js | 0 .../src/useIsFocusVisible.ts | 178 ++++++++++++++++++ .../material-ui/src/utils/capitalize.d.ts | 4 +- packages/material-ui/src/utils/capitalize.js | 13 +- .../src/utils/createChainedFunction.d.ts | 6 +- .../src/utils/createChainedFunction.js | 32 +--- packages/material-ui/src/utils/debounce.d.ts | 9 +- packages/material-ui/src/utils/debounce.js | 19 +- .../src/utils/deprecatedPropType.d.ts | 4 +- .../src/utils/deprecatedPropType.js | 20 +- .../material-ui/src/utils/getScrollbarSize.ts | 17 +- .../material-ui/src/utils/isMuiElement.d.ts | 13 +- .../material-ui/src/utils/isMuiElement.js | 6 +- .../material-ui/src/utils/ownerDocument.ts | 6 +- packages/material-ui/src/utils/ownerWindow.ts | 7 +- .../src/utils/requirePropFactory.d.ts | 4 +- .../src/utils/requirePropFactory.js | 26 +-- packages/material-ui/src/utils/scrollLeft.js | 78 +------- packages/material-ui/src/utils/setRef.ts | 26 +-- .../src/utils/unsupportedProp.d.ts | 10 +- .../material-ui/src/utils/unsupportedProp.js | 14 +- .../material-ui/src/utils/useControlled.d.ts | 23 +-- .../material-ui/src/utils/useControlled.js | 50 +---- .../src/utils/useEnhancedEffect.d.ts | 7 +- .../src/utils/useEnhancedEffect.js | 7 +- .../src/utils/useEventCallback.d.ts | 4 +- .../material-ui/src/utils/useEventCallback.js | 15 +- .../material-ui/src/utils/useForkRef.d.ts | 4 +- packages/material-ui/src/utils/useForkRef.js | 20 +- packages/material-ui/src/utils/useId.d.ts | 4 +- packages/material-ui/src/utils/useId.js | 19 +- .../src/utils/useIsFocusVisible.d.ts | 9 +- .../src/utils/useIsFocusVisible.js | 168 +---------------- 62 files changed, 725 insertions(+), 577 deletions(-) rename packages/{material-ui/src/utils => material-ui-utils/src}/capitalize.test.js (100%) create mode 100644 packages/material-ui-utils/src/capitalize.ts create mode 100644 packages/material-ui-utils/src/createChainedFunction.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/debounce.test.js (100%) create mode 100644 packages/material-ui-utils/src/debounce.ts rename packages/{material-ui/src/utils/deprecatedPropType.test.js => material-ui-utils/src/deprecatedPropType.test.ts} (100%) create mode 100644 packages/material-ui-utils/src/deprecatedPropType.ts create mode 100644 packages/material-ui-utils/src/getScrollbarSize.ts create mode 100644 packages/material-ui-utils/src/isMuiElement.ts create mode 100644 packages/material-ui-utils/src/ownerDocument.ts create mode 100644 packages/material-ui-utils/src/ownerWindow.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/requirePropFactory.test.js (100%) create mode 100644 packages/material-ui-utils/src/requirePropFactory.ts create mode 100644 packages/material-ui-utils/src/scrollLeft.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/setRef.spec.tsx (100%) create mode 100644 packages/material-ui-utils/src/setRef.ts create mode 100644 packages/material-ui-utils/src/unsupportedProp.d.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/unsupportedProp.test.js (100%) create mode 100644 packages/material-ui-utils/src/unsupportedProp.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/useControlled.test.js (100%) create mode 100644 packages/material-ui-utils/src/useControlled.ts create mode 100644 packages/material-ui-utils/src/useEnhancedEffect.d.ts create mode 100644 packages/material-ui-utils/src/useEnhancedEffect.js create mode 100644 packages/material-ui-utils/src/useEventCallback.ts create mode 100644 packages/material-ui-utils/src/useForkRef.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/useId.test.js (100%) create mode 100644 packages/material-ui-utils/src/useId.ts create mode 100644 packages/material-ui-utils/src/useIsFocusVisible.d.ts rename packages/{material-ui/src/utils => material-ui-utils/src}/useIsFocusVisible.test.js (100%) create mode 100644 packages/material-ui-utils/src/useIsFocusVisible.ts diff --git a/packages/material-ui/src/utils/capitalize.test.js b/packages/material-ui-utils/src/capitalize.test.js similarity index 100% rename from packages/material-ui/src/utils/capitalize.test.js rename to packages/material-ui-utils/src/capitalize.test.js diff --git a/packages/material-ui-utils/src/capitalize.ts b/packages/material-ui-utils/src/capitalize.ts new file mode 100644 index 00000000000000..d1ab320ca7d005 --- /dev/null +++ b/packages/material-ui-utils/src/capitalize.ts @@ -0,0 +1,13 @@ +// TODO: error TS7016: Could not find a declaration file for module '../macros/MuiError.macro'. '/tmp/material-ui/packages/material-ui-utils/macros/MuiError.macro.js' implicitly has an 'any' type. +// import MuiError from '../macros/MuiError.macro'; +// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. +// +// A strict capitalization should uppercase the first letter of each word a the sentence. +// We only handle the first word. +export default function capitalize(string: string): string { + if (typeof string !== 'string') { + throw new Error('Material-UI: capitalize(string) expects a string argument.'); + } + + return string.charAt(0).toUpperCase() + string.slice(1); +} diff --git a/packages/material-ui-utils/src/createChainedFunction.ts b/packages/material-ui-utils/src/createChainedFunction.ts new file mode 100644 index 00000000000000..dd7a827f5d7ccc --- /dev/null +++ b/packages/material-ui-utils/src/createChainedFunction.ts @@ -0,0 +1,37 @@ +export type ChainedFunction = ((...args: any[]) => void) | undefined | null; + +/** + * Safe chained function + * + * Will only create a new function if needed, + * otherwise will pass back existing functions or null. + * @param {function} functions to chain + * @returns {function|null} + */ +export default function createChainedFunction( + ...funcs: ChainedFunction[] +): (...args: any[]) => never { + return funcs.reduce( + (acc, func) => { + if (func == null) { + return acc; + } + + if (process.env.NODE_ENV !== 'production') { + if (typeof func !== 'function') { + console.error( + 'Material-UI: Invalid Argument Type, must only provide functions, undefined, or null.', + ); + } + } + + return function chainedFunction(...args) { + // @ts-ignore + acc.apply(this, args); + // @ts-ignore + func.apply(this, args); + }; + }, + () => {}, + ) as (...args: any[]) => never; +} diff --git a/packages/material-ui/src/utils/debounce.test.js b/packages/material-ui-utils/src/debounce.test.js similarity index 100% rename from packages/material-ui/src/utils/debounce.test.js rename to packages/material-ui-utils/src/debounce.test.js diff --git a/packages/material-ui-utils/src/debounce.ts b/packages/material-ui-utils/src/debounce.ts new file mode 100644 index 00000000000000..18e67eaa10cf9b --- /dev/null +++ b/packages/material-ui-utils/src/debounce.ts @@ -0,0 +1,26 @@ +export interface Cancelable { + clear(): void; +} + +// Corresponds to 10 frames at 60 Hz. +// A few bytes payload overhead when lodash/debounce is ~3 kB and debounce ~300 B. +export default function debounce any>( + func: T, + wait: number = 166, +): T & Cancelable { + let timeout: any; + function debounced(...args: any[]) { + const later = () => { + // @ts-ignore + func.apply(this, args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + } + + debounced.clear = () => { + clearTimeout(timeout); + }; + + return debounced as T & Cancelable; +} diff --git a/packages/material-ui/src/utils/deprecatedPropType.test.js b/packages/material-ui-utils/src/deprecatedPropType.test.ts similarity index 100% rename from packages/material-ui/src/utils/deprecatedPropType.test.js rename to packages/material-ui-utils/src/deprecatedPropType.test.ts diff --git a/packages/material-ui-utils/src/deprecatedPropType.ts b/packages/material-ui-utils/src/deprecatedPropType.ts new file mode 100644 index 00000000000000..9cef6f880699cb --- /dev/null +++ b/packages/material-ui-utils/src/deprecatedPropType.ts @@ -0,0 +1,20 @@ +export default function deprecatedPropType(validator: T, reason: string): T | Function { + if (process.env.NODE_ENV === 'production') { + return () => null; + } + + // @ts-ignore + return (props, propName, componentName, location, propFullName) => { + const componentNameSafe = componentName || '<>'; + const propFullNameSafe = propFullName || propName; + + if (typeof props[propName] !== 'undefined') { + return new Error( + `The ${location} \`${propFullNameSafe}\` of ` + + `\`${componentNameSafe}\` is deprecated. ${reason}`, + ); + } + + return null; + }; +} diff --git a/packages/material-ui-utils/src/getScrollbarSize.ts b/packages/material-ui-utils/src/getScrollbarSize.ts new file mode 100644 index 00000000000000..33c787300c6d37 --- /dev/null +++ b/packages/material-ui-utils/src/getScrollbarSize.ts @@ -0,0 +1,16 @@ +// A change of the browser zoom change the scrollbar size. +// Credit https://github.com/twbs/bootstrap/blob/3ffe3a5d82f6f561b82ff78d82b32a7d14aed558/js/src/modal.js#L512-L519 +export default function getScrollbarSize(doc: Document): number { + const scrollDiv = doc.createElement('div'); + scrollDiv.style.width = '99px'; + scrollDiv.style.height = '99px'; + scrollDiv.style.position = 'absolute'; + scrollDiv.style.top = '-9999px'; + scrollDiv.style.overflow = 'scroll'; + + doc.body.appendChild(scrollDiv); + const scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; + doc.body.removeChild(scrollDiv); + + return scrollbarSize; +} diff --git a/packages/material-ui-utils/src/index.ts b/packages/material-ui-utils/src/index.ts index 03b77400974236..a9944e8a6f3bb9 100644 --- a/packages/material-ui-utils/src/index.ts +++ b/packages/material-ui-utils/src/index.ts @@ -8,3 +8,21 @@ export { default as getDisplayName } from './getDisplayName'; export { default as HTMLElementType } from './HTMLElementType'; export { default as ponyfillGlobal } from './ponyfillGlobal'; export { default as refType } from './refType'; +export { default as capitalize } from './capitalize'; +export { default as createChainedFunction } from './createChainedFunction'; +export { default as debounce } from './debounce'; +export { default as deprecatedPropType } from './deprecatedPropType'; +export { default as isMuiElement } from './isMuiElement'; +export { default as ownerDocument } from './ownerDocument'; +export { default as ownerWindow } from './ownerWindow'; +export { default as requirePropFactory } from './requirePropFactory'; +export { default as setRef } from './setRef'; +export { default as unstable_useEnhancedEffect } from './useEnhancedEffect'; +export { default as unstable_useId } from './useId'; +export { default as unsupportedProp } from './unsupportedProp'; +export { default as useControlled } from './useControlled'; +export { default as useEventCallback } from './useEventCallback'; +export { default as useForkRef } from './useForkRef'; +export { default as useIsFocusVisible } from './useIsFocusVisible'; +export { default as getScrollbarSize } from './getScrollbarSize'; +export { detectScrollType, getNormalizedScrollLeft } from './scrollLeft'; diff --git a/packages/material-ui-utils/src/isMuiElement.ts b/packages/material-ui-utils/src/isMuiElement.ts new file mode 100644 index 00000000000000..5823dbd77d2ae7 --- /dev/null +++ b/packages/material-ui-utils/src/isMuiElement.ts @@ -0,0 +1,40 @@ +import * as React from 'react'; + +export type ClassNameMap = Record; + +export interface StyledComponentProps { + /** + * Override or extend the styles applied to the component. + */ + classes?: Partial>; + innerRef?: React.Ref; +} + +/** + * @private ONLY USE FROM WITHIN mui-org/material-ui + * + * Internal helper type for conform (describeConformance) components that are decorated with `withStyles + * However, we don't declare classes on this type. + * It is recommended to declare them manually with an interface so that each class can have a separate JSDOC. + */ +export type StandardProps = Omit & + // each component declares it's classes in a separate interface for proper JSDOC + StyledComponentProps & { + ref?: C extends { ref?: infer RefType } ? RefType : React.Ref; + // TODO: Remove implicit props. Up to each component. + className?: string; + style?: React.CSSProperties; + }; + +export type NamedMuiComponent = React.ComponentType & { muiName: string }; + +export interface NamedMuiElement { + type: NamedMuiComponent; + props: StandardProps<{}>; + key: string | number | null; +} + +export default function isMuiElement(element: any, muiNames: string[]): element is NamedMuiElement { + // @ts-ignore + return React.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1; +} diff --git a/packages/material-ui-utils/src/ownerDocument.ts b/packages/material-ui-utils/src/ownerDocument.ts new file mode 100644 index 00000000000000..eed9b51474ccbf --- /dev/null +++ b/packages/material-ui-utils/src/ownerDocument.ts @@ -0,0 +1,3 @@ +export default function ownerDocument(node: Node | undefined): Document { + return (node && node.ownerDocument) || document; +} diff --git a/packages/material-ui-utils/src/ownerWindow.ts b/packages/material-ui-utils/src/ownerWindow.ts new file mode 100644 index 00000000000000..b1b796370bcc3d --- /dev/null +++ b/packages/material-ui-utils/src/ownerWindow.ts @@ -0,0 +1,6 @@ +import ownerDocument from './ownerDocument'; + +export default function ownerWindow(node: Node | undefined): Window { + const doc = ownerDocument(node); + return doc.defaultView || window; +} diff --git a/packages/material-ui/src/utils/requirePropFactory.test.js b/packages/material-ui-utils/src/requirePropFactory.test.js similarity index 100% rename from packages/material-ui/src/utils/requirePropFactory.test.js rename to packages/material-ui-utils/src/requirePropFactory.test.js diff --git a/packages/material-ui-utils/src/requirePropFactory.ts b/packages/material-ui-utils/src/requirePropFactory.ts new file mode 100644 index 00000000000000..3fd8625b51f868 --- /dev/null +++ b/packages/material-ui-utils/src/requirePropFactory.ts @@ -0,0 +1,25 @@ +export default function requirePropFactory(componentNameInError: string): any { + if (process.env.NODE_ENV === 'production') { + return () => null; + } + + const requireProp = (requiredProp: string): any => ( + props: { [key: string]: any }, + propName: string, + componentName: string, + location: string, + propFullName: string, + ) => { + const propFullNameSafe = propFullName || propName; + + if (typeof props[propName] !== 'undefined' && !props[requiredProp]) { + return new Error( + `The prop \`${propFullNameSafe}\` of ` + + `\`${componentNameInError}\` must be used on \`${requiredProp}\`.`, + ); + } + + return null; + }; + return requireProp; +} diff --git a/packages/material-ui-utils/src/scrollLeft.ts b/packages/material-ui-utils/src/scrollLeft.ts new file mode 100644 index 00000000000000..a54811f3171c64 --- /dev/null +++ b/packages/material-ui-utils/src/scrollLeft.ts @@ -0,0 +1,77 @@ +// Source from https://github.com/alitaheri/normalize-scroll-left +let cachedType: string; + +/** + * Based on the jquery plugin https://github.com/othree/jquery.rtl-scroll-type + * + * Types of scrollLeft, assuming scrollWidth=100 and direction is rtl. + * + * Type | <- Most Left | Most Right -> | Initial + * ---------------- | ------------ | ------------- | ------- + * default | 0 | 100 | 100 + * negative (spec*) | -100 | 0 | 0 + * reverse | 100 | 0 | 0 + * + * Edge 85: default + * Safari 14: negative + * Chrome 85: negative + * Firefox 81: negative + * IE11: reverse + * + * spec* https://drafts.csswg.org/cssom-view/#dom-window-scroll + */ +export function detectScrollType(): string { + if (cachedType) { + return cachedType; + } + + const dummy = document.createElement('div'); + const container = document.createElement('div'); + container.style.width = '10px'; + container.style.height = '1px'; + dummy.appendChild(container); + dummy.dir = 'rtl'; + dummy.style.fontSize = '14px'; + dummy.style.width = '4px'; + dummy.style.height = '1px'; + dummy.style.position = 'absolute'; + dummy.style.top = '-1000px'; + dummy.style.overflow = 'scroll'; + + document.body.appendChild(dummy); + + cachedType = 'reverse'; + + if (dummy.scrollLeft > 0) { + cachedType = 'default'; + } else { + dummy.scrollLeft = 1; + if (dummy.scrollLeft === 0) { + cachedType = 'negative'; + } + } + + document.body.removeChild(dummy); + return cachedType; +} + +// Based on https://stackoverflow.com/a/24394376 +export function getNormalizedScrollLeft(element: Element, direction: string): number { + const scrollLeft = element.scrollLeft; + + // Perform the calculations only when direction is rtl to avoid messing up the ltr behavior + if (direction !== 'rtl') { + return scrollLeft; + } + + const type = detectScrollType(); + + switch (type) { + case 'negative': + return element.scrollWidth - element.clientWidth + scrollLeft; + case 'reverse': + return element.scrollWidth - element.clientWidth - scrollLeft; + default: + return scrollLeft; + } +} diff --git a/packages/material-ui/src/utils/setRef.spec.tsx b/packages/material-ui-utils/src/setRef.spec.tsx similarity index 100% rename from packages/material-ui/src/utils/setRef.spec.tsx rename to packages/material-ui-utils/src/setRef.spec.tsx diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts new file mode 100644 index 00000000000000..29ebef0d3527c7 --- /dev/null +++ b/packages/material-ui-utils/src/setRef.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; + +/** + * TODO v5: consider to make it private + * + * passes {value} to {ref} + * + * WARNING: Be sure to only call this inside a callback that is passed as a ref. + * Otherwise make sure to cleanup previous {ref} if it changes. See + * https://github.com/mui-org/material-ui/issues/13539 + * + * useful if you want to expose the ref of an inner component to the public api + * while still using it inside the component + * @param ref a ref callback or ref object if anything falsy this is a no-op + */ +export default function setRef( + ref: React.MutableRefObject | ((instance: T | null) => void) | null | undefined, + value: T | null, +): void { + if (typeof ref === 'function') { + ref(value); + } else if (ref) { + ref.current = value; + } +} diff --git a/packages/material-ui-utils/src/unsupportedProp.d.ts b/packages/material-ui-utils/src/unsupportedProp.d.ts new file mode 100644 index 00000000000000..e08c9a729fccab --- /dev/null +++ b/packages/material-ui-utils/src/unsupportedProp.d.ts @@ -0,0 +1,7 @@ +export default function unsupportedProp( + props: { [key: string]: any }, + propName: string, + componentName: string, + location: string, + propFullName: string +): Error | null; diff --git a/packages/material-ui/src/utils/unsupportedProp.test.js b/packages/material-ui-utils/src/unsupportedProp.test.js similarity index 100% rename from packages/material-ui/src/utils/unsupportedProp.test.js rename to packages/material-ui-utils/src/unsupportedProp.test.js diff --git a/packages/material-ui-utils/src/unsupportedProp.ts b/packages/material-ui-utils/src/unsupportedProp.ts new file mode 100644 index 00000000000000..b92f324400e8a8 --- /dev/null +++ b/packages/material-ui-utils/src/unsupportedProp.ts @@ -0,0 +1,19 @@ +export default function unsupportedProp( + props: { [key: string]: any }, + propName: string, + componentName: string, + location: string, + propFullName: string, +): Error | null { + if (process.env.NODE_ENV === 'production') { + return null; + } + + const propFullNameSafe = propFullName || propName; + + if (typeof props[propName] !== 'undefined') { + return new Error(`The prop \`${propFullNameSafe}\` is not supported. Please remove it.`); + } + + return null; +} diff --git a/packages/material-ui/src/utils/useControlled.test.js b/packages/material-ui-utils/src/useControlled.test.js similarity index 100% rename from packages/material-ui/src/utils/useControlled.test.js rename to packages/material-ui-utils/src/useControlled.test.js diff --git a/packages/material-ui-utils/src/useControlled.ts b/packages/material-ui-utils/src/useControlled.ts new file mode 100644 index 00000000000000..6509ea3d40085e --- /dev/null +++ b/packages/material-ui-utils/src/useControlled.ts @@ -0,0 +1,73 @@ +/* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */ +import * as React from 'react'; + +export interface UseControlledProps { + /** + * This prop contains the component value when it's controlled. + */ + controlled: T | undefined; + /** + * The default value when uncontrolled. + */ + default: T | undefined; + /** + * The component name displayed in warnings. + */ + name: string; + /** + * The name of the state variable displayed in warnings. + */ + state?: string; +} + +export default function useControlled({ + controlled, + default: defaultProp, + name, + state = 'value', +}: UseControlledProps): [T, (newValue: T) => void] { + // isControlled is ignored in the hook dependency lists as it should never change. + const { current: isControlled } = React.useRef(controlled !== undefined); + const [valueState, setValue] = React.useState(defaultProp); + const value = isControlled ? controlled : valueState; + + if (process.env.NODE_ENV !== 'production') { + React.useEffect(() => { + if (isControlled !== (controlled !== undefined)) { + console.error( + [ + `Material-UI: A component is changing the ${ + isControlled ? '' : 'un' + }controlled ${state} state of ${name} to be ${isControlled ? 'un' : ''}controlled.`, + 'Elements should not switch from uncontrolled to controlled (or vice versa).', + `Decide between using a controlled or uncontrolled ${name} ` + + 'element for the lifetime of the component.', + "The nature of the state is determined during the first render, it's considered controlled if the value is not `undefined`.", + 'More info: https://fb.me/react-controlled-components', + ].join('\n'), + ); + } + }, [state, name, controlled]); + + const { current: defaultValue } = React.useRef(defaultProp); + + React.useEffect(() => { + if (!isControlled && defaultValue !== defaultProp) { + console.error( + [ + `Material-UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` + + `To suppress this warning opt to use a controlled ${name}.`, + ].join('\n'), + ); + } + }, [JSON.stringify(defaultProp)]); + } + + const setValueIfUncontrolled = React.useCallback((newValue) => { + if (!isControlled) { + setValue(newValue); + } + }, []); + + return [value, setValueIfUncontrolled] as [T, (newValue: T) => void]; +} diff --git a/packages/material-ui-utils/src/useEnhancedEffect.d.ts b/packages/material-ui-utils/src/useEnhancedEffect.d.ts new file mode 100644 index 00000000000000..9d060a00b0230c --- /dev/null +++ b/packages/material-ui-utils/src/useEnhancedEffect.d.ts @@ -0,0 +1,6 @@ +import * as React from 'react'; + +export default function useEnhancedEffect( + effect: React.EffectCallback, + deps?: React.DependencyList +): void; diff --git a/packages/material-ui-utils/src/useEnhancedEffect.js b/packages/material-ui-utils/src/useEnhancedEffect.js new file mode 100644 index 00000000000000..beefea01128179 --- /dev/null +++ b/packages/material-ui-utils/src/useEnhancedEffect.js @@ -0,0 +1,8 @@ +import * as React from 'react'; + +const useEnhancedEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect; + +/** + * Private module reserved for @material-ui packages. + */ +export default useEnhancedEffect; diff --git a/packages/material-ui-utils/src/useEventCallback.ts b/packages/material-ui-utils/src/useEventCallback.ts new file mode 100644 index 00000000000000..6988f5e51df07a --- /dev/null +++ b/packages/material-ui-utils/src/useEventCallback.ts @@ -0,0 +1,16 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +import * as React from 'react'; +import useEnhancedEffect from './useEnhancedEffect'; + +/** + * https://github.com/facebook/react/issues/14099#issuecomment-440013892 + * @param {function} fn + */ +export default function useEventCallback any>(fn: T): T { + const ref = React.useRef(fn); + useEnhancedEffect(() => { + ref.current = fn; + }); + // @ts-ignore + return React.useCallback(((...args) => (0, ref.current)(...args)) as T, []); +} diff --git a/packages/material-ui-utils/src/useForkRef.ts b/packages/material-ui-utils/src/useForkRef.ts new file mode 100644 index 00000000000000..8efcc40c3bda76 --- /dev/null +++ b/packages/material-ui-utils/src/useForkRef.ts @@ -0,0 +1,19 @@ +import * as React from 'react'; +import setRef from './setRef'; + +export default function useForkRef(refA: React.Ref, refB: React.Ref): React.Ref { + /** + * This will create a new function if the ref props change and are defined. + * This means react will call the old forkRef with `null` and the new forkRef + * with the ref. Cleanup naturally emerges from this behavior + */ + return React.useMemo(() => { + if (refA == null && refB == null) { + return null; + } + return (refValue) => { + setRef(refA, refValue); + setRef(refB, refValue); + }; + }, [refA, refB]); +} diff --git a/packages/material-ui/src/utils/useId.test.js b/packages/material-ui-utils/src/useId.test.js similarity index 100% rename from packages/material-ui/src/utils/useId.test.js rename to packages/material-ui-utils/src/useId.test.js diff --git a/packages/material-ui-utils/src/useId.ts b/packages/material-ui-utils/src/useId.ts new file mode 100644 index 00000000000000..bf9f068219c456 --- /dev/null +++ b/packages/material-ui-utils/src/useId.ts @@ -0,0 +1,18 @@ +import * as React from 'react'; + +/** + * Private module reserved for @material-ui packages. + */ +export default function useId(idOverride?: string): string { + const [defaultId, setDefaultId] = React.useState(idOverride); + const id = idOverride || defaultId; + React.useEffect(() => { + if (defaultId == null) { + // Fallback to this default id when possible. + // Use the random value for client-side rendering only. + // We can't use it server-side. + setDefaultId(`mui-${Math.round(Math.random() * 1e5)}`); + } + }, [defaultId]); + return id as string; +} diff --git a/packages/material-ui-utils/src/useIsFocusVisible.d.ts b/packages/material-ui-utils/src/useIsFocusVisible.d.ts new file mode 100644 index 00000000000000..bc64b8b201deb7 --- /dev/null +++ b/packages/material-ui-utils/src/useIsFocusVisible.d.ts @@ -0,0 +1,8 @@ +import * as React from 'react'; + +export default function useIsFocusVisible(): { + isFocusVisibleRef: React.MutableRefObject; + onBlur: (event: React.FocusEvent) => void; + onFocus: (event: React.FocusEvent) => void; + ref: React.Ref; +}; diff --git a/packages/material-ui/src/utils/useIsFocusVisible.test.js b/packages/material-ui-utils/src/useIsFocusVisible.test.js similarity index 100% rename from packages/material-ui/src/utils/useIsFocusVisible.test.js rename to packages/material-ui-utils/src/useIsFocusVisible.test.js diff --git a/packages/material-ui-utils/src/useIsFocusVisible.ts b/packages/material-ui-utils/src/useIsFocusVisible.ts new file mode 100644 index 00000000000000..974762e9e87781 --- /dev/null +++ b/packages/material-ui-utils/src/useIsFocusVisible.ts @@ -0,0 +1,178 @@ +// based on https://github.com/WICG/focus-visible/blob/v4.1.5/src/focus-visible.js +import * as React from 'react'; + +let hadKeyboardEvent = true; +let hadFocusVisibleRecently = false; +let hadFocusVisibleRecentlyTimeout: any = null; + +const inputTypesWhitelist = { + text: true, + search: true, + url: true, + tel: true, + email: true, + password: true, + number: true, + date: true, + month: true, + week: true, + time: true, + datetime: true, + 'datetime-local': true, +}; + +/** + * Computes whether the given element should automatically trigger the + * `focus-visible` class being added, i.e. whether it should always match + * `:focus-visible` when focused. + * @param {Element} node + * @returns {boolean} + */ +// @ts-ignore +function focusTriggersKeyboardModality(node) { + const { type, tagName } = node; + + // @ts-ignore + if (tagName === 'INPUT' && inputTypesWhitelist[type] && !node.readOnly) { + return true; + } + + if (tagName === 'TEXTAREA' && !node.readOnly) { + return true; + } + + if (node.isContentEditable) { + return true; + } + + return false; +} + +/** + * Keep track of our keyboard modality state with `hadKeyboardEvent`. + * If the most recent user interaction was via the keyboard; + * and the key press did not include a meta, alt/option, or control key; + * then the modality is keyboard. Otherwise, the modality is not keyboard. + * @param {KeyboardEvent} event + */ +// @ts-ignore +function handleKeyDown(event) { + if (event.metaKey || event.altKey || event.ctrlKey) { + return; + } + hadKeyboardEvent = true; +} + +/** + * If at any point a user clicks with a pointing device, ensure that we change + * the modality away from keyboard. + * This avoids the situation where a user presses a key on an already focused + * element, and then clicks on a different element, focusing it with a + * pointing device, while we still think we're in keyboard modality. + */ +function handlePointerDown() { + hadKeyboardEvent = false; +} + +function handleVisibilityChange() { + // @ts-ignore + if (this.visibilityState === 'hidden') { + // If the tab becomes active again, the browser will handle calling focus + // on the element (Safari actually calls it twice). + // If this tab change caused a blur on an element with focus-visible, + // re-apply the class when the user switches back to the tab. + if (hadFocusVisibleRecently) { + hadKeyboardEvent = true; + } + } +} + +function prepare(doc: Document) { + doc.addEventListener('keydown', handleKeyDown, true); + doc.addEventListener('mousedown', handlePointerDown, true); + doc.addEventListener('pointerdown', handlePointerDown, true); + doc.addEventListener('touchstart', handlePointerDown, true); + doc.addEventListener('visibilitychange', handleVisibilityChange, true); +} + +export function teardown(doc: Document) { + doc.removeEventListener('keydown', handleKeyDown, true); + doc.removeEventListener('mousedown', handlePointerDown, true); + doc.removeEventListener('pointerdown', handlePointerDown, true); + doc.removeEventListener('touchstart', handlePointerDown, true); + doc.removeEventListener('visibilitychange', handleVisibilityChange, true); +} + +// @ts-ignore +function isFocusVisible(event) { + const { target } = event; + try { + return target.matches(':focus-visible'); + } catch (error) { + // browsers not implementing :focus-visible will throw a SyntaxError + // we use our own heuristic for those browsers + // rethrow might be better if it's not the expected error but do we really + // want to crash if focus-visible malfunctioned? + } + + // no need for validFocusTarget check. the user does that by attaching it to + // focusable events only + return hadKeyboardEvent || focusTriggersKeyboardModality(target); +} + +export default function useIsFocusVisible(): { + isFocusVisibleRef: React.MutableRefObject; + onBlur: (event: React.FocusEvent) => void; + onFocus: (event: React.FocusEvent) => void; + ref: React.Ref; +} { + const ref = React.useCallback((node) => { + if (node != null) { + prepare(node.ownerDocument); + } + }, []); + + const isFocusVisibleRef = React.useRef(false); + + /** + * Should be called if a blur event is fired + */ + function handleBlurVisible() { + // checking against potential state variable does not suffice if we focus and blur synchronously. + // React wouldn't have time to trigger a re-render so `focusVisible` would be stale. + // Ideally we would adjust `isFocusVisible(event)` to look at `relatedTarget` for blur events. + // This doesn't work in IE11 due to https://github.com/facebook/react/issues/3751 + // TODO: check again if React releases their internal changes to focus event handling (https://github.com/facebook/react/pull/19186). + if (isFocusVisibleRef.current) { + // To detect a tab/window switch, we look for a blur event followed + // rapidly by a visibility change. + // If we don't see a visibility change within 100ms, it's probably a + // regular focus change. + hadFocusVisibleRecently = true; + window.clearTimeout(hadFocusVisibleRecentlyTimeout); + hadFocusVisibleRecentlyTimeout = window.setTimeout(() => { + hadFocusVisibleRecently = false; + }, 100); + + isFocusVisibleRef.current = false; + + return true; + } + + return false; + } + + /** + * Should be called if a blur event is fired + */ + // @ts-ignore + function handleFocusVisible(event) { + if (isFocusVisible(event)) { + isFocusVisibleRef.current = true; + return true; + } + return false; + } + + return { isFocusVisibleRef, onFocus: handleFocusVisible, onBlur: handleBlurVisible, ref }; +} diff --git a/packages/material-ui/src/utils/capitalize.d.ts b/packages/material-ui/src/utils/capitalize.d.ts index 3fc792144be532..0ff91901fa1280 100644 --- a/packages/material-ui/src/utils/capitalize.d.ts +++ b/packages/material-ui/src/utils/capitalize.d.ts @@ -1 +1,3 @@ -export default function capitalize(string: string): string; +import { capitalize } from '@material-ui/utils'; + +export default capitalize; diff --git a/packages/material-ui/src/utils/capitalize.js b/packages/material-ui/src/utils/capitalize.js index 4c87d3020595a1..0ff91901fa1280 100644 --- a/packages/material-ui/src/utils/capitalize.js +++ b/packages/material-ui/src/utils/capitalize.js @@ -1,12 +1,3 @@ -import MuiError from '@material-ui/utils/macros/MuiError.macro'; -// It should to be noted that this function isn't equivalent to `text-transform: capitalize`. -// -// A strict capitalization should uppercase the first letter of each word a the sentence. -// We only handle the first word. -export default function capitalize(string) { - if (typeof string !== 'string') { - throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); - } +import { capitalize } from '@material-ui/utils'; - return string.charAt(0).toUpperCase() + string.slice(1); -} +export default capitalize; diff --git a/packages/material-ui/src/utils/createChainedFunction.d.ts b/packages/material-ui/src/utils/createChainedFunction.d.ts index 53d4a3c3d378a2..acaffd5d8b700f 100644 --- a/packages/material-ui/src/utils/createChainedFunction.d.ts +++ b/packages/material-ui/src/utils/createChainedFunction.d.ts @@ -1,5 +1,3 @@ -export type ChainedFunction = ((...args: any[]) => void) | undefined | null; +import { createChainedFunction } from '@material-ui/utils'; -export default function createChainedFunction( - ...funcs: ChainedFunction[] -): (...args: any[]) => never; +export default createChainedFunction; diff --git a/packages/material-ui/src/utils/createChainedFunction.js b/packages/material-ui/src/utils/createChainedFunction.js index a023586cc3ea88..acaffd5d8b700f 100644 --- a/packages/material-ui/src/utils/createChainedFunction.js +++ b/packages/material-ui/src/utils/createChainedFunction.js @@ -1,31 +1,3 @@ -/** - * Safe chained function - * - * Will only create a new function if needed, - * otherwise will pass back existing functions or null. - * @param {function} functions to chain - * @returns {function|null} - */ -export default function createChainedFunction(...funcs) { - return funcs.reduce( - (acc, func) => { - if (func == null) { - return acc; - } +import { createChainedFunction } from '@material-ui/utils'; - if (process.env.NODE_ENV !== 'production') { - if (typeof func !== 'function') { - console.error( - 'Material-UI: Invalid Argument Type, must only provide functions, undefined, or null.', - ); - } - } - - return function chainedFunction(...args) { - acc.apply(this, args); - func.apply(this, args); - }; - }, - () => {}, - ); -} +export default createChainedFunction; diff --git a/packages/material-ui/src/utils/debounce.d.ts b/packages/material-ui/src/utils/debounce.d.ts index ead5017e3d59cc..cf9df8d0377b23 100644 --- a/packages/material-ui/src/utils/debounce.d.ts +++ b/packages/material-ui/src/utils/debounce.d.ts @@ -1,8 +1,3 @@ -export interface Cancelable { - clear(): void; -} +import { debounce } from '@material-ui/utils'; -export default function debounce any>( - func: T, - wait?: number -): T & Cancelable; +export default debounce; diff --git a/packages/material-ui/src/utils/debounce.js b/packages/material-ui/src/utils/debounce.js index 7b47300636d936..cf9df8d0377b23 100644 --- a/packages/material-ui/src/utils/debounce.js +++ b/packages/material-ui/src/utils/debounce.js @@ -1,18 +1,3 @@ -// Corresponds to 10 frames at 60 Hz. -// A few bytes payload overhead when lodash/debounce is ~3 kB and debounce ~300 B. -export default function debounce(func, wait = 166) { - let timeout; - function debounced(...args) { - const later = () => { - func.apply(this, args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - } +import { debounce } from '@material-ui/utils'; - debounced.clear = () => { - clearTimeout(timeout); - }; - - return debounced; -} +export default debounce; diff --git a/packages/material-ui/src/utils/deprecatedPropType.d.ts b/packages/material-ui/src/utils/deprecatedPropType.d.ts index b21c9a984992e4..1772f7c5876ed2 100644 --- a/packages/material-ui/src/utils/deprecatedPropType.d.ts +++ b/packages/material-ui/src/utils/deprecatedPropType.d.ts @@ -1 +1,3 @@ -export default function deprecatedPropType(validator: T, reason: string): T; +import { deprecatedPropType } from '@material-ui/utils'; + +export default deprecatedPropType; diff --git a/packages/material-ui/src/utils/deprecatedPropType.js b/packages/material-ui/src/utils/deprecatedPropType.js index 66b0caed3b0185..1772f7c5876ed2 100644 --- a/packages/material-ui/src/utils/deprecatedPropType.js +++ b/packages/material-ui/src/utils/deprecatedPropType.js @@ -1,19 +1,3 @@ -export default function deprecatedPropType(validator, reason) { - if (process.env.NODE_ENV === 'production') { - return () => null; - } +import { deprecatedPropType } from '@material-ui/utils'; - return (props, propName, componentName, location, propFullName) => { - const componentNameSafe = componentName || '<>'; - const propFullNameSafe = propFullName || propName; - - if (typeof props[propName] !== 'undefined') { - return new Error( - `The ${location} \`${propFullNameSafe}\` of ` + - `\`${componentNameSafe}\` is deprecated. ${reason}`, - ); - } - - return null; - }; -} +export default deprecatedPropType; diff --git a/packages/material-ui/src/utils/getScrollbarSize.ts b/packages/material-ui/src/utils/getScrollbarSize.ts index 33c787300c6d37..e26b87399ce8c6 100644 --- a/packages/material-ui/src/utils/getScrollbarSize.ts +++ b/packages/material-ui/src/utils/getScrollbarSize.ts @@ -1,16 +1,3 @@ -// A change of the browser zoom change the scrollbar size. -// Credit https://github.com/twbs/bootstrap/blob/3ffe3a5d82f6f561b82ff78d82b32a7d14aed558/js/src/modal.js#L512-L519 -export default function getScrollbarSize(doc: Document): number { - const scrollDiv = doc.createElement('div'); - scrollDiv.style.width = '99px'; - scrollDiv.style.height = '99px'; - scrollDiv.style.position = 'absolute'; - scrollDiv.style.top = '-9999px'; - scrollDiv.style.overflow = 'scroll'; +import { getScrollbarSize } from '@material-ui/utils'; - doc.body.appendChild(scrollDiv); - const scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; - doc.body.removeChild(scrollDiv); - - return scrollbarSize; -} +export default getScrollbarSize; diff --git a/packages/material-ui/src/utils/isMuiElement.d.ts b/packages/material-ui/src/utils/isMuiElement.d.ts index e15f13bdaf60fc..4f4f3013c87ad0 100644 --- a/packages/material-ui/src/utils/isMuiElement.d.ts +++ b/packages/material-ui/src/utils/isMuiElement.d.ts @@ -1,12 +1,3 @@ -import * as React from 'react'; -import { InternalStandardProps as StandardProps } from '..'; +import { isMuiElement } from '@material-ui/utils'; -export type NamedMuiComponent = React.ComponentType & { muiName: string }; - -export interface NamedMuiElement { - type: NamedMuiComponent; - props: StandardProps<{}>; - key: string | number | null; -} - -export default function isMuiElement(element: any, muiNames: string[]): element is NamedMuiElement; +export default isMuiElement; diff --git a/packages/material-ui/src/utils/isMuiElement.js b/packages/material-ui/src/utils/isMuiElement.js index e64372aa6ae18d..4f4f3013c87ad0 100644 --- a/packages/material-ui/src/utils/isMuiElement.js +++ b/packages/material-ui/src/utils/isMuiElement.js @@ -1,5 +1,3 @@ -import * as React from 'react'; +import { isMuiElement } from '@material-ui/utils'; -export default function isMuiElement(element, muiNames) { - return React.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1; -} +export default isMuiElement; diff --git a/packages/material-ui/src/utils/ownerDocument.ts b/packages/material-ui/src/utils/ownerDocument.ts index eed9b51474ccbf..06e7d93e535795 100644 --- a/packages/material-ui/src/utils/ownerDocument.ts +++ b/packages/material-ui/src/utils/ownerDocument.ts @@ -1,3 +1,3 @@ -export default function ownerDocument(node: Node | undefined): Document { - return (node && node.ownerDocument) || document; -} +import { ownerDocument } from '@material-ui/utils'; + +export default ownerDocument; diff --git a/packages/material-ui/src/utils/ownerWindow.ts b/packages/material-ui/src/utils/ownerWindow.ts index b1b796370bcc3d..b8833afc28d338 100644 --- a/packages/material-ui/src/utils/ownerWindow.ts +++ b/packages/material-ui/src/utils/ownerWindow.ts @@ -1,6 +1,3 @@ -import ownerDocument from './ownerDocument'; +import { ownerWindow } from '@material-ui/utils'; -export default function ownerWindow(node: Node | undefined): Window { - const doc = ownerDocument(node); - return doc.defaultView || window; -} +export default ownerWindow; diff --git a/packages/material-ui/src/utils/requirePropFactory.d.ts b/packages/material-ui/src/utils/requirePropFactory.d.ts index 63ae30db9f2831..31be0e9d3ca142 100644 --- a/packages/material-ui/src/utils/requirePropFactory.d.ts +++ b/packages/material-ui/src/utils/requirePropFactory.d.ts @@ -1 +1,3 @@ -export default function requirePropFactory(componentNameInError: string): any; +import { requirePropFactory } from '@material-ui/utils'; + +export default requirePropFactory; diff --git a/packages/material-ui/src/utils/requirePropFactory.js b/packages/material-ui/src/utils/requirePropFactory.js index 4d6707aab111be..31be0e9d3ca142 100644 --- a/packages/material-ui/src/utils/requirePropFactory.js +++ b/packages/material-ui/src/utils/requirePropFactory.js @@ -1,25 +1,3 @@ -export default function requirePropFactory(componentNameInError) { - if (process.env.NODE_ENV === 'production') { - return () => null; - } +import { requirePropFactory } from '@material-ui/utils'; - const requireProp = (requiredProp) => ( - props, - propName, - componentName, - location, - propFullName, - ) => { - const propFullNameSafe = propFullName || propName; - - if (typeof props[propName] !== 'undefined' && !props[requiredProp]) { - return new Error( - `The prop \`${propFullNameSafe}\` of ` + - `\`${componentNameInError}\` must be used on \`${requiredProp}\`.`, - ); - } - - return null; - }; - return requireProp; -} +export default requirePropFactory; diff --git a/packages/material-ui/src/utils/scrollLeft.js b/packages/material-ui/src/utils/scrollLeft.js index e9998373024ca4..67da7e12e8d648 100644 --- a/packages/material-ui/src/utils/scrollLeft.js +++ b/packages/material-ui/src/utils/scrollLeft.js @@ -1,77 +1 @@ -// Source from https://github.com/alitaheri/normalize-scroll-left -let cachedType; - -/** - * Based on the jquery plugin https://github.com/othree/jquery.rtl-scroll-type - * - * Types of scrollLeft, assuming scrollWidth=100 and direction is rtl. - * - * Type | <- Most Left | Most Right -> | Initial - * ---------------- | ------------ | ------------- | ------- - * default | 0 | 100 | 100 - * negative (spec*) | -100 | 0 | 0 - * reverse | 100 | 0 | 0 - * - * Edge 85: default - * Safari 14: negative - * Chrome 85: negative - * Firefox 81: negative - * IE11: reverse - * - * spec* https://drafts.csswg.org/cssom-view/#dom-window-scroll - */ -export function detectScrollType() { - if (cachedType) { - return cachedType; - } - - const dummy = document.createElement('div'); - const container = document.createElement('div'); - container.style.width = '10px'; - container.style.height = '1px'; - dummy.appendChild(container); - dummy.dir = 'rtl'; - dummy.style.fontSize = '14px'; - dummy.style.width = '4px'; - dummy.style.height = '1px'; - dummy.style.position = 'absolute'; - dummy.style.top = '-1000px'; - dummy.style.overflow = 'scroll'; - - document.body.appendChild(dummy); - - cachedType = 'reverse'; - - if (dummy.scrollLeft > 0) { - cachedType = 'default'; - } else { - dummy.scrollLeft = 1; - if (dummy.scrollLeft === 0) { - cachedType = 'negative'; - } - } - - document.body.removeChild(dummy); - return cachedType; -} - -// Based on https://stackoverflow.com/a/24394376 -export function getNormalizedScrollLeft(element, direction) { - const scrollLeft = element.scrollLeft; - - // Perform the calculations only when direction is rtl to avoid messing up the ltr behavior - if (direction !== 'rtl') { - return scrollLeft; - } - - const type = detectScrollType(); - - switch (type) { - case 'negative': - return element.scrollWidth - element.clientWidth + scrollLeft; - case 'reverse': - return element.scrollWidth - element.clientWidth - scrollLeft; - default: - return scrollLeft; - } -} +export { detectScrollType, getNormalizedScrollLeft } from '@material-ui/utils'; diff --git a/packages/material-ui/src/utils/setRef.ts b/packages/material-ui/src/utils/setRef.ts index 29ebef0d3527c7..25e30871f243c5 100644 --- a/packages/material-ui/src/utils/setRef.ts +++ b/packages/material-ui/src/utils/setRef.ts @@ -1,25 +1,3 @@ -import * as React from 'react'; +import { setRef } from '@material-ui/utils'; -/** - * TODO v5: consider to make it private - * - * passes {value} to {ref} - * - * WARNING: Be sure to only call this inside a callback that is passed as a ref. - * Otherwise make sure to cleanup previous {ref} if it changes. See - * https://github.com/mui-org/material-ui/issues/13539 - * - * useful if you want to expose the ref of an inner component to the public api - * while still using it inside the component - * @param ref a ref callback or ref object if anything falsy this is a no-op - */ -export default function setRef( - ref: React.MutableRefObject | ((instance: T | null) => void) | null | undefined, - value: T | null, -): void { - if (typeof ref === 'function') { - ref(value); - } else if (ref) { - ref.current = value; - } -} +export default setRef; diff --git a/packages/material-ui/src/utils/unsupportedProp.d.ts b/packages/material-ui/src/utils/unsupportedProp.d.ts index e08c9a729fccab..2f0a48a6057b86 100644 --- a/packages/material-ui/src/utils/unsupportedProp.d.ts +++ b/packages/material-ui/src/utils/unsupportedProp.d.ts @@ -1,7 +1,3 @@ -export default function unsupportedProp( - props: { [key: string]: any }, - propName: string, - componentName: string, - location: string, - propFullName: string -): Error | null; +import { unsupportedProp } from '@material-ui/utils'; + +export default unsupportedProp; diff --git a/packages/material-ui/src/utils/unsupportedProp.js b/packages/material-ui/src/utils/unsupportedProp.js index 925bca3ce9eacd..2f0a48a6057b86 100644 --- a/packages/material-ui/src/utils/unsupportedProp.js +++ b/packages/material-ui/src/utils/unsupportedProp.js @@ -1,13 +1,3 @@ -export default function unsupportedProp(props, propName, componentName, location, propFullName) { - if (process.env.NODE_ENV === 'production') { - return null; - } +import { unsupportedProp } from '@material-ui/utils'; - const propFullNameSafe = propFullName || propName; - - if (typeof props[propName] !== 'undefined') { - return new Error(`The prop \`${propFullNameSafe}\` is not supported. Please remove it.`); - } - - return null; -} +export default unsupportedProp; diff --git a/packages/material-ui/src/utils/useControlled.d.ts b/packages/material-ui/src/utils/useControlled.d.ts index 87e785ae289356..6d916849a36d86 100644 --- a/packages/material-ui/src/utils/useControlled.d.ts +++ b/packages/material-ui/src/utils/useControlled.d.ts @@ -1,22 +1,3 @@ -export interface UseControlledProps { - /** - * This prop contains the component value when it's controlled. - */ - controlled: T | undefined; - /** - * The default value when uncontrolled. - */ - default: T | undefined; - /** - * The component name displayed in warnings. - */ - name: string; - /** - * The name of the state variable displayed in warnings. - */ - state?: string; -} +import { useControlled } from '@material-ui/utils'; -export default function useControlled( - props: UseControlledProps -): [T, (newValue: T) => void]; +export default useControlled; diff --git a/packages/material-ui/src/utils/useControlled.js b/packages/material-ui/src/utils/useControlled.js index 3eb0b699910936..20901efb8bdac0 100644 --- a/packages/material-ui/src/utils/useControlled.js +++ b/packages/material-ui/src/utils/useControlled.js @@ -1,49 +1,3 @@ -/* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */ -import * as React from 'react'; +import { useControlled } from '@material-ui/utils'; -export default function useControlled({ controlled, default: defaultProp, name, state = 'value' }) { - // isControlled is ignored in the hook dependency lists as it should never change. - const { current: isControlled } = React.useRef(controlled !== undefined); - const [valueState, setValue] = React.useState(defaultProp); - const value = isControlled ? controlled : valueState; - - if (process.env.NODE_ENV !== 'production') { - React.useEffect(() => { - if (isControlled !== (controlled !== undefined)) { - console.error( - [ - `Material-UI: A component is changing the ${ - isControlled ? '' : 'un' - }controlled ${state} state of ${name} to be ${isControlled ? 'un' : ''}controlled.`, - 'Elements should not switch from uncontrolled to controlled (or vice versa).', - `Decide between using a controlled or uncontrolled ${name} ` + - 'element for the lifetime of the component.', - "The nature of the state is determined during the first render, it's considered controlled if the value is not `undefined`.", - 'More info: https://fb.me/react-controlled-components', - ].join('\n'), - ); - } - }, [state, name, controlled]); - - const { current: defaultValue } = React.useRef(defaultProp); - - React.useEffect(() => { - if (!isControlled && defaultValue !== defaultProp) { - console.error( - [ - `Material-UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` + - `To suppress this warning opt to use a controlled ${name}.`, - ].join('\n'), - ); - } - }, [JSON.stringify(defaultProp)]); - } - - const setValueIfUncontrolled = React.useCallback((newValue) => { - if (!isControlled) { - setValue(newValue); - } - }, []); - - return [value, setValueIfUncontrolled]; -} +export default useControlled; \ No newline at end of file diff --git a/packages/material-ui/src/utils/useEnhancedEffect.d.ts b/packages/material-ui/src/utils/useEnhancedEffect.d.ts index 9d060a00b0230c..2d24ca475df1ad 100644 --- a/packages/material-ui/src/utils/useEnhancedEffect.d.ts +++ b/packages/material-ui/src/utils/useEnhancedEffect.d.ts @@ -1,6 +1,3 @@ -import * as React from 'react'; +import { unstable_useEnhancedEffect as useEnhancedEffect } from '@material-ui/utils'; -export default function useEnhancedEffect( - effect: React.EffectCallback, - deps?: React.DependencyList -): void; +export default useEnhancedEffect; diff --git a/packages/material-ui/src/utils/useEnhancedEffect.js b/packages/material-ui/src/utils/useEnhancedEffect.js index beefea01128179..2d24ca475df1ad 100644 --- a/packages/material-ui/src/utils/useEnhancedEffect.js +++ b/packages/material-ui/src/utils/useEnhancedEffect.js @@ -1,8 +1,3 @@ -import * as React from 'react'; +import { unstable_useEnhancedEffect as useEnhancedEffect } from '@material-ui/utils'; -const useEnhancedEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect; - -/** - * Private module reserved for @material-ui packages. - */ export default useEnhancedEffect; diff --git a/packages/material-ui/src/utils/useEventCallback.d.ts b/packages/material-ui/src/utils/useEventCallback.d.ts index 81f39f979486f0..7f4bdae47cc111 100644 --- a/packages/material-ui/src/utils/useEventCallback.d.ts +++ b/packages/material-ui/src/utils/useEventCallback.d.ts @@ -1 +1,3 @@ -export default function useEventCallback any>(func: T): T; +import { useEventCallback } from '@material-ui/utils'; + +export default useEventCallback; diff --git a/packages/material-ui/src/utils/useEventCallback.js b/packages/material-ui/src/utils/useEventCallback.js index 7ff34781cd75cd..00cf7a23ab6947 100644 --- a/packages/material-ui/src/utils/useEventCallback.js +++ b/packages/material-ui/src/utils/useEventCallback.js @@ -1,14 +1,3 @@ -import * as React from 'react'; -import useEnhancedEffect from './useEnhancedEffect'; +import { useEventCallback } from '@material-ui/utils'; -/** - * https://github.com/facebook/react/issues/14099#issuecomment-440013892 - * @param {function} fn - */ -export default function useEventCallback(fn) { - const ref = React.useRef(fn); - useEnhancedEffect(() => { - ref.current = fn; - }); - return React.useCallback((...args) => (0, ref.current)(...args), []); -} +export default useEventCallback; \ No newline at end of file diff --git a/packages/material-ui/src/utils/useForkRef.d.ts b/packages/material-ui/src/utils/useForkRef.d.ts index 877be87b037a71..49234c415516d8 100644 --- a/packages/material-ui/src/utils/useForkRef.d.ts +++ b/packages/material-ui/src/utils/useForkRef.d.ts @@ -1,3 +1,3 @@ -import * as React from 'react'; +import { useForkRef } from '@material-ui/utils'; -export default function useForkRef(refA: React.Ref, refB: React.Ref): React.Ref; +export default useForkRef; diff --git a/packages/material-ui/src/utils/useForkRef.js b/packages/material-ui/src/utils/useForkRef.js index 5e67bbaf0b421e..49234c415516d8 100644 --- a/packages/material-ui/src/utils/useForkRef.js +++ b/packages/material-ui/src/utils/useForkRef.js @@ -1,19 +1,3 @@ -import * as React from 'react'; -import setRef from './setRef'; +import { useForkRef } from '@material-ui/utils'; -export default function useForkRef(refA, refB) { - /** - * This will create a new function if the ref props change and are defined. - * This means react will call the old forkRef with `null` and the new forkRef - * with the ref. Cleanup naturally emerges from this behavior - */ - return React.useMemo(() => { - if (refA == null && refB == null) { - return null; - } - return (refValue) => { - setRef(refA, refValue); - setRef(refB, refValue); - }; - }, [refA, refB]); -} +export default useForkRef; diff --git a/packages/material-ui/src/utils/useId.d.ts b/packages/material-ui/src/utils/useId.d.ts index 06368a53d01428..0b6bcab4d378a2 100644 --- a/packages/material-ui/src/utils/useId.d.ts +++ b/packages/material-ui/src/utils/useId.d.ts @@ -1 +1,3 @@ -export default function useId(idOverride?: string): string; +import { unstable_useId as useId } from '@material-ui/utils'; + +export default useId; diff --git a/packages/material-ui/src/utils/useId.js b/packages/material-ui/src/utils/useId.js index 16ab5c9eda794c..0b6bcab4d378a2 100644 --- a/packages/material-ui/src/utils/useId.js +++ b/packages/material-ui/src/utils/useId.js @@ -1,18 +1,3 @@ -import * as React from 'react'; +import { unstable_useId as useId } from '@material-ui/utils'; -/** - * Private module reserved for @material-ui packages. - */ -export default function useId(idOverride) { - const [defaultId, setDefaultId] = React.useState(idOverride); - const id = idOverride || defaultId; - React.useEffect(() => { - if (defaultId == null) { - // Fallback to this default id when possible. - // Use the random value for client-side rendering only. - // We can't use it server-side. - setDefaultId(`mui-${Math.round(Math.random() * 1e5)}`); - } - }, [defaultId]); - return id; -} +export default useId; diff --git a/packages/material-ui/src/utils/useIsFocusVisible.d.ts b/packages/material-ui/src/utils/useIsFocusVisible.d.ts index bc64b8b201deb7..4a1f761fc86e2b 100644 --- a/packages/material-ui/src/utils/useIsFocusVisible.d.ts +++ b/packages/material-ui/src/utils/useIsFocusVisible.d.ts @@ -1,8 +1,3 @@ -import * as React from 'react'; +import { useIsFocusVisible } from '@material-ui/utils'; -export default function useIsFocusVisible(): { - isFocusVisibleRef: React.MutableRefObject; - onBlur: (event: React.FocusEvent) => void; - onFocus: (event: React.FocusEvent) => void; - ref: React.Ref; -}; +export default useIsFocusVisible; diff --git a/packages/material-ui/src/utils/useIsFocusVisible.js b/packages/material-ui/src/utils/useIsFocusVisible.js index 7b01d9d9eb982e..4a1f761fc86e2b 100644 --- a/packages/material-ui/src/utils/useIsFocusVisible.js +++ b/packages/material-ui/src/utils/useIsFocusVisible.js @@ -1,167 +1,3 @@ -// based on https://github.com/WICG/focus-visible/blob/v4.1.5/src/focus-visible.js -import * as React from 'react'; +import { useIsFocusVisible } from '@material-ui/utils'; -let hadKeyboardEvent = true; -let hadFocusVisibleRecently = false; -let hadFocusVisibleRecentlyTimeout = null; - -const inputTypesWhitelist = { - text: true, - search: true, - url: true, - tel: true, - email: true, - password: true, - number: true, - date: true, - month: true, - week: true, - time: true, - datetime: true, - 'datetime-local': true, -}; - -/** - * Computes whether the given element should automatically trigger the - * `focus-visible` class being added, i.e. whether it should always match - * `:focus-visible` when focused. - * @param {Element} node - * @returns {boolean} - */ -function focusTriggersKeyboardModality(node) { - const { type, tagName } = node; - - if (tagName === 'INPUT' && inputTypesWhitelist[type] && !node.readOnly) { - return true; - } - - if (tagName === 'TEXTAREA' && !node.readOnly) { - return true; - } - - if (node.isContentEditable) { - return true; - } - - return false; -} - -/** - * Keep track of our keyboard modality state with `hadKeyboardEvent`. - * If the most recent user interaction was via the keyboard; - * and the key press did not include a meta, alt/option, or control key; - * then the modality is keyboard. Otherwise, the modality is not keyboard. - * @param {KeyboardEvent} event - */ -function handleKeyDown(event) { - if (event.metaKey || event.altKey || event.ctrlKey) { - return; - } - hadKeyboardEvent = true; -} - -/** - * If at any point a user clicks with a pointing device, ensure that we change - * the modality away from keyboard. - * This avoids the situation where a user presses a key on an already focused - * element, and then clicks on a different element, focusing it with a - * pointing device, while we still think we're in keyboard modality. - */ -function handlePointerDown() { - hadKeyboardEvent = false; -} - -function handleVisibilityChange() { - if (this.visibilityState === 'hidden') { - // If the tab becomes active again, the browser will handle calling focus - // on the element (Safari actually calls it twice). - // If this tab change caused a blur on an element with focus-visible, - // re-apply the class when the user switches back to the tab. - if (hadFocusVisibleRecently) { - hadKeyboardEvent = true; - } - } -} - -function prepare(doc) { - doc.addEventListener('keydown', handleKeyDown, true); - doc.addEventListener('mousedown', handlePointerDown, true); - doc.addEventListener('pointerdown', handlePointerDown, true); - doc.addEventListener('touchstart', handlePointerDown, true); - doc.addEventListener('visibilitychange', handleVisibilityChange, true); -} - -export function teardown(doc) { - doc.removeEventListener('keydown', handleKeyDown, true); - doc.removeEventListener('mousedown', handlePointerDown, true); - doc.removeEventListener('pointerdown', handlePointerDown, true); - doc.removeEventListener('touchstart', handlePointerDown, true); - doc.removeEventListener('visibilitychange', handleVisibilityChange, true); -} - -function isFocusVisible(event) { - const { target } = event; - try { - return target.matches(':focus-visible'); - } catch (error) { - // browsers not implementing :focus-visible will throw a SyntaxError - // we use our own heuristic for those browsers - // rethrow might be better if it's not the expected error but do we really - // want to crash if focus-visible malfunctioned? - } - - // no need for validFocusTarget check. the user does that by attaching it to - // focusable events only - return hadKeyboardEvent || focusTriggersKeyboardModality(target); -} - -export default function useIsFocusVisible() { - const ref = React.useCallback((node) => { - if (node != null) { - prepare(node.ownerDocument); - } - }, []); - - const isFocusVisibleRef = React.useRef(false); - - /** - * Should be called if a blur event is fired - */ - function handleBlurVisible() { - // checking against potential state variable does not suffice if we focus and blur synchronously. - // React wouldn't have time to trigger a re-render so `focusVisible` would be stale. - // Ideally we would adjust `isFocusVisible(event)` to look at `relatedTarget` for blur events. - // This doesn't work in IE11 due to https://github.com/facebook/react/issues/3751 - // TODO: check again if React releases their internal changes to focus event handling (https://github.com/facebook/react/pull/19186). - if (isFocusVisibleRef.current) { - // To detect a tab/window switch, we look for a blur event followed - // rapidly by a visibility change. - // If we don't see a visibility change within 100ms, it's probably a - // regular focus change. - hadFocusVisibleRecently = true; - window.clearTimeout(hadFocusVisibleRecentlyTimeout); - hadFocusVisibleRecentlyTimeout = window.setTimeout(() => { - hadFocusVisibleRecently = false; - }, 100); - - isFocusVisibleRef.current = false; - - return true; - } - - return false; - } - - /** - * Should be called if a blur event is fired - */ - function handleFocusVisible(event) { - if (isFocusVisible(event)) { - isFocusVisibleRef.current = true; - return true; - } - return false; - } - - return { isFocusVisibleRef, onFocus: handleFocusVisible, onBlur: handleBlurVisible, ref }; -} +export default useIsFocusVisible; From c9489d730e39d84d597e5697626e90c8b79839fa Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 26 Oct 2020 11:15:04 +0100 Subject: [PATCH 02/34] prettier --- packages/material-ui/src/utils/useControlled.js | 2 +- packages/material-ui/src/utils/useEventCallback.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/material-ui/src/utils/useControlled.js b/packages/material-ui/src/utils/useControlled.js index 20901efb8bdac0..6d916849a36d86 100644 --- a/packages/material-ui/src/utils/useControlled.js +++ b/packages/material-ui/src/utils/useControlled.js @@ -1,3 +1,3 @@ import { useControlled } from '@material-ui/utils'; -export default useControlled; \ No newline at end of file +export default useControlled; diff --git a/packages/material-ui/src/utils/useEventCallback.js b/packages/material-ui/src/utils/useEventCallback.js index 00cf7a23ab6947..7f4bdae47cc111 100644 --- a/packages/material-ui/src/utils/useEventCallback.js +++ b/packages/material-ui/src/utils/useEventCallback.js @@ -1,3 +1,3 @@ import { useEventCallback } from '@material-ui/utils'; -export default useEventCallback; \ No newline at end of file +export default useEventCallback; From e866f5e92d291d95ab72635be0ba61bbe9d98301 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 26 Oct 2020 13:49:34 +0100 Subject: [PATCH 03/34] MuiError --- packages/material-ui-utils/src/capitalize.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/material-ui-utils/src/capitalize.ts b/packages/material-ui-utils/src/capitalize.ts index d1ab320ca7d005..35f1ab3badd758 100644 --- a/packages/material-ui-utils/src/capitalize.ts +++ b/packages/material-ui-utils/src/capitalize.ts @@ -1,12 +1,11 @@ -// TODO: error TS7016: Could not find a declaration file for module '../macros/MuiError.macro'. '/tmp/material-ui/packages/material-ui-utils/macros/MuiError.macro.js' implicitly has an 'any' type. -// import MuiError from '../macros/MuiError.macro'; +import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // // A strict capitalization should uppercase the first letter of each word a the sentence. // We only handle the first word. export default function capitalize(string: string): string { if (typeof string !== 'string') { - throw new Error('Material-UI: capitalize(string) expects a string argument.'); + throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); } return string.charAt(0).toUpperCase() + string.slice(1); From 080dd7e6b6117fe08e519ab9121277761b95d812 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 26 Oct 2020 13:50:38 +0100 Subject: [PATCH 04/34] ts-ignore --- packages/material-ui-utils/src/capitalize.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/material-ui-utils/src/capitalize.ts b/packages/material-ui-utils/src/capitalize.ts index 35f1ab3badd758..4c21f6659441db 100644 --- a/packages/material-ui-utils/src/capitalize.ts +++ b/packages/material-ui-utils/src/capitalize.ts @@ -1,3 +1,4 @@ +// @ts-ignore import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // From c625415734ded91e0206afc8c23c24df0d9dc29b Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 27 Oct 2020 11:21:18 +0100 Subject: [PATCH 05/34] Add compat for usage in utils itself --- .../macros/MuiError.macro.d.ts | 3 ++ .../macros/MuiError.macro.js | 41 +++++++++++++++---- .../macros/MuiError.macro.test.js | 8 ++++ .../relative-import/error-codes.json | 3 ++ .../__fixtures__/relative-import/input.js | 4 ++ .../__fixtures__/relative-import/output.js | 7 ++++ packages/material-ui-utils/src/capitalize.ts | 1 - 7 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 packages/material-ui-utils/macros/MuiError.macro.d.ts create mode 100644 packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json create mode 100644 packages/material-ui-utils/macros/__fixtures__/relative-import/input.js create mode 100644 packages/material-ui-utils/macros/__fixtures__/relative-import/output.js diff --git a/packages/material-ui-utils/macros/MuiError.macro.d.ts b/packages/material-ui-utils/macros/MuiError.macro.d.ts new file mode 100644 index 00000000000000..53d894b2241058 --- /dev/null +++ b/packages/material-ui-utils/macros/MuiError.macro.d.ts @@ -0,0 +1,3 @@ +export default class MuiError { + constructor(message: string); +} diff --git a/packages/material-ui-utils/macros/MuiError.macro.js b/packages/material-ui-utils/macros/MuiError.macro.js index a91c70c8c105ff..c0e2f13b357fda 100644 --- a/packages/material-ui-utils/macros/MuiError.macro.js +++ b/packages/material-ui-utils/macros/MuiError.macro.js @@ -1,6 +1,7 @@ const { createMacro, MacroError } = require('babel-plugin-macros'); const helperModuleImports = require('@babel/helper-module-imports'); const fs = require('fs'); +const path = require('path'); function invertObject(object) { const inverted = {}; @@ -11,9 +12,13 @@ function invertObject(object) { } /** + * Supported imports: + * 1. bare specifier e.g. `'@material-ui/utils/macros/MuiError.macro'` + * 2. relative import from `packages/material-ui-utils/src` e.g. `'../macros/MuiError.macro'` + * * @param {import('babel-plugin-macros').MacroParams} param0 */ -function muiError({ references, babel, config }) { +function muiError({ references, babel, config, source }) { const { errorCodesPath = {}, missingError = 'annotate' } = config; const errorCodes = JSON.parse(fs.readFileSync(errorCodesPath, { encoding: 'utf8' })); const errorCodesLookup = invertObject(errorCodes); @@ -125,13 +130,33 @@ function muiError({ references, babel, config }) { errorCode = parseInt(errorCode, 10); if (formatMuiErrorMessageIdentifier === null) { - // Outputs: - // import { formatMuiErrorMessage } from '@material-ui/utils'; - formatMuiErrorMessageIdentifier = helperModuleImports.addNamed( - babelPath, - 'formatMuiErrorMessage', - '@material-ui/utils', - ); + const isBareImportSourceIdentifier = source.startsWith('@material-ui/utils'); + if (isBareImportSourceIdentifier) { + // Input: import MuiError from '@material-ui/utils/macros/MuiError.macro' + // Outputs: + // import { formatMuiErrorMessage } from '@material-ui/utils'; + formatMuiErrorMessageIdentifier = helperModuleImports.addNamed( + babelPath, + 'formatMuiErrorMessage', + '@material-ui/utils', + ); + } else { + const normalizedRelativeImport = path.normalize( + source.replace('../macros/MuiError.macro', './formatMuiErrorMessage'), + ); + // 'formatMuiErrorMessage' implies './formatMuiErrorMessage' for fs paths but not for import specifiers. + const formatMuiErrorMessageImportSource = normalizedRelativeImport.startsWith('.') + ? normalizedRelativeImport + : `./${normalizedRelativeImport}`; + // Input: import MuiError from '../macros/MuiError.macro' + // Outputs: + // import formatMuiErrorMessage from './formatMuiErrorMessage'; + formatMuiErrorMessageIdentifier = helperModuleImports.addDefault( + babelPath, + formatMuiErrorMessageImportSource, + { nameHint: 'formatMuiErrorMessage' }, + ); + } } // Outputs: diff --git a/packages/material-ui-utils/macros/MuiError.macro.test.js b/packages/material-ui-utils/macros/MuiError.macro.test.js index d5bdf637a533e8..e503820c75e6cb 100644 --- a/packages/material-ui-utils/macros/MuiError.macro.test.js +++ b/packages/material-ui-utils/macros/MuiError.macro.test.js @@ -95,5 +95,13 @@ pluginTester({ }, }, }, + { + title: 'relative-import', + pluginOptions: { + muiError: { errorCodesPath: path.join(fixturePath, 'relative-import', 'error-codes.json') }, + }, + fixture: path.join(fixturePath, 'relative-import', 'input.js'), + output: readOutputFixtureSync('relative-import', 'output.js'), + }, ], }); diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json b/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json new file mode 100644 index 00000000000000..3fe90729b7efe7 --- /dev/null +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json @@ -0,0 +1,3 @@ +{ + "1": "Material-UI: Expected valid input target.\nDid you use `inputComponent`" +} diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js new file mode 100644 index 00000000000000..b8727eb2e54546 --- /dev/null +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js @@ -0,0 +1,4 @@ +// eslint-disable-next-line import/no-useless-path-segments -- macro requirement +import MuiError from '../../../macros/MuiError.macro'; + +throw new MuiError('Material-UI: Expected valid input target.\n' + 'Did you use `inputComponent`'); diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js b/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js new file mode 100644 index 00000000000000..b0e82ed1768e0e --- /dev/null +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js @@ -0,0 +1,7 @@ +import _formatMuiErrorMessage from '../../formatMuiErrorMessage'; +throw new Error( + process.env.NODE_ENV !== 'production' + ? `Material-UI: Expected valid input target. +Did you use \`inputComponent\`` + : _formatMuiErrorMessage(1), +); diff --git a/packages/material-ui-utils/src/capitalize.ts b/packages/material-ui-utils/src/capitalize.ts index 4c21f6659441db..35f1ab3badd758 100644 --- a/packages/material-ui-utils/src/capitalize.ts +++ b/packages/material-ui-utils/src/capitalize.ts @@ -1,4 +1,3 @@ -// @ts-ignore import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // From bd907da7973a923cd6d372facafc1d0d2ef315c9 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 27 Oct 2020 14:50:56 +0100 Subject: [PATCH 06/34] Fix lint --- .eslintignore | 1 + .../macros/__fixtures__/relative-import/input.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index edefeeeebadd18..8da77316e6795e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -18,6 +18,7 @@ /packages/material-ui-icons/legacy /packages/material-ui-icons/src /packages/material-ui-icons/templateSvgIcon.js +/packages/material-ui-utils/macros/__fixtures__/ # Ignore fixtures /packages/typescript-to-proptypes/test/*/* /tmp diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js index b8727eb2e54546..492b6cb19cd307 100644 --- a/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/no-useless-path-segments -- macro requirement import MuiError from '../../../macros/MuiError.macro'; throw new MuiError('Material-UI: Expected valid input target.\n' + 'Did you use `inputComponent`'); From 324b3a8809cf3ec8b9e23e5ac6b0c7fa46b531aa Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Tue, 27 Oct 2020 15:37:38 +0100 Subject: [PATCH 07/34] exported new utils as unstable_ --- packages/material-ui-utils/src/index.ts | 35 ++++++++++--------- .../material-ui/src/utils/capitalize.d.ts | 2 +- packages/material-ui/src/utils/capitalize.js | 2 +- .../src/utils/createChainedFunction.d.ts | 2 +- .../src/utils/createChainedFunction.js | 2 +- packages/material-ui/src/utils/debounce.d.ts | 2 +- packages/material-ui/src/utils/debounce.js | 2 +- .../src/utils/deprecatedPropType.d.ts | 2 +- .../src/utils/deprecatedPropType.js | 2 +- .../material-ui/src/utils/getScrollbarSize.ts | 2 +- .../material-ui/src/utils/isMuiElement.d.ts | 2 +- .../material-ui/src/utils/isMuiElement.js | 2 +- .../material-ui/src/utils/ownerDocument.ts | 2 +- packages/material-ui/src/utils/ownerWindow.ts | 2 +- .../src/utils/requirePropFactory.d.ts | 2 +- .../src/utils/requirePropFactory.js | 2 +- packages/material-ui/src/utils/scrollLeft.js | 5 ++- packages/material-ui/src/utils/setRef.ts | 2 +- .../src/utils/unsupportedProp.d.ts | 2 +- .../material-ui/src/utils/unsupportedProp.js | 2 +- .../material-ui/src/utils/useControlled.d.ts | 2 +- .../material-ui/src/utils/useControlled.js | 2 +- .../src/utils/useEventCallback.d.ts | 2 +- .../material-ui/src/utils/useEventCallback.js | 2 +- .../material-ui/src/utils/useForkRef.d.ts | 2 +- packages/material-ui/src/utils/useForkRef.js | 2 +- .../src/utils/useIsFocusVisible.d.ts | 2 +- .../src/utils/useIsFocusVisible.js | 2 +- 28 files changed, 49 insertions(+), 43 deletions(-) diff --git a/packages/material-ui-utils/src/index.ts b/packages/material-ui-utils/src/index.ts index a9944e8a6f3bb9..e3cd7c13caadb3 100644 --- a/packages/material-ui-utils/src/index.ts +++ b/packages/material-ui-utils/src/index.ts @@ -8,21 +8,24 @@ export { default as getDisplayName } from './getDisplayName'; export { default as HTMLElementType } from './HTMLElementType'; export { default as ponyfillGlobal } from './ponyfillGlobal'; export { default as refType } from './refType'; -export { default as capitalize } from './capitalize'; -export { default as createChainedFunction } from './createChainedFunction'; -export { default as debounce } from './debounce'; -export { default as deprecatedPropType } from './deprecatedPropType'; -export { default as isMuiElement } from './isMuiElement'; -export { default as ownerDocument } from './ownerDocument'; -export { default as ownerWindow } from './ownerWindow'; -export { default as requirePropFactory } from './requirePropFactory'; -export { default as setRef } from './setRef'; +export { default as unstable_capitalize } from './capitalize'; +export { default as unstable_createChainedFunction } from './createChainedFunction'; +export { default as unstable_debounce } from './debounce'; +export { default as unstable_deprecatedPropType } from './deprecatedPropType'; +export { default as unstable_isMuiElement } from './isMuiElement'; +export { default as unstable_ownerDocument } from './ownerDocument'; +export { default as unstable_ownerWindow } from './ownerWindow'; +export { default as unstable_requirePropFactory } from './requirePropFactory'; +export { default as unstable_setRef } from './setRef'; export { default as unstable_useEnhancedEffect } from './useEnhancedEffect'; export { default as unstable_useId } from './useId'; -export { default as unsupportedProp } from './unsupportedProp'; -export { default as useControlled } from './useControlled'; -export { default as useEventCallback } from './useEventCallback'; -export { default as useForkRef } from './useForkRef'; -export { default as useIsFocusVisible } from './useIsFocusVisible'; -export { default as getScrollbarSize } from './getScrollbarSize'; -export { detectScrollType, getNormalizedScrollLeft } from './scrollLeft'; +export { default as unstable_unsupportedProp } from './unsupportedProp'; +export { default as unstable_useControlled } from './useControlled'; +export { default as unstable_useEventCallback } from './useEventCallback'; +export { default as unstable_useForkRef } from './useForkRef'; +export { default as unstable_useIsFocusVisible } from './useIsFocusVisible'; +export { default as unstable_getScrollbarSize } from './getScrollbarSize'; +export { + detectScrollType as unstable_detectScrollType, + getNormalizedScrollLeft as unstable_getNormalizedScrollLeft, +} from './scrollLeft'; diff --git a/packages/material-ui/src/utils/capitalize.d.ts b/packages/material-ui/src/utils/capitalize.d.ts index 0ff91901fa1280..dd825d99c21660 100644 --- a/packages/material-ui/src/utils/capitalize.d.ts +++ b/packages/material-ui/src/utils/capitalize.d.ts @@ -1,3 +1,3 @@ -import { capitalize } from '@material-ui/utils'; +import { unstable_capitalize as capitalize } from '@material-ui/utils'; export default capitalize; diff --git a/packages/material-ui/src/utils/capitalize.js b/packages/material-ui/src/utils/capitalize.js index 0ff91901fa1280..dd825d99c21660 100644 --- a/packages/material-ui/src/utils/capitalize.js +++ b/packages/material-ui/src/utils/capitalize.js @@ -1,3 +1,3 @@ -import { capitalize } from '@material-ui/utils'; +import { unstable_capitalize as capitalize } from '@material-ui/utils'; export default capitalize; diff --git a/packages/material-ui/src/utils/createChainedFunction.d.ts b/packages/material-ui/src/utils/createChainedFunction.d.ts index acaffd5d8b700f..5dfc830559ec32 100644 --- a/packages/material-ui/src/utils/createChainedFunction.d.ts +++ b/packages/material-ui/src/utils/createChainedFunction.d.ts @@ -1,3 +1,3 @@ -import { createChainedFunction } from '@material-ui/utils'; +import { unstable_createChainedFunction as createChainedFunction } from '@material-ui/utils'; export default createChainedFunction; diff --git a/packages/material-ui/src/utils/createChainedFunction.js b/packages/material-ui/src/utils/createChainedFunction.js index acaffd5d8b700f..5dfc830559ec32 100644 --- a/packages/material-ui/src/utils/createChainedFunction.js +++ b/packages/material-ui/src/utils/createChainedFunction.js @@ -1,3 +1,3 @@ -import { createChainedFunction } from '@material-ui/utils'; +import { unstable_createChainedFunction as createChainedFunction } from '@material-ui/utils'; export default createChainedFunction; diff --git a/packages/material-ui/src/utils/debounce.d.ts b/packages/material-ui/src/utils/debounce.d.ts index cf9df8d0377b23..2ca0d8f37f512c 100644 --- a/packages/material-ui/src/utils/debounce.d.ts +++ b/packages/material-ui/src/utils/debounce.d.ts @@ -1,3 +1,3 @@ -import { debounce } from '@material-ui/utils'; +import { unstable_debounce as debounce } from '@material-ui/utils'; export default debounce; diff --git a/packages/material-ui/src/utils/debounce.js b/packages/material-ui/src/utils/debounce.js index cf9df8d0377b23..2ca0d8f37f512c 100644 --- a/packages/material-ui/src/utils/debounce.js +++ b/packages/material-ui/src/utils/debounce.js @@ -1,3 +1,3 @@ -import { debounce } from '@material-ui/utils'; +import { unstable_debounce as debounce } from '@material-ui/utils'; export default debounce; diff --git a/packages/material-ui/src/utils/deprecatedPropType.d.ts b/packages/material-ui/src/utils/deprecatedPropType.d.ts index 1772f7c5876ed2..9dca74eb4e75b2 100644 --- a/packages/material-ui/src/utils/deprecatedPropType.d.ts +++ b/packages/material-ui/src/utils/deprecatedPropType.d.ts @@ -1,3 +1,3 @@ -import { deprecatedPropType } from '@material-ui/utils'; +import { unstable_deprecatedPropType as deprecatedPropType } from '@material-ui/utils'; export default deprecatedPropType; diff --git a/packages/material-ui/src/utils/deprecatedPropType.js b/packages/material-ui/src/utils/deprecatedPropType.js index 1772f7c5876ed2..9dca74eb4e75b2 100644 --- a/packages/material-ui/src/utils/deprecatedPropType.js +++ b/packages/material-ui/src/utils/deprecatedPropType.js @@ -1,3 +1,3 @@ -import { deprecatedPropType } from '@material-ui/utils'; +import { unstable_deprecatedPropType as deprecatedPropType } from '@material-ui/utils'; export default deprecatedPropType; diff --git a/packages/material-ui/src/utils/getScrollbarSize.ts b/packages/material-ui/src/utils/getScrollbarSize.ts index e26b87399ce8c6..9edfe93d11cf9d 100644 --- a/packages/material-ui/src/utils/getScrollbarSize.ts +++ b/packages/material-ui/src/utils/getScrollbarSize.ts @@ -1,3 +1,3 @@ -import { getScrollbarSize } from '@material-ui/utils'; +import { unstable_getScrollbarSize as getScrollbarSize } from '@material-ui/utils'; export default getScrollbarSize; diff --git a/packages/material-ui/src/utils/isMuiElement.d.ts b/packages/material-ui/src/utils/isMuiElement.d.ts index 4f4f3013c87ad0..5ffef839cb3c8a 100644 --- a/packages/material-ui/src/utils/isMuiElement.d.ts +++ b/packages/material-ui/src/utils/isMuiElement.d.ts @@ -1,3 +1,3 @@ -import { isMuiElement } from '@material-ui/utils'; +import { unstable_isMuiElement as isMuiElement } from '@material-ui/utils'; export default isMuiElement; diff --git a/packages/material-ui/src/utils/isMuiElement.js b/packages/material-ui/src/utils/isMuiElement.js index 4f4f3013c87ad0..5ffef839cb3c8a 100644 --- a/packages/material-ui/src/utils/isMuiElement.js +++ b/packages/material-ui/src/utils/isMuiElement.js @@ -1,3 +1,3 @@ -import { isMuiElement } from '@material-ui/utils'; +import { unstable_isMuiElement as isMuiElement } from '@material-ui/utils'; export default isMuiElement; diff --git a/packages/material-ui/src/utils/ownerDocument.ts b/packages/material-ui/src/utils/ownerDocument.ts index 06e7d93e535795..75df5785ed3d43 100644 --- a/packages/material-ui/src/utils/ownerDocument.ts +++ b/packages/material-ui/src/utils/ownerDocument.ts @@ -1,3 +1,3 @@ -import { ownerDocument } from '@material-ui/utils'; +import { unstable_ownerDocument as ownerDocument } from '@material-ui/utils'; export default ownerDocument; diff --git a/packages/material-ui/src/utils/ownerWindow.ts b/packages/material-ui/src/utils/ownerWindow.ts index b8833afc28d338..548c997dc8708f 100644 --- a/packages/material-ui/src/utils/ownerWindow.ts +++ b/packages/material-ui/src/utils/ownerWindow.ts @@ -1,3 +1,3 @@ -import { ownerWindow } from '@material-ui/utils'; +import { unstable_ownerWindow as ownerWindow } from '@material-ui/utils'; export default ownerWindow; diff --git a/packages/material-ui/src/utils/requirePropFactory.d.ts b/packages/material-ui/src/utils/requirePropFactory.d.ts index 31be0e9d3ca142..b93c715ed7c449 100644 --- a/packages/material-ui/src/utils/requirePropFactory.d.ts +++ b/packages/material-ui/src/utils/requirePropFactory.d.ts @@ -1,3 +1,3 @@ -import { requirePropFactory } from '@material-ui/utils'; +import { unstable_requirePropFactory as requirePropFactory } from '@material-ui/utils'; export default requirePropFactory; diff --git a/packages/material-ui/src/utils/requirePropFactory.js b/packages/material-ui/src/utils/requirePropFactory.js index 31be0e9d3ca142..b93c715ed7c449 100644 --- a/packages/material-ui/src/utils/requirePropFactory.js +++ b/packages/material-ui/src/utils/requirePropFactory.js @@ -1,3 +1,3 @@ -import { requirePropFactory } from '@material-ui/utils'; +import { unstable_requirePropFactory as requirePropFactory } from '@material-ui/utils'; export default requirePropFactory; diff --git a/packages/material-ui/src/utils/scrollLeft.js b/packages/material-ui/src/utils/scrollLeft.js index 67da7e12e8d648..4e09588843158a 100644 --- a/packages/material-ui/src/utils/scrollLeft.js +++ b/packages/material-ui/src/utils/scrollLeft.js @@ -1 +1,4 @@ -export { detectScrollType, getNormalizedScrollLeft } from '@material-ui/utils'; +export { + unstable_detectScrollType as detectScrollType, + unstable_getNormalizedScrollLeft as getNormalizedScrollLeft, +} from '@material-ui/utils'; diff --git a/packages/material-ui/src/utils/setRef.ts b/packages/material-ui/src/utils/setRef.ts index 25e30871f243c5..e5ad3e7b2336b4 100644 --- a/packages/material-ui/src/utils/setRef.ts +++ b/packages/material-ui/src/utils/setRef.ts @@ -1,3 +1,3 @@ -import { setRef } from '@material-ui/utils'; +import { unstable_setRef as setRef } from '@material-ui/utils'; export default setRef; diff --git a/packages/material-ui/src/utils/unsupportedProp.d.ts b/packages/material-ui/src/utils/unsupportedProp.d.ts index 2f0a48a6057b86..9bfe899838ee3c 100644 --- a/packages/material-ui/src/utils/unsupportedProp.d.ts +++ b/packages/material-ui/src/utils/unsupportedProp.d.ts @@ -1,3 +1,3 @@ -import { unsupportedProp } from '@material-ui/utils'; +import { unstable_unsupportedProp as unsupportedProp } from '@material-ui/utils'; export default unsupportedProp; diff --git a/packages/material-ui/src/utils/unsupportedProp.js b/packages/material-ui/src/utils/unsupportedProp.js index 2f0a48a6057b86..9bfe899838ee3c 100644 --- a/packages/material-ui/src/utils/unsupportedProp.js +++ b/packages/material-ui/src/utils/unsupportedProp.js @@ -1,3 +1,3 @@ -import { unsupportedProp } from '@material-ui/utils'; +import { unstable_unsupportedProp as unsupportedProp } from '@material-ui/utils'; export default unsupportedProp; diff --git a/packages/material-ui/src/utils/useControlled.d.ts b/packages/material-ui/src/utils/useControlled.d.ts index 6d916849a36d86..75b0a1cb095dbf 100644 --- a/packages/material-ui/src/utils/useControlled.d.ts +++ b/packages/material-ui/src/utils/useControlled.d.ts @@ -1,3 +1,3 @@ -import { useControlled } from '@material-ui/utils'; +import { unstable_useControlled as useControlled } from '@material-ui/utils'; export default useControlled; diff --git a/packages/material-ui/src/utils/useControlled.js b/packages/material-ui/src/utils/useControlled.js index 6d916849a36d86..75b0a1cb095dbf 100644 --- a/packages/material-ui/src/utils/useControlled.js +++ b/packages/material-ui/src/utils/useControlled.js @@ -1,3 +1,3 @@ -import { useControlled } from '@material-ui/utils'; +import { unstable_useControlled as useControlled } from '@material-ui/utils'; export default useControlled; diff --git a/packages/material-ui/src/utils/useEventCallback.d.ts b/packages/material-ui/src/utils/useEventCallback.d.ts index 7f4bdae47cc111..3e334fcb9bd9e5 100644 --- a/packages/material-ui/src/utils/useEventCallback.d.ts +++ b/packages/material-ui/src/utils/useEventCallback.d.ts @@ -1,3 +1,3 @@ -import { useEventCallback } from '@material-ui/utils'; +import { unstable_useEventCallback as useEventCallback } from '@material-ui/utils'; export default useEventCallback; diff --git a/packages/material-ui/src/utils/useEventCallback.js b/packages/material-ui/src/utils/useEventCallback.js index 7f4bdae47cc111..3e334fcb9bd9e5 100644 --- a/packages/material-ui/src/utils/useEventCallback.js +++ b/packages/material-ui/src/utils/useEventCallback.js @@ -1,3 +1,3 @@ -import { useEventCallback } from '@material-ui/utils'; +import { unstable_useEventCallback as useEventCallback } from '@material-ui/utils'; export default useEventCallback; diff --git a/packages/material-ui/src/utils/useForkRef.d.ts b/packages/material-ui/src/utils/useForkRef.d.ts index 49234c415516d8..981d58b14e59ad 100644 --- a/packages/material-ui/src/utils/useForkRef.d.ts +++ b/packages/material-ui/src/utils/useForkRef.d.ts @@ -1,3 +1,3 @@ -import { useForkRef } from '@material-ui/utils'; +import { unstable_useForkRef as useForkRef } from '@material-ui/utils'; export default useForkRef; diff --git a/packages/material-ui/src/utils/useForkRef.js b/packages/material-ui/src/utils/useForkRef.js index 49234c415516d8..981d58b14e59ad 100644 --- a/packages/material-ui/src/utils/useForkRef.js +++ b/packages/material-ui/src/utils/useForkRef.js @@ -1,3 +1,3 @@ -import { useForkRef } from '@material-ui/utils'; +import { unstable_useForkRef as useForkRef } from '@material-ui/utils'; export default useForkRef; diff --git a/packages/material-ui/src/utils/useIsFocusVisible.d.ts b/packages/material-ui/src/utils/useIsFocusVisible.d.ts index 4a1f761fc86e2b..055b994c4c4058 100644 --- a/packages/material-ui/src/utils/useIsFocusVisible.d.ts +++ b/packages/material-ui/src/utils/useIsFocusVisible.d.ts @@ -1,3 +1,3 @@ -import { useIsFocusVisible } from '@material-ui/utils'; +import { unstable_useIsFocusVisible as useIsFocusVisible } from '@material-ui/utils'; export default useIsFocusVisible; diff --git a/packages/material-ui/src/utils/useIsFocusVisible.js b/packages/material-ui/src/utils/useIsFocusVisible.js index 4a1f761fc86e2b..055b994c4c4058 100644 --- a/packages/material-ui/src/utils/useIsFocusVisible.js +++ b/packages/material-ui/src/utils/useIsFocusVisible.js @@ -1,3 +1,3 @@ -import { useIsFocusVisible } from '@material-ui/utils'; +import { unstable_useIsFocusVisible as useIsFocusVisible } from '@material-ui/utils'; export default useIsFocusVisible; From a9a42470d4db47559b29da7ae03d40396911b5bb Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 11:53:38 +0100 Subject: [PATCH 08/34] replaced .ts files with original .js & d.ts files --- docs/src/pages/system/sx/GettingStarted.js | 18 ++++++++++++ .../material-ui-utils/src/capitalize.d.ts | 1 + .../src/{capitalize.ts => capitalize.js} | 4 +-- .../src/createChainedFunction.d.ts | 5 ++++ ...edFunction.ts => createChainedFunction.js} | 10 ++----- packages/material-ui-utils/src/debounce.d.ts | 8 ++++++ .../src/{debounce.ts => debounce.js} | 16 +++-------- .../src/deprecatedPropType.d.ts | 1 + ...catedPropType.ts => deprecatedPropType.js} | 3 +- ...ype.test.ts => deprecatedPropType.test.js} | 0 .../{isMuiElement.ts => isMuiElement.d.ts} | 5 +--- .../material-ui-utils/src/isMuiElement.js | 5 ++++ .../src/requirePropFactory.d.ts | 1 + ...rePropFactory.ts => requirePropFactory.js} | 14 +++++----- .../material-ui-utils/src/scrollLeft.d.ts | 2 ++ .../src/{scrollLeft.ts => scrollLeft.js} | 6 ++-- ...{unsupportedProp.ts => unsupportedProp.js} | 8 +----- .../material-ui-utils/src/useControlled.d.ts | 22 +++++++++++++++ .../{useControlled.ts => useControlled.js} | 28 ++----------------- .../src/useEventCallback.d.ts | 1 + ...seEventCallback.ts => useEventCallback.js} | 6 ++-- .../material-ui-utils/src/useForkRef.d.ts | 3 ++ .../src/{useForkRef.ts => useForkRef.js} | 2 +- packages/material-ui-utils/src/useId.d.ts | 1 + .../src/{useId.ts => useId.js} | 6 ++-- ...IsFocusVisible.ts => useIsFocusVisible.js} | 19 +++---------- 26 files changed, 101 insertions(+), 94 deletions(-) create mode 100644 docs/src/pages/system/sx/GettingStarted.js create mode 100644 packages/material-ui-utils/src/capitalize.d.ts rename packages/material-ui-utils/src/{capitalize.ts => capitalize.js} (78%) create mode 100644 packages/material-ui-utils/src/createChainedFunction.d.ts rename packages/material-ui-utils/src/{createChainedFunction.ts => createChainedFunction.js} (72%) create mode 100644 packages/material-ui-utils/src/debounce.d.ts rename packages/material-ui-utils/src/{debounce.ts => debounce.js} (52%) create mode 100644 packages/material-ui-utils/src/deprecatedPropType.d.ts rename packages/material-ui-utils/src/{deprecatedPropType.ts => deprecatedPropType.js} (82%) rename packages/material-ui-utils/src/{deprecatedPropType.test.ts => deprecatedPropType.test.js} (100%) rename packages/material-ui-utils/src/{isMuiElement.ts => isMuiElement.d.ts} (90%) create mode 100644 packages/material-ui-utils/src/isMuiElement.js create mode 100644 packages/material-ui-utils/src/requirePropFactory.d.ts rename packages/material-ui-utils/src/{requirePropFactory.ts => requirePropFactory.js} (61%) create mode 100644 packages/material-ui-utils/src/scrollLeft.d.ts rename packages/material-ui-utils/src/{scrollLeft.ts => scrollLeft.js} (92%) rename packages/material-ui-utils/src/{unsupportedProp.ts => unsupportedProp.js} (61%) create mode 100644 packages/material-ui-utils/src/useControlled.d.ts rename packages/material-ui-utils/src/{useControlled.ts => useControlled.js} (74%) create mode 100644 packages/material-ui-utils/src/useEventCallback.d.ts rename packages/material-ui-utils/src/{useEventCallback.ts => useEventCallback.js} (54%) create mode 100644 packages/material-ui-utils/src/useForkRef.d.ts rename packages/material-ui-utils/src/{useForkRef.ts => useForkRef.js} (84%) create mode 100644 packages/material-ui-utils/src/useId.d.ts rename packages/material-ui-utils/src/{useId.ts => useId.js} (71%) rename packages/material-ui-utils/src/{useIsFocusVisible.ts => useIsFocusVisible.js} (92%) diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js new file mode 100644 index 00000000000000..83e014fb529a58 --- /dev/null +++ b/docs/src/pages/system/sx/GettingStarted.js @@ -0,0 +1,18 @@ +import * as React from 'react'; +import Box from '@material-ui/core/Box'; + +export default function GettingStarted() { + return ( + How to use the sx prop + ); +} \ No newline at end of file diff --git a/packages/material-ui-utils/src/capitalize.d.ts b/packages/material-ui-utils/src/capitalize.d.ts new file mode 100644 index 00000000000000..3fc792144be532 --- /dev/null +++ b/packages/material-ui-utils/src/capitalize.d.ts @@ -0,0 +1 @@ +export default function capitalize(string: string): string; diff --git a/packages/material-ui-utils/src/capitalize.ts b/packages/material-ui-utils/src/capitalize.js similarity index 78% rename from packages/material-ui-utils/src/capitalize.ts rename to packages/material-ui-utils/src/capitalize.js index 35f1ab3badd758..4c87d3020595a1 100644 --- a/packages/material-ui-utils/src/capitalize.ts +++ b/packages/material-ui-utils/src/capitalize.js @@ -1,9 +1,9 @@ -import MuiError from '../macros/MuiError.macro'; +import MuiError from '@material-ui/utils/macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // // A strict capitalization should uppercase the first letter of each word a the sentence. // We only handle the first word. -export default function capitalize(string: string): string { +export default function capitalize(string) { if (typeof string !== 'string') { throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); } diff --git a/packages/material-ui-utils/src/createChainedFunction.d.ts b/packages/material-ui-utils/src/createChainedFunction.d.ts new file mode 100644 index 00000000000000..53d4a3c3d378a2 --- /dev/null +++ b/packages/material-ui-utils/src/createChainedFunction.d.ts @@ -0,0 +1,5 @@ +export type ChainedFunction = ((...args: any[]) => void) | undefined | null; + +export default function createChainedFunction( + ...funcs: ChainedFunction[] +): (...args: any[]) => never; diff --git a/packages/material-ui-utils/src/createChainedFunction.ts b/packages/material-ui-utils/src/createChainedFunction.js similarity index 72% rename from packages/material-ui-utils/src/createChainedFunction.ts rename to packages/material-ui-utils/src/createChainedFunction.js index dd7a827f5d7ccc..a023586cc3ea88 100644 --- a/packages/material-ui-utils/src/createChainedFunction.ts +++ b/packages/material-ui-utils/src/createChainedFunction.js @@ -1,5 +1,3 @@ -export type ChainedFunction = ((...args: any[]) => void) | undefined | null; - /** * Safe chained function * @@ -8,9 +6,7 @@ export type ChainedFunction = ((...args: any[]) => void) | undefined | null; * @param {function} functions to chain * @returns {function|null} */ -export default function createChainedFunction( - ...funcs: ChainedFunction[] -): (...args: any[]) => never { +export default function createChainedFunction(...funcs) { return funcs.reduce( (acc, func) => { if (func == null) { @@ -26,12 +22,10 @@ export default function createChainedFunction( } return function chainedFunction(...args) { - // @ts-ignore acc.apply(this, args); - // @ts-ignore func.apply(this, args); }; }, () => {}, - ) as (...args: any[]) => never; + ); } diff --git a/packages/material-ui-utils/src/debounce.d.ts b/packages/material-ui-utils/src/debounce.d.ts new file mode 100644 index 00000000000000..ead5017e3d59cc --- /dev/null +++ b/packages/material-ui-utils/src/debounce.d.ts @@ -0,0 +1,8 @@ +export interface Cancelable { + clear(): void; +} + +export default function debounce any>( + func: T, + wait?: number +): T & Cancelable; diff --git a/packages/material-ui-utils/src/debounce.ts b/packages/material-ui-utils/src/debounce.js similarity index 52% rename from packages/material-ui-utils/src/debounce.ts rename to packages/material-ui-utils/src/debounce.js index 18e67eaa10cf9b..7b47300636d936 100644 --- a/packages/material-ui-utils/src/debounce.ts +++ b/packages/material-ui-utils/src/debounce.js @@ -1,17 +1,9 @@ -export interface Cancelable { - clear(): void; -} - // Corresponds to 10 frames at 60 Hz. // A few bytes payload overhead when lodash/debounce is ~3 kB and debounce ~300 B. -export default function debounce any>( - func: T, - wait: number = 166, -): T & Cancelable { - let timeout: any; - function debounced(...args: any[]) { +export default function debounce(func, wait = 166) { + let timeout; + function debounced(...args) { const later = () => { - // @ts-ignore func.apply(this, args); }; clearTimeout(timeout); @@ -22,5 +14,5 @@ export default function debounce any>( clearTimeout(timeout); }; - return debounced as T & Cancelable; + return debounced; } diff --git a/packages/material-ui-utils/src/deprecatedPropType.d.ts b/packages/material-ui-utils/src/deprecatedPropType.d.ts new file mode 100644 index 00000000000000..b21c9a984992e4 --- /dev/null +++ b/packages/material-ui-utils/src/deprecatedPropType.d.ts @@ -0,0 +1 @@ +export default function deprecatedPropType(validator: T, reason: string): T; diff --git a/packages/material-ui-utils/src/deprecatedPropType.ts b/packages/material-ui-utils/src/deprecatedPropType.js similarity index 82% rename from packages/material-ui-utils/src/deprecatedPropType.ts rename to packages/material-ui-utils/src/deprecatedPropType.js index 9cef6f880699cb..66b0caed3b0185 100644 --- a/packages/material-ui-utils/src/deprecatedPropType.ts +++ b/packages/material-ui-utils/src/deprecatedPropType.js @@ -1,9 +1,8 @@ -export default function deprecatedPropType(validator: T, reason: string): T | Function { +export default function deprecatedPropType(validator, reason) { if (process.env.NODE_ENV === 'production') { return () => null; } - // @ts-ignore return (props, propName, componentName, location, propFullName) => { const componentNameSafe = componentName || '<>'; const propFullNameSafe = propFullName || propName; diff --git a/packages/material-ui-utils/src/deprecatedPropType.test.ts b/packages/material-ui-utils/src/deprecatedPropType.test.js similarity index 100% rename from packages/material-ui-utils/src/deprecatedPropType.test.ts rename to packages/material-ui-utils/src/deprecatedPropType.test.js diff --git a/packages/material-ui-utils/src/isMuiElement.ts b/packages/material-ui-utils/src/isMuiElement.d.ts similarity index 90% rename from packages/material-ui-utils/src/isMuiElement.ts rename to packages/material-ui-utils/src/isMuiElement.d.ts index 5823dbd77d2ae7..104cc6602cee50 100644 --- a/packages/material-ui-utils/src/isMuiElement.ts +++ b/packages/material-ui-utils/src/isMuiElement.d.ts @@ -34,7 +34,4 @@ export interface NamedMuiElement { key: string | number | null; } -export default function isMuiElement(element: any, muiNames: string[]): element is NamedMuiElement { - // @ts-ignore - return React.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1; -} +export default function isMuiElement(element: any, muiNames: string[]): element is NamedMuiElement; diff --git a/packages/material-ui-utils/src/isMuiElement.js b/packages/material-ui-utils/src/isMuiElement.js new file mode 100644 index 00000000000000..e64372aa6ae18d --- /dev/null +++ b/packages/material-ui-utils/src/isMuiElement.js @@ -0,0 +1,5 @@ +import * as React from 'react'; + +export default function isMuiElement(element, muiNames) { + return React.isValidElement(element) && muiNames.indexOf(element.type.muiName) !== -1; +} diff --git a/packages/material-ui-utils/src/requirePropFactory.d.ts b/packages/material-ui-utils/src/requirePropFactory.d.ts new file mode 100644 index 00000000000000..63ae30db9f2831 --- /dev/null +++ b/packages/material-ui-utils/src/requirePropFactory.d.ts @@ -0,0 +1 @@ +export default function requirePropFactory(componentNameInError: string): any; diff --git a/packages/material-ui-utils/src/requirePropFactory.ts b/packages/material-ui-utils/src/requirePropFactory.js similarity index 61% rename from packages/material-ui-utils/src/requirePropFactory.ts rename to packages/material-ui-utils/src/requirePropFactory.js index 3fd8625b51f868..4d6707aab111be 100644 --- a/packages/material-ui-utils/src/requirePropFactory.ts +++ b/packages/material-ui-utils/src/requirePropFactory.js @@ -1,14 +1,14 @@ -export default function requirePropFactory(componentNameInError: string): any { +export default function requirePropFactory(componentNameInError) { if (process.env.NODE_ENV === 'production') { return () => null; } - const requireProp = (requiredProp: string): any => ( - props: { [key: string]: any }, - propName: string, - componentName: string, - location: string, - propFullName: string, + const requireProp = (requiredProp) => ( + props, + propName, + componentName, + location, + propFullName, ) => { const propFullNameSafe = propFullName || propName; diff --git a/packages/material-ui-utils/src/scrollLeft.d.ts b/packages/material-ui-utils/src/scrollLeft.d.ts new file mode 100644 index 00000000000000..cd6227f302cf45 --- /dev/null +++ b/packages/material-ui-utils/src/scrollLeft.d.ts @@ -0,0 +1,2 @@ +export function detectScrollType(): string; +export function getNormalizedScrollLeft(element: HTMLElement, direction: string): number; diff --git a/packages/material-ui-utils/src/scrollLeft.ts b/packages/material-ui-utils/src/scrollLeft.js similarity index 92% rename from packages/material-ui-utils/src/scrollLeft.ts rename to packages/material-ui-utils/src/scrollLeft.js index a54811f3171c64..e9998373024ca4 100644 --- a/packages/material-ui-utils/src/scrollLeft.ts +++ b/packages/material-ui-utils/src/scrollLeft.js @@ -1,5 +1,5 @@ // Source from https://github.com/alitaheri/normalize-scroll-left -let cachedType: string; +let cachedType; /** * Based on the jquery plugin https://github.com/othree/jquery.rtl-scroll-type @@ -20,7 +20,7 @@ let cachedType: string; * * spec* https://drafts.csswg.org/cssom-view/#dom-window-scroll */ -export function detectScrollType(): string { +export function detectScrollType() { if (cachedType) { return cachedType; } @@ -56,7 +56,7 @@ export function detectScrollType(): string { } // Based on https://stackoverflow.com/a/24394376 -export function getNormalizedScrollLeft(element: Element, direction: string): number { +export function getNormalizedScrollLeft(element, direction) { const scrollLeft = element.scrollLeft; // Perform the calculations only when direction is rtl to avoid messing up the ltr behavior diff --git a/packages/material-ui-utils/src/unsupportedProp.ts b/packages/material-ui-utils/src/unsupportedProp.js similarity index 61% rename from packages/material-ui-utils/src/unsupportedProp.ts rename to packages/material-ui-utils/src/unsupportedProp.js index b92f324400e8a8..925bca3ce9eacd 100644 --- a/packages/material-ui-utils/src/unsupportedProp.ts +++ b/packages/material-ui-utils/src/unsupportedProp.js @@ -1,10 +1,4 @@ -export default function unsupportedProp( - props: { [key: string]: any }, - propName: string, - componentName: string, - location: string, - propFullName: string, -): Error | null { +export default function unsupportedProp(props, propName, componentName, location, propFullName) { if (process.env.NODE_ENV === 'production') { return null; } diff --git a/packages/material-ui-utils/src/useControlled.d.ts b/packages/material-ui-utils/src/useControlled.d.ts new file mode 100644 index 00000000000000..87e785ae289356 --- /dev/null +++ b/packages/material-ui-utils/src/useControlled.d.ts @@ -0,0 +1,22 @@ +export interface UseControlledProps { + /** + * This prop contains the component value when it's controlled. + */ + controlled: T | undefined; + /** + * The default value when uncontrolled. + */ + default: T | undefined; + /** + * The component name displayed in warnings. + */ + name: string; + /** + * The name of the state variable displayed in warnings. + */ + state?: string; +} + +export default function useControlled( + props: UseControlledProps +): [T, (newValue: T) => void]; diff --git a/packages/material-ui-utils/src/useControlled.ts b/packages/material-ui-utils/src/useControlled.js similarity index 74% rename from packages/material-ui-utils/src/useControlled.ts rename to packages/material-ui-utils/src/useControlled.js index 6509ea3d40085e..3eb0b699910936 100644 --- a/packages/material-ui-utils/src/useControlled.ts +++ b/packages/material-ui-utils/src/useControlled.js @@ -1,31 +1,7 @@ /* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */ import * as React from 'react'; -export interface UseControlledProps { - /** - * This prop contains the component value when it's controlled. - */ - controlled: T | undefined; - /** - * The default value when uncontrolled. - */ - default: T | undefined; - /** - * The component name displayed in warnings. - */ - name: string; - /** - * The name of the state variable displayed in warnings. - */ - state?: string; -} - -export default function useControlled({ - controlled, - default: defaultProp, - name, - state = 'value', -}: UseControlledProps): [T, (newValue: T) => void] { +export default function useControlled({ controlled, default: defaultProp, name, state = 'value' }) { // isControlled is ignored in the hook dependency lists as it should never change. const { current: isControlled } = React.useRef(controlled !== undefined); const [valueState, setValue] = React.useState(defaultProp); @@ -69,5 +45,5 @@ export default function useControlled({ } }, []); - return [value, setValueIfUncontrolled] as [T, (newValue: T) => void]; + return [value, setValueIfUncontrolled]; } diff --git a/packages/material-ui-utils/src/useEventCallback.d.ts b/packages/material-ui-utils/src/useEventCallback.d.ts new file mode 100644 index 00000000000000..81f39f979486f0 --- /dev/null +++ b/packages/material-ui-utils/src/useEventCallback.d.ts @@ -0,0 +1 @@ +export default function useEventCallback any>(func: T): T; diff --git a/packages/material-ui-utils/src/useEventCallback.ts b/packages/material-ui-utils/src/useEventCallback.js similarity index 54% rename from packages/material-ui-utils/src/useEventCallback.ts rename to packages/material-ui-utils/src/useEventCallback.js index 6988f5e51df07a..7ff34781cd75cd 100644 --- a/packages/material-ui-utils/src/useEventCallback.ts +++ b/packages/material-ui-utils/src/useEventCallback.js @@ -1,4 +1,3 @@ -/* eslint-disable react-hooks/exhaustive-deps */ import * as React from 'react'; import useEnhancedEffect from './useEnhancedEffect'; @@ -6,11 +5,10 @@ import useEnhancedEffect from './useEnhancedEffect'; * https://github.com/facebook/react/issues/14099#issuecomment-440013892 * @param {function} fn */ -export default function useEventCallback any>(fn: T): T { +export default function useEventCallback(fn) { const ref = React.useRef(fn); useEnhancedEffect(() => { ref.current = fn; }); - // @ts-ignore - return React.useCallback(((...args) => (0, ref.current)(...args)) as T, []); + return React.useCallback((...args) => (0, ref.current)(...args), []); } diff --git a/packages/material-ui-utils/src/useForkRef.d.ts b/packages/material-ui-utils/src/useForkRef.d.ts new file mode 100644 index 00000000000000..877be87b037a71 --- /dev/null +++ b/packages/material-ui-utils/src/useForkRef.d.ts @@ -0,0 +1,3 @@ +import * as React from 'react'; + +export default function useForkRef(refA: React.Ref, refB: React.Ref): React.Ref; diff --git a/packages/material-ui-utils/src/useForkRef.ts b/packages/material-ui-utils/src/useForkRef.js similarity index 84% rename from packages/material-ui-utils/src/useForkRef.ts rename to packages/material-ui-utils/src/useForkRef.js index 8efcc40c3bda76..5e67bbaf0b421e 100644 --- a/packages/material-ui-utils/src/useForkRef.ts +++ b/packages/material-ui-utils/src/useForkRef.js @@ -1,7 +1,7 @@ import * as React from 'react'; import setRef from './setRef'; -export default function useForkRef(refA: React.Ref, refB: React.Ref): React.Ref { +export default function useForkRef(refA, refB) { /** * This will create a new function if the ref props change and are defined. * This means react will call the old forkRef with `null` and the new forkRef diff --git a/packages/material-ui-utils/src/useId.d.ts b/packages/material-ui-utils/src/useId.d.ts new file mode 100644 index 00000000000000..06368a53d01428 --- /dev/null +++ b/packages/material-ui-utils/src/useId.d.ts @@ -0,0 +1 @@ +export default function useId(idOverride?: string): string; diff --git a/packages/material-ui-utils/src/useId.ts b/packages/material-ui-utils/src/useId.js similarity index 71% rename from packages/material-ui-utils/src/useId.ts rename to packages/material-ui-utils/src/useId.js index bf9f068219c456..16ab5c9eda794c 100644 --- a/packages/material-ui-utils/src/useId.ts +++ b/packages/material-ui-utils/src/useId.js @@ -3,8 +3,8 @@ import * as React from 'react'; /** * Private module reserved for @material-ui packages. */ -export default function useId(idOverride?: string): string { - const [defaultId, setDefaultId] = React.useState(idOverride); +export default function useId(idOverride) { + const [defaultId, setDefaultId] = React.useState(idOverride); const id = idOverride || defaultId; React.useEffect(() => { if (defaultId == null) { @@ -14,5 +14,5 @@ export default function useId(idOverride?: string): string { setDefaultId(`mui-${Math.round(Math.random() * 1e5)}`); } }, [defaultId]); - return id as string; + return id; } diff --git a/packages/material-ui-utils/src/useIsFocusVisible.ts b/packages/material-ui-utils/src/useIsFocusVisible.js similarity index 92% rename from packages/material-ui-utils/src/useIsFocusVisible.ts rename to packages/material-ui-utils/src/useIsFocusVisible.js index 974762e9e87781..7b01d9d9eb982e 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.ts +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -3,7 +3,7 @@ import * as React from 'react'; let hadKeyboardEvent = true; let hadFocusVisibleRecently = false; -let hadFocusVisibleRecentlyTimeout: any = null; +let hadFocusVisibleRecentlyTimeout = null; const inputTypesWhitelist = { text: true, @@ -28,11 +28,9 @@ const inputTypesWhitelist = { * @param {Element} node * @returns {boolean} */ -// @ts-ignore function focusTriggersKeyboardModality(node) { const { type, tagName } = node; - // @ts-ignore if (tagName === 'INPUT' && inputTypesWhitelist[type] && !node.readOnly) { return true; } @@ -55,7 +53,6 @@ function focusTriggersKeyboardModality(node) { * then the modality is keyboard. Otherwise, the modality is not keyboard. * @param {KeyboardEvent} event */ -// @ts-ignore function handleKeyDown(event) { if (event.metaKey || event.altKey || event.ctrlKey) { return; @@ -75,7 +72,6 @@ function handlePointerDown() { } function handleVisibilityChange() { - // @ts-ignore if (this.visibilityState === 'hidden') { // If the tab becomes active again, the browser will handle calling focus // on the element (Safari actually calls it twice). @@ -87,7 +83,7 @@ function handleVisibilityChange() { } } -function prepare(doc: Document) { +function prepare(doc) { doc.addEventListener('keydown', handleKeyDown, true); doc.addEventListener('mousedown', handlePointerDown, true); doc.addEventListener('pointerdown', handlePointerDown, true); @@ -95,7 +91,7 @@ function prepare(doc: Document) { doc.addEventListener('visibilitychange', handleVisibilityChange, true); } -export function teardown(doc: Document) { +export function teardown(doc) { doc.removeEventListener('keydown', handleKeyDown, true); doc.removeEventListener('mousedown', handlePointerDown, true); doc.removeEventListener('pointerdown', handlePointerDown, true); @@ -103,7 +99,6 @@ export function teardown(doc: Document) { doc.removeEventListener('visibilitychange', handleVisibilityChange, true); } -// @ts-ignore function isFocusVisible(event) { const { target } = event; try { @@ -120,12 +115,7 @@ function isFocusVisible(event) { return hadKeyboardEvent || focusTriggersKeyboardModality(target); } -export default function useIsFocusVisible(): { - isFocusVisibleRef: React.MutableRefObject; - onBlur: (event: React.FocusEvent) => void; - onFocus: (event: React.FocusEvent) => void; - ref: React.Ref; -} { +export default function useIsFocusVisible() { const ref = React.useCallback((node) => { if (node != null) { prepare(node.ownerDocument); @@ -165,7 +155,6 @@ export default function useIsFocusVisible(): { /** * Should be called if a blur event is fired */ - // @ts-ignore function handleFocusVisible(event) { if (isFocusVisible(event)) { isFocusVisibleRef.current = true; From 395711902df63a2e4730fa9de7f822ce53bc2cde Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 11:56:41 +0100 Subject: [PATCH 09/34] fixed import --- packages/material-ui-utils/src/capitalize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js index 4c87d3020595a1..ce5846c529b6a3 100644 --- a/packages/material-ui-utils/src/capitalize.js +++ b/packages/material-ui-utils/src/capitalize.js @@ -1,4 +1,4 @@ -import MuiError from '@material-ui/utils/macros/MuiError.macro'; +import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // // A strict capitalization should uppercase the first letter of each word a the sentence. From 328ca778c92ad7465f672a0fb8d6fc457a477a44 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 12:01:12 +0100 Subject: [PATCH 10/34] removed file --- docs/src/pages/system/sx/GettingStarted.js | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js index 83e014fb529a58..7134a3523ce9cb 100644 --- a/docs/src/pages/system/sx/GettingStarted.js +++ b/docs/src/pages/system/sx/GettingStarted.js @@ -2,17 +2,19 @@ import * as React from 'react'; import Box from '@material-ui/core/Box'; export default function GettingStarted() { - return ( - How to use the sx prop - ); -} \ No newline at end of file + return ( + + How to use the sx prop + + ); +} From 27473278b6e96cf3002c328365b56ce10d8f1346 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 12:01:21 +0100 Subject: [PATCH 11/34] removed file --- docs/src/pages/system/sx/GettingStarted.js | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 docs/src/pages/system/sx/GettingStarted.js diff --git a/docs/src/pages/system/sx/GettingStarted.js b/docs/src/pages/system/sx/GettingStarted.js deleted file mode 100644 index 7134a3523ce9cb..00000000000000 --- a/docs/src/pages/system/sx/GettingStarted.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react'; -import Box from '@material-ui/core/Box'; - -export default function GettingStarted() { - return ( - - How to use the sx prop - - ); -} From 9066f7a738fd0cd7c4d03f4b484c9810ce32a631 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:20:07 +0100 Subject: [PATCH 12/34] Update packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json Co-authored-by: Matt --- .../macros/__fixtures__/relative-import/error-codes.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json b/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json index 3fe90729b7efe7..94a681317bf508 100644 --- a/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/error-codes.json @@ -1,3 +1,3 @@ { - "1": "Material-UI: Expected valid input target.\nDid you use `inputComponent`" + "1": "Material-UI: Expected valid input target.\nDid you use `inputComponent`?" } From e0f137c9a0433d046969f92c6bf019442827f4f7 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:20:22 +0100 Subject: [PATCH 13/34] Update packages/material-ui-utils/macros/__fixtures__/relative-import/input.js Co-authored-by: Matt --- .../macros/__fixtures__/relative-import/input.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js index 492b6cb19cd307..5def863cce3505 100644 --- a/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/input.js @@ -1,3 +1,3 @@ import MuiError from '../../../macros/MuiError.macro'; -throw new MuiError('Material-UI: Expected valid input target.\n' + 'Did you use `inputComponent`'); +throw new MuiError('Material-UI: Expected valid input target.\n' + 'Did you use `inputComponent`?'); From 2d1ac56ffaabc212aee3575fd0cc5a51f9623d09 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:20:35 +0100 Subject: [PATCH 14/34] Update packages/material-ui-utils/macros/__fixtures__/relative-import/output.js Co-authored-by: Matt --- .../macros/__fixtures__/relative-import/output.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js b/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js index b0e82ed1768e0e..f2786cea115007 100644 --- a/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js +++ b/packages/material-ui-utils/macros/__fixtures__/relative-import/output.js @@ -2,6 +2,6 @@ import _formatMuiErrorMessage from '../../formatMuiErrorMessage'; throw new Error( process.env.NODE_ENV !== 'production' ? `Material-UI: Expected valid input target. -Did you use \`inputComponent\`` +Did you use \`inputComponent\`?` : _formatMuiErrorMessage(1), ); From c9e7ba0be0a510dde62b997c89730a1a31dc3712 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:21:00 +0100 Subject: [PATCH 15/34] Update packages/material-ui-utils/src/capitalize.js Co-authored-by: Matt --- packages/material-ui-utils/src/capitalize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js index ce5846c529b6a3..236c76ce8367b6 100644 --- a/packages/material-ui-utils/src/capitalize.js +++ b/packages/material-ui-utils/src/capitalize.js @@ -1,7 +1,7 @@ import MuiError from '../macros/MuiError.macro'; // It should to be noted that this function isn't equivalent to `text-transform: capitalize`. // -// A strict capitalization should uppercase the first letter of each word a the sentence. +// A strict capitalization should uppercase the first letter of each word in the sentence. // We only handle the first word. export default function capitalize(string) { if (typeof string !== 'string') { From 7a3b4c267cf50d780b21ad541ede25960a789d7b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:21:30 +0100 Subject: [PATCH 16/34] Update packages/material-ui-utils/src/capitalize.js Co-authored-by: Matt --- packages/material-ui-utils/src/capitalize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/capitalize.js b/packages/material-ui-utils/src/capitalize.js index 236c76ce8367b6..86acc05961b330 100644 --- a/packages/material-ui-utils/src/capitalize.js +++ b/packages/material-ui-utils/src/capitalize.js @@ -5,7 +5,7 @@ import MuiError from '../macros/MuiError.macro'; // We only handle the first word. export default function capitalize(string) { if (typeof string !== 'string') { - throw new MuiError('Material-UI: capitalize(string) expects a string argument.'); + throw new MuiError('Material-UI: `capitalize(string)` expects a string argument.'); } return string.charAt(0).toUpperCase() + string.slice(1); From fca1e8d13a5eb8e8a432bcde9563bdd8d5517740 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:22:55 +0100 Subject: [PATCH 17/34] Update packages/material-ui-utils/src/createChainedFunction.js Co-authored-by: Matt --- packages/material-ui-utils/src/createChainedFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/createChainedFunction.js b/packages/material-ui-utils/src/createChainedFunction.js index a023586cc3ea88..2ae9d0b8695750 100644 --- a/packages/material-ui-utils/src/createChainedFunction.js +++ b/packages/material-ui-utils/src/createChainedFunction.js @@ -16,7 +16,7 @@ export default function createChainedFunction(...funcs) { if (process.env.NODE_ENV !== 'production') { if (typeof func !== 'function') { console.error( - 'Material-UI: Invalid Argument Type, must only provide functions, undefined, or null.', + 'Material-UI: Invalid argument type - must only provide functions, undefined, or null.', ); } } From ebfdc0657da3a0375411418a45b3d51b375de92b Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:23:36 +0100 Subject: [PATCH 18/34] Update packages/material-ui-utils/src/setRef.ts Co-authored-by: Matt --- packages/material-ui-utils/src/setRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts index 29ebef0d3527c7..51499fb9a95564 100644 --- a/packages/material-ui-utils/src/setRef.ts +++ b/packages/material-ui-utils/src/setRef.ts @@ -1,7 +1,7 @@ import * as React from 'react'; /** - * TODO v5: consider to make it private + * TODO v5: consider making it private * * passes {value} to {ref} * From 623a89e192e92c5ce5d8cb5751355b2041db9ea9 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:24:07 +0100 Subject: [PATCH 19/34] Update packages/material-ui-utils/src/setRef.ts Co-authored-by: Matt --- packages/material-ui-utils/src/setRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts index 51499fb9a95564..3cecb3847fcffd 100644 --- a/packages/material-ui-utils/src/setRef.ts +++ b/packages/material-ui-utils/src/setRef.ts @@ -6,7 +6,7 @@ import * as React from 'react'; * passes {value} to {ref} * * WARNING: Be sure to only call this inside a callback that is passed as a ref. - * Otherwise make sure to cleanup previous {ref} if it changes. See + * Otherwise, make sure to cleanup the previous {ref} if it changes. See * https://github.com/mui-org/material-ui/issues/13539 * * useful if you want to expose the ref of an inner component to the public api From 76810d74b81a8f3d0f9756cf1f10c5f87d78905d Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:24:32 +0100 Subject: [PATCH 20/34] Update packages/material-ui-utils/src/setRef.ts Co-authored-by: Matt --- packages/material-ui-utils/src/setRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts index 3cecb3847fcffd..418ae9b0652e70 100644 --- a/packages/material-ui-utils/src/setRef.ts +++ b/packages/material-ui-utils/src/setRef.ts @@ -9,7 +9,7 @@ import * as React from 'react'; * Otherwise, make sure to cleanup the previous {ref} if it changes. See * https://github.com/mui-org/material-ui/issues/13539 * - * useful if you want to expose the ref of an inner component to the public api + * Useful if you want to expose the ref of an inner component to the public API * while still using it inside the component * @param ref a ref callback or ref object if anything falsy this is a no-op */ From 831d74b128369026fbf9deedd1e211df81213f29 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:24:52 +0100 Subject: [PATCH 21/34] Update packages/material-ui-utils/src/setRef.ts Co-authored-by: Matt --- packages/material-ui-utils/src/setRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts index 418ae9b0652e70..2a1c4d8e9d1e95 100644 --- a/packages/material-ui-utils/src/setRef.ts +++ b/packages/material-ui-utils/src/setRef.ts @@ -10,7 +10,7 @@ import * as React from 'react'; * https://github.com/mui-org/material-ui/issues/13539 * * Useful if you want to expose the ref of an inner component to the public API - * while still using it inside the component + * while still using it inside the component. * @param ref a ref callback or ref object if anything falsy this is a no-op */ export default function setRef( From e0bc92167885df6b488711a136e0ad4cb3208817 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:25:17 +0100 Subject: [PATCH 22/34] Update packages/material-ui-utils/src/setRef.ts Co-authored-by: Matt --- packages/material-ui-utils/src/setRef.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/setRef.ts b/packages/material-ui-utils/src/setRef.ts index 2a1c4d8e9d1e95..54cbca739cce0d 100644 --- a/packages/material-ui-utils/src/setRef.ts +++ b/packages/material-ui-utils/src/setRef.ts @@ -11,7 +11,7 @@ import * as React from 'react'; * * Useful if you want to expose the ref of an inner component to the public API * while still using it inside the component. - * @param ref a ref callback or ref object if anything falsy this is a no-op + * @param ref A ref callback or ref object. If anything falsy, this is a no-op. */ export default function setRef( ref: React.MutableRefObject | ((instance: T | null) => void) | null | undefined, From b5fe610591579feb19fffb39c4e1d2e51c89dce1 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:25:42 +0100 Subject: [PATCH 23/34] Update packages/material-ui-utils/src/useControlled.d.ts Co-authored-by: Matt --- packages/material-ui-utils/src/useControlled.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useControlled.d.ts b/packages/material-ui-utils/src/useControlled.d.ts index 87e785ae289356..6d994c30b77d5e 100644 --- a/packages/material-ui-utils/src/useControlled.d.ts +++ b/packages/material-ui-utils/src/useControlled.d.ts @@ -1,6 +1,6 @@ export interface UseControlledProps { /** - * This prop contains the component value when it's controlled. + * Holds the component value when it's controlled. */ controlled: T | undefined; /** From 39dac58aa77cd3e42d9acb983224a8f446cd7285 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:26:03 +0100 Subject: [PATCH 24/34] Update packages/material-ui-utils/src/useForkRef.js Co-authored-by: Matt --- packages/material-ui-utils/src/useForkRef.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useForkRef.js b/packages/material-ui-utils/src/useForkRef.js index 5e67bbaf0b421e..673e0f0a8b7f9e 100644 --- a/packages/material-ui-utils/src/useForkRef.js +++ b/packages/material-ui-utils/src/useForkRef.js @@ -5,7 +5,7 @@ export default function useForkRef(refA, refB) { /** * This will create a new function if the ref props change and are defined. * This means react will call the old forkRef with `null` and the new forkRef - * with the ref. Cleanup naturally emerges from this behavior + * with the ref. Cleanup naturally emerges from this behavior. */ return React.useMemo(() => { if (refA == null && refB == null) { From b65508ee2555d6509eefd0d2d218108f2e7429d2 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:26:31 +0100 Subject: [PATCH 25/34] Update packages/material-ui-utils/src/useControlled.js Co-authored-by: Matt --- packages/material-ui-utils/src/useControlled.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useControlled.js b/packages/material-ui-utils/src/useControlled.js index 3eb0b699910936..dae83eeb89d686 100644 --- a/packages/material-ui-utils/src/useControlled.js +++ b/packages/material-ui-utils/src/useControlled.js @@ -18,7 +18,7 @@ export default function useControlled({ controlled, default: defaultProp, name, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled ${name} ` + 'element for the lifetime of the component.', - "The nature of the state is determined during the first render, it's considered controlled if the value is not `undefined`.", + "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", 'More info: https://fb.me/react-controlled-components', ].join('\n'), ); From 6fd966fed2c3b397fd01486433116292f0a61f44 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:26:59 +0100 Subject: [PATCH 26/34] Update packages/material-ui-utils/src/useIsFocusVisible.js Co-authored-by: Matt --- packages/material-ui-utils/src/useIsFocusVisible.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useIsFocusVisible.js b/packages/material-ui-utils/src/useIsFocusVisible.js index 7b01d9d9eb982e..9758c9458bf3a3 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.js +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -104,7 +104,7 @@ function isFocusVisible(event) { try { return target.matches(':focus-visible'); } catch (error) { - // browsers not implementing :focus-visible will throw a SyntaxError + // Browsers not implementing :focus-visible will throw a SyntaxError. // we use our own heuristic for those browsers // rethrow might be better if it's not the expected error but do we really // want to crash if focus-visible malfunctioned? From 837e33fdbeb79207a1a8f03db81b3604ff855bec Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:27:33 +0100 Subject: [PATCH 27/34] Update packages/material-ui-utils/src/useIsFocusVisible.js Co-authored-by: Matt --- packages/material-ui-utils/src/useIsFocusVisible.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useIsFocusVisible.js b/packages/material-ui-utils/src/useIsFocusVisible.js index 9758c9458bf3a3..446d39105fca6f 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.js +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -105,7 +105,7 @@ function isFocusVisible(event) { return target.matches(':focus-visible'); } catch (error) { // Browsers not implementing :focus-visible will throw a SyntaxError. - // we use our own heuristic for those browsers + // We use our own heuristic for those browsers. // rethrow might be better if it's not the expected error but do we really // want to crash if focus-visible malfunctioned? } From 9eefcca063a047f8541abfafc1b57570dd93d310 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:27:58 +0100 Subject: [PATCH 28/34] Update packages/material-ui-utils/src/useIsFocusVisible.js Co-authored-by: Matt --- packages/material-ui-utils/src/useIsFocusVisible.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useIsFocusVisible.js b/packages/material-ui-utils/src/useIsFocusVisible.js index 446d39105fca6f..3607549a4be2d3 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.js +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -106,7 +106,7 @@ function isFocusVisible(event) { } catch (error) { // Browsers not implementing :focus-visible will throw a SyntaxError. // We use our own heuristic for those browsers. - // rethrow might be better if it's not the expected error but do we really + // Rethrow might be better if it's not the expected error but do we really // want to crash if focus-visible malfunctioned? } From 57060369309feecbc0393cc4f644a51b392e0040 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:28:17 +0100 Subject: [PATCH 29/34] Update packages/material-ui-utils/src/useIsFocusVisible.js Co-authored-by: Matt --- packages/material-ui-utils/src/useIsFocusVisible.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useIsFocusVisible.js b/packages/material-ui-utils/src/useIsFocusVisible.js index 3607549a4be2d3..a1092999218708 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.js +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -110,7 +110,7 @@ function isFocusVisible(event) { // want to crash if focus-visible malfunctioned? } - // no need for validFocusTarget check. the user does that by attaching it to + // No need for validFocusTarget check. The user does that by attaching it to // focusable events only return hadKeyboardEvent || focusTriggersKeyboardModality(target); } From 21c706dce30158037d5936ada1c0275edb8ed6e2 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:28:40 +0100 Subject: [PATCH 30/34] Update packages/material-ui-utils/src/useIsFocusVisible.js Co-authored-by: Matt --- packages/material-ui-utils/src/useIsFocusVisible.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/useIsFocusVisible.js b/packages/material-ui-utils/src/useIsFocusVisible.js index a1092999218708..3b87da3db5cb94 100644 --- a/packages/material-ui-utils/src/useIsFocusVisible.js +++ b/packages/material-ui-utils/src/useIsFocusVisible.js @@ -111,7 +111,7 @@ function isFocusVisible(event) { } // No need for validFocusTarget check. The user does that by attaching it to - // focusable events only + // focusable events only. return hadKeyboardEvent || focusTriggersKeyboardModality(target); } From 18be04686c479a3f246add62d03e128b830f7ed3 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:34:46 +0100 Subject: [PATCH 31/34] Removed private method comment --- packages/material-ui-utils/src/useEnhancedEffect.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/material-ui-utils/src/useEnhancedEffect.js b/packages/material-ui-utils/src/useEnhancedEffect.js index beefea01128179..5856a3922f4ab9 100644 --- a/packages/material-ui-utils/src/useEnhancedEffect.js +++ b/packages/material-ui-utils/src/useEnhancedEffect.js @@ -2,7 +2,4 @@ import * as React from 'react'; const useEnhancedEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect; -/** - * Private module reserved for @material-ui packages. - */ export default useEnhancedEffect; From 84386589cd420d3f9852e62b7c1b62846fce54af Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:35:49 +0100 Subject: [PATCH 32/34] removed private method comment --- packages/material-ui-utils/src/isMuiElement.d.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/material-ui-utils/src/isMuiElement.d.ts b/packages/material-ui-utils/src/isMuiElement.d.ts index 104cc6602cee50..b0c8bd5d15391c 100644 --- a/packages/material-ui-utils/src/isMuiElement.d.ts +++ b/packages/material-ui-utils/src/isMuiElement.d.ts @@ -11,9 +11,7 @@ export interface StyledComponentProps { } /** - * @private ONLY USE FROM WITHIN mui-org/material-ui - * - * Internal helper type for conform (describeConformance) components that are decorated with `withStyles + * Helper type for conform (describeConformance) components that are decorated with `withStyles * However, we don't declare classes on this type. * It is recommended to declare them manually with an interface so that each class can have a separate JSDOC. */ From e2104a52a7161bee17ad450daac4cb1e6b119fb0 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 19:36:20 +0100 Subject: [PATCH 33/34] remove private method comment --- packages/material-ui-utils/src/useId.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/material-ui-utils/src/useId.js b/packages/material-ui-utils/src/useId.js index 16ab5c9eda794c..546ee8c7be4fbf 100644 --- a/packages/material-ui-utils/src/useId.js +++ b/packages/material-ui-utils/src/useId.js @@ -1,8 +1,5 @@ import * as React from 'react'; -/** - * Private module reserved for @material-ui packages. - */ export default function useId(idOverride) { const [defaultId, setDefaultId] = React.useState(idOverride); const id = idOverride || defaultId; From 1312f19aaab212ebb636f48b6dafbdea16decb05 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Wed, 28 Oct 2020 20:22:23 +0100 Subject: [PATCH 34/34] Update packages/material-ui-utils/src/createChainedFunction.js --- packages/material-ui-utils/src/createChainedFunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-utils/src/createChainedFunction.js b/packages/material-ui-utils/src/createChainedFunction.js index 2ae9d0b8695750..4e72e2d4afeee4 100644 --- a/packages/material-ui-utils/src/createChainedFunction.js +++ b/packages/material-ui-utils/src/createChainedFunction.js @@ -1,5 +1,5 @@ /** - * Safe chained function + * Safe chained function. * * Will only create a new function if needed, * otherwise will pass back existing functions or null.