@elastic/eui-docusaurus-theme 2.4.0 → 2.5.0-snapshot.1783954480414

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,5 +30,7 @@ const getDemoActionsBarStyles = (euiTheme) => {
30
30
  };
31
31
  export const DemoActionsBar = ({ isSourceOpen, setSourceOpen, activeSource, sources, extraFiles, previewWrapperSource, onClickReloadExample, onClickCopyToClipboard, }) => {
32
32
  const styles = useEuiMemoizedStyles(getDemoActionsBarStyles);
33
- return (_jsxs(EuiFlexGroup, { alignItems: "center", css: styles.actionsBar, gutterSize: "s", children: [_jsx(EuiButton, { css: styles.button, onClick: () => setSourceOpen(!isSourceOpen), size: "s", color: "text", minWidth: false, children: isSourceOpen ? 'Hide source' : 'Show source' }), extraActions.map((ActionComponent) => (_jsx(ActionComponent, { sources: sources, extraFiles: extraFiles, previewWrapperSource: previewWrapperSource, activeSource: activeSource }, ActionComponent.displayName ?? ActionComponent.name))), _jsx(EuiToolTip, { content: "Copy to clipboard", children: _jsx(EuiButtonIcon, { size: "s", iconType: "copy", color: "text", onClick: onClickCopyToClipboard, "aria-label": "Copy code to clipboard" }) }), _jsx(EuiToolTip, { content: "Reload example", children: _jsx(EuiButtonIcon, { size: "s", iconType: "refresh", color: "text", onClick: onClickReloadExample, "aria-label": "Reload example" }) })] }));
33
+ const copyToClipboardLabel = 'Copy to clipboard';
34
+ const reloadExampleLabel = 'Reload example';
35
+ return (_jsxs(EuiFlexGroup, { alignItems: "center", css: styles.actionsBar, gutterSize: "s", children: [_jsx(EuiButton, { css: styles.button, onClick: () => setSourceOpen(!isSourceOpen), size: "s", color: "text", minWidth: false, children: isSourceOpen ? 'Hide source' : 'Show source' }), extraActions.map((ActionComponent) => (_jsx(ActionComponent, { sources: sources, extraFiles: extraFiles, previewWrapperSource: previewWrapperSource, activeSource: activeSource }, ActionComponent.displayName ?? ActionComponent.name))), _jsx(EuiToolTip, { content: copyToClipboardLabel, disableScreenReaderOutput: true, children: _jsx(EuiButtonIcon, { size: "s", iconType: "copy", color: "text", onClick: onClickCopyToClipboard, "aria-label": copyToClipboardLabel }) }), _jsx(EuiToolTip, { content: reloadExampleLabel, disableScreenReaderOutput: true, children: _jsx(EuiButtonIcon, { size: "s", iconType: "refresh", color: "text", onClick: onClickReloadExample, "aria-label": reloadExampleLabel }) })] }));
34
36
  };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Encodes sandbox parameters for CodeSandbox's `define` API.
3
+ */
4
+ export declare const getParameters: (parameters: unknown) => string;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ import { compressToBase64 } from 'lz-string';
9
+ /**
10
+ * Encodes sandbox parameters for CodeSandbox's `define` API.
11
+ */
12
+ export const getParameters = (parameters) => {
13
+ return compressToBase64(JSON.stringify(parameters))
14
+ .replace(/\+/g, '-')
15
+ .replace(/\//g, '_')
16
+ .replace(/=+$/, '');
17
+ };
@@ -7,7 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
7
7
  * Side Public License, v 1.
8
8
  */
9
9
  import { useMemo } from 'react';
10
- import { getParameters } from 'codesandbox/lib/api/define';
10
+ import { getParameters } from './get_parameters';
11
11
  import dedent from 'dedent';
12
12
  import { EuiButtonIcon, EuiToolTip } from '@elastic/eui';
13
13
  import { CodeSandboxIcon } from '../../codesandbox_icon';
@@ -115,5 +115,6 @@ export const createOpenInCodeSandboxAction = ({ files = {}, dependencies }) => (
115
115
  },
116
116
  });
117
117
  }, [activeSource, extraFiles, previewWrapperSource]);
118
- return (_jsxs("form", { action: "https://codesandbox.io/api/v1/sandboxes/define", method: "POST", target: "_blank", children: [_jsx("input", { type: "hidden", name: "parameters", value: parameters }), _jsx("input", { type: "hidden", name: "query", value: `module=/demo.tsx&view=split` }), _jsx(EuiToolTip, { content: "Open in CodeSandbox", children: _jsx(EuiButtonIcon, { type: "submit", size: "s", iconType: CodeSandboxIcon, color: "text", "aria-label": "Open in CodeSandbox" }) })] }));
118
+ const openInCodeSandboxLabel = 'Open in CodeSandbox';
119
+ return (_jsxs("form", { action: "https://codesandbox.io/api/v1/sandboxes/define", method: "POST", target: "_blank", children: [_jsx("input", { type: "hidden", name: "parameters", value: parameters }), _jsx("input", { type: "hidden", name: "query", value: `module=/demo.tsx&view=split` }), _jsx(EuiToolTip, { content: openInCodeSandboxLabel, disableScreenReaderOutput: true, children: _jsx(EuiButtonIcon, { type: "submit", size: "s", iconType: CodeSandboxIcon, color: "text", "aria-label": openInCodeSandboxLabel }) })] }));
119
120
  };
@@ -10,7 +10,7 @@ import { Children, useCallback, useMemo, useState, } from 'react';
10
10
  import { isElement } from 'react-is';
11
11
  import { LiveProvider } from 'react-live';
12
12
  import { themes as prismThemes } from 'prism-react-renderer';
13
- import { useEuiMemoizedStyles, copyToClipboard, } from '@elastic/eui';
13
+ import { useEuiMemoizedStyles, copyToClipboard, useIsDarkMode, } from '@elastic/eui';
14
14
  import { css } from '@emotion/react';
15
15
  import { demoDefaultScope } from '@theme/Demo/default_scope';
16
16
  import { DemoContext } from './context';
@@ -33,9 +33,11 @@ const getDemoStyles = (euiTheme) => ({
33
33
  });
34
34
  export const Demo = ({ children, scope, extraFiles, isSourceOpen: _isSourceOpen = false, previewPadding, previewWrapper, previewWrapperSource, }) => {
35
35
  const styles = useEuiMemoizedStyles(getDemoStyles);
36
+ const isDarkMode = useIsDarkMode();
36
37
  const [sources, setSources] = useState([]);
37
38
  const [isSourceOpen, setIsSourceOpen] = useState(_isSourceOpen);
38
39
  const activeSource = sources[0] || null;
40
+ const prismTheme = isDarkMode ? prismThemes.dracula : prismThemes.github;
39
41
  // liveProviderKey restarts the demo to its initial state
40
42
  const [liveProviderKey, setLiveProviderKey] = useState(0);
41
43
  const finalScope = useMemo(() => ({
@@ -52,7 +54,7 @@ export const Demo = ({ children, scope, extraFiles, isSourceOpen: _isSourceOpen
52
54
  const onClickReloadExample = useCallback(() => {
53
55
  setLiveProviderKey((liveProviderKey) => liveProviderKey + 1);
54
56
  }, []);
55
- return (_jsx("div", { css: styles.demo, children: _jsxs(DemoContext.Provider, { value: { sources, addSource }, children: [_jsxs(LiveProvider, { code: activeSource?.code || '', transformCode: demoCodeTransformer, theme: prismThemes.dracula, scope: finalScope, children: [_jsx(DemoPreview, { padding: previewPadding, wrapperComponent: previewWrapper }), _jsx(DemoActionsBar, { isSourceOpen: isSourceOpen, setSourceOpen: setIsSourceOpen, activeSource: activeSource, extraFiles: extraFiles, sources: sources, previewWrapperSource: previewWrapperSource, onClickCopyToClipboard: onClickCopyToClipboard, onClickReloadExample: onClickReloadExample }), isSourceOpen && _jsx(DemoEditor, {})] }, liveProviderKey), Children.map(children, (child, index) => {
57
+ return (_jsx("div", { css: styles.demo, children: _jsxs(DemoContext.Provider, { value: { sources, addSource }, children: [_jsxs(LiveProvider, { code: activeSource?.code || '', transformCode: demoCodeTransformer, theme: prismTheme, scope: finalScope, children: [_jsx(DemoPreview, { padding: previewPadding, wrapperComponent: previewWrapper }), _jsx(DemoActionsBar, { isSourceOpen: isSourceOpen, setSourceOpen: setIsSourceOpen, activeSource: activeSource, extraFiles: extraFiles, sources: sources, previewWrapperSource: previewWrapperSource, onClickCopyToClipboard: onClickCopyToClipboard, onClickReloadExample: onClickReloadExample }), isSourceOpen && _jsx(DemoEditor, {})] }, liveProviderKey), Children.map(children, (child, index) => {
56
58
  if (isElement(child) && child.type === DemoSource) {
57
59
  return child;
58
60
  }
@@ -12,7 +12,7 @@ import { Fragment, } from 'react';
12
12
  import BrowserOnly from '@docusaurus/BrowserOnly';
13
13
  import ErrorBoundary from '@docusaurus/ErrorBoundary';
14
14
  import { ErrorBoundaryErrorMessageFallback } from '@docusaurus/theme-common';
15
- import { useEuiTheme, euiPaddingSize, } from '@elastic/eui';
15
+ import { useEuiTheme, EuiThemeProvider, euiPaddingSize, } from '@elastic/eui';
16
16
  const getPreviewStyles = (euiTheme) => ({
17
17
  previewWrapper: css `
18
18
  padding: var(--docs-demo-preview-padding);
@@ -32,5 +32,5 @@ export const DemoPreview = ({ padding = 'l', wrapperComponent: WrapperComponent
32
32
  const style = {
33
33
  '--docs-demo-preview-padding': paddingSize,
34
34
  };
35
- return (_jsx(BrowserOnly, { fallback: _jsx(PreviewLoader, {}), children: () => (_jsx(_Fragment, { children: _jsx(ErrorBoundary, { fallback: (params) => (_jsx(ErrorBoundaryErrorMessageFallback, { ...params })), children: _jsx("div", { css: styles.previewWrapper, style: style, children: _jsx(WrapperComponent, { children: _jsx(LivePreview, {}) }) }) }) })) }));
35
+ return (_jsx(BrowserOnly, { fallback: _jsx(PreviewLoader, {}), children: () => (_jsx(_Fragment, { children: _jsx(ErrorBoundary, { fallback: (params) => (_jsx(ErrorBoundaryErrorMessageFallback, { ...params })), children: _jsx("div", { css: styles.previewWrapper, style: style, children: _jsx(EuiThemeProvider, { modify: { font: { lineHeightMultiplier: 1.5 } }, children: _jsx(WrapperComponent, { children: _jsx(LivePreview, {}) }) }) }) }) })) }));
36
36
  };
@@ -6,7 +6,7 @@ type SharedProps = {
6
6
  isSelected?: boolean;
7
7
  } & CommonProps;
8
8
  type Props = ExclusiveUnion<PropsForAnchor<SharedProps>, PropsForButton<SharedProps>>;
9
- export declare const getStyles: ({ euiTheme }: UseEuiTheme) => {
9
+ export declare const getStyles: (euiThemeContext: UseEuiTheme) => {
10
10
  item: import("@emotion/react").SerializedStyles;
11
11
  navItem: import("@emotion/react").SerializedStyles;
12
12
  menuItem: import("@emotion/react").SerializedStyles;
@@ -14,6 +14,7 @@ export declare const getStyles: ({ euiTheme }: UseEuiTheme) => {
14
14
  disabled: import("@emotion/react").SerializedStyles;
15
15
  selected: import("@emotion/react").SerializedStyles;
16
16
  title: import("@emotion/react").SerializedStyles;
17
+ tooltipAnchor: import("@emotion/react").SerializedStyles;
17
18
  };
18
19
  export declare const NavbarItem: (props: Props) => import("@emotion/react/jsx-runtime").JSX.Element;
19
20
  export {};
@@ -9,58 +9,66 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/reac
9
9
  import { useContext } from 'react';
10
10
  import { css } from '@emotion/react';
11
11
  import useIsBrowser from '@docusaurus/useIsBrowser';
12
- import { EuiIcon, useEuiMemoizedStyles, } from '@elastic/eui';
12
+ import { EuiIcon, EuiToolTip, useEuiMemoizedStyles, } from '@elastic/eui';
13
13
  import { AppThemeContext } from '../theme_context';
14
+ import { getNavbarBreakpoint } from '../../theme/Navbar/breakpoint';
14
15
  // converted from css modules to Emotion
15
- export const getStyles = ({ euiTheme }) => ({
16
- item: css `
17
- display: flex;
18
- align-items: center;
19
- flex-shrink: 0;
16
+ export const getStyles = (euiThemeContext) => {
17
+ const { euiTheme } = euiThemeContext;
18
+ const { desktopMediaQuery } = getNavbarBreakpoint(euiThemeContext);
19
+ return {
20
+ item: css `
21
+ display: flex;
22
+ align-items: center;
23
+ flex-shrink: 0;
20
24
 
21
- -webkit-tap-highlight-color: transparent;
22
- transition: background var(--ifm-transition-fast);
25
+ -webkit-tap-highlight-color: transparent;
26
+ transition: background var(--ifm-transition-fast);
23
27
 
24
- &:hover {
25
- background-color: ${euiTheme.components.buttons.backgroundTextHover};
26
- color: currentColor;
27
- }
28
- `,
29
- navItem: css `
30
- justify-content: center;
31
- width: ${euiTheme.size.xl};
32
- height: ${euiTheme.size.xl};
33
- border-radius: 50%;
34
- `,
35
- menuItem: css `
36
- justify-content: flex-start;
37
- gap: ${euiTheme.size.s};
38
-
39
- @media (min-width: 997px) {
28
+ &:hover {
29
+ background-color: ${euiTheme.components.buttons.backgroundTextHover};
30
+ color: currentColor;
31
+ }
32
+ `,
33
+ navItem: css `
40
34
  justify-content: center;
41
35
  width: ${euiTheme.size.xl};
42
36
  height: ${euiTheme.size.xl};
43
37
  border-radius: 50%;
44
- }
45
- `,
46
- darkMode: css `
47
- &:hover {
48
- color: currentColor;
49
- }
50
- `,
51
- disabled: css `
52
- cursor: not-allowed;
53
- `,
54
- selected: css `
55
- background-color: ${euiTheme.colors.backgroundFilledText};
56
- color: ${euiTheme.colors.textInverse};
57
- `,
58
- title: css `
59
- @media (min-width: 997px) {
60
- display: none;
61
- }
62
- `,
63
- });
38
+ `,
39
+ menuItem: css `
40
+ justify-content: flex-start;
41
+ gap: ${euiTheme.size.s};
42
+
43
+ ${desktopMediaQuery} {
44
+ justify-content: center;
45
+ width: ${euiTheme.size.xl};
46
+ height: ${euiTheme.size.xl};
47
+ border-radius: 50%;
48
+ }
49
+ `,
50
+ darkMode: css `
51
+ &:hover {
52
+ color: currentColor;
53
+ }
54
+ `,
55
+ disabled: css `
56
+ cursor: not-allowed;
57
+ `,
58
+ selected: css `
59
+ background-color: ${euiTheme.colors.backgroundFilledText};
60
+ color: ${euiTheme.colors.textInverse};
61
+ `,
62
+ title: css `
63
+ ${desktopMediaQuery} {
64
+ display: none;
65
+ }
66
+ `,
67
+ tooltipAnchor: css `
68
+ display: inline-flex;
69
+ `,
70
+ };
71
+ };
64
72
  // using a type guard to ensure proper typing from ExclusiveUnion
65
73
  const isAnchorClick = (onClick, href) => href != null;
66
74
  export const NavbarItem = (props) => {
@@ -75,10 +83,12 @@ export const NavbarItem = (props) => {
75
83
  !isBrowser && styles.disabled,
76
84
  isSelected && styles.selected,
77
85
  isDarkMode && styles.darkMode,
86
+ css,
78
87
  ];
79
88
  const content = showLabel ? (_jsxs(_Fragment, { children: [_jsx(EuiIcon, { type: icon }), _jsx("span", { css: styles.title, children: title })] })) : (_jsx(EuiIcon, { type: icon }));
80
- if (isAnchorClick(onClick, href)) {
81
- return (_jsx("a", { href: href, target: target ?? '_blank', title: title, className: className, css: cssStyles, onClick: onClick, "aria-label": title, "aria-live": "polite", children: content }));
89
+ const control = isAnchorClick(onClick, href) ? (_jsx("a", { href: href, target: target ?? '_blank', className: className, css: cssStyles, onClick: onClick, "aria-label": title, "aria-live": "polite", children: content })) : (_jsx("button", { type: "button", disabled: !isBrowser, className: className, css: cssStyles, onClick: onClick, "aria-label": title, "aria-live": "polite", "aria-pressed": isSelected != null ? isSelected : undefined, children: content }));
90
+ if (!title) {
91
+ return control;
82
92
  }
83
- return (_jsx("button", { type: "button", disabled: !isBrowser, className: className, css: cssStyles, onClick: onClick, title: title, "aria-label": title, "aria-live": "polite", "aria-pressed": isSelected != null ? isSelected : undefined, children: content }));
93
+ return (_jsx(EuiToolTip, { content: title, disableScreenReaderOutput: true, repositionOnScroll: true, anchorProps: { css: styles.tooltipAnchor }, children: control }));
84
94
  };
@@ -9,7 +9,7 @@ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
9
9
  import { css } from '@emotion/react';
10
10
  import { EuiCallOut } from '@elastic/eui';
11
11
  const VARIANT_TO_PROPS_MAP = {
12
- note: { iconType: 'paperClip', color: 'accent' },
12
+ note: { iconType: 'paperClip', color: 'primary' },
13
13
  tip: { iconType: 'faceHappy', color: 'success' },
14
14
  info: { iconType: 'info', color: 'primary' },
15
15
  accessibility: { iconType: 'accessibility', color: 'primary' },
@@ -31,7 +31,7 @@ const nestedParagraphStyleReset = css `
31
31
  `;
32
32
  const Callout = ({ title, type, children }) => {
33
33
  const variantProps = VARIANT_TO_PROPS_MAP[type];
34
- return (_jsx(EuiCallOut, { title: title, iconType: "info", color: "primary", ...variantProps, css: css `
34
+ return (_jsx(EuiCallOut, { title: title, color: "primary", ...variantProps, css: css `
35
35
  margin-block: var(--eui-theme-content-vertical-spacing);
36
36
  ${nestedParagraphStyleReset}
37
37
  `, children: children }));
@@ -8,8 +8,14 @@ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
8
8
  */
9
9
  import React, { isValidElement } from 'react';
10
10
  import { css } from '@emotion/react';
11
- import { EuiCodeBlock } from '@elastic/eui';
11
+ import { EuiCodeBlock, useEuiMemoizedStyles } from '@elastic/eui';
12
12
  import { Demo } from '../../components/demo';
13
+ const getStyles = ({ euiTheme }) => ({
14
+ codeBlock: css `
15
+ margin-block: ${euiTheme.size.base};
16
+ word-break: break-word;
17
+ `,
18
+ });
13
19
  /**
14
20
  * Best attempt to make the children a plain string so it is copyable. If there
15
21
  * are react elements, we will not be able to copy the content, and it will
@@ -26,10 +32,11 @@ function maybeStringifyChildren(children) {
26
32
  export default function CodeBlock({ children: rawChildren, metastring, className, ...props }) {
27
33
  const children = maybeStringifyChildren(rawChildren);
28
34
  const language = className?.replace('language-', '') || undefined;
35
+ const styles = useEuiMemoizedStyles(getStyles);
29
36
  if (metastring?.startsWith('interactive')) {
30
37
  return _jsx(Demo, { ...props, children: children });
31
38
  }
32
- return (_jsx(EuiCodeBlock, { ...props, fontSize: "m", overflowHeight: 450, language: language, isCopyable: true, css: css `
33
- word-break: break-word;
34
- `, children: children }));
39
+ // Don't show the fullscreen button for one-liner snippets
40
+ const isOneLiner = typeof children === 'string' && !children.trim().includes('\n');
41
+ return (_jsx(EuiCodeBlock, { ...props, fontSize: "m", overflowHeight: isOneLiner ? undefined : 450, language: language, isCopyable: true, css: styles.codeBlock, children: children }));
35
42
  }
@@ -7,7 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
7
7
  * Side Public License, v 1.
8
8
  */
9
9
  import useBrokenLinks from '@docusaurus/useBrokenLinks';
10
- import { EuiTitle, EuiButtonIcon, useEuiMemoizedStyles, } from '@elastic/eui';
10
+ import { EuiTitle, EuiButtonIcon, EuiToolTip, useEuiMemoizedStyles, } from '@elastic/eui';
11
11
  import { css } from '@emotion/react';
12
12
  const TAG_TO_TITLE_SIZE_MAP = {
13
13
  h6: 'xxxs',
@@ -44,6 +44,6 @@ const Heading = ({ as: Component, children, id, ...restProps }) => {
44
44
  const anchorTitle = `Direct link to ${typeof children === 'string' ? children : id}`;
45
45
  // We don't want to show section links on document title headings
46
46
  const shouldShowSectionLink = Component !== 'h1';
47
- return (_jsx(EuiTitle, { size: TAG_TO_TITLE_SIZE_MAP[Component], children: _jsxs(Component, { ...restProps, className: "heading anchor", css: styles.heading, id: id, children: [children, shouldShowSectionLink && (_jsx(EuiButtonIcon, { css: styles.anchor, href: `#${id}`, "aria-label": anchorTitle, title: anchorTitle, iconType: "link", color: "text", size: "xs" }))] }) }));
47
+ return (_jsx(EuiTitle, { size: TAG_TO_TITLE_SIZE_MAP[Component], children: _jsxs(Component, { ...restProps, className: "heading anchor", css: styles.heading, id: id, children: [children, shouldShowSectionLink && (_jsx(EuiToolTip, { content: anchorTitle, disableScreenReaderOutput: true, children: _jsx(EuiButtonIcon, { css: styles.anchor, href: `#${id}`, "aria-label": anchorTitle, iconType: "link", color: "text", size: "xs" }) }))] }) }));
48
48
  };
49
49
  export default Heading;
@@ -16,6 +16,7 @@ import { euiFormControlText, euiFormVariables,
16
16
  } from '@elastic/eui/lib/components/form/form.styles';
17
17
  import { VersionSwitcher, } from '../../../components/version_switcher';
18
18
  import { HighContrastModeToggle } from '../../../components/high_contrast_mode_toggle';
19
+ import { getNavbarBreakpoint } from '../breakpoint';
19
20
  const DOCS_PATH = '/docs';
20
21
  const placeHolderStyles = (content) => `
21
22
  &::-webkit-input-placeholder { ${content} }
@@ -27,6 +28,7 @@ const getStyles = (euiThemeContext) => {
27
28
  const { euiTheme } = euiThemeContext;
28
29
  const form = euiFormVariables(euiThemeContext);
29
30
  const iconColor = encodeURIComponent(euiTheme.colors.text);
31
+ const { desktopMediaQuery, mobileMediaQuery } = getNavbarBreakpoint(euiThemeContext);
30
32
  return {
31
33
  navbarItems: css `
32
34
  --ifm-navbar-item-padding-horizontal: 0;
@@ -34,7 +36,7 @@ const getStyles = (euiThemeContext) => {
34
36
 
35
37
  .navbar__item,
36
38
  [class*='colorModeToggle'] {
37
- @media (max-width: 996px) {
39
+ ${mobileMediaQuery} {
38
40
  display: none;
39
41
  }
40
42
  }
@@ -46,12 +48,16 @@ const getStyles = (euiThemeContext) => {
46
48
  background-color: var(--ifm-color-emphasis-200);
47
49
  color: currentColor;
48
50
  }
51
+
52
+ ${mobileMediaQuery} {
53
+ display: inherit;
54
+ }
49
55
  }
50
56
  `,
51
57
  navbarItemsLeft: css `
52
58
  gap: ${euiTheme.size.s};
53
59
 
54
- @media (min-width: 997px) {
60
+ ${desktopMediaQuery} {
55
61
  gap: ${euiTheme.size.l};
56
62
  }
57
63
 
@@ -63,7 +69,7 @@ const getStyles = (euiThemeContext) => {
63
69
  gap: ${euiTheme.size.s};
64
70
  `,
65
71
  actions: css `
66
- @media (max-width: 996px) {
72
+ ${mobileMediaQuery} {
67
73
  display: none;
68
74
  }
69
75
  `,
@@ -102,22 +108,18 @@ const getStyles = (euiThemeContext) => {
102
108
  max-inline-size: 25rem;
103
109
  }
104
110
 
105
- @media (min-width: 997px) {
111
+ ${desktopMediaQuery} {
106
112
  min-inline-size: 15rem;
107
113
  }
108
-
109
- @media (min-width: 1200px) {
110
- min-inline-size: 25rem;
111
- }
112
114
  }
113
115
  `,
114
116
  versionSwitcher: css `
115
- @media (max-width: 996px) {
117
+ ${mobileMediaQuery} {
116
118
  display: none;
117
119
  }
118
120
  `,
119
121
  themeSwitcher: css `
120
- @media (max-width: 996px) {
122
+ ${mobileMediaQuery} {
121
123
  display: none;
122
124
  }
123
125
  `,
@@ -1,13 +1,36 @@
1
1
  import { jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ /*
3
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
4
+ * or more contributor license agreements. Licensed under the Elastic License
5
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
6
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
7
+ * Side Public License, v 1.
8
+ */
9
+ import { useEffect } from 'react';
10
+ import { useWindowSize } from '@docusaurus/theme-common';
2
11
  import { useLockBodyScroll, useNavbarMobileSidebar, } from '@docusaurus/theme-common/internal';
3
12
  import NavbarMobileSidebarLayout from '@theme-original/Navbar/MobileSidebar/Layout';
4
13
  import NavbarMobileSidebarHeader from './Header';
5
14
  import NavbarMobileSidebarPrimaryMenu from '@theme-original/Navbar/MobileSidebar/PrimaryMenu';
6
15
  import NavbarMobileSidebarSecondaryMenu from '@theme-original/Navbar/MobileSidebar/SecondaryMenu';
16
+ import { useEuiTheme } from '@elastic/eui';
17
+ import { getNavbarBreakpoint } from '../breakpoint';
7
18
  export default function NavbarMobileSidebar({ versionSwitcherOptions, }) {
8
19
  const mobileSidebar = useNavbarMobileSidebar();
9
- useLockBodyScroll(mobileSidebar.shown);
10
- if (!mobileSidebar.shouldRender) {
20
+ const { disabled, shouldRender: shouldRenderDefault, shown, toggle, } = mobileSidebar;
21
+ const euiThemeContext = useEuiTheme();
22
+ const { mobileBreakpoint } = getNavbarBreakpoint(euiThemeContext);
23
+ const windowSize = useWindowSize({
24
+ desktopBreakpoint: mobileBreakpoint,
25
+ });
26
+ const shouldRender = shouldRenderDefault || (!disabled && windowSize === 'mobile');
27
+ useLockBodyScroll(shouldRender && shown);
28
+ useEffect(() => {
29
+ if (windowSize === 'desktop' && shown) {
30
+ toggle();
31
+ }
32
+ }, [shown, toggle, windowSize]);
33
+ if (!shouldRender) {
11
34
  return null;
12
35
  }
13
36
  return (_jsx(NavbarMobileSidebarLayout, { header: _jsx(NavbarMobileSidebarHeader, { versionSwitcherOptions: versionSwitcherOptions }), primaryMenu: _jsx(NavbarMobileSidebarPrimaryMenu, {}), secondaryMenu: _jsx(NavbarMobileSidebarSecondaryMenu, {}) }));
@@ -0,0 +1,7 @@
1
+ import type { UseEuiTheme } from '@elastic/eui';
2
+ export declare const getNavbarBreakpoint: ({ euiTheme }: UseEuiTheme) => {
3
+ desktopBreakpoint: number;
4
+ desktopMediaQuery: string;
5
+ mobileBreakpoint: number;
6
+ mobileMediaQuery: string;
7
+ };
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+ const NAVBAR_MOBILE_BREAKPOINT_KEY = 'xl';
9
+ export const getNavbarBreakpoint = ({ euiTheme }) => {
10
+ const mobileBreakpoint = euiTheme.breakpoint[NAVBAR_MOBILE_BREAKPOINT_KEY];
11
+ const desktopBreakpoint = mobileBreakpoint + 1;
12
+ return {
13
+ desktopBreakpoint,
14
+ desktopMediaQuery: `@media (min-width: ${desktopBreakpoint}px)`,
15
+ mobileBreakpoint,
16
+ mobileMediaQuery: `@media (max-width: ${mobileBreakpoint}px)`,
17
+ };
18
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elastic/eui-docusaurus-theme",
3
- "version": "2.4.0",
3
+ "version": "2.5.0-snapshot.1783954480414",
4
4
  "description": "EUI theme for Docusaurus",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "scripts": {
@@ -40,14 +40,14 @@
40
40
  "@docusaurus/theme-common": "^3.7.0",
41
41
  "@docusaurus/utils-validation": "^3.7.0",
42
42
  "@elastic/datemath": "^5.0.3",
43
- "@elastic/eui": "^116.0.0",
44
- "@elastic/eui-theme-borealis": "^8.0.0",
43
+ "@elastic/eui": "^117.0.0-snapshot.1783954480414",
44
+ "@elastic/eui-theme-borealis": "^8.0.0-snapshot.1783954480414",
45
45
  "@emotion/css": "^11.11.2",
46
46
  "@emotion/react": "^11.11.4",
47
47
  "@types/react-window": "^1.8.8",
48
48
  "clsx": "^2.1.1",
49
- "codesandbox": "^2.2.3",
50
49
  "dedent": "^1.5.3",
50
+ "lz-string": "^1.5.0",
51
51
  "moment": "^2.30.1",
52
52
  "prism-react-renderer": "^2.3.1",
53
53
  "react-is": "^18.3.1",
@@ -57,5 +57,6 @@
57
57
  "peerDependencies": {
58
58
  "react": "^18.0.0",
59
59
  "react-dom": "^18.0.0"
60
- }
60
+ },
61
+ "stableVersion": "2.5.0"
61
62
  }
@@ -61,6 +61,8 @@ export const DemoActionsBar = ({
61
61
  onClickCopyToClipboard,
62
62
  }: DemoActionsBarProps) => {
63
63
  const styles = useEuiMemoizedStyles(getDemoActionsBarStyles);
64
+ const copyToClipboardLabel = 'Copy to clipboard';
65
+ const reloadExampleLabel = 'Reload example';
64
66
 
65
67
  return (
66
68
  <EuiFlexGroup alignItems="center" css={styles.actionsBar} gutterSize="s">
@@ -82,22 +84,22 @@ export const DemoActionsBar = ({
82
84
  activeSource={activeSource}
83
85
  />
84
86
  ))}
85
- <EuiToolTip content="Copy to clipboard">
87
+ <EuiToolTip content={copyToClipboardLabel} disableScreenReaderOutput>
86
88
  <EuiButtonIcon
87
89
  size="s"
88
90
  iconType="copy"
89
91
  color="text"
90
92
  onClick={onClickCopyToClipboard}
91
- aria-label="Copy code to clipboard"
93
+ aria-label={copyToClipboardLabel}
92
94
  />
93
95
  </EuiToolTip>
94
- <EuiToolTip content="Reload example">
96
+ <EuiToolTip content={reloadExampleLabel} disableScreenReaderOutput>
95
97
  <EuiButtonIcon
96
98
  size="s"
97
99
  iconType="refresh"
98
100
  color="text"
99
101
  onClick={onClickReloadExample}
100
- aria-label="Reload example"
102
+ aria-label={reloadExampleLabel}
101
103
  />
102
104
  </EuiToolTip>
103
105
  </EuiFlexGroup>
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
5
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
6
+ * Side Public License, v 1.
7
+ */
8
+
9
+ import { compressToBase64 } from 'lz-string';
10
+
11
+ /**
12
+ * Encodes sandbox parameters for CodeSandbox's `define` API.
13
+ */
14
+ export const getParameters = (parameters: unknown): string => {
15
+ return compressToBase64(JSON.stringify(parameters))
16
+ .replace(/\+/g, '-')
17
+ .replace(/\//g, '_')
18
+ .replace(/=+$/, '');
19
+ };
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { useMemo } from 'react';
10
- import { getParameters } from 'codesandbox/lib/api/define';
10
+ import { getParameters } from './get_parameters';
11
11
  import dedent from 'dedent';
12
12
  import { EuiButtonIcon, EuiToolTip } from '@elastic/eui';
13
13
  import type { ActionComponent } from '../../../theme/Demo/actions';
@@ -142,9 +142,11 @@ export const createOpenInCodeSandboxAction =
142
142
  },
143
143
  ...codeSandboxFiles,
144
144
  },
145
- } as any);
145
+ });
146
146
  }, [activeSource, extraFiles, previewWrapperSource]);
147
147
 
148
+ const openInCodeSandboxLabel = 'Open in CodeSandbox';
149
+
148
150
  return (
149
151
  <form
150
152
  action="https://codesandbox.io/api/v1/sandboxes/define"
@@ -157,13 +159,13 @@ export const createOpenInCodeSandboxAction =
157
159
  name="query"
158
160
  value={`module=/demo.tsx&view=split`}
159
161
  />
160
- <EuiToolTip content="Open in CodeSandbox">
162
+ <EuiToolTip content={openInCodeSandboxLabel} disableScreenReaderOutput>
161
163
  <EuiButtonIcon
162
164
  type="submit"
163
165
  size="s"
164
166
  iconType={CodeSandboxIcon}
165
167
  color="text"
166
- aria-label="Open in CodeSandbox"
168
+ aria-label={openInCodeSandboxLabel}
167
169
  />
168
170
  </EuiToolTip>
169
171
  </form>
@@ -20,6 +20,7 @@ import {
20
20
  useEuiMemoizedStyles,
21
21
  copyToClipboard,
22
22
  UseEuiTheme,
23
+ useIsDarkMode,
23
24
  } from '@elastic/eui';
24
25
  import { css } from '@emotion/react';
25
26
  import { demoDefaultScope } from '@theme/Demo/default_scope';
@@ -104,9 +105,11 @@ export const Demo = ({
104
105
  previewWrapperSource,
105
106
  }: DemoProps) => {
106
107
  const styles = useEuiMemoizedStyles(getDemoStyles);
108
+ const isDarkMode = useIsDarkMode();
107
109
  const [sources, setSources] = useState<DemoSourceMeta[]>([]);
108
110
  const [isSourceOpen, setIsSourceOpen] = useState<boolean>(_isSourceOpen);
109
111
  const activeSource = sources[0] || null;
112
+ const prismTheme = isDarkMode ? prismThemes.dracula : prismThemes.github;
110
113
 
111
114
  // liveProviderKey restarts the demo to its initial state
112
115
  const [liveProviderKey, setLiveProviderKey] = useState<number>(0);
@@ -142,7 +145,7 @@ export const Demo = ({
142
145
  key={liveProviderKey}
143
146
  code={activeSource?.code || ''}
144
147
  transformCode={demoCodeTransformer}
145
- theme={prismThemes.dracula}
148
+ theme={prismTheme}
146
149
  scope={finalScope}
147
150
  >
148
151
  <DemoPreview