From aab5e1116704998bcd6c7dcf8190b2ab5dd6c0cb Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Fri, 25 Sep 2020 10:50:30 +0200 Subject: [PATCH] [core] Port createSpacing to TypeScript (#22720) --- .../progress/CircularIntegration.js | 2 +- .../progress/CircularIntegration.tsx | 2 +- .../components/progress/DelayingAppearance.js | 2 +- .../progress/DelayingAppearance.tsx | 2 +- docs/tsconfig.json | 2 +- framer/tsconfig.json | 3 +- package.json | 1 + packages/material-ui-system/src/index.d.ts | 10 +++++ .../src/styles/createSpacing.spec.ts | 11 ----- ...eSpacing.test.js => createSpacing.test.ts} | 5 ++- .../{createSpacing.js => createSpacing.ts} | 33 ++++++++++++-- packages/material-ui/tsconfig.build.json | 5 +-- tsconfig.json | 2 +- yarn.lock | 43 +++++++++++++++++++ 14 files changed, 95 insertions(+), 28 deletions(-) delete mode 100644 packages/material-ui/src/styles/createSpacing.spec.ts rename packages/material-ui/src/styles/{createSpacing.test.js => createSpacing.test.ts} (94%) rename packages/material-ui/src/styles/{createSpacing.js => createSpacing.ts} (51%) diff --git a/docs/src/pages/components/progress/CircularIntegration.js b/docs/src/pages/components/progress/CircularIntegration.js index f72e74baccf152..613f7ed6d238cf 100644 --- a/docs/src/pages/components/progress/CircularIntegration.js +++ b/docs/src/pages/components/progress/CircularIntegration.js @@ -60,7 +60,7 @@ export default function CircularIntegration() { if (!loading) { setSuccess(false); setLoading(true); - timer.current = setTimeout(() => { + timer.current = window.setTimeout(() => { setSuccess(true); setLoading(false); }, 2000); diff --git a/docs/src/pages/components/progress/CircularIntegration.tsx b/docs/src/pages/components/progress/CircularIntegration.tsx index 3cb6baf78f5d30..1d81b8964f5e5a 100644 --- a/docs/src/pages/components/progress/CircularIntegration.tsx +++ b/docs/src/pages/components/progress/CircularIntegration.tsx @@ -62,7 +62,7 @@ export default function CircularIntegration() { if (!loading) { setSuccess(false); setLoading(true); - timer.current = setTimeout(() => { + timer.current = window.setTimeout(() => { setSuccess(true); setLoading(false); }, 2000); diff --git a/docs/src/pages/components/progress/DelayingAppearance.js b/docs/src/pages/components/progress/DelayingAppearance.js index bebe6fd1957931..ff03dd29a768ea 100644 --- a/docs/src/pages/components/progress/DelayingAppearance.js +++ b/docs/src/pages/components/progress/DelayingAppearance.js @@ -45,7 +45,7 @@ export default function DelayingAppearance() { } setQuery('progress'); - timerRef.current = setTimeout(() => { + timerRef.current = window.setTimeout(() => { setQuery('success'); }, 2000); }; diff --git a/docs/src/pages/components/progress/DelayingAppearance.tsx b/docs/src/pages/components/progress/DelayingAppearance.tsx index 7f17a421d8ac5f..03e15e1899df59 100644 --- a/docs/src/pages/components/progress/DelayingAppearance.tsx +++ b/docs/src/pages/components/progress/DelayingAppearance.tsx @@ -47,7 +47,7 @@ export default function DelayingAppearance() { } setQuery('progress'); - timerRef.current = setTimeout(() => { + timerRef.current = window.setTimeout(() => { setQuery('success'); }, 2000); }; diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 2c10e5735fb6df..556a86efd76546 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "../tsconfig.json", - "include": ["types", "src/pages/**/*"], + "include": ["next-env.d.ts", "types", "src/pages/**/*"], "compilerOptions": { "allowJs": false, "isolatedModules": true, diff --git a/framer/tsconfig.json b/framer/tsconfig.json index 0d352e887f5925..a71b844a9204eb 100644 --- a/framer/tsconfig.json +++ b/framer/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "skipLibCheck": true, - "noUnusedLocals": true, - "types": ["react"] + "noUnusedLocals": true }, "include": ["Material-UI.framerfx/code"] } diff --git a/package.json b/package.json index 1110d49d415dee..2539b40667b8c7 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "@types/prettier": "^2.0.0", "@types/react": "^16.9.44", "@types/sinon": "^9.0.0", + "@types/webpack": "^4.41.22", "@types/yargs": "^15.0.5", "@typescript-eslint/eslint-plugin": "^3.9.1", "@typescript-eslint/parser": "^3.9.1", diff --git a/packages/material-ui-system/src/index.d.ts b/packages/material-ui-system/src/index.d.ts index 510abda24a186d..01852b04881085 100644 --- a/packages/material-ui-system/src/index.d.ts +++ b/packages/material-ui-system/src/index.d.ts @@ -167,6 +167,16 @@ export const spacing: SimpleStyleFunction< | 'paddingY' >; export type SpacingProps = PropsFor; +export function createUnarySpacing(theme: { + spacing: Spacing; +}): Spacing extends number + ? (abs: number) => number + : Spacing extends any[] + ? (abs: Index) => Spacing[Index] + : Spacing extends (...args: unknown[]) => unknown + ? Spacing + : // warns in Dev + () => undefined; // style.js export interface StyleOptions { diff --git a/packages/material-ui/src/styles/createSpacing.spec.ts b/packages/material-ui/src/styles/createSpacing.spec.ts deleted file mode 100644 index f9ba632a7f02bb..00000000000000 --- a/packages/material-ui/src/styles/createSpacing.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createMuiTheme } from '@material-ui/core/styles'; - -{ - let theme; - theme = createMuiTheme({ - spacing: 8, - }); - theme = createMuiTheme({ - spacing: (factor: number) => `${0.8 * factor}rem`, - }); -} diff --git a/packages/material-ui/src/styles/createSpacing.test.js b/packages/material-ui/src/styles/createSpacing.test.ts similarity index 94% rename from packages/material-ui/src/styles/createSpacing.test.js rename to packages/material-ui/src/styles/createSpacing.test.ts index 1948a233568623..66e7ed2f650d7b 100644 --- a/packages/material-ui/src/styles/createSpacing.test.js +++ b/packages/material-ui/src/styles/createSpacing.test.ts @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import createSpacing from './createSpacing'; +import createSpacing, { Spacing } from './createSpacing'; describe('createSpacing', () => { it('should be configurable', () => { - let spacing; + let spacing: Spacing; spacing = createSpacing(); expect(spacing(1)).to.equal('8px'); spacing = createSpacing(10); @@ -51,6 +51,7 @@ describe('createSpacing', () => { it('should warn for wrong input', () => { expect(() => { createSpacing({ + // @ts-expect-error unit: 4, }); }).toErrorDev('Material-UI: The `theme.spacing` value ([object Object]) is invalid'); diff --git a/packages/material-ui/src/styles/createSpacing.js b/packages/material-ui/src/styles/createSpacing.ts similarity index 51% rename from packages/material-ui/src/styles/createSpacing.js rename to packages/material-ui/src/styles/createSpacing.ts index f0b1e306e67e38..9e34226d383d8d 100644 --- a/packages/material-ui/src/styles/createSpacing.js +++ b/packages/material-ui/src/styles/createSpacing.ts @@ -1,9 +1,34 @@ import { createUnarySpacing } from '@material-ui/system'; -export default function createSpacing(spacingInput = 8) { +export type SpacingOptions = + | number + | Spacing + | ((abs: number) => number | string) + | Array; + +export type SpacingArgument = number | string; + +// The different signatures imply different meaning for their arguments that can't be expressed structurally. +// We express the difference with variable names. +/* tslint:disable:unified-signatures */ +export interface Spacing { + (): string; + (value: number): string; + (topBottom: SpacingArgument, rightLeft: SpacingArgument): string; + (top: SpacingArgument, rightLeft: SpacingArgument, bottom: SpacingArgument): string; + ( + top: SpacingArgument, + right: SpacingArgument, + bottom: SpacingArgument, + left: SpacingArgument, + ): string; +} +/* tslint:enable:unified-signatures */ + +export default function createSpacing(spacingInput: SpacingOptions = 8): Spacing { // Already transformed. - if (spacingInput.mui) { - return spacingInput; + if ((spacingInput as any).mui) { + return spacingInput as Spacing; } // Material Design layouts are visually balanced. Most measurements align to an 8dp grid, which aligns both spacing and the overall layout. @@ -13,7 +38,7 @@ export default function createSpacing(spacingInput = 8) { spacing: spacingInput, }); - const spacing = (...args) => { + const spacing = (...args: Array): string => { if (process.env.NODE_ENV !== 'production') { if (!(args.length <= 4)) { console.error( diff --git a/packages/material-ui/tsconfig.build.json b/packages/material-ui/tsconfig.build.json index 5d9f9a7f63c3ba..38573df329bab7 100644 --- a/packages/material-ui/tsconfig.build.json +++ b/packages/material-ui/tsconfig.build.json @@ -7,9 +7,8 @@ "noEmit": false, "emitDeclarationOnly": true, "outDir": "build", - "rootDir": "./src", - "types": ["react"] + "rootDir": "./src" }, "include": ["src/**/*.ts"], - "exclude": ["src/**/*.spec.ts"] + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] } diff --git a/tsconfig.json b/tsconfig.json index 63439ca95da593..d11baad69c0603 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,7 +31,7 @@ "typescript-to-proptypes": ["./packages/typescript-to-proptypes/src"] }, // Otherwise we get react-native typings which conflict with dom.lib. - "types": ["react"] + "types": ["node", "react"] }, "exclude": ["**/build", "**/node_modules", "docs/.next", "docs/export"] } diff --git a/yarn.lock b/yarn.lock index de6214c43ed174..c8dbab68f6849c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2499,6 +2499,11 @@ lodash.omit "^4.5.0" prop-types "^15.5.8" +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -2919,6 +2924,11 @@ resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + "@types/styled-components@5.1.3": version "5.1.3" resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.3.tgz#6fab3d9c8f7d9a15cbb89d379d850c985002f363" @@ -2929,6 +2939,11 @@ "@types/react-native" "*" csstype "^3.0.2" +"@types/tapable@*": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + "@types/testing-library__react-hooks@^3.3.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.3.0.tgz#f5d3e4ba1c811ef04f7f2309c9f5946e420060cd" @@ -2942,6 +2957,13 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== +"@types/uglify-js@*": + version "3.9.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.3.tgz#d94ed608e295bc5424c9600e6b8565407b6b4b6b" + integrity sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w== + dependencies: + source-map "^0.6.1" + "@types/unist@^2.0.0", "@types/unist@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -2952,6 +2974,27 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== +"@types/webpack-sources@*": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.2.tgz#5d3d4dea04008a779a90135ff96fb5c0c9e6292c" + integrity sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.41.22": + version "4.41.22" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.22.tgz#ff9758a17c6bd499e459b91e78539848c32d0731" + integrity sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"