-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Slider] Create unstyled version and migrate to emotion & styled-components #22435
Changes from 120 commits
f966e23
4c58672
7fe38a0
0f9b659
6adbc82
0c98292
99499b6
d375e3d
40f7019
4777a55
f891647
2c22ace
5e7f826
940f6d7
3a80cda
27e7286
2946ee1
03a64fa
b05a8e7
a21e199
ff8af15
fa0b76f
8f22840
c448969
7564cc0
4333ed1
79b8a26
0780a15
530b79f
49e50e4
9ec7c65
6f87bc1
4cdb02c
551e2f9
bb0e959
0fbd75e
1da5ffe
6152305
d249d83
47911ac
4f71ad6
95bb696
983f447
bd51f79
5a42c9f
396cee8
a5569b5
61673cd
47c4105
dc7a03e
e39ab3b
b02c56b
1c9e41d
8f2fedd
dc4caee
0cf297b
5c96a89
47d46ef
e6134a2
0eacc0d
8fb4591
d4a6092
cb9bb24
f2fcb52
0048c13
9ba5d01
90cec13
9a0b87c
2479eaa
9ce3a13
8fb98fd
2c4032e
76171a8
858c4b7
f4bba69
ff85f47
fffc2d7
7411958
aa414ff
9ca5f62
669ba1e
fdce96d
deb6e60
b804b36
3d0e31e
03cc79f
37a384f
645edee
9849608
4254cd3
2daf270
3533342
3a3def4
8897bb3
81578de
714b5ba
d681065
ca825c7
2e86e9c
1999fb4
6cd4a5f
c5bec5b
58cda5d
3d232e0
a362702
c9ea84f
f053755
9e77509
a8e1d46
0f8bfc9
a37b64f
cbeb6e9
2f224d6
37f37f1
1636fb8
1d64929
7088108
9cff369
ecda71a
27359e4
836f610
ea3730a
2c80925
3c4701d
5a697bb
1db5ee4
67ede91
34d19ab
f8e347b
bb9fc68
95d8826
f4cd959
c9993b7
24d8ba8
8ee44f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import React from 'react'; | ||
import { ServerStyleSheets } from '@material-ui/styles'; | ||
import { ServerStyleSheet } from 'styled-components'; | ||
import Document, { Html, Head, Main, NextScript } from 'next/document'; | ||
import { LANGUAGES_SSR } from 'docs/src/modules/constants'; | ||
import { pathnameToLanguage } from 'docs/src/modules/utils/helpers'; | ||
|
@@ -92,55 +93,70 @@ export default class MyDocument extends Document { | |
} | ||
} | ||
|
||
// `getInitialProps` belongs to `_document` (instead of `_app`), | ||
// it's compatible with static-site generation (SSG). | ||
MyDocument.getInitialProps = async (ctx) => { | ||
// Resolution order | ||
// | ||
// On the server: | ||
// 1. page.getInitialProps | ||
// 2. document.getInitialProps | ||
// 3. page.render | ||
// 4. document.render | ||
// 1. app.getInitialProps | ||
// 2. page.getInitialProps | ||
// 3. document.getInitialProps | ||
// 4. app.render | ||
// 5. page.render | ||
// 6. document.render | ||
// | ||
// On the server with error: | ||
// 2. document.getInitialProps | ||
// 1. document.getInitialProps | ||
// 2. app.render | ||
// 3. page.render | ||
// 4. document.render | ||
// | ||
// On the client | ||
// 1. page.getInitialProps | ||
// 3. page.render | ||
// 1. app.getInitialProps | ||
// 2. page.getInitialProps | ||
// 3. app.render | ||
// 4. page.render | ||
|
||
// Render app and page and get the context of the page with collected side effects. | ||
const sheets = new ServerStyleSheets(); | ||
const materialSheets = new ServerStyleSheets(); | ||
const styledComponentsSheet = new ServerStyleSheet(); | ||
const originalRenderPage = ctx.renderPage; | ||
|
||
ctx.renderPage = () => | ||
originalRenderPage({ | ||
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />), | ||
}); | ||
try { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Support for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Careful with these statements especially for hydration. Even if you did take a screenshot before and after hydration there could still be styles that mismatch that only apply to UI revealed after interaction. So this needs to be fixed before a stable release. Every warning we have that isn't actionable generates noise which is confusing to beginners and erodes trust in these warnings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we configure emotion too before moving forward? I guess we could also have it as a follow up task. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will work tomorrow on both configuring emption and solving the styled components warning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like emotion above 10 doesn't need any config for next.js🥳: https://emotion.sh/docs/ssr#nextjs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding the warning with styled-components, it still shows after you do the changes and refresh the page. I have tried everything I found on the matter and stamble apon this comment in the end - vercel/next.js#7322 (comment) So I will ignore it for now, as it is anyway not our default build, it's just for local testing of styled-components. |
||
ctx.renderPage = () => | ||
originalRenderPage({ | ||
enhanceApp: (App) => (props) => | ||
styledComponentsSheet.collectStyles(materialSheets.collect(<App {...props} />)), | ||
}); | ||
|
||
const initialProps = await Document.getInitialProps(ctx); | ||
const initialProps = await Document.getInitialProps(ctx); | ||
|
||
let css = sheets.toString(); | ||
// It might be undefined, e.g. after an error. | ||
if (css && process.env.NODE_ENV === 'production') { | ||
const result1 = await prefixer.process(css, { from: undefined }); | ||
css = result1.css; | ||
css = cleanCSS.minify(css).styles; | ||
} | ||
let css = materialSheets.toString(); | ||
// It might be undefined, e.g. after an error. | ||
if (css && process.env.NODE_ENV === 'production') { | ||
const result1 = await prefixer.process(css, { from: undefined }); | ||
css = result1.css; | ||
css = cleanCSS.minify(css).styles; | ||
} | ||
|
||
return { | ||
...initialProps, | ||
canonical: pathnameToLanguage(ctx.req.url).canonical, | ||
userLanguage: ctx.query.userLanguage || 'en', | ||
styles: [ | ||
...React.Children.toArray(initialProps.styles), | ||
<style | ||
id="jss-server-side" | ||
key="jss-server-side" | ||
// eslint-disable-next-line react/no-danger | ||
dangerouslySetInnerHTML={{ __html: css }} | ||
/>, | ||
], | ||
}; | ||
return { | ||
...initialProps, | ||
canonical: pathnameToLanguage(ctx.req.url).canonical, | ||
userLanguage: ctx.query.userLanguage || 'en', | ||
// Styles fragment is rendered after the app and page rendering finish. | ||
styles: [ | ||
...React.Children.toArray(initialProps.styles), | ||
<style | ||
id="jss-server-side" | ||
key="jss-server-side" | ||
// eslint-disable-next-line react/no-danger | ||
dangerouslySetInnerHTML={{ __html: css }} | ||
/>, | ||
styledComponentsSheet.getStyleElement(), | ||
], | ||
}; | ||
} finally { | ||
styledComponentsSheet.seal(); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; | ||
import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; | ||
|
||
const pageFilename = 'api/slider-styled'; | ||
const requireRaw = require.context('!raw-loader!./', false, /\/slider-styled\.md$/); | ||
|
||
export default function Page({ docs }) { | ||
return <MarkdownDocs docs={docs} />; | ||
} | ||
|
||
Page.getInitialProps = () => { | ||
const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); | ||
return { demos, docs }; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
filename: /packages/material-ui-lab/src/SliderStyled/SliderStyled.js | ||
--- | ||
|
||
<!--- This documentation is automatically generated, do not try to edit it. --> | ||
|
||
# SliderStyled API | ||
|
||
<p class="description">The API documentation of the SliderStyled React component. Learn more about the props and the CSS customization points.</p> | ||
|
||
## Import | ||
|
||
```js | ||
import SliderStyled from '@material-ui/lab/SliderStyled'; | ||
// or | ||
import { SliderStyled } from '@material-ui/lab'; | ||
``` | ||
|
||
You can learn more about the difference by [reading this guide](/guides/minimizing-bundle-size/). | ||
|
||
|
||
|
||
|
||
|
||
## Props | ||
|
||
| Name | Type | Default | Description | | ||
|:-----|:-----|:--------|:------------| | ||
|
||
The `ref` is forwarded to the root element. | ||
|
||
Any other props supplied will be provided to the root element (native element). | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; | ||
import { prepareMarkdown } from 'docs/src/modules/utils/parseMarkdown'; | ||
|
||
const pageFilename = 'api/slider-unstyled'; | ||
const requireRaw = require.context('!raw-loader!./', false, /\/slider-unstyled\.md$/); | ||
|
||
export default function Page({ docs }) { | ||
return <MarkdownDocs docs={docs} />; | ||
} | ||
|
||
Page.getInitialProps = () => { | ||
const { demos, docs } = prepareMarkdown({ pageFilename, requireRaw }); | ||
return { demos, docs }; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
filename: /packages/material-ui-lab/src/SliderUnstyled/SliderUnstyled.js | ||
--- | ||
|
||
<!--- This documentation is automatically generated, do not try to edit it. --> | ||
|
||
# SliderUnstyled API | ||
|
||
<p class="description">The API documentation of the SliderUnstyled React component. Learn more about the props and the CSS customization points.</p> | ||
|
||
## Import | ||
|
||
```js | ||
import SliderUnstyled from '@material-ui/lab/SliderUnstyled'; | ||
// or | ||
import { SliderUnstyled } from '@material-ui/lab'; | ||
``` | ||
|
||
You can learn more about the difference by [reading this guide](/guides/minimizing-bundle-size/). | ||
|
||
|
||
|
||
|
||
|
||
## Props | ||
|
||
| Name | Type | Default | Description | | ||
|:-----|:-----|:--------|:------------| | ||
| <span class="prop-name">aria-label</span> | <span class="prop-type">string</span> | | The label of the slider. | | ||
| <span class="prop-name">aria-labelledby</span> | <span class="prop-type">string</span> | | The id of the element containing a label for the slider. | | ||
| <span class="prop-name">aria-valuetext</span> | <span class="prop-type">string</span> | | A string value that provides a user-friendly name for the current value of the slider. | | ||
| <span class="prop-name">classes</span> | <span class="prop-type">object</span> | <span class="prop-default">{}</span> | Override or extend the styles applied to the component. | | ||
| <span class="prop-name">color</span> | <span class="prop-type">'primary'<br>| 'secondary'</span> | <span class="prop-default">'primary'</span> | The color of the component. It supports those theme colors that make sense for this component. | | ||
| <span class="prop-name">component</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'span'</span> | The component used for the root node. Either a string to use a HTML element or a component. | | ||
| <span class="prop-name">defaultValue</span> | <span class="prop-type">Array<number><br>| number</span> | | The default element value. Use when the component is not controlled. | | ||
| <span class="prop-name">disabled</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the slider will be disabled. | | ||
| <span class="prop-name">getAriaLabel</span> | <span class="prop-type">func</span> | | Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider.<br><br>**Signature:**<br>`function(index: number) => string`<br>*index:* The thumb label's index to format. | | ||
| <span class="prop-name">getAriaValueText</span> | <span class="prop-type">func</span> | | Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider.<br><br>**Signature:**<br>`function(value: number, index: number) => string`<br>*value:* The thumb label's value to format.<br>*index:* The thumb label's index to format. | | ||
| <span class="prop-name">isRtl</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Indicates whether the theme context has rtl direction. It is set automatically. | | ||
| <span class="prop-name">marks</span> | <span class="prop-type">Array<{ label?: node, value: number }><br>| bool</span> | <span class="prop-default">false</span> | Marks indicate predetermined values to which the user can move the slider. If `true` the marks will be spaced according the value of the `step` prop. If an array, it should contain objects with `value` and an optional `label` keys. | | ||
| <span class="prop-name">max</span> | <span class="prop-type">number</span> | <span class="prop-default">100</span> | The maximum allowed value of the slider. Should not be equal to min. | | ||
| <span class="prop-name">min</span> | <span class="prop-type">number</span> | <span class="prop-default">0</span> | The minimum allowed value of the slider. Should not be equal to max. | | ||
| <span class="prop-name">name</span> | <span class="prop-type">string</span> | | Name attribute of the hidden `input` element. | | ||
| <span class="prop-name">onChange</span> | <span class="prop-type">func</span> | | Callback function that is fired when the slider's value changed.<br><br>**Signature:**<br>`function(event: object, value: number \| number[]) => void`<br>*event:* The event source of the callback. **Warning**: This is a generic event not a change event.<br>*value:* The new value. | | ||
| <span class="prop-name">onChangeCommitted</span> | <span class="prop-type">func</span> | | Callback function that is fired when the `mouseup` is triggered.<br><br>**Signature:**<br>`function(event: object, value: number \| number[]) => void`<br>*event:* The event source of the callback. **Warning**: This is a generic event not a change event.<br>*value:* The new value. | | ||
| <span class="prop-name">orientation</span> | <span class="prop-type">'horizontal'<br>| 'vertical'</span> | <span class="prop-default">'horizontal'</span> | The slider orientation. | | ||
| <span class="prop-name">scale</span> | <span class="prop-type">func</span> | <span class="prop-default">(x) => x</span> | A transformation function, to change the scale of the slider. | | ||
| <span class="prop-name">step</span> | <span class="prop-type">number</span> | <span class="prop-default">1</span> | The granularity with which the slider can step through values. (A "discrete" slider.) The `min` prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.<br>When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. | | ||
| <span class="prop-name">ThumbComponent</span> | <span class="prop-type">elementType</span> | | The component used to display the value label. | | ||
| <span class="prop-name">track</span> | <span class="prop-type">'inverted'<br>| 'normal'<br>| false</span> | <span class="prop-default">'normal'</span> | The track presentation:<br>- `normal` the track will render a bar representing the slider value. - `inverted` the track will render a bar representing the remaining slider value. - `false` the track will render without a bar. | | ||
| <span class="prop-name">value</span> | <span class="prop-type">Array<number><br>| number</span> | | The value of the slider. For ranged sliders, provide an array with two values. | | ||
| <span class="prop-name">ValueLabelComponent</span> | <span class="prop-type">elementType</span> | | The value label component. | | ||
| <span class="prop-name">valueLabelDisplay</span> | <span class="prop-type">'auto'<br>| 'off'<br>| 'on'</span> | <span class="prop-default">'off'</span> | Controls when the value label is displayed:<br>- `auto` the value label will display when the thumb is hovered or focused. - `on` will display persistently. - `off` will never display. | | ||
| <span class="prop-name">valueLabelFormat</span> | <span class="prop-type">func<br>| string</span> | <span class="prop-default">(x) => x</span> | The format function the value label's value.<br>When a function is provided, it should have the following signature:<br>- {number} value The value label's value to format - {number} index The value label's index to format | | ||
|
||
The `ref` is forwarded to the root element. | ||
|
||
Any other props supplied will be provided to the root element (native element). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is using
mui
working? In https://emotion.sh/docs/@emotion/cache#key I'm not sure if it mean same DOM or VM.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is working bit note that these changes are only for the docs... I like when expecting the element I see mui-some_classname as I know immediately that it comes from emotion. Also we have two caches on the page, not at the same time but still I am worried if the styles will conflict. We can test it anyway