Skip to content
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

[CSS-in-JS] Starting simple usage docs #4558

Merged
merged 6 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ import { I18nTokens } from './views/package/i18n_tokens';

import { SuperSelectExample } from './views/super_select/super_select_example';

import { ThemeExample } from './views/theme/theme_example';

/** Elastic Charts */

import { ElasticChartsThemingExample } from './views/elastic_charts/theming_example';
Expand Down Expand Up @@ -484,6 +486,7 @@ const navigation = [
ResizeObserverExample,
ResponsiveExample,
TextDiffExample,
ThemeExample,
WindowEventExample,
].map((example) => createExample(example)),
},
Expand Down
49 changes: 49 additions & 0 deletions src-docs/src/views/theme/computed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { FunctionComponent, ReactNode } from 'react';
import { EuiIcon } from '../../../../src/components/icon';
import { EuiCode } from '../../../../src/components/code';
import { EuiText } from '../../../../src/components/text';
import { EuiThemeProvider, useEuiTheme } from '../../../../src/services';

const Box: FunctionComponent<{ children: ReactNode }> = ({ children }) => {
const [theme] = useEuiTheme();

return (
<EuiText
css={{
background: theme.colors.euiFocusBackgroundColor,
padding: theme.sizes.euiSizeXL,
color: theme.colors.euiColorPrimaryText,
}}>
<p>
<EuiIcon type="stopFilled" color={theme.colors.euiColorPrimary} />{' '}
{children}
</p>
</EuiText>
);
};

export default () => {
const primaryOverrides = {
colors: {
light: {
euiColorPrimary: '#db1dde',
},
dark: {
euiColorPrimary: '#e378e4',
},
},
};

return (
<div>
<EuiThemeProvider modify={primaryOverrides}>
<Box>
The <EuiCode>euiColorPrimary</EuiCode> color has been changed to{' '}
<EuiCode>#db1dde</EuiCode> (<EuiCode>#e378e4</EuiCode> for dark mode)
and so the calculated values of <EuiCode>euiColorPrimaryText</EuiCode>{' '}
and <EuiCode>euiFocusBackgroundColor</EuiCode> have also been updated.
</Box>
</EuiThemeProvider>
</div>
);
};
30 changes: 30 additions & 0 deletions src-docs/src/views/theme/consuming.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { EuiSpacer } from '../../../../src/components/spacer';
import { EuiIcon } from '../../../../src/components/icon';
import { useEuiTheme } from '../../../../src/services';

export default () => {
const [theme] = useEuiTheme();
return (
<div>
<p>
<EuiIcon
type="stopFilled"
size="xxl"
css={{ color: theme.colors.euiColorPrimary }}
/>{' '}
This primary color will adjust based on the light or dark theme value
</p>
<EuiSpacer />
<div
css={{
background: theme.colors.euiColorLightShade,
padding: theme.sizes.euiSizeXL,
}}>
<p>
The padding of this box is passed as a raw unit translated to pixels
</p>
</div>
</div>
);
};
29 changes: 29 additions & 0 deletions src-docs/src/views/theme/consuming_hoc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { css } from '@emotion/react';
import { withEuiTheme } from '../../../../src/services';
import { EuiIcon } from '../../../../src/components/icon';

// eslint-disable-next-line react/prefer-stateless-function
class Block extends React.Component<any> {
render() {
const { theme } = this.props;

const divStyle = css`
background: ${theme.theme.colors.euiColorLightShade};
// This way of providing sizing values doesn't output correctly
padding: ${theme.theme.sizes.euiSizeXL};
border-radius: ${theme.theme.borders.euiBorderRadius};
`;

return (
<div css={divStyle}>
<p>
<EuiIcon type="faceSad" /> This box has it&apos;s background, padding,
and border-radius controlled by custom css
</p>
</div>
);
}
}

export const ConsumingHOC = withEuiTheme(Block);
80 changes: 80 additions & 0 deletions src-docs/src/views/theme/create_computed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { FunctionComponent, ReactNode } from 'react';
import { tint, shade } from '../../../../src/services/theme/theme';
import { EuiIcon } from '../../../../src/components/icon';
import { EuiCode } from '../../../../src/components/code';
import { EuiText } from '../../../../src/components/text';
import {
computed,
EuiThemeProvider,
useEuiTheme,
} from '../../../../src/services';

const Box: FunctionComponent<{ children: ReactNode }> = ({ children }) => {
const [theme] = useEuiTheme();

return (
<EuiText
css={{
// @ts-ignore Needs to be fixed in types
background: theme.colors.customColorPrimaryHighlight,
padding: theme.sizes.euiSizeXL,
// @ts-ignore Needs to be fixed in types
color: theme.colors.customColorPrimaryText,
Comment on lines +18 to +22
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to ignore these because TS complains that the custom keys don't exist.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to tell useEuiTheme that the custom keys exist:

const [theme] = useEuiTheme<{colors: {
  customColorPrimaryHighlight: string;
  customColorPrimaryText: string
}}>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to do that on creation of the modifications instead of usage?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, no. A given useEuiTheme doesn't/can't have enough knowledge about which provider it's accessing to be able to infer any extensions. This is mostly a limitation of how React context works.
If we want typed, autocomplete-ready theme variables for the base EUI theme, then we have to do this extra step to get extensions to work also.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd imagine that if an app is planning on extending the theme and wants to use it in many places, they could create a wrapped hook to hide the details:

const useExtendedEuiTheme = () => {
  const [theme, colorMode, modifications] = useEuiTheme<{colors: {
    customColorPrimaryHighlight: string;
    customColorPrimaryText: string
  }}>();
  return [theme, colorMode, modifications];
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K, then I'm just going to leave the ts comments in for now to see if we can address a bit better.

}}>
<p>
<EuiIcon
type="stopFilled"
// @ts-ignore Needs to be fixed in types
color={theme.colors.customColorPrimary}
/>{' '}
{children}
</p>
</EuiText>
);
};

export default () => {
const primaryOverrides = {
colors: {
light: {
customColorPrimary: 'rgb(29, 222, 204)',
customColorPrimaryHighlight: computed(
['colors.customColorPrimary'],
([customColorPrimary]) => tint(customColorPrimary, 0.8)
),
// Need a global contrast function
customColorPrimaryText: computed(
['colors.customColorPrimary'],
([customColorPrimary]) => shade(customColorPrimary, 0.8)
),
},
dark: {
customColorPrimary: 'rgb(29, 222, 204)',
customColorPrimaryHighlight: computed(
['colors.customColorPrimary'],
([customColorPrimary]) => shade(customColorPrimary, 0.8)
),
// Need a global contrast function
customColorPrimaryText: computed(
['colors.customColorPrimary'],
([customColorPrimary]) => tint(customColorPrimary, 0.8)
),
},
},
};

return (
<div>
<EuiThemeProvider modify={primaryOverrides}>
<Box>
A new key of <EuiCode>customColorPrimary</EuiCode> has been added as
<EuiCode>rgb(29, 222, 204)</EuiCode>.
<br />
<br />
There is also two new computed color keys create off of this for
better contrast.
</Box>
</EuiThemeProvider>
</div>
);
};
46 changes: 46 additions & 0 deletions src-docs/src/views/theme/inverse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { FunctionComponent, ReactNode } from 'react';
import { EuiIcon } from '../../../../src/components/icon';
import { EuiSpacer } from '../../../../src/components/spacer';
import { EuiThemeProvider, useEuiTheme } from '../../../../src/services';

const Box: FunctionComponent<{ children: ReactNode }> = ({ children }) => {
const [theme] = useEuiTheme();

return (
<div
css={{
background: theme.colors.euiColorLightShade,
padding: theme.sizes.euiSizeXL,
color: theme.colors.euiTextColor,
}}>
<p>{children}</p>
</div>
);
};

export default () => {
return (
<div>
<EuiThemeProvider colorMode="light">
<Box>
<EuiIcon type="faceHappy" /> The colors of this box are will always be
in <strong>light</strong> mode
</Box>
</EuiThemeProvider>
<EuiSpacer />
<EuiThemeProvider colorMode="dark">
<Box>
<EuiIcon type="faceHappy" /> The colors of this box are will always be
in <strong>dark</strong> mode
</Box>
</EuiThemeProvider>
<EuiSpacer />
<EuiThemeProvider colorMode="inverse">
<Box>
<EuiIcon type="faceHappy" /> The colors of this box are the opposite (
<strong>inverse</strong>) of the current color mode
</Box>
</EuiThemeProvider>
</div>
);
};
37 changes: 37 additions & 0 deletions src-docs/src/views/theme/override_simple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { FunctionComponent, ReactNode } from 'react';
import { EuiCode } from '../../../../src/components/code';
import { EuiThemeProvider, useEuiTheme } from '../../../../src/services';

const Box: FunctionComponent<{ children: ReactNode }> = ({ children }) => {
const [theme] = useEuiTheme();

return (
<div
css={{
background: theme.colors.euiColorLightShade,
padding: theme.sizes.euiSizeXL,
}}>
<p>{children}</p>
</div>
);
};

export default () => {
const overrides = {
colors: {
light: { euiColorLightShade: '#d3e6df' },
dark: { euiColorLightShade: '#394c4b' },
},
};

return (
<div>
<EuiThemeProvider modify={overrides}>
<Box>
The background of this box is using the locally overridden value of{' '}
<EuiCode>theme.colors.euiColorLightShade</EuiCode>
</Box>
</EuiThemeProvider>
</div>
);
};
Loading