Skip to content

Commit

Permalink
Merge branch 'main' into jzempel/element-types
Browse files Browse the repository at this point in the history
  • Loading branch information
jzempel committed Jan 26, 2022
2 parents 4107c0a + c711002 commit db114b2
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 19 deletions.
16 changes: 8 additions & 8 deletions packages/chrome/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"index.cjs.js": {
"bundled": 71484,
"minified": 54170,
"gzipped": 10419
"bundled": 72647,
"minified": 54785,
"gzipped": 10568
},
"index.esm.js": {
"bundled": 65911,
"minified": 49322,
"gzipped": 10143,
"bundled": 67062,
"minified": 49925,
"gzipped": 10286,
"treeshaked": {
"rollup": {
"code": 38460,
"code": 38879,
"import_statements": 676
},
"webpack": {
"code": 43132
"code": 43586
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/chrome/demo/sheet.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
hasClose: true,
hasFooter: true,
hasHeader: true,
hasTitle: true,
hasDescription: true,
title: TITLE,
description: DESCRIPTION,
footerItems: FOOTER_ITEMS
Expand All @@ -52,7 +54,9 @@ import {
hasHeader: { name: 'Sheet.Header', table: { category: 'Story' } },
footerItems: { name: 'Sheet.FooterItem[]', table: { category: 'Story' } },
body: { name: 'children', table: { category: 'Sheet.Body' } },
hasTitle: { name: 'Sheet.Title', table: { category: 'Story' } },
title: { name: 'children', table: { category: 'Sheet.Title' } },
hasDescription: { name: 'Sheet.Description', table: { category: 'Story' } },
description: { name: 'children', table: { category: 'Sheet.Description' } },
isCompact: { control: 'boolean', table: { category: 'Sheet.Footer' } }
}}
Expand Down
8 changes: 6 additions & 2 deletions packages/chrome/demo/stories/SheetStory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ interface ISheetComponentProps extends ISheetProps {
footerItems: IFooterItem[];
hasHeader: boolean;
isCompact: boolean;
hasTitle?: boolean;
title: string;
hasDescription?: boolean;
description: string;
}

export const SheetComponent = ({
hasHeader,
title,
hasTitle = !!title,
description,
hasDescription = !!description,
hasBody,
body,
hasFooter,
Expand All @@ -43,8 +47,8 @@ export const SheetComponent = ({
<Sheet {...props}>
{hasHeader && (
<Sheet.Header>
<Sheet.Title>{title}</Sheet.Title>
<Sheet.Description>{description}</Sheet.Description>
{hasTitle && <Sheet.Title>{title}</Sheet.Title>}
{hasDescription && <Sheet.Description>{description}</Sheet.Description>}
</Sheet.Header>
)}
{hasBody ? <Sheet.Body>{body}</Sheet.Body> : body}
Expand Down
11 changes: 10 additions & 1 deletion packages/chrome/src/elements/sheet/Sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,20 @@ const SheetComponent = React.forwardRef<HTMLElement, ISheetProps>(
const sheetRef = useRef<HTMLElement>(null);

const seed = useUIDSeed();
const [isCloseButtonPresent, setCloseButtonPresent] = useState<boolean>(false);
const [idPrefix] = useState<string>(id || seed(`sheet_${PACKAGE_VERSION}`));
const titleId = `${idPrefix}--title`;
const descriptionId = `${idPrefix}--description`;

const sheetContext = useMemo(() => ({ titleId, descriptionId }), [titleId, descriptionId]);
const sheetContext = useMemo(
() => ({
titleId,
descriptionId,
isCloseButtonPresent,
setCloseButtonPresent
}),
[titleId, descriptionId, isCloseButtonPresent]
);

useFocusableMount({ targetRef: sheetRef, isMounted: isOpen, focusOnMount, restoreFocus });

Expand Down
30 changes: 30 additions & 0 deletions packages/chrome/src/elements/sheet/components/Close.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,23 @@ import { render, screen } from 'garden-test-utils';

import { Close } from './Close';

import { useSheetContext } from '../../../utils/useSheetContext';

jest.mock('../../../utils/useSheetContext', () => {
const setCloseButtonPresent = jest.fn();

return {
useSheetContext: () => ({
setCloseButtonPresent
})
};
});

describe('Sheet.Close', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('passes ref to underlying DOM element', () => {
const ref = React.createRef<HTMLButtonElement>();

Expand All @@ -20,4 +36,18 @@ describe('Sheet.Close', () => {

expect(btn).toBe(ref.current);
});

describe('functionality', () => {
it('calls setCloseButtonPresent when mounting and unmounting', () => {
const { unmount } = render(<Close />);
const { setCloseButtonPresent } = useSheetContext();

expect(setCloseButtonPresent).toHaveBeenCalledWith(true);

unmount();

expect(setCloseButtonPresent).toHaveBeenCalledWith(false);
expect(setCloseButtonPresent).toHaveBeenCalledTimes(2);
});
});
});
11 changes: 10 additions & 1 deletion packages/chrome/src/elements/sheet/components/Close.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/

import React, { ButtonHTMLAttributes, forwardRef } from 'react';
import React, { ButtonHTMLAttributes, forwardRef, useEffect } from 'react';
import XStrokeIcon from '@zendeskgarden/svg-icons/src/16/x-stroke.svg';

import { StyledSheetClose } from '../../../styled';
import { useSheetContext } from '../../../utils/useSheetContext';

const SheetClose = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(
(props, ref) => {
const { setCloseButtonPresent } = useSheetContext();

useEffect(() => {
setCloseButtonPresent(true);

return () => setCloseButtonPresent(false);
}, [setCloseButtonPresent]);

return (
<StyledSheetClose aria-label="Close Sheet" ref={ref} {...props}>
<XStrokeIcon />
Expand Down
6 changes: 5 additions & 1 deletion packages/chrome/src/elements/sheet/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
*/

import React, { forwardRef, HTMLAttributes } from 'react';

import { StyledSheetHeader } from '../../../styled';
import { useSheetContext } from '../../../utils/useSheetContext';

const SheetHeader = forwardRef<HTMLElement, HTMLAttributes<HTMLElement>>((props, ref) => {
return <StyledSheetHeader ref={ref} {...props} />;
const { isCloseButtonPresent } = useSheetContext();

return <StyledSheetHeader ref={ref} isCloseButtonPresent={isCloseButtonPresent} {...props} />;
});

SheetHeader.displayName = 'Sheet.Header';
Expand Down
15 changes: 11 additions & 4 deletions packages/chrome/src/styled/sheet/StyledSheetClose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import { getColor, retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden

const COMPONENT_ID = 'chrome.sheet_close';

export const baseMultipliers = {
top: 2.5,
side: 2,
size: 10
};

const colorStyles = (props: ThemeProps<DefaultTheme>) => {
const backgroundColor = 'primaryHue';
const foregroundColor = 'neutralHue';
Expand Down Expand Up @@ -46,8 +52,9 @@ export const StyledSheetClose = styled.button.attrs({
})<ThemeProps<DefaultTheme>>`
display: flex;
position: absolute;
top: ${props => props.theme.space.base * 2.5}px;
${props => (props.theme.rtl ? 'left' : 'right')}: ${props => `${props.theme.space.base * 2}px`};
top: ${props => props.theme.space.base * baseMultipliers.top}px;
${props => (props.theme.rtl ? 'left' : 'right')}: ${props =>
`${props.theme.space.base * baseMultipliers.side}px`};
align-items: center;
justify-content: center;
/* prettier-ignore */
Expand All @@ -59,8 +66,8 @@ export const StyledSheetClose = styled.button.attrs({
border-radius: 50%;
cursor: pointer;
padding: 0;
width: ${props => props.theme.space.base * 10}px;
height: ${props => props.theme.space.base * 10}px;
width: ${props => props.theme.space.base * baseMultipliers.size}px;
height: ${props => props.theme.space.base * baseMultipliers.size}px;
overflow: hidden;
text-decoration: none;
font-size: 0;
Expand Down
41 changes: 41 additions & 0 deletions packages/chrome/src/styled/sheet/StyledSheetHeader.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright Zendesk, Inc.
*
* Use of this source code is governed under the Apache License, Version 2.0
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/

import React from 'react';
import { renderRtl, render, screen } from 'garden-test-utils';
import { DEFAULT_THEME, getColor } from '@zendeskgarden/react-theming';

import { StyledSheetHeader } from './StyledSheetHeader';

describe('StyledSheetHeader', () => {
it('renders default styling', () => {
render(<StyledSheetHeader>Header</StyledSheetHeader>);

expect(screen.getByText('Header')).toHaveStyleRule(
'border-bottom',
`${DEFAULT_THEME.borders.sm} ${getColor('neutralHue', 300, DEFAULT_THEME)}`
);
});

it('renders correctly when button is present', () => {
render(<StyledSheetHeader isCloseButtonPresent>Header</StyledSheetHeader>);

expect(screen.getByText('Header')).toHaveStyleRule(
'padding-right',
`${DEFAULT_THEME.space.base * 14}px`
);
});

it('renders correctly in rtl mode when button is present', () => {
renderRtl(<StyledSheetHeader isCloseButtonPresent>Header</StyledSheetHeader>);

expect(screen.getByText('Header')).toHaveStyleRule(
'padding-left',
`${DEFAULT_THEME.space.base * 14}px`
);
});
});
15 changes: 14 additions & 1 deletion packages/chrome/src/styled/sheet/StyledSheetHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,28 @@
import styled, { ThemeProps, DefaultTheme } from 'styled-components';
import { getColor, retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';

import { baseMultipliers } from './StyledSheetClose';

const COMPONENT_ID = 'chrome.sheet_header';

export interface IStyledSheetHeaderProps {
isCloseButtonPresent?: boolean;
}

export const StyledSheetHeader = styled.header.attrs({
'data-garden-id': COMPONENT_ID,
'data-garden-version': PACKAGE_VERSION
})<ThemeProps<DefaultTheme>>`
})<IStyledSheetHeaderProps & ThemeProps<DefaultTheme>>`
border-bottom: ${props =>
`${props.theme.borders.sm} ${getColor('neutralHue', 300, props.theme)}}`};
padding: ${props => props.theme.space.base * 5}px;
${props =>
props.isCloseButtonPresent &&
// the padding size accounts for 40px (10 base units) size of the button,
// 8px additional padding and 8px padding for the button position from a given side.
`padding-${props.theme.rtl ? 'left' : 'right'}: ${
props.theme.space.base * (baseMultipliers.size + baseMultipliers.side + 2)
}px;`}
${props => retrieveComponentStyles(COMPONENT_ID, props)};
`;
Expand Down
7 changes: 6 additions & 1 deletion packages/chrome/src/utils/useSheetContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ import { createContext, useContext } from 'react';
export interface ISheetContext {
titleId?: string;
descriptionId?: string;
isCloseButtonPresent?: boolean;
setCloseButtonPresent: (isPresent: boolean) => void;
}

export const SheetContext = createContext<ISheetContext>({});
export const SheetContext = createContext<ISheetContext>({
// eslint-disable-next-line @typescript-eslint/no-empty-function
setCloseButtonPresent() {}
});

export const useSheetContext = () => {
return useContext(SheetContext);
Expand Down

0 comments on commit db114b2

Please sign in to comment.