diff --git a/CHANGELOG.md b/CHANGELOG.md
index 75bbd1ad245..9ae92a3df24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,11 +5,19 @@
- Updated props of `EuiCode` and `EuiCodeBlock` to reflect only functional props ([#3647](https://github.com/elastic/eui/pull/3647))
- Updated `EuiResizableContainer` `onPanelWidthChange` callback method to include all panel widths ([#3630](https://github.com/elastic/eui/pull/3630))
- Extended `Query` / `EuiSearchBar` to allow any character inside double-quoted phrases ([#3432](https://github.com/elastic/eui/pull/3432))
+- Added `headerZindexLocation` prop to `EuiOverlayMask` ([#3655](https://github.com/elastic/eui/pull/3655))
+- Added `maskProps` prop to `EuiFlyout` and `EuiCollapsibleNav` ([#3655](https://github.com/elastic/eui/pull/3655))
**Bug fixes**
- Fixed `EuiContextMenu` panel `onAnimationEnd` transition bug in Chrome ([#3656](https://github.com/elastic/eui/pull/3656))
- Fixed `EuiSkipLink` interactive props and Safari click issue ([#3665](https://github.com/elastic/eui/pull/3665))
+- Fixed `z-index` issues with `EuiHeader`, `EuiFlyout`, and other portal content ([#3655](https://github.com/elastic/eui/pull/3655))
+- Fixed `color` prop error in `EuiBadge` to be more flexible with what format it accepts ([#3655](https://github.com/elastic/eui/pull/3655))
+
+**Theme: Amsterdam**
+
+- Fixed `EuiHeaderBreadcrumb` height, `onClick`, border-radius, and single item display ([#3655](https://github.com/elastic/eui/pull/3655))
## [`26.1.0`](https://github.com/elastic/eui/tree/v26.1.0)
diff --git a/generator-eui/documentation/index.js b/generator-eui/documentation/index.js
index e812de48857..4d3046a23af 100644
--- a/generator-eui/documentation/index.js
+++ b/generator-eui/documentation/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
const chalk = require('chalk');
const Generator = require('yeoman-generator');
const utils = require('../utils');
@@ -12,16 +31,20 @@ module.exports = class extends Generator {
}
prompting() {
- let prompts = [{
- message: 'What\'s the name of the component you\'re documenting? Use snake_case, please.',
- name: 'name',
- type: 'input',
- store: true,
- }];
+ const prompts = [
+ {
+ message:
+ "What's the name of the component you're documenting? Use snake_case, please.",
+ name: 'name',
+ type: 'input',
+ store: true,
+ },
+ ];
if (this.fileType === 'demo') {
prompts.push({
- message: `What's the name of the directory this demo should go in? (Within src-docs/src/views). Use snake_case, please.`,
+ message:
+ "What's the name of the directory this demo should go in? (Within src-docs/src/views). Use snake_case, please.",
name: 'folderName',
type: 'input',
store: true,
@@ -29,7 +52,8 @@ module.exports = class extends Generator {
});
prompts.push({
- message: 'What would you like to name this demo? Use snake_case, please.',
+ message:
+ 'What would you like to name this demo? Use snake_case, please.',
name: 'demoName',
type: 'input',
store: true,
@@ -46,22 +70,24 @@ module.exports = class extends Generator {
const writeDocumentationPage = () => {
const componentExampleName = utils.makeComponentName(config.name, false);
- const componentExamplePrefix = utils.lowerCaseFirstLetter(componentExampleName);
+ const componentExamplePrefix = utils.lowerCaseFirstLetter(
+ componentExampleName
+ );
const componentName = utils.makeComponentName(config.name);
const fileName = config.name;
const path = DOCUMENTATION_PAGE_PATH;
- const vars = config.documentationVars = {
+ const vars = (config.documentationVars = {
componentExampleName,
componentExamplePrefix,
componentName,
fileName,
- };
+ });
- const documentationPagePath
- = config.documentationPagePath
- = `${path}/${config.name}/${config.name}_example.js`;
+ const documentationPagePath = (config.documentationPagePath = `${path}/${
+ config.name
+ }/${config.name}_example.js`);
this.fs.copyTpl(
this.templatePath('documentation_page.js'),
@@ -72,21 +98,22 @@ module.exports = class extends Generator {
const writeDocumentationPageDemo = (fileName, folderName) => {
const componentExampleName = utils.makeComponentName(fileName, false);
- const componentExamplePrefix = utils.lowerCaseFirstLetter(componentExampleName);
+ const componentExamplePrefix = utils.lowerCaseFirstLetter(
+ componentExampleName
+ );
const componentName = utils.makeComponentName(config.name);
const path = DOCUMENTATION_PAGE_PATH;
- const vars = config.documentationVars = {
+ const vars = (config.documentationVars = {
componentExampleName,
componentExamplePrefix,
componentName,
fileName,
- };
+ folderName,
+ });
- const documentationPageDemoPath
- = config.documentationPageDemoPath
- = `${path}/${folderName}/${fileName}.tsx`;
+ const documentationPageDemoPath = (config.documentationPageDemoPath = `${path}/${folderName}/${fileName}.tsx`);
this.fs.copyTpl(
this.templatePath('documentation_page_demo.tsx'),
@@ -117,44 +144,55 @@ module.exports = class extends Generator {
this.log(chalk.white('\n// Import demo into example.'));
this.log(
- `${chalk.magenta('import')} ${componentExampleName} from ${chalk.cyan(`'./${fileName}'`)};\n` +
- `${chalk.magenta('const')} ${componentExamplePrefix}Source = require(${chalk.cyan(`'!!raw-loader!./${fileName}'`)});\n` +
- `${chalk.magenta('const')} ${componentExamplePrefix}Html = renderToHtml(${componentExampleName});`
+ `${chalk.magenta('import')} ${componentExampleName} from ${chalk.cyan(
+ `'./${fileName}'`
+ )};\n` +
+ `${chalk.magenta(
+ 'const'
+ )} ${componentExamplePrefix}Source = require(${chalk.cyan(
+ `'!!raw-loader!./${fileName}'`
+ )});\n` +
+ `${chalk.magenta(
+ 'const'
+ )} ${componentExamplePrefix}Html = renderToHtml(${componentExampleName});`
);
this.log(chalk.white('\n// Render demo.'));
this.log(
- `Description needed: how to use the ${componentExampleName} component.
\n` +
- ` }\n` +
- ` demo={\n` +
- ` <${componentExampleName} />\n` +
- ` }\n` +
- `/>\n`
+ 'Description needed: how to use the ${componentExampleName} component.\n` +
+ ' }\n' +
+ ' demo={\n' +
+ ` <${componentExampleName} />\n` +
+ ' }\n' +
+ '/>\n'
);
};
const showImportRouteSnippet = (suffix, appendToRoute) => {
- const {
- componentExampleName,
- fileName,
- } = this.config.documentationVars;
+ const { componentExampleName, fileName } = this.config.documentationVars;
- this.log(chalk.white('\n// Import example into routes.js and then add it to the "components" array.'));
+ this.log(
+ chalk.white(
+ '\n// Import example into routes.js and then add it to the "components" array.'
+ )
+ );
this.log(
`${chalk.magenta('import')} { ${componentExampleName}${suffix} }\n` +
- ` ${chalk.magenta('from')} ${chalk.cyan(`'./views/${fileName}/${fileName}_${suffix.toLowerCase()}'`)};`
+ ` ${chalk.magenta('from')} ${chalk.cyan(
+ `'./views/${fileName}/${fileName}_${suffix.toLowerCase()}'`
+ )};`
);
- }
+ };
this.log('------------------------------------------------');
this.log(chalk.bold('Import snippets:'));
@@ -170,4 +208,4 @@ module.exports = class extends Generator {
}
this.log('------------------------------------------------');
}
-}
+};
diff --git a/generator-eui/documentation/templates/documentation_page_demo.tsx b/generator-eui/documentation/templates/documentation_page_demo.tsx
index 47f4baedc9d..0d28a268e73 100644
--- a/generator-eui/documentation/templates/documentation_page_demo.tsx
+++ b/generator-eui/documentation/templates/documentation_page_demo.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import {
<%= componentName %>,
-} from '../../../../src/components/<%= fileName %>';
+} from '../../../../src/components/<%= folderName %>';
export default () => (
<<%= componentName %>>
diff --git a/src-docs/src/components/guide_components.scss b/src-docs/src/components/guide_components.scss
index ddcd3add658..661a486db67 100644
--- a/src-docs/src/components/guide_components.scss
+++ b/src-docs/src/components/guide_components.scss
@@ -25,6 +25,12 @@ $guideZLevelHighest: $euiZLevel9 + 1000;
.guideSideNav {
top: $euiHeaderHeightCompensation * 2;
}
+
+ .euiHeader:not(.euiHeader--fixed) {
+ // Force headers below the full screen.
+ // This shouldn't be necessary in consuming applications because headers should always be at the top of the page
+ z-index: 0;
+ }
}
.guidePage {
diff --git a/src-docs/src/views/header/header_alert.js b/src-docs/src/views/header/header_alert.js
index 3beaac75e6d..8a8473d4dfe 100644
--- a/src-docs/src/views/header/header_alert.js
+++ b/src-docs/src/views/header/header_alert.js
@@ -1,24 +1,14 @@
-import React from 'react';
-import { GuideFullScreen } from '../../services/full_screen/full_screen';
+import React, { useState } from 'react';
import {
- EuiButton,
EuiHeader,
EuiHeaderSection,
EuiHeaderSectionItem,
EuiHeaderLogo,
EuiHeaderLink,
EuiHeaderLinks,
- EuiIcon,
- EuiPage,
- EuiPageBody,
- EuiPageHeader,
- EuiPageHeaderSection,
- EuiPageContent,
- EuiPageContentHeader,
- EuiPageContentHeaderSection,
- EuiPageContentBody,
- EuiTitle,
+ EuiSpacer,
+ EuiSwitch,
} from '../../../../src/components';
import HeaderUserMenu from './header_user_menu';
@@ -26,6 +16,8 @@ import HeaderSpacesMenu from './header_spaces_menu';
import HeaderUpdates from './header_updates';
export default () => {
+ const [position, setPosition] = useState('static');
+
const renderLogo = () => {
return (
{
};
return (
-
- {setIsFullScreen => (
-
-
-
-
- {renderLogo()}
-
-
-
-
-
- Home
-
-
-
-
-
-
-
-
-
-
-
-
+ <>
+
setPosition(e.target.checked ? 'fixed' : 'static')}
+ />
+
+
+
+
+ {renderLogo()}
+
+
+
+
+
+ Home
+
+
-
-
-
-
-
- Kibana news feed demo
-
-
-
-
-
-
-
- Click the button to see
- ‘What’s new?’
-
-
-
-
- setIsFullScreen(false)}
- iconType="exit"
- aria-label="Exit fullscreen demo">
- Exit fullscreen demo
-
-
-
-
-
-
- )}
-
+
+
+
+
+
+
+
+
+
+ >
);
};
diff --git a/src-docs/src/views/header/header_elastic_pattern.js b/src-docs/src/views/header/header_elastic_pattern.js
new file mode 100644
index 00000000000..74353d46981
--- /dev/null
+++ b/src-docs/src/views/header/header_elastic_pattern.js
@@ -0,0 +1,323 @@
+import React, { useState, useEffect } from 'react';
+import { Link } from 'react-router-dom';
+// Uncomment to use in consuming apps or CodeSandbox
+// import theme from '@elastic/eui/dist/eui_theme_light.json';
+
+import {
+ EuiAvatar,
+ EuiBadge,
+ EuiButton,
+ EuiCollapsibleNav,
+ EuiCollapsibleNavGroup,
+ EuiFlexItem,
+ EuiFlyout,
+ EuiFlyoutBody,
+ EuiFlyoutHeader,
+ EuiFocusTrap,
+ EuiHeader,
+ EuiHeaderLink,
+ EuiHeaderLinks,
+ EuiHeaderLogo,
+ EuiHeaderSectionItemButton,
+ EuiIcon,
+ EuiListGroupItem,
+ EuiPage,
+ EuiPopover,
+ EuiPortal,
+ EuiShowFor,
+ EuiText,
+ EuiTitle,
+} from '../../../../src/components';
+
+export default ({ theme }) => {
+ /**
+ * FullScreen for docs only
+ */
+ const [fullScreen, setFullScreen] = useState(false);
+ useEffect(() => {
+ if (fullScreen) {
+ document.body.classList.add('guideBody--overflowHidden');
+ document.body.classList.add('euiBody--headerIsFixed--double');
+ }
+ return () => {
+ document.body.classList.remove('guideBody--overflowHidden');
+ document.body.classList.remove('euiBody--headerIsFixed--double');
+ };
+ }, [fullScreen]);
+
+ /**
+ * Collapsible Nav
+ */
+ const [navIsOpen, setNavIsOpen] = useState(
+ JSON.parse(String(localStorage.getItem('navIsDocked'))) || false
+ );
+ const [navIsDocked, setNavIsDocked] = useState(
+ JSON.parse(String(localStorage.getItem('navIsDocked'))) || false
+ );
+ const collapsibleNav = (
+
+ );
+
+ /**
+ * Header Alerts
+ */
+ const [isAlertFlyoutVisible, setIsAlertFlyoutVisible] = useState(false);
+ const headerAlerts = (
+
+ setIsAlertFlyoutVisible(false)}
+ size="s"
+ id="guideHeaderAlertExample"
+ aria-labelledby="guideHeaderAlertExampleTitle">
+
+
+
+
+
+
+
+
+ Please see the component page for{' '}
+
+ EuiHeaderAlert
+ {' '}
+ on how to configure your alerts.
+
+
+
+
+
+ );
+
+ /**
+ * User Menu
+ */
+ const [isUserMenuVisible, setIsUserMenuVisible] = useState(false);
+ const userMenu = (
+
+ );
+
+ /**
+ * Spaces Menu
+ */
+ const [isSpacesMenuVisible, setIsSpacesMenuVisible] = useState(false);
+ const spacesMenu = (
+
+ );
+
+ /**
+ * Deployment Menu
+ */
+ const [isDeploymentMenuVisible, setIsDeploymentMenuVisible] = useState(false);
+ const deploymentMenu = (
+
+ );
+
+ return (
+ <>
+ setFullScreen(true)} iconType="fullScreen">
+ Show fullscreen demo
+
+ {/* FocusTrap for Docs only */}
+ {fullScreen && (
+
+
+ Elastic
+ ,
+ ],
+ borders: 'none',
+ },
+ {
+ items: [
+ deploymentMenu,
+
+ setIsAlertFlyoutVisible(!isAlertFlyoutVisible)
+ }>
+
+ ,
+ userMenu,
+ ],
+ borders: 'none',
+ },
+ ]}
+ />
+ {},
+ },
+ {
+ text: 'Users',
+ },
+ ],
+ borders: 'right',
+ },
+ {
+ items: [
+
+ Share
+ Clone
+ {
+ setFullScreen(false);
+ document.body.classList.remove(
+ 'euiBody--headerIsFixed--double'
+ );
+ }}>
+ Exit full screen
+
+ ,
+ ],
+ },
+ ]}
+ />
+
+ {isAlertFlyoutVisible ? headerAlerts : null}
+
+
+
+ )}
+ >
+ );
+};
diff --git a/src-docs/src/views/header/header_example.js b/src-docs/src/views/header/header_example.js
index fb97e465e4b..c78bb0b32ab 100644
--- a/src-docs/src/views/header/header_example.js
+++ b/src-docs/src/views/header/header_example.js
@@ -49,6 +49,10 @@ import HeaderStacked from './header_stacked';
const headerStackedSource = require('!!raw-loader!./header_stacked');
const headerStackedHtml = renderToHtml(HeaderStacked);
+import HeaderElasticPattern from './header_elastic_pattern';
+const headerElasticPatternSource = require('!!raw-loader!./header_elastic_pattern');
+const headerElasticPatternHtml = renderToHtml(HeaderElasticPattern);
+
const headerSnippet = `
@@ -264,7 +268,7 @@ export const HeaderExample = {
demo: ,
},
{
- title: 'Alerts in the header',
+ title: 'Portal content in the header',
source: [
{
type: GuideSectionTypes.JS,
@@ -276,20 +280,27 @@ export const HeaderExample = {
},
],
text: (
-
- Use an EuiHeaderSectionItemButton to display
- additional information in an{' '}
-
- EuiPopover
- {' '}
- or{' '}
-
- EuiFlyout
-
- , such as a user profile or news feed. In the latter example, this
- additional content can be presented in a list style format using{' '}
- EuiHeaderAlert components, as shown below.
-
+ <>
+
+ Use an EuiHeaderSectionItemButton to display
+ additional information in popovers{' '}
+ or flyouts, such as a user profile
+ or news feed. When using{' '}
+
+ EuiFlyout
+
+ , be sure to wrap it in a{' '}
+
+ EuiPortal
+
+ .
+
+
+ The example below shows how to incorporate{' '}
+ EuiHeaderAlert components to show a list of
+ updates.
+
+ >
),
props: {
EuiHeaderAlert,
@@ -311,12 +322,12 @@ export const HeaderExample = {
],
text: (
- Stacking multiple headers provide a great way to separate global
+ Stacking multiple headers provides a great way to separate global
navigation concerns. However, the{' '}
{'position="fixed"'} option will not
- be aware of the number of headers. Therefore, if you do need fixed and
- stacked headers, you will need to apply the helper mixin and pass in
- the correct height to afford for.
+ be aware of the number of headers. If you do need fixed{' '}
+ and stacked headers, you will need to apply the SASS
+ helper mixin and pass in the correct height to afford for.
),
snippet: [
@@ -326,5 +337,40 @@ export const HeaderExample = {
],
demo: ,
},
+ {
+ title: 'The Elastic navigation pattern',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: headerElasticPatternSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: headerElasticPatternHtml,
+ },
+ ],
+ text: (
+ <>
+ Putting it all together
+
+ The button below will launch a full screen example that includes two{' '}
+ EuiHeaders with all the appropriate navigation
+ pieces including{' '}
+
+ EuiCollapsibleNav ,
+ {' '}
+ EuiHeaderAlerts , user menu, deployment switcher,
+ space selector, EuiHeaderBreadcrumbs and{' '}
+ EuiHeaderLinks for app menu items.
+
+
+ This is just a pattern and should be treated as such. Consuming
+ applications will need to recreate the pattern according to their
+ context and save the states as is appropriate to their data store.
+
+ >
+ ),
+ demo: ,
+ },
],
};
diff --git a/src-docs/src/views/header/header_stacked.tsx b/src-docs/src/views/header/header_stacked.tsx
index 6b5a5b96ff3..996701b9c2b 100644
--- a/src-docs/src/views/header/header_stacked.tsx
+++ b/src-docs/src/views/header/header_stacked.tsx
@@ -70,7 +70,11 @@ export default () => {
borders: 'right',
},
{
- items: isFixed ? [ ] : undefined,
+ items: [
+ ,
+ ],
borders: 'none',
},
]}
diff --git a/src-docs/src/views/header/header_updates.js b/src-docs/src/views/header/header_updates.js
index 474a1efa69d..fdc60f2ad6c 100644
--- a/src-docs/src/views/header/header_updates.js
+++ b/src-docs/src/views/header/header_updates.js
@@ -1,4 +1,4 @@
-import React, { useState, Fragment } from 'react';
+import React, { useState } from 'react';
import {
EuiIcon,
@@ -15,9 +15,14 @@ import {
EuiButtonEmpty,
EuiText,
EuiBadge,
+ EuiPopover,
+ EuiPopoverTitle,
+ EuiPopoverFooter,
+ EuiSpacer,
} from '../../../../src/components';
+import { EuiPortal } from '../../../../src/components/portal';
-export default () => {
+export default ({ flyoutOrPopover = 'flyout' }) => {
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const [showBadge, setShowBadge] = useState(true);
@@ -120,20 +125,69 @@ export default () => {
);
- let flyout;
- if (isFlyoutVisible) {
- flyout = (
- closeFlyout()}
- size="s"
- id="headerNewsFeed"
- aria-labelledby="flyoutSmallTitle">
-
-
- What's new
-
-
-
+ let content;
+ if (flyoutOrPopover === 'flyout') {
+ content = (
+ <>
+ {button}
+ {isFlyoutVisible && (
+
+ closeFlyout()}
+ size="s"
+ id="headerNewsFeed"
+ aria-labelledby="flyoutSmallTitle">
+
+
+ What's new
+
+
+
+ {alerts.map((alert, i) => (
+
+ ))}
+
+
+
+
+ closeFlyout()}
+ flush="left">
+ Close
+
+
+
+
+ Version 7.0
+
+
+
+
+
+
+ )}
+ >
+ );
+ }
+
+ if (flyoutOrPopover === 'popover') {
+ content = (
+ closeFlyout()}
+ panelPaddingSize="none">
+ What's new
+
+
{alerts.map((alert, i) => (
{
badge={alert.badge}
/>
))}
-
-
-
-
- closeFlyout()}
- flush="left">
- Close
-
-
-
-
- Version 7.0
-
-
-
-
-
+
+
+
+ Version 7.0
+
+
+
);
}
- return (
-
- {button}
- {flyout}
-
- );
+ return content;
};
diff --git a/src-docs/src/views/overlay_mask/overlay_mask.js b/src-docs/src/views/overlay_mask/overlay_mask.js
index b8794454e25..c318adb60b4 100644
--- a/src-docs/src/views/overlay_mask/overlay_mask.js
+++ b/src-docs/src/views/overlay_mask/overlay_mask.js
@@ -4,73 +4,51 @@ import {
EuiOverlayMask,
EuiButton,
EuiSpacer,
- EuiFlyout,
EuiTitle,
- EuiFlyoutHeader,
} from '../../../../src/components';
export default () => {
- const [modalOpen, changeModal] = useState(false);
- const [selectedModal, selectModal] = useState(1);
- const [flyOut, changeFlyOut] = useState(false);
+ const [maskOpen, changeMask] = useState(false);
+ const [maskWithClickOpen, changeMaskWithClick] = useState(false);
- const openModal = modal => {
- selectModal(modal);
- changeModal(!modalOpen);
- };
-
- const closeModal = () => {
- changeModal(!modalOpen);
- };
-
- const toggleFlyOut = () => {
- changeFlyOut(!flyOut);
- };
-
- if (modalOpen) {
- if (selectedModal === 1) {
- return (
-
-
-
- Click anywhere to close overlay.
-
-
-
- );
- }
-
- return (
-
- Click this button to close
+ const modal = (
+
+ {
+ changeMask(false);
+ }}>
+
+ Click anywhere to close overlay.
+
- );
- }
+
+ );
- if (flyOut) {
- return (
-
-
-
-
-
- Click outside this flyout to close overlay.
-
-
-
-
- );
- }
+ const maskWithClick = (
+
+ {
+ changeMaskWithClick(false);
+ }}>
+ Click this button to close
+
+
+ );
return (
- openModal(1)}>Overlay with onClick
-
- openModal(2)}>Overlay with button
+ {
+ changeMask(true);
+ }}>
+ Overlay with onClick
+
- toggleFlyOut()}>
- Overlay as a sibling of a flyout
+ changeMaskWithClick(true)}>
+ Overlay with button
+ {maskOpen ? modal : undefined}
+ {maskWithClickOpen ? maskWithClick : undefined}
);
};
diff --git a/src-docs/src/views/overlay_mask/overlay_mask_example.js b/src-docs/src/views/overlay_mask/overlay_mask_example.js
index 4df9912a382..a5116302f76 100644
--- a/src-docs/src/views/overlay_mask/overlay_mask_example.js
+++ b/src-docs/src/views/overlay_mask/overlay_mask_example.js
@@ -11,9 +11,9 @@ import OverlayMask from './overlay_mask';
const overlayMaskSource = require('!!raw-loader!./overlay_mask');
const overlayMaskHtml = renderToHtml(OverlayMask);
-const overlayMaskSnippet = `
-
- `;
+import OverlayMaskHeader from './overlay_mask_header';
+const overlayMaskHeaderSource = require('!!raw-loader!./overlay_mask_header');
+const overlayMaskHeaderHtml = renderToHtml(OverlayMaskHeader);
export const OverlayMaskExample = {
title: 'Overlay mask',
@@ -46,16 +46,57 @@ export const OverlayMaskExample = {
to make before choosing to use an overlay. At the very least, you
must provide a visible button to close the overlay. You can also
pass an onClick handler to handle closing the
- overlay. However, be wary of using onClick and{' '}
- children , as clicking the{' '}
- children will also trigger the{' '}
- onClick .
+ overlay.
),
props: { EuiOverlayMask },
- snippet: overlayMaskSnippet,
+ snippet: ` {}}>
+
+ `,
demo: ,
},
+ {
+ title: 'Masks with header',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: overlayMaskHeaderSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: overlayMaskHeaderHtml,
+ },
+ ],
+ text: (
+
+
+ Managing z-index levels of multiple portal-positioned components and
+ their different contexts is complicated from within the library.{' '}
+ EuiOverlayMask gives you control over whether it
+ should appear below or above an{' '}
+
+ EuiHeader
+ {' '}
+ by providing the headerZindexLocation prop. By
+ default this is set to {'"above"'} for common
+ cases like with{' '}
+
+ EuiModal
+ {' '}
+ where the header should be obscured. However, a component like{' '}
+
+ EuiFlyout
+ {' '}
+ which utilizes the overlay mask but should keep the header visible
+ needs to change this prop to {'"below"'} .
+
+
+ ),
+ props: { EuiOverlayMask },
+ snippet: `
+ `,
+ demo: ,
+ },
],
};
diff --git a/src-docs/src/views/overlay_mask/overlay_mask_header.js b/src-docs/src/views/overlay_mask/overlay_mask_header.js
new file mode 100644
index 00000000000..8cc6053ef44
--- /dev/null
+++ b/src-docs/src/views/overlay_mask/overlay_mask_header.js
@@ -0,0 +1,42 @@
+import React, { useState } from 'react';
+
+import {
+ EuiOverlayMask,
+ EuiButton,
+ EuiFlyout,
+ EuiTitle,
+ EuiFlyoutHeader,
+} from '../../../../src/components';
+
+export default () => {
+ const [flyOut, changeFlyOut] = useState(false);
+
+ const toggleFlyOut = () => {
+ changeFlyOut(!flyOut);
+ };
+
+ let flyout;
+ if (flyOut) {
+ flyout = (
+
+
+
+
+
+ Click outside this flyout to close overlay.
+
+
+
+
+ );
+ }
+
+ return (
+
+ toggleFlyOut()}>
+ Overlay as a sibling of a flyout
+
+ {flyout}
+
+ );
+};
diff --git a/src/components/badge/__snapshots__/badge.test.tsx.snap b/src/components/badge/__snapshots__/badge.test.tsx.snap
index 3bf52801022..4c326db3643 100644
--- a/src/components/badge/__snapshots__/badge.test.tsx.snap
+++ b/src/components/badge/__snapshots__/badge.test.tsx.snap
@@ -175,6 +175,40 @@ exports[`EuiBadge props color accent is rendered 1`] = `
`;
+exports[`EuiBadge props color accepts hex 1`] = `
+
+
+
+ Content
+
+
+
+`;
+
+exports[`EuiBadge props color accepts rgba 1`] = `
+
+
+
+ Content
+
+
+
+`;
+
exports[`EuiBadge props color danger is rendered 1`] = `
{
expect(component).toMatchSnapshot();
});
});
+
+ it('accepts rgba', () => {
+ const component = render(
+ Content
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
+ it('accepts hex', () => {
+ const component = render(Content );
+
+ expect(component).toMatchSnapshot();
+ });
});
describe('iconSide', () => {
diff --git a/src/components/badge/badge.tsx b/src/components/badge/badge.tsx
index 6a6efa87e98..0bbc160d9db 100644
--- a/src/components/badge/badge.tsx
+++ b/src/components/badge/badge.tsx
@@ -26,15 +26,16 @@ import React, {
Ref,
} from 'react';
import classNames from 'classnames';
-import { CommonProps, ExclusiveUnion, keysOf, PropsOf } from '../common';
import chroma from 'chroma-js';
+import { CommonProps, ExclusiveUnion, keysOf, PropsOf } from '../common';
import {
euiPaletteColorBlindBehindText,
- isValidHex,
getSecureRelForTarget,
+ isColorDark,
} from '../../services';
import { EuiInnerText } from '../inner_text';
import { EuiIcon, IconColor, IconType } from '../icon';
+import { chromaValid, parseColor } from '../color_picker/utils';
type IconSide = 'left' | 'right';
@@ -354,24 +355,23 @@ function getColorContrast(textColor: string, color: string) {
}
function setTextColor(bgColor: string) {
- const textColor =
- getColorContrast(colorInk, bgColor) > getColorContrast(colorGhost, bgColor)
- ? colorInk
- : colorGhost;
+ const textColor = isColorDark(...chroma(bgColor).rgb())
+ ? colorGhost
+ : colorInk;
return textColor;
}
function checkValidColor(color: null | IconColor | string) {
- if (
- color != null &&
- !isValidHex(color) &&
- !COLORS.includes(color) &&
- color !== 'hollow'
- ) {
+ const colorExists = !!color;
+ const isNamedColor = (color && COLORS.includes(color)) || color === 'hollow';
+ const isValidColorString = color && chromaValid(parseColor(color) || '');
+
+ if (!colorExists && !isNamedColor && !isValidColorString) {
console.warn(
'EuiBadge expects a valid color. This can either be a three or six ' +
- `character hex value, hollow, or one of the following: ${COLORS}`
+ `character hex value, rgb(a) value, hsv value, hollow, or one of the following: ${COLORS}. ` +
+ `Instead got ${color}.`
);
}
}
diff --git a/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.tsx.snap b/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.tsx.snap
index 358d9be5b22..d4fa97dc334 100644
--- a/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.tsx.snap
+++ b/src/components/breadcrumbs/__snapshots__/breadcrumbs.test.tsx.snap
@@ -48,12 +48,12 @@ exports[`EuiBreadcrumbs is rendered 1`] = `
-
Reptiles
-
+
@@ -128,12 +128,12 @@ exports[`EuiBreadcrumbs props max doesn't break when max exceeds the number of b
-
Reptiles
-
+
@@ -244,12 +244,12 @@ exports[`EuiBreadcrumbs props max renders all items with null 1`] = `
-
Reptiles
-
+
@@ -319,12 +319,12 @@ exports[`EuiBreadcrumbs props responsive is rendered 1`] = `
-
Reptiles
-
+
@@ -394,12 +394,12 @@ exports[`EuiBreadcrumbs props responsive is rendered as false 1`] = `
-
Reptiles
-
+
@@ -505,12 +505,12 @@ exports[`EuiBreadcrumbs props truncate as false is rendered 1`] = `
-
Reptiles
-
+
diff --git a/src/components/breadcrumbs/breadcrumbs.tsx b/src/components/breadcrumbs/breadcrumbs.tsx
index dd22061a686..6da5869109c 100644
--- a/src/components/breadcrumbs/breadcrumbs.tsx
+++ b/src/components/breadcrumbs/breadcrumbs.tsx
@@ -223,7 +223,7 @@ export const EuiBreadcrumbs: FunctionComponent = ({
let link;
- if (!href) {
+ if (!href && !onClick) {
link = (
{(ref, innerText) => (
diff --git a/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap b/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
index db665c0f2d4..43fabc7dfea 100644
--- a/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
+++ b/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
@@ -195,6 +195,57 @@ Array [
]
`;
+exports[`EuiCollapsibleNav props can alter mask props with maskProps without throwing error 1`] = `
+Array [
+
,
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+
+
+
,
+]
+`;
+
exports[`EuiCollapsibleNav props dockedBreakpoint 1`] = `
Array [
,
diff --git a/src/components/collapsible_nav/_collapsible_nav.scss b/src/components/collapsible_nav/_collapsible_nav.scss
index 6ac09a8de6e..e2d36a5d8ee 100644
--- a/src/components/collapsible_nav/_collapsible_nav.scss
+++ b/src/components/collapsible_nav/_collapsible_nav.scss
@@ -10,6 +10,7 @@
width: $euiCollapsibleNavWidth;
max-width: 80vw;
animation: euiCollapsibleNavIn $euiAnimSpeedNormal $euiAnimSlightResistance;
+ clip-path: polygon(0 0, 150% 0, 150% 100%, 0 100%); // Must include the width of the close button too
}
.euiCollapsibleNav__closeButton {
@@ -37,6 +38,7 @@
.euiCollapsibleNav.euiCollapsibleNav--isDocked {
@include euiBottomShadowMedium;
z-index: $euiZHeader; // When docked, make it the same level as the header
+ clip-path: none;
.euiCollapsibleNav__closeButton {
display: none;
diff --git a/src/components/collapsible_nav/collapsible_nav.test.tsx b/src/components/collapsible_nav/collapsible_nav.test.tsx
index 92f7a8564e7..32f0c401bfa 100644
--- a/src/components/collapsible_nav/collapsible_nav.test.tsx
+++ b/src/components/collapsible_nav/collapsible_nav.test.tsx
@@ -24,7 +24,9 @@ import { requiredProps } from '../../test/required_props';
import { EuiCollapsibleNav } from './collapsible_nav';
jest.mock('../overlay_mask', () => ({
- EuiOverlayMask: (props: any) =>
,
+ EuiOverlayMask: ({ headerZindexLocation, ...props }: any) => (
+
+ ),
}));
const propsNeededToRender = { id: 'id', isOpen: true };
@@ -83,6 +85,17 @@ describe('EuiCollapsibleNav', () => {
expect(component).toMatchSnapshot();
});
+
+ test('can alter mask props with maskProps without throwing error', () => {
+ const component = render(
+
+ );
+
+ expect(component).toMatchSnapshot();
+ });
});
describe('close button', () => {
diff --git a/src/components/collapsible_nav/collapsible_nav.tsx b/src/components/collapsible_nav/collapsible_nav.tsx
index 7b699db1cbf..c9b5f745d0e 100644
--- a/src/components/collapsible_nav/collapsible_nav.tsx
+++ b/src/components/collapsible_nav/collapsible_nav.tsx
@@ -30,7 +30,7 @@ import classNames from 'classnames';
import { throttle } from '../color_picker/utils';
import { EuiWindowEvent, keys, htmlIdGenerator } from '../../services';
import { EuiFocusTrap } from '../focus_trap';
-import { EuiOverlayMask } from '../overlay_mask';
+import { EuiOverlayMask, EuiOverlayMaskProps } from '../overlay_mask';
import { CommonProps } from '../common';
import { EuiButtonEmpty, EuiButtonEmptyProps } from '../button';
import { EuiI18n } from '../i18n';
@@ -69,6 +69,10 @@ export type EuiCollapsibleNavProps = CommonProps &
*/
closeButtonProps?: EuiButtonEmptyProps;
onClose?: () => void;
+ /**
+ * Adjustments to the EuiOverlayMask
+ */
+ maskProps?: EuiOverlayMaskProps;
};
export const EuiCollapsibleNav: FunctionComponent = ({
@@ -83,6 +87,7 @@ export const EuiCollapsibleNav: FunctionComponent = ({
closeButtonProps,
onClose,
id,
+ maskProps,
...rest
}) => {
const [flyoutID] = useState(id || htmlIdGenerator()('euiCollapsibleNav'));
@@ -141,7 +146,13 @@ export const EuiCollapsibleNav: FunctionComponent = ({
let optionalOverlay;
if (!navIsDocked) {
- optionalOverlay = ;
+ optionalOverlay = (
+
+ );
}
// Show a trigger button if one was passed but
diff --git a/src/components/flyout/__snapshots__/flyout.test.tsx.snap b/src/components/flyout/__snapshots__/flyout.test.tsx.snap
index 1744e4a6802..f19ba8d840b 100644
--- a/src/components/flyout/__snapshots__/flyout.test.tsx.snap
+++ b/src/components/flyout/__snapshots__/flyout.test.tsx.snap
@@ -44,7 +44,7 @@ exports[`EuiFlyout is rendered 1`] = `
`;
-exports[`EuiFlyout max width can be set to a custom number 1`] = `
+exports[`EuiFlyout props accepts div props 1`] = `
`;
-exports[`EuiFlyout max width can be set to a custom value and measurement 1`] = `
+exports[`EuiFlyout props close button is not rendered 1`] = `
`;
-exports[`EuiFlyout max width can be set to a default 1`] = `
+exports[`EuiFlyout props max width can be set to a custom number 1`] = `
`;
-exports[`EuiFlyout props accepts div props 1`] = `
+exports[`EuiFlyout props max width can be set to a custom value and measurement 1`] = `
`;
-exports[`EuiFlyout props close button is not rendered 1`] = `
+exports[`EuiFlyout props max width can be set to a default 1`] = `
`;
-exports[`EuiFlyout size l is rendered 1`] = `
+exports[`EuiFlyout props ownFocus can alter mask props with maskProps without throwing error 1`] = `
+Array [
+
,
+
,
+]
+`;
+
+exports[`EuiFlyout props ownFocus is rendered 1`] = `
+Array [
+
,
+
,
+]
+`;
+
+exports[`EuiFlyout props size l is rendered 1`] = `
`;
-exports[`EuiFlyout size m is rendered 1`] = `
+exports[`EuiFlyout props size m is rendered 1`] = `
`;
-exports[`EuiFlyout size s is rendered 1`] = `
+exports[`EuiFlyout props size s is rendered 1`] = `
({
+ EuiOverlayMask: ({ headerZindexLocation, ...props }: any) => (
+
+ ),
+}));
+
const SIZES: EuiFlyoutSize[] = ['s', 'm', 'l'];
describe('EuiFlyout', () => {
@@ -71,41 +77,63 @@ describe('EuiFlyout', () => {
expect(component).toMatchSnapshot();
});
- });
- describe('size', () => {
- SIZES.forEach(size => {
- it(`${size} is rendered`, () => {
- const component = render(
{}} size={size} />);
+ describe('size', () => {
+ SIZES.forEach(size => {
+ it(`${size} is rendered`, () => {
+ const component = render(
+ {}} size={size} />
+ );
- expect(component).toMatchSnapshot();
+ expect(component).toMatchSnapshot();
+ });
});
});
- });
- describe('max width', () => {
- test('can be set to a default', () => {
- const component = render(
- {}} maxWidth={true} />
- );
+ describe('max width', () => {
+ test('can be set to a default', () => {
+ const component = render(
+ {}} maxWidth={true} />
+ );
- expect(component).toMatchSnapshot();
- });
+ expect(component).toMatchSnapshot();
+ });
- test('can be set to a custom number', () => {
- const component = render(
- {}} maxWidth={1024} />
- );
+ test('can be set to a custom number', () => {
+ const component = render(
+ {}} maxWidth={1024} />
+ );
- expect(component).toMatchSnapshot();
+ expect(component).toMatchSnapshot();
+ });
+
+ test('can be set to a custom value and measurement', () => {
+ const component = render(
+ {}} maxWidth="24rem" />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
});
- test('can be set to a custom value and measurement', () => {
- const component = render(
- {}} maxWidth="24rem" />
- );
+ describe('ownFocus', () => {
+ test('is rendered', () => {
+ const component = render( {}} ownFocus />);
- expect(component).toMatchSnapshot();
+ expect(component).toMatchSnapshot();
+ });
+
+ test('can alter mask props with maskProps without throwing error', () => {
+ const component = render(
+ {}}
+ ownFocus
+ maskProps={{ headerZindexLocation: 'above' }}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
});
});
});
diff --git a/src/components/flyout/flyout.tsx b/src/components/flyout/flyout.tsx
index 88918718b8d..1077bd16a17 100644
--- a/src/components/flyout/flyout.tsx
+++ b/src/components/flyout/flyout.tsx
@@ -30,7 +30,7 @@ import { keys, EuiWindowEvent } from '../../services';
import { CommonProps } from '../common';
import { EuiFocusTrap } from '../focus_trap';
-import { EuiOverlayMask } from '../overlay_mask';
+import { EuiOverlayMask, EuiOverlayMaskProps } from '../overlay_mask';
import { EuiButtonIcon } from '../button';
import { EuiI18n } from '../i18n';
@@ -55,7 +55,8 @@ export interface EuiFlyoutProps
*/
hideCloseButton?: boolean;
/**
- * Locks the mouse / keyboard focus to within the flyout
+ * Locks the mouse / keyboard focus to within the flyout,
+ * and shows an EuiOverlayMask
*/
ownFocus?: boolean;
/**
@@ -73,6 +74,11 @@ export interface EuiFlyoutProps
maxWidth?: boolean | number | string;
style?: CSSProperties;
+
+ /**
+ * Adjustments to the EuiOverlayMask that is added when `ownFocus = true`
+ */
+ maskProps?: EuiOverlayMaskProps;
}
export const EuiFlyout: FunctionComponent = ({
@@ -85,6 +91,7 @@ export const EuiFlyout: FunctionComponent = ({
closeButtonAriaLabel,
maxWidth = false,
style,
+ maskProps,
...rest
}) => {
const onKeyDown = (event: KeyboardEvent) => {
@@ -152,7 +159,13 @@ export const EuiFlyout: FunctionComponent = ({
// to click it to close it.
let optionalOverlay;
if (ownFocus) {
- optionalOverlay = ;
+ optionalOverlay = (
+
+ );
}
return (
diff --git a/src/components/header/_header.scss b/src/components/header/_header.scss
index 948e76fe187..328d51f40c6 100644
--- a/src/components/header/_header.scss
+++ b/src/components/header/_header.scss
@@ -19,13 +19,6 @@
}
}
-.euiBody--collapsibleNavIsOpen,
-.euiBody--hasFlyout {
- .euiHeader--fixed {
- z-index: $euiZModal + 1;
- }
-}
-
.euiHeader--fixed + .euiHeader--fixed {
top: $euiHeaderHeightCompensation;
}
diff --git a/src/components/header/header_breadcrumbs/__snapshots__/header_breadcrumbs.test.tsx.snap b/src/components/header/header_breadcrumbs/__snapshots__/header_breadcrumbs.test.tsx.snap
index 80a9ffae819..e94cccfdafc 100644
--- a/src/components/header/header_breadcrumbs/__snapshots__/header_breadcrumbs.test.tsx.snap
+++ b/src/components/header/header_breadcrumbs/__snapshots__/header_breadcrumbs.test.tsx.snap
@@ -17,12 +17,12 @@ exports[`EuiHeaderBreadcrumbs is rendered 1`] = `
-
Reptiles
-
+
diff --git a/src/components/header/header_links/_header_link.scss b/src/components/header/header_links/_header_link.scss
index 42f656488ef..de088d4c576 100644
--- a/src/components/header/header_links/_header_link.scss
+++ b/src/components/header/header_links/_header_link.scss
@@ -1,13 +1,14 @@
+@import '../../link/mixins';
+
.euiHeaderLink {
@include euiLink;
- margin: 0 $euiSizeS;
}
.euiHeaderLinks__mobileList {
.euiHeaderLink {
display: block;
+ width: 100%;
padding: $euiSizeS;
- margin: 0;
// EuiButtons normally center, which makes sense. In mobile though we want
// them to align left. This is a safe hack given the specificity.
diff --git a/src/components/header/header_links/_header_links.scss b/src/components/header/header_links/_header_links.scss
index f77ac959eba..862350756ea 100644
--- a/src/components/header/header_links/_header_links.scss
+++ b/src/components/header/header_links/_header_links.scss
@@ -1,5 +1,3 @@
-@import '../../link/mixins';
-
.euiHeaderLinks {
display: flex;
justify-content: space-between;
@@ -11,6 +9,11 @@
overflow: hidden;
display: flex;
align-items: center;
+
+ > * {
+ // Apply margins to any children
+ margin: 0 $euiSizeS;
+ }
}
.euiHeaderLinks__mobile {
diff --git a/src/components/overlay_mask/_overlay_mask.scss b/src/components/overlay_mask/_overlay_mask.scss
index d17517fc44b..4f2fddc112e 100644
--- a/src/components/overlay_mask/_overlay_mask.scss
+++ b/src/components/overlay_mask/_overlay_mask.scss
@@ -1,6 +1,5 @@
.euiOverlayMask {
position: fixed;
- z-index: $euiZMask;
top: 0;
left: 0;
right: 0;
@@ -23,3 +22,12 @@
.euiBody-hasOverlayMask {
overflow: hidden;
}
+
+// Handling the z-index based on whether it should be displayed above or below the header
+.euiOverlayMask--aboveHeader {
+ z-index: $euiZMask;
+}
+
+.euiOverlayMask--belowHeader {
+ z-index: $euiZHeader - 1;
+}
diff --git a/src/components/overlay_mask/overlay_mask.tsx b/src/components/overlay_mask/overlay_mask.tsx
index 57efb9f8307..981221cc719 100644
--- a/src/components/overlay_mask/overlay_mask.tsx
+++ b/src/components/overlay_mask/overlay_mask.tsx
@@ -35,8 +35,15 @@ import classNames from 'classnames';
import { CommonProps, keysOf } from '../common';
export interface EuiOverlayMaskInterface {
+ /**
+ * Function that applies to clicking the mask itself and not the children
+ */
onClick?: () => void;
children?: ReactNode;
+ /**
+ * Should the mask visually sit above or below the EuiHeader (controlled by z-index)
+ */
+ headerZindexLocation?: 'above' | 'below';
}
export type EuiOverlayMaskProps = CommonProps &
@@ -50,6 +57,7 @@ export const EuiOverlayMask: FunctionComponent = ({
className,
children,
onClick,
+ headerZindexLocation = 'above',
...rest
}) => {
const overlayMaskNode = useRef(document.createElement('div'));
@@ -89,8 +97,12 @@ export const EuiOverlayMask: FunctionComponent = ({
useEffect(() => {
if (!overlayMaskNode.current) return;
- overlayMaskNode.current.className = classNames('euiOverlayMask', className);
- }, [className]);
+ overlayMaskNode.current.className = classNames(
+ 'euiOverlayMask',
+ `euiOverlayMask--${headerZindexLocation}Header`,
+ className
+ );
+ }, [className, headerZindexLocation]);
useEffect(() => {
if (!overlayMaskNode.current || !onClick) return;
diff --git a/src/global_styling/variables/_z_index.scss b/src/global_styling/variables/_z_index.scss
index a092f5bc1f0..2cf4bc9e27c 100644
--- a/src/global_styling/variables/_z_index.scss
+++ b/src/global_styling/variables/_z_index.scss
@@ -27,6 +27,7 @@ $euiZLevel9: 9000;
$euiZContent: $euiZLevel0;
$euiZHeader: $euiZLevel1;
$euiZContentMenu: $euiZLevel2;
+$euiZFlyout: $euiZLevel3;
$euiZNavigation: $euiZLevel4;
$euiZMask: $euiZLevel6;
$euiZModal: $euiZLevel8;
diff --git a/src/themes/eui-amsterdam/overrides/_flyout.scss b/src/themes/eui-amsterdam/overrides/_flyout.scss
deleted file mode 100644
index 6e78d2fe0ce..00000000000
--- a/src/themes/eui-amsterdam/overrides/_flyout.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-// Amsterdam shadows extend upwards as well, but this means flyouts shadows can overlap fixed headers.
-// The clip path ensures only the left side of the shadow is exposed.
-.euiFlyout {
- clip-path: polygon(-10% 0, 100% 0, 100% 100%, -10% 100%);
-}
diff --git a/src/themes/eui-amsterdam/overrides/_header.scss b/src/themes/eui-amsterdam/overrides/_header.scss
index f32c374f462..1f9a52cbb36 100644
--- a/src/themes/eui-amsterdam/overrides/_header.scss
+++ b/src/themes/eui-amsterdam/overrides/_header.scss
@@ -32,8 +32,8 @@
// Breadcrumbs
.euiHeaderBreadcrumbs {
- @include euiFontSizeXS;
- font-weight: $euiFontWeightMedium;
+ font-size: $euiFontSizeXS;
+ line-height: $euiSize;
margin-left: $euiSizeS;
margin-right: $euiSizeS;
@@ -46,7 +46,9 @@
// still be default text only breadcrumbs for places like EuiControlBar
.euiBreadcrumb {
@include euiButtonDefaultStyle($euiTextColor);
- padding: $euiSizeXS $euiSizeM $euiSizeXS $euiSize;
+ line-height: $euiSize;
+ font-weight: $euiFontWeightMedium;
+ padding: $euiSizeXS $euiSize;
clip-path: polygon(0 0, calc(100% - #{$euiSizeS}) 0, 100% 50%, calc(100% - #{$euiSizeS}) 100%, 0 100%, $euiSizeS 50%);
// If it's a link the easiest way to detect is via our .euiLink class since it can accept either href or onClick
@@ -75,15 +77,23 @@
&:first-child {
padding-left: $euiSizeM;
- border-radius: $euiSizeS 0 0 $euiSizeS;
+ border-radius: $euiBorderRadius 0 0 $euiBorderRadius;
clip-path: polygon(0 0, calc(100% - #{$euiSizeS}) 0, 100% 50%, calc(100% - #{$euiSizeS}) 100%, 0 100%);
}
}
.euiBreadcrumb--last {
- border-radius: 0 #{$euiSizeS} #{$euiSizeS} 0;
+ border-radius: 0 $euiBorderRadius $euiBorderRadius 0;
padding-right: $euiSizeM;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, #{$euiSizeS} 50%);
}
+
+ // In case the item is first AND last, aka only, just make it a fully rounded item
+ .euiBreadcrumb:only-child {
+ clip-path: none;
+ padding-left: $euiSizeM;
+ padding-right: $euiSizeM;
+ border-radius: $euiBorderRadius;
+ }
}
diff --git a/src/themes/eui-amsterdam/overrides/_index.scss b/src/themes/eui-amsterdam/overrides/_index.scss
index a8fcf7a02d1..d02573172ba 100644
--- a/src/themes/eui-amsterdam/overrides/_index.scss
+++ b/src/themes/eui-amsterdam/overrides/_index.scss
@@ -4,7 +4,6 @@
@import 'call_out';
@import 'code';
@import 'filter_group';
-@import 'flyout';
@import 'header';
@import 'image';
@import 'modal';