Skip to content

Commit

Permalink
refactor(labs): Rename getTheme to useTheme so it's more hook-like
Browse files Browse the repository at this point in the history
  • Loading branch information
anicholls committed Oct 29, 2019
1 parent 1348cb5 commit d6f8db3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
9 changes: 7 additions & 2 deletions modules/_labs/core/react/lib/CanvasProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export interface CanvasProviderProps {

declare global {
interface Window {
wdCanvasTheme: CanvasTheme;
wdCanvas: {
theme?: CanvasTheme;
};
}
}

Expand All @@ -25,7 +27,10 @@ export default class CanvasProvider extends React.Component<CanvasProviderProps>

componentDidMount() {
if (this.props.setThemeGlobal) {
window.wdCanvasTheme = this.props.theme;
if (!window.wdCanvas) {
window.wdCanvas = {};
}
window.wdCanvas.theme = this.props.theme;
}
}

Expand Down
32 changes: 27 additions & 5 deletions modules/_labs/core/react/lib/theming/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import colors from '@workday/canvas-colors-web';
import deepmerge from 'deepmerge';
import {CanvasTheme} from './types';
import {ThemeContext} from '@emotion/core';
import {breakpoints, up, down, between, only} from './breakpoints';

/**
Expand Down Expand Up @@ -54,14 +56,34 @@ export const defaultCanvasTheme: CanvasTheme = {
};

/**
* Currently a work around for a default theme if no ThemeProvider exists.
* Hook function to get the correct theme object.
* @param {Object=} theme - The theme object returned from the emotion ThemeContext
* (through ThemeProvider).
* NOTE: If you are using a class component, you MUST pass the theme.
* If not passed, the function will try to pull the theme from ThemeContext.
* If that does not work, it will try to retrieve it from the window object.
* As a last resort, it will return the default Canvas theme.
*
* Providing the default theme here is currently a work around for when no
* ThemeProvider or context exists.
* Tracked on https://github.com/emotion-js/emotion/issues/1193.
*/
export function getTheme(theme: Object): CanvasTheme {
if (Object.entries(theme).length !== 0) {
export function useTheme(theme?: Object): CanvasTheme {
if (theme && Object.entries(theme).length !== 0) {
return theme as CanvasTheme;
} else if (window.wdCanvasTheme) {
return window.wdCanvasTheme;
}

try {
const context = React.useContext(ThemeContext);
if (context) {
return context as CanvasTheme;
}
} catch (e) {
// Context not supported or invalid (probably called from within a class component)
}

if (window.wdCanvas && window.wdCanvas.theme) {
return window.wdCanvas.theme;
}

return defaultCanvasTheme;
Expand Down
4 changes: 2 additions & 2 deletions modules/banner/react/lib/Banner.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import styled from '@emotion/styled';
import {colors, spacing, borderRadius, type} from '@workday/canvas-kit-react-core';
import {Themeable, getTheme} from '@workday/canvas-kit-labs-react-core';
import {Themeable, useTheme} from '@workday/canvas-kit-labs-react-core';
import {SystemIcon} from '@workday/canvas-kit-react-icon';
import {exclamationCircleIcon, exclamationTriangleIcon} from '@workday/canvas-system-icons-web';
import {ErrorType, focusRing} from '@workday/canvas-kit-react-common';
Expand Down Expand Up @@ -53,7 +53,7 @@ const BannerWrapper = styled('button')<BannerProps>(
},
},
({error, theme}) => {
theme = getTheme(theme); // eslint-disable-line no-param-reassign
theme = useTheme(theme); // eslint-disable-line no-param-reassign
return {
backgroundColor:
error === ErrorType.Error ? theme.palette.error.main : theme.palette.alert.main,
Expand Down
5 changes: 1 addition & 4 deletions utils/storybook/CanvasProviderDecorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import {object} from '@storybook/addon-knobs';
const label = 'theme';

export default (storyFn: () => React.ReactNode) => (
<CanvasProvider
theme={createCanvasTheme(object(label, defaultCanvasTheme))}
setThemeGlobal={true}
>
<CanvasProvider theme={createCanvasTheme(object(label, defaultCanvasTheme))}>
{storyFn()}
</CanvasProvider>
);

0 comments on commit d6f8db3

Please sign in to comment.