Skip to content

Commit

Permalink
[refactor] Add new body & footer components
Browse files Browse the repository at this point in the history
- instead of relying on consumers to use `EuiFlyoutBody` and `EuiFlyoutFooter` directly
  • Loading branch information
cee-chen committed Sep 26, 2023
1 parent ee2c6e0 commit 5152f08
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiCollapsibleNavBody renders 1`] = `
<div
aria-label="aria-label"
class="euiFlyoutBody euiCollapsibleNav__body testClass1 testClass2 emotion-euiFlyoutBody-euiCollapsibleNav__body-euiTestCss"
data-test-subj="test subject string"
>
<div
class="euiFlyoutBody__overflow css-18yrfj9-noBanner"
tabindex="-1"
>
<div
class="euiFlyoutBody__overflowContent"
/>
</div>
</div>
`;

exports[`EuiCollapsibleNavFooter renders 1`] = `
<div
aria-label="aria-label"
class="euiFlyoutFooter euiCollapsibleNav__footer testClass1 testClass2 emotion-euiFlyoutFooter-euiCollapsibleNav__footer-euiTestCss"
data-test-subj="test subject string"
/>
`;
25 changes: 4 additions & 21 deletions src/components/collapsible_nav_beta/collapsible_nav_beta.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { logicalCSS, euiYScroll } from '../../global_styling';
import { euiShadowFlat } from '../../themes';
import { euiHeaderVariables } from '../header/header.styles';

import { euiCollapsibleNavBodyStyles } from './collapsible_nav_body_footer.styles';

export const euiCollapsibleNavBetaStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme } = euiThemeContext;

Expand All @@ -26,22 +28,12 @@ export const euiCollapsibleNavBetaStyles = (euiThemeContext: UseEuiTheme) => {
/* Fixed header affordance */
${logicalCSS('top', fixedHeaderOffset)}
/* Allow the nav to scroll, in case consumers don't use EuiFlyoutBody/EuiFyoutFooter */
/* Allow the nav to scroll, in case consumers don't use the body or footer components */
${euiYScroll(euiThemeContext, { height: 'inherit' })}
/* This extra padding is needed for EuiPopovers to have enough
space to render with the right anchorPosition */
${logicalCSS('padding-bottom', euiTheme.size.xs)}
/* In case things get really dire responsively, ensure the footer doesn't overtake the body */
.euiFlyoutBody {
${logicalCSS('min-height', '50%')}
}
.euiFlyoutFooter {
background-color: ${euiTheme.colors.emptyShade};
${logicalCSS('border-top', euiTheme.border.thin)}
}
`,
left: css`
${logicalCSS('border-right', euiTheme.border.thin)}
Expand All @@ -53,16 +45,7 @@ export const euiCollapsibleNavBetaStyles = (euiThemeContext: UseEuiTheme) => {
${euiShadowFlat(euiThemeContext)}
`,
isPushCollapsed: css`
/* Hide the scrollbar for docked mode (while still keeping the nav scrollable)
Otherwise if scrollbars are visible, button icon visibility suffers */
&,
.euiFlyoutBody__overflow {
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none; /* Chrome, Edge, & Safari */
}
}
${euiCollapsibleNavBodyStyles._isPushCollapsed}
`,
isOverlayFullWidth: css`
/* Override EuiFlyout's max-width */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { css } from '@emotion/react';
import { UseEuiTheme } from '../../services';
import { logicalCSS } from '../../global_styling';

export const euiCollapsibleNavBodyStyles = {
// In case things get really dire responsively, ensure the footer doesn't overtake the body
euiCollapsibleNav__body: css`
${logicalCSS('min-height', '50%')}
`,
get isPushCollapsed() {
return css`
.euiFlyoutBody__overflow {
${this._isPushCollapsed}
}
`;
},
// CSS is reused by main euiCollapsibleNav styles in case the body component isn't used
_isPushCollapsed: `
/* Hide the scrollbar for docked mode (while still keeping the nav scrollable)
Otherwise if scrollbars are visible, button icon visibility suffers. */
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none; /* Chrome, Edge, & Safari */
}
`,
};

export const euiCollapsibleNavFooterStyles = ({ euiTheme }: UseEuiTheme) => {
return {
euiCollapsibleNav__footer: css`
background-color: ${euiTheme.colors.emptyShade};
${logicalCSS('border-top', euiTheme.border.thin)}
`,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import { render } from '../../test/rtl';
import { shouldRenderCustomStyles } from '../../test/internal';
import { requiredProps } from '../../test';

import { EuiCollapsibleNavContext } from './context';
import {
EuiCollapsibleNavBody,
EuiCollapsibleNavFooter,
} from './collapsible_nav_body_footer';

describe('EuiCollapsibleNavBody', () => {
shouldRenderCustomStyles(<EuiCollapsibleNavBody />);

it('renders', () => {
const { container } = render(<EuiCollapsibleNavBody {...requiredProps} />);
expect(container.firstChild).toMatchSnapshot();
});

it('renders with docked styles', () => {
const { container } = render(
<EuiCollapsibleNavContext.Provider
value={{ side: 'left', isPush: true, isCollapsed: true }}
>
<EuiCollapsibleNavBody {...requiredProps} />
</EuiCollapsibleNavContext.Provider>
);

expect(container.innerHTML).toContain('isPushCollapsed');
});
});

describe('EuiCollapsibleNavFooter', () => {
shouldRenderCustomStyles(<EuiCollapsibleNavFooter />);

it('renders', () => {
const { container } = render(
<EuiCollapsibleNavFooter {...requiredProps} />
);
expect(container.firstChild).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React, { useContext } from 'react';
import classNames from 'classnames';

import { useEuiTheme } from '../../services';
import {
EuiFlyoutBody,
EuiFlyoutBodyProps,
EuiFlyoutFooter,
EuiFlyoutFooterProps,
} from '../flyout';

import { EuiCollapsibleNavContext } from './context';
import {
euiCollapsibleNavBodyStyles as bodyStyles,
euiCollapsibleNavFooterStyles,
} from './collapsible_nav_body_footer.styles';

/**
* These components are incredibly light wrappers around `EuiFlyoutBody`
* and `EuiFlyoutFooter` with collapsible nav-specific styling/considerations.
*
* Note: They are not intended to be used standalone outside of EuiCollapsibleNav
*/

export const EuiCollapsibleNavBody: EuiFlyoutBodyProps = ({
className,
...props
}) => {
const classes = classNames('euiCollapsibleNav__body', className);

const { isCollapsed, isPush } = useContext(EuiCollapsibleNavContext);
const cssStyles = [
bodyStyles.euiCollapsibleNav__body,
isCollapsed && isPush && bodyStyles.isPushCollapsed,
];

return (
<EuiFlyoutBody
className={classes}
css={cssStyles}
// Since this is a nav, we can almost guarantee there will be clickable
// children/links that will enable scrolling. As such, we're optimistically
// removing the extra tab stop
scrollableTabIndex={-1}
{...props}
/>
);
};

export const EuiCollapsibleNavFooter: EuiFlyoutFooterProps = ({
className,
...props
}) => {
const classes = classNames('euiCollapsibleNav__footer', className);

const euiTheme = useEuiTheme();
const styles = euiCollapsibleNavFooterStyles(euiTheme);
const cssStyles = [styles.euiCollapsibleNav__footer];

return <EuiFlyoutFooter className={classes} css={cssStyles} {...props} />;
};

0 comments on commit 5152f08

Please sign in to comment.