From 4937751d5332a2a6d3d50a5d3633a1339e637469 Mon Sep 17 00:00:00 2001 From: Lene Gadewoll Date: Tue, 2 Jul 2024 19:01:48 +0200 Subject: [PATCH] [EUI+] Initial typography and doc content updates (#7848) --- .../src/components/call_out/index.tsx | 81 +++++++++++++++++++ .../theme_context/theme_overrides.ts | 3 + .../src/theme/Admonition/Type/Danger.tsx | 16 ++++ .../src/theme/Admonition/Type/Info.tsx | 16 ++++ .../src/theme/Admonition/Type/Note.tsx | 16 ++++ .../src/theme/Admonition/Type/Tip.tsx | 16 ++++ .../src/theme/Admonition/Type/Warning.tsx | 16 ++++ .../src/theme/DocItem/Content/index.tsx | 33 ++++++++ .../src/theme/Footer/index.tsx | 38 +++++---- .../src/theme/MDXComponents/A.tsx | 22 +++++ .../src/theme/MDXComponents/Code.tsx | 47 +++++++++++ .../src/theme/MDXComponents/Heading.tsx | 29 +++++++ .../src/theme/MDXContent/index.tsx | 35 ++++++++ .../docusaurus-theme/src/theme/Root.styles.ts | 68 ++++++++++++++-- packages/docusaurus-theme/src/theme/Root.tsx | 7 ++ .../01_guidelines/testing/introduction.mdx | 4 +- .../01_guidelines/testing/recommendations.mdx | 4 +- 17 files changed, 426 insertions(+), 25 deletions(-) create mode 100644 packages/docusaurus-theme/src/components/call_out/index.tsx create mode 100644 packages/docusaurus-theme/src/theme/Admonition/Type/Danger.tsx create mode 100644 packages/docusaurus-theme/src/theme/Admonition/Type/Info.tsx create mode 100644 packages/docusaurus-theme/src/theme/Admonition/Type/Note.tsx create mode 100644 packages/docusaurus-theme/src/theme/Admonition/Type/Tip.tsx create mode 100644 packages/docusaurus-theme/src/theme/Admonition/Type/Warning.tsx create mode 100644 packages/docusaurus-theme/src/theme/DocItem/Content/index.tsx create mode 100644 packages/docusaurus-theme/src/theme/MDXComponents/A.tsx create mode 100644 packages/docusaurus-theme/src/theme/MDXComponents/Code.tsx create mode 100644 packages/docusaurus-theme/src/theme/MDXComponents/Heading.tsx create mode 100644 packages/docusaurus-theme/src/theme/MDXContent/index.tsx diff --git a/packages/docusaurus-theme/src/components/call_out/index.tsx b/packages/docusaurus-theme/src/components/call_out/index.tsx new file mode 100644 index 00000000000..b0d4e9b298e --- /dev/null +++ b/packages/docusaurus-theme/src/components/call_out/index.tsx @@ -0,0 +1,81 @@ +import { css } from '@emotion/react'; +import { EuiText, useEuiMemoizedStyles, UseEuiTheme } from '@elastic/eui'; +import { FunctionComponent, PropsWithChildren } from 'react'; + +type VARIANTS = 'info' | 'tip' | 'note' | 'danger' | 'warning'; +type TEXT_COLORS = 'primaryText' | 'successText' | 'dangerText' | 'warningText'; + +const VARIANT_TO_COLOR_MAP: Record< + VARIANTS, + { backgroundVariable: string; colorKey: TEXT_COLORS } +> = { + info: { + backgroundVariable: 'var(--eui-background-color-primary)', + colorKey: 'primaryText', + }, + note: { + backgroundVariable: 'var(--eui-background-color-primary)', + colorKey: 'primaryText', + }, + tip: { + backgroundVariable: 'var(--eui-background-color-success)', + colorKey: 'successText', + }, + danger: { + backgroundVariable: 'var(--eui-background-color-danger)', + colorKey: 'dangerText', + }, + warning: { + backgroundVariable: 'var(--eui-background-color-warning)', + colorKey: 'warningText', + }, +}; + +const getStyles = ({ euiTheme }: UseEuiTheme, variant: VARIANTS) => { + const colorKey = VARIANT_TO_COLOR_MAP[variant].colorKey; + const color = euiTheme.colors[colorKey]; + + return { + note: css` + &:not(:last-of-type) { + margin-block-end: ${euiTheme.size.m}; + } + + .alert { + --ifm-alert-background-color: ${VARIANT_TO_COLOR_MAP[variant] + .backgroundVariable}; + --ifm-alert-foreground-color: ${euiTheme.colors.text}; + --ifm-alert-padding-horizontal: ${euiTheme.size.base}; + --ifm-alert-padding-vertical: ${euiTheme.size.base}; + --ifm-alert-border-width: ${euiTheme.border.width.thin}; + --ifm-alert-border-left-width: ${euiTheme.border.width.thin}; + --ifm-alert-border-color: ${color}; + + [class^='admonitionHeading'] { + --ifm-alert-foreground-color: ${color}; + + color: var(--ifm-alert-foreground-color); + } + } + `, + }; +}; + +type CallOutProps = PropsWithChildren & { + variant: VARIANTS; +}; + +export const CallOut: FunctionComponent = ({ + children, + variant, +}) => { + const styles = useEuiMemoizedStyles((euiTheme) => + getStyles(euiTheme, variant) + ); + + return ( + + {children} + + ); +}; diff --git a/packages/docusaurus-theme/src/components/theme_context/theme_overrides.ts b/packages/docusaurus-theme/src/components/theme_context/theme_overrides.ts index bed2b481bf5..d51e4c70368 100644 --- a/packages/docusaurus-theme/src/components/theme_context/theme_overrides.ts +++ b/packages/docusaurus-theme/src/components/theme_context/theme_overrides.ts @@ -6,4 +6,7 @@ export const EuiThemeOverrides: EuiThemeModifications = { body: '#fff', }, }, + font: { + lineHeightMultiplier: 1.75, + }, }; diff --git a/packages/docusaurus-theme/src/theme/Admonition/Type/Danger.tsx b/packages/docusaurus-theme/src/theme/Admonition/Type/Danger.tsx new file mode 100644 index 00000000000..89e0d6bb664 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Admonition/Type/Danger.tsx @@ -0,0 +1,16 @@ +import OriginalDanger from '@theme-init/Admonition/Type/Danger'; +import type WarningType from '@theme-init/Admonition/Type/Danger'; +import type { WrapperProps } from '@docusaurus/types'; +import { CallOut } from '../../../components/call_out'; + +type Props = WrapperProps; + +const Danger = (props: Props): JSX.Element => { + return ( + + + + ); +}; + +export default Danger; diff --git a/packages/docusaurus-theme/src/theme/Admonition/Type/Info.tsx b/packages/docusaurus-theme/src/theme/Admonition/Type/Info.tsx new file mode 100644 index 00000000000..f6f9390e8d2 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Admonition/Type/Info.tsx @@ -0,0 +1,16 @@ +import OriginalInfo from '@theme-init/Admonition/Type/Info'; +import type InfoType from '@theme-init/Admonition/Type/Info'; +import type { WrapperProps } from '@docusaurus/types'; +import { CallOut } from '../../../components/call_out'; + +type Props = WrapperProps; + +const Note = (props: Props): JSX.Element => { + return ( + + + + ); +}; + +export default Note; diff --git a/packages/docusaurus-theme/src/theme/Admonition/Type/Note.tsx b/packages/docusaurus-theme/src/theme/Admonition/Type/Note.tsx new file mode 100644 index 00000000000..22f6b1eabbc --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Admonition/Type/Note.tsx @@ -0,0 +1,16 @@ +import OriginalNote from '@theme-init/Admonition/Type/Note'; +import type NoteType from '@theme-init/Admonition/Type/Note'; +import type { WrapperProps } from '@docusaurus/types'; +import { CallOut } from '../../../components/call_out'; + +type Props = WrapperProps; + +const Note = (props: Props): JSX.Element => { + return ( + + + + ); +}; + +export default Note; diff --git a/packages/docusaurus-theme/src/theme/Admonition/Type/Tip.tsx b/packages/docusaurus-theme/src/theme/Admonition/Type/Tip.tsx new file mode 100644 index 00000000000..c2bc24a9832 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Admonition/Type/Tip.tsx @@ -0,0 +1,16 @@ +import OriginalTip from '@theme-init/Admonition/Type/Tip'; +import type TipType from '@theme-init/Admonition/Type/Tip'; +import type { WrapperProps } from '@docusaurus/types'; +import { CallOut } from '../../../components/call_out'; + +type Props = WrapperProps; + +const Tip = (props: Props): JSX.Element => { + return ( + + + + ); +}; + +export default Tip; diff --git a/packages/docusaurus-theme/src/theme/Admonition/Type/Warning.tsx b/packages/docusaurus-theme/src/theme/Admonition/Type/Warning.tsx new file mode 100644 index 00000000000..18786294a5c --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Admonition/Type/Warning.tsx @@ -0,0 +1,16 @@ +import OriginalWarning from '@theme-init/Admonition/Type/Warning'; +import type WarningType from '@theme-init/Admonition/Type/Warning'; +import type { WrapperProps } from '@docusaurus/types'; +import { CallOut } from '../../../components/call_out'; + +type Props = WrapperProps; + +const Warning = (props: Props): JSX.Element => { + return ( + + + + ); +}; + +export default Warning; diff --git a/packages/docusaurus-theme/src/theme/DocItem/Content/index.tsx b/packages/docusaurus-theme/src/theme/DocItem/Content/index.tsx new file mode 100644 index 00000000000..b5cf7bfe378 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/DocItem/Content/index.tsx @@ -0,0 +1,33 @@ +import OriginalContent from '@theme-init/DocItem/Content'; +import type ContentType from '@theme-init/DocItem/Content'; +import type { WrapperProps } from '@docusaurus/types'; +import { useEuiMemoizedStyles, UseEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; + +type Props = WrapperProps; + +const getContentStyles = ({ euiTheme }: UseEuiTheme) => { + return { + content: css` + // required specificity to apply styles + .markdown header > h1 { + --ifm-h1-font-size: 2.86rem; + --ifm-h1-vertical-rhythm-bottom: 1.486; + } + `, + }; +}; + +/* OriginalContent holds the document title and markdown content +NOTE: ejecting this results in an error due to using useDoc() hook outside of DocProvider +https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/DocItem/Content/index.tsx */ +const Content = (props: Props): JSX.Element => { + const styles = useEuiMemoizedStyles(getContentStyles); + return ( +
+ +
+ ); +}; + +export default Content; diff --git a/packages/docusaurus-theme/src/theme/Footer/index.tsx b/packages/docusaurus-theme/src/theme/Footer/index.tsx index 488c80f4f16..10e2bc38b07 100644 --- a/packages/docusaurus-theme/src/theme/Footer/index.tsx +++ b/packages/docusaurus-theme/src/theme/Footer/index.tsx @@ -1,17 +1,28 @@ import { css } from '@emotion/react'; -import { EuiText, EuiLink, UseEuiTheme, EuiThemeProvider, useEuiMemoizedStyles } from '@elastic/eui'; +import { + EuiText, + EuiLink, + UseEuiTheme, + EuiThemeProvider, + useEuiMemoizedStyles, +} from '@elastic/eui'; -const ELASTIC_LICENSE_URL = "https://github.com/elastic/eui/blob/main/licenses/ELASTIC-LICENSE-2.0.md"; -const SSPL_LICENSE_URL = "https://github.com/elastic/eui/blob/main/licenses/SSPL-LICENSE.md"; +const ELASTIC_LICENSE_URL = + 'https://github.com/elastic/eui/blob/main/licenses/ELASTIC-LICENSE-2.0.md'; +const SSPL_LICENSE_URL = + 'https://github.com/elastic/eui/blob/main/licenses/SSPL-LICENSE.md'; const getFooterStyles = ({ euiTheme }: UseEuiTheme) => { return { root: css` - background: #1C1E23; // Color not available in EUI + background: #1c1e23; // Color not available in EUI border-radius: ${euiTheme.size.s} ${euiTheme.size.s} 0 0; padding: ${euiTheme.size.l}; text-align: center; `, + text: css` + line-height: var(--eui-line-height-s); + `, heart: css` color: ${euiTheme.colors.accent}; `, @@ -22,22 +33,21 @@ const Footer = () => { const styles = useEuiMemoizedStyles(getFooterStyles); return ( - +
- - EUI is dual-licensed under {' '} - - Elastic License 2.0 - + + EUI is dual-licensed under{' '} + Elastic License 2.0 {' and '} Server Side Public License, v 1 {' | '} - Crafted with by{' '} - - Elastic - + Crafted with{' '} + + ❤ + {' '} + by Elastic
diff --git a/packages/docusaurus-theme/src/theme/MDXComponents/A.tsx b/packages/docusaurus-theme/src/theme/MDXComponents/A.tsx new file mode 100644 index 00000000000..66a4b9a130e --- /dev/null +++ b/packages/docusaurus-theme/src/theme/MDXComponents/A.tsx @@ -0,0 +1,22 @@ +import type AType from '@theme-init/MDXComponents/A'; +import type { WrapperProps } from '@docusaurus/types'; +import { css } from '@emotion/react'; +import { EuiLink, useEuiMemoizedStyles, UseEuiTheme } from '@elastic/eui'; + +type Props = WrapperProps; + +const getStyles = ({ euiTheme }: UseEuiTheme) => { + return { + link: css` + text-decoration: underline; + `, + }; +}; + +const A = (props: Props): JSX.Element => { + const styles = useEuiMemoizedStyles(getStyles); + + return ; +}; + +export default A; diff --git a/packages/docusaurus-theme/src/theme/MDXComponents/Code.tsx b/packages/docusaurus-theme/src/theme/MDXComponents/Code.tsx new file mode 100644 index 00000000000..56b15d04f18 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/MDXComponents/Code.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import type CodeType from '@theme-init/MDXComponents/Code'; +import type { WrapperProps } from '@docusaurus/types'; +import { css } from '@emotion/react'; +import { + EuiCode, + EuiCodeBlock, + useEuiMemoizedStyles, + UseEuiTheme, +} from '@elastic/eui'; + +type Props = WrapperProps; + +const getStyles = ({ euiTheme }: UseEuiTheme) => { + return { + code: css` + // reset docusaurus code styles + border: none; + vertical-align: initial; + `, + }; +}; + +const Code = ({ children, className, ...rest }: Props): JSX.Element => { + const styles = useEuiMemoizedStyles(getStyles); + const language = className?.startsWith('language-') + ? className.replace('language-', '') + : undefined; + + const isInlineCode = children + ? React.Children.toArray(children).every( + (el) => typeof el === 'string' && !el.includes('\n') + ) + : false; + + return isInlineCode ? ( + + {children} + + ) : ( + + {children} + + ); +}; + +export default Code; diff --git a/packages/docusaurus-theme/src/theme/MDXComponents/Heading.tsx b/packages/docusaurus-theme/src/theme/MDXComponents/Heading.tsx new file mode 100644 index 00000000000..82005f273ab --- /dev/null +++ b/packages/docusaurus-theme/src/theme/MDXComponents/Heading.tsx @@ -0,0 +1,29 @@ +import OriginalHeading from '@theme-init/MDXComponents/Heading'; +import type HeadingType from '@theme-init/MDXComponents/Heading'; +import type { WrapperProps } from '@docusaurus/types'; +import { EuiTitle, EuiTitleSize } from '@elastic/eui'; +import { FunctionComponent } from 'react'; + +type Props = WrapperProps; + +const SIZE_TO_LEVEL_MAP: Record = { + h6: 'xxxs', + h5: 'xxs', + h4: 'xs', + h3: 's', + h2: 'm', + h1: 'l', +}; + +const Heading: FunctionComponent & { as: string }> = ({ + as, + ...rest +}): JSX.Element => { + return ( + + + + ); +}; + +export default Heading; diff --git a/packages/docusaurus-theme/src/theme/MDXContent/index.tsx b/packages/docusaurus-theme/src/theme/MDXContent/index.tsx new file mode 100644 index 00000000000..9970915a3b9 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/MDXContent/index.tsx @@ -0,0 +1,35 @@ +import OriginalMDXContent from '@theme-init/MDXContent'; +import type MDXContentType from '@theme-init/MDXContent'; +import type { WrapperProps } from '@docusaurus/types'; +import { css } from '@emotion/react'; +import { EuiText, useEuiMemoizedStyles, UseEuiTheme } from '@elastic/eui'; + +type Props = WrapperProps; + +const getStyles = ({ euiTheme }: UseEuiTheme) => { + return { + text: css` + p { + margin-block-end: ${euiTheme.size.xl}; + } + + ul, + ol { + margin-inline-start: 0; + margin-block-end: ${euiTheme.size.xl}; + } + `, + }; +}; + +const MDXContent = (props: Props): JSX.Element => { + const styles = useEuiMemoizedStyles(getStyles); + + return ( + + + + ); +}; + +export default MDXContent; diff --git a/packages/docusaurus-theme/src/theme/Root.styles.ts b/packages/docusaurus-theme/src/theme/Root.styles.ts index d1878cc5a9b..d64c75ef10c 100644 --- a/packages/docusaurus-theme/src/theme/Root.styles.ts +++ b/packages/docusaurus-theme/src/theme/Root.styles.ts @@ -1,18 +1,72 @@ -import { UseEuiTheme } from '@elastic/eui'; +import { + euiLineHeightFromBaseline, + useEuiBackgroundColor, + UseEuiTheme, +} from '@elastic/eui'; // override docusaurus variables as needed export const getGlobalStyles = ({ euiTheme }: UseEuiTheme) => { - const { colors } = euiTheme; + const { font, base, colors, size } = euiTheme; + const fontBodyScale = font.scale[font.body.scale]; + const fontBase = { + fontFamily: font.family, + fontSize: `${ + font.defaultUnits === 'px' ? fontBodyScale * base : fontBodyScale + }${font.defaultUnits}`, + fontWeight: font.weight[font.body.weight], + }; + + const lineHeightL = '1.75rem'; + const lineHeightM = euiLineHeightFromBaseline('s', euiTheme); + const lineHeightS = euiLineHeightFromBaseline('xs', euiTheme); + const lineHeightXS = '1.33rem'; - // overriding Docusaurus variables: - // since EUI handles the token value updates, we can override both - // color modes at the same time (Docusaurus separates based on `data-theme`) return ` + // color theme related variables :root, - [data-theme='dark']:root { - // base + [data-theme='dark']:root { + /* EUI theme variables */ + --eui-background-color-primary: ${useEuiBackgroundColor('primary')}; + --eui-background-color-success: ${useEuiBackgroundColor('success')}; + --eui-background-color-danger: ${useEuiBackgroundColor('danger')}; + --eui-background-color-warning: ${useEuiBackgroundColor('warning')}; + + /* Docusaurus theme variables */ --ifm-background-color: ${colors.body}; --ifm-font-color-base: ${colors.text}; } + + :root { + /* EUI theme variables */ + --eui-line-height-base: ${lineHeightL}; + --eui-line-height-m: ${lineHeightM}; + --eui-line-height-s: ${lineHeightS}; + --eui-line-height-xs: ${lineHeightXS}; + + /* Docusaurus theme variables */ + --ifm-font-family-base: ${fontBase.fontFamily}; + --ifm-font-size-base: ${fontBase.fontSize}; + --ifm-font-weight-base: ${fontBase.fontWeight}; + --ifm-line-height-base: var(--eui-line-height-base); + + } + + /* base styles & resets */ + h1, h2, h3, h4, h5, h6 { + margin-block-start: ${size.l}; + margin-block-end: ${size.m}; + + font-weight: ${font.weight.bold}; + } + + button { + background: none; + border: none; + padding: 0; + margin: 0; + color: inherit; + border-radius: 0; + font-size: inherit; + } `; }; diff --git a/packages/docusaurus-theme/src/theme/Root.tsx b/packages/docusaurus-theme/src/theme/Root.tsx index d4d928e1bd0..f9648dbb82a 100644 --- a/packages/docusaurus-theme/src/theme/Root.tsx +++ b/packages/docusaurus-theme/src/theme/Root.tsx @@ -7,6 +7,7 @@ */ import { FunctionComponent, PropsWithChildren } from 'react'; +import Head from '@docusaurus/Head'; import { Props } from '@theme/Root'; import { Global } from '@emotion/react'; import { _EuiThemeFontScale, useEuiTheme } from '@elastic/eui'; @@ -21,6 +22,12 @@ const _Root: FunctionComponent = ({ children }) => { return ( <> + + + {children} diff --git a/packages/website/docs/01_guidelines/testing/introduction.mdx b/packages/website/docs/01_guidelines/testing/introduction.mdx index e9ae6d100ec..473ebd6383c 100644 --- a/packages/website/docs/01_guidelines/testing/introduction.mdx +++ b/packages/website/docs/01_guidelines/testing/introduction.mdx @@ -4,10 +4,10 @@ slug: /guidelines/testing id: testing-introduction --- -

+

Learn how we test our code internally and how you should test integration with EUI components to ensure good test coverage and easy maintainability. -

+
## How we test our components diff --git a/packages/website/docs/01_guidelines/testing/recommendations.mdx b/packages/website/docs/01_guidelines/testing/recommendations.mdx index 6cb3f93eb66..7058491319a 100644 --- a/packages/website/docs/01_guidelines/testing/recommendations.mdx +++ b/packages/website/docs/01_guidelines/testing/recommendations.mdx @@ -3,9 +3,9 @@ title: Testing recommendations sidebar_label: Recommendations --- -

+

Our general set of do's and don'ts for testing components and views. -

+
## Choose the right selectors