-
Notifications
You must be signed in to change notification settings - Fork 51
feat(docs): adding theme switcher #280
Changes from all commits
d368f8d
f15bbf9
c094e36
3ed0545
27cf9d1
fa1bec0
be911d7
4dcbc30
0a67747
6455358
e18b8fc
cf9c277
cfd9dac
d6ccfb3
a62497e
a032a55
e81677a
6d35bb3
2933d8f
de34860
090364b
e7d7ca3
efdc0af
60c8720
a08e6b7
94f5942
9a71f3d
6f91a46
426fd71
68eb2b1
7e4835b
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 |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import * as React from 'react' | ||
| import { Provider, themes } from '@stardust-ui/react' | ||
|
|
||
| import { mergeThemes } from '../../src/lib' | ||
| import { semanticCssOverrides } from './Style' | ||
| import { ThemeContext } from './context/theme-context' | ||
| import Router from './routes' | ||
|
|
||
| const semanticStyleOverrides = { | ||
| staticStyles: [semanticCssOverrides], | ||
| } | ||
|
|
||
| interface IAppState { | ||
| themeName: string | ||
| changeTheme: (newTheme: string) => void | ||
| } | ||
|
|
||
| class App extends React.Component<any, IAppState> { | ||
| private changeTheme | ||
|
|
||
| constructor(props) { | ||
| super(props) | ||
|
|
||
| this.changeTheme = newTheme => { | ||
| this.setState({ | ||
| themeName: newTheme, | ||
| }) | ||
| } | ||
|
|
||
| // State also contains the updater function so it will | ||
| // be passed down into the context provider | ||
| this.state = { | ||
| themeName: 'teams', | ||
| changeTheme: this.changeTheme, | ||
| } | ||
| } | ||
| render() { | ||
| const { themeName } = this.state | ||
| return ( | ||
| <ThemeContext.Provider value={this.state}> | ||
| <Provider | ||
| theme={mergeThemes(semanticStyleOverrides, themes[themeName], { | ||
| // adjust Teams' theme to Semantic UI's font size scheme | ||
| siteVariables: { | ||
| htmlFontSize: '14px', | ||
| bodyFontSize: '1rem', | ||
| }, | ||
| })} | ||
| > | ||
| <Router /> | ||
| </Provider> | ||
| </ThemeContext.Provider> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default App |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| import * as _ from 'lodash' | ||
| import PropTypes from 'prop-types' | ||
| import * as React from 'react' | ||
| import { withRouter, RouteComponentProps } from 'react-router' | ||
| import { RouteComponentProps, withRouter } from 'react-router' | ||
| import { renderToStaticMarkup } from 'react-dom/server' | ||
| import { html } from 'js-beautify' | ||
| import * as copyToClipboard from 'copy-to-clipboard' | ||
|
|
@@ -23,17 +23,21 @@ import ComponentExampleTitle from './ComponentExampleTitle' | |
| import ContributionPrompt from '../ContributionPrompt' | ||
| import getSourceCodeManager, { ISourceCodeManager, SourceCodeType } from './SourceCodeManager' | ||
| import { IThemeInput, IThemePrepared } from 'types/theme' | ||
| import { mergeThemeVariables } from '../../../../../src/lib/mergeThemes' | ||
| import { ThemeContext } from '../../../context/theme-context' | ||
|
|
||
| export interface IComponentExampleProps extends RouteComponentProps<any, any> { | ||
| title: string | ||
| description: string | ||
| examplePath: string | ||
| suiVersion?: string | ||
| themeName?: string | ||
| } | ||
|
|
||
| interface IComponentExampleState { | ||
| knobs: Object | ||
| theme: IThemeInput | ||
| themeName: string | ||
| componentVariables: Object | ||
| exampleElement?: JSX.Element | ||
| handleMouseLeave?: () => void | ||
| handleMouseMove?: () => void | ||
|
|
@@ -62,7 +66,7 @@ const codeTypeApiButtonLabels: { [key in SourceCodeType]: string } = { | |
| * Renders a `component` and the raw `code` that produced it. | ||
| * Allows toggling the the raw `code` code block. | ||
| */ | ||
| class ComponentExample extends React.PureComponent<IComponentExampleProps, IComponentExampleState> { | ||
| class ComponentExample extends React.Component<IComponentExampleProps, IComponentExampleState> { | ||
| private componentRef: React.Component | ||
| private sourceCodeMgr: ISourceCodeManager | ||
| private anchorName: string | ||
|
|
@@ -71,7 +75,8 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
|
|
||
| public state: IComponentExampleState = { | ||
| knobs: {}, | ||
| theme: themes.teams, | ||
| themeName: 'teams', | ||
| componentVariables: {}, | ||
| sourceCode: '', | ||
| markup: '', | ||
| showCode: false, | ||
|
|
@@ -95,6 +100,7 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| match: PropTypes.object.isRequired, | ||
| suiVersion: PropTypes.string, | ||
| title: PropTypes.node, | ||
| themeName: PropTypes.string, | ||
| } | ||
|
|
||
| public componentWillMount() { | ||
|
|
@@ -123,6 +129,10 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| ) { | ||
| this.clearActiveState() | ||
| } | ||
| const { themeName } = nextProps | ||
| if (this.state.themeName !== themeName) { | ||
|
Contributor
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. a bit unsure - do we really need to store
Contributor
Author
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. Sorry, this was changed when the name of the theme was fetch from the mobx store, the themeName prop should be enough now. Will change it.
Contributor
Author
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. Ah, I got it now. This was added because we want to invoke renderSourceCode if the themeName prop is changed. Since we are invoking this method here, we need to have a way to get the new themeName, that's why I have it in the state as well. Any other idea about how can we achive this?
Contributor
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. actually, yes - but just to unblock the PR, we could make a notch, merge it and I will try to experiment on that further. To me |
||
| this.setState({ themeName }, this.renderSourceCode) | ||
| } | ||
| } | ||
|
|
||
| private clearActiveState = () => { | ||
|
|
@@ -346,10 +356,13 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| private getDisplayName = () => this.props.examplePath.split('/')[1] | ||
|
|
||
| private renderWithProvider(ExampleComponent) { | ||
| const { showRtl, theme } = this.state | ||
| const { showRtl, componentVariables, themeName } = this.state | ||
| const theme = themes[themeName] | ||
|
|
||
| const newTheme: IThemeInput = { | ||
| componentVariables: theme.componentVariables, | ||
| componentVariables: mergeThemeVariables(theme.componentVariables, { | ||
| [this.getDisplayName()]: componentVariables, | ||
| }), | ||
| rtl: showRtl, | ||
| } | ||
|
|
||
|
|
@@ -540,7 +553,10 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| </Divider> | ||
| <Provider.Consumer | ||
| render={({ siteVariables, componentVariables }: IThemePrepared) => { | ||
| const variables = componentVariables[displayName] | ||
| const mergedVariables = mergeThemeVariables(componentVariables, { | ||
|
Contributor
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 merge them again here? May be missing something, but it seems that we already merged these variables on line 364, so they will be consumed as already merged ones
Contributor
Author
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. It took me also lot of time to figure this out, but this consumer is for the root Theme Provider, where in contrast, the example, uses it's own provider where these are merged (overriden). This is why we actually have previously bug where the componentVariables were not reflecting the latest status of the variables applied on the example.
Contributor
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. got it - still, see it to be a problem that we are merging in two different places of the ComponentExample code. Let me take a look on that after PR will be merged |
||
| [displayName]: this.state.componentVariables, | ||
| }) | ||
| const variables = mergedVariables[displayName] | ||
|
|
||
| if (!variables) { | ||
| return ( | ||
|
|
@@ -580,15 +596,9 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| private handleVariableChange = (component, variable) => (e, { value }) => { | ||
| this.setState( | ||
| state => ({ | ||
| theme: { | ||
| ...state.theme, | ||
| componentVariables: { | ||
| ...state.theme.componentVariables, | ||
| [component]: { | ||
| ...(state.theme.componentVariables && state.theme.componentVariables[component]), | ||
| [variable]: value, | ||
| }, | ||
| }, | ||
| componentVariables: { | ||
| ...state.componentVariables, | ||
| [variable]: value, | ||
| }, | ||
|
Contributor
Author
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. @kuzhelov please take a look into the changes in this file regarding the componentVariables. It seems to work okay in my opinion, but would like to have your approval on this, as the initial changes were yours. Thanks!
Contributor
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. these changes were made at the moment where there were no
Contributor
Author
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. I changed the state's componentVariable to store just the variables for the component being rendered, and then I am using the mergeThemeVariables for generating the final componentVariables. Please take a look now. |
||
| }), | ||
| this.renderSourceCode, | ||
|
|
@@ -697,4 +707,10 @@ class ComponentExample extends React.PureComponent<IComponentExampleProps, IComp | |
| } | ||
| } | ||
|
|
||
| export default withRouter(ComponentExample) | ||
| const ComponentExampleWithTheme = React.forwardRef((props: IComponentExampleProps) => ( | ||
| <ThemeContext.Consumer> | ||
| {({ themeName }) => <ComponentExample {...props} themeName={themeName} />} | ||
| </ThemeContext.Consumer> | ||
| )) | ||
|
|
||
| export default withRouter(ComponentExampleWithTheme) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import * as React from 'react' | ||
|
|
||
| export const ThemeContext = React.createContext({ | ||
| themeName: 'teams', | ||
| changeTheme: (newTheme: string) => {}, | ||
| }) |
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.
👍