Skip to content

Commit

Permalink
feat: new default and custom colors for appchrome (#715)
Browse files Browse the repository at this point in the history
These changes affect the AppChrome sidebar and header style.
Changes include refactoring of components such as removing React.FC.

BREAKING CHANGE: The fallback theme colors for the AppChrome component have been updated. The header fallback has changed from purple to white. The sidebar
fallback has changed from black to gray.
  • Loading branch information
nataliepina authored May 12, 2022
1 parent 4ba391f commit fa57957
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 119 deletions.
69 changes: 33 additions & 36 deletions packages/appChrome/components/AppChrome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,52 @@ import {
flush
} from "../../shared/styles/styleUtils";
import { ThemeProvider } from "@emotion/react";
import getCSSVarValue from "../../utilities/getCSSVarValue";
import { themeBgPrimaryInverted } from "../../design-tokens/build/js/designTokens";
import {
defaultSidebarItemHorizPaddingSize,
defaultSidebarItemVertPaddingSize
} from "./SidebarItem";
import {
defaultBgColor,
defaultHeaderPaddingHor,
defaultHeaderPaddingVert
} from "./HeaderBar";

export interface AppChromeProps {
sidebar: React.ReactNode;
headerBar: React.ReactNode;
mainContent: React.ReactNode;
}

class AppChrome extends React.PureComponent<AppChromeProps, {}> {
public render() {
const { sidebar, headerBar, mainContent } = this.props;

return (
<ThemeProvider
theme={{
sidebarBackgroundColor: getCSSVarValue(themeBgPrimaryInverted),
sidebarItemPaddingHor: defaultSidebarItemHorizPaddingSize,
sidebarItemPaddingVert: defaultSidebarItemVertPaddingSize
}}
const AppChrome = ({ sidebar, headerBar, mainContent }: AppChromeProps) => {
return (
<ThemeProvider
theme={{
sidebarItemPaddingHor: defaultSidebarItemHorizPaddingSize,
sidebarItemPaddingVert: defaultSidebarItemVertPaddingSize,
headerPaddingHor: defaultHeaderPaddingHor,
headerPaddingVert: defaultHeaderPaddingVert,
headerBackgroundColor: defaultBgColor
}}
>
<div
className={cx(appChrome, textSize("m"), flex({ direction: "column" }))}
data-cy="appChrome"
>
<div
className={cx(
appChrome,
textSize("m"),
flex({ direction: "column" })
)}
data-cy="appChrome"
>
<div data-cy="headerBar">{headerBar}</div>
<div className={cx(flex(), appWrapper)}>
<div className={flexItem("shrink")} data-cy="sidebar">
{sidebar}
</div>
<main
className={cx(flexItem("grow"), flush("left"), appWrapper)}
data-cy="main"
>
{mainContent}
</main>
<div data-cy="headerBar">{headerBar}</div>
<div className={cx(flex(), appWrapper)}>
<div className={flexItem("shrink")} data-cy="sidebar">
{sidebar}
</div>
<main
className={cx(flexItem("grow"), flush("left"), appWrapper)}
data-cy="main"
>
{mainContent}
</main>
</div>
</ThemeProvider>
);
}
}
</div>
</ThemeProvider>
);
};

export default AppChrome;
34 changes: 32 additions & 2 deletions packages/appChrome/components/HeaderBar.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,47 @@
import * as React from "react";
import { cx } from "@emotion/css";
import { flex } from "../../shared/styles/styleUtils";
import { useTheme } from "@emotion/react";
import { ThemeProvider, useTheme } from "@emotion/react";
import { headerBar } from "../style";
import { AppChromeTheme } from "../types";
import { getCSSVarValue } from "../../utilities";
import { themeBgPrimary } from "../../design-tokens/build/js/designTokens";

const Header: React.FC = ({ children }) => {
export const defaultBgColor = getCSSVarValue(themeBgPrimary);
export const defaultHeaderPaddingHor = "none";
export const defaultHeaderPaddingVert = "none";

interface HeaderProps {
children?: React.ReactNode;
/**
* Changes the background color for the entire sidebar
*/
bgColor?: string;
}

const StyledHeader = ({ children }: HeaderProps) => {
const theme: AppChromeTheme = useTheme();

return (
<div className={cx(headerBar(theme), flex({ align: "center" }))}>
{children}
</div>
);
};

const Header = ({ bgColor, children }: HeaderProps) => {
const adjustedTheme = ancestorTheme => {
return {
headerBackgroundColor: bgColor || getCSSVarValue(themeBgPrimary),
...ancestorTheme
};
};

return (
<ThemeProvider theme={adjustedTheme}>
<StyledHeader>{children}</StyledHeader>
</ThemeProvider>
);
};

export default Header;
40 changes: 31 additions & 9 deletions packages/appChrome/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,41 @@ import * as React from "react";
import { cx } from "@emotion/css";
import { ThemeProvider, useTheme } from "@emotion/react";
import { sidebar, sidebarAnimator, sidebarContainer } from "../style";
import { themeBgPrimaryInverted } from "../../design-tokens/build/js/designTokens";
import { themeBgDisabled } from "../../design-tokens/build/js/designTokens";
import getCSSVarValue from "../../utilities/getCSSVarValue";
import { getResponsiveStyle } from "../../shared/styles/styleUtils";
import { AppChromeTheme } from "../types";
export interface SidebarProps {
/**
* Whether a sidebar items contents are visible
*/
isOpen: boolean;
/** Function that gets called when a sidebar item opens */
onOpen?: () => void;
/** Function that gets called when a sidebar item closes */
onClose?: () => void;
/** Children to render inside of the sidebar */
children?: React.ReactNode;
/**
* Changes the background color for the entire sidebar
*/
bgColor?: string;
/**
* Changes the color for sidebar items on hover
*/
hoverColor?: string;
/**
* Changes the color for sidebar items in an active selected state
*/
activeColor?: string;
}

const defaultSidebarWidths = {
default: "240px",
large: "280px"
};

const StyledSidebar: React.FC<{ isOpen?: boolean }> = ({
children,
isOpen
}) => {
const StyledSidebar = ({ children, isOpen }: SidebarProps) => {
const theme: AppChromeTheme = useTheme();

return (
Expand All @@ -43,12 +59,15 @@ const StyledSidebar: React.FC<{ isOpen?: boolean }> = ({
);
};

const Sidebar: React.FC<SidebarProps> = ({
const Sidebar = ({
children,
isOpen,
onClose,
onOpen
}) => {
onOpen,
bgColor,
activeColor,
hoverColor
}: SidebarProps) => {
// Used to only call `onOpen`/`onClose` when the `isOpen` prop changes.
// Source: https://dev.to/savagepixie/how-to-mimic-componentdidupdate-with-react-hooks-3j8c
const didMountRef = React.useRef(false);
Expand All @@ -66,7 +85,10 @@ const Sidebar: React.FC<SidebarProps> = ({

const adjustedTheme = ancestorTheme => {
return {
sidebarBackgroundColor: getCSSVarValue(themeBgPrimaryInverted),
sidebarBackgroundColor: bgColor || getCSSVarValue(themeBgDisabled),
// TODO update these with design tokens
itemActiveBackgroundColor: activeColor || "#D0D4D7",
itemHoverBackgroundColor: hoverColor || "#DDDFE2",
sidebarWidth: defaultSidebarWidths,
...ancestorTheme
};
Expand Down
4 changes: 2 additions & 2 deletions packages/appChrome/components/SidebarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ export interface SidebarItemProps extends SidebarNavItemProps {
export const defaultSidebarItemHorizPaddingSize = "l";
export const defaultSidebarItemVertPaddingSize = "none";

const SidebarItemComponent: React.FC<SidebarItemProps> = ({
const SidebarItemComponent = ({
children,
disabled,
isActive,
onClick,
openInNewTab,
url
}) => {
}: SidebarItemProps) => {
const theme: AppChromeTheme = useTheme();
const dataCy = [
"sidebarItem",
Expand Down
42 changes: 20 additions & 22 deletions packages/appChrome/components/SidebarItemLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,32 @@ import IconPropAdapter from "../../icon/components/IconPropAdapter";
import { IconSize } from "../../shared/types/iconSize";

export interface SidebarItemLabelProps {
children?: React.ReactElement<HTMLElement> | string;
children?: React.ReactNode;
icon?: IconShapes | React.ReactElement<HTMLElement>;
iconWidth?: IconSize;
}

const SidebarItemLabel: React.FC<SidebarItemLabelProps> = ({
const SidebarItemLabel = ({
children,
icon,
iconWidth
}) => (
<div className={cx(flex({ align: "center" }), sidebarItemHeight)}>
{icon && (
<div
className={cx(
flexItem("shrink"),
padding("right", "m"),
sidebarNavItemIconWrap
)}
>
<IconPropAdapter icon={icon} size={iconWidth} color="inherit" />
</div>
)}
<div className={flexItem("grow")}>{children}</div>
</div>
);

SidebarItemLabel.defaultProps = {
iconWidth: "s"
iconWidth = "s"
}: SidebarItemLabelProps) => {
return (
<div className={cx(flex({ align: "center" }), sidebarItemHeight)}>
{icon && (
<div
className={cx(
flexItem("shrink"),
padding("right", "m"),
sidebarNavItemIconWrap
)}
>
<IconPropAdapter icon={icon} size={iconWidth} color="inherit" />
</div>
)}
<div className={flexItem("grow")}>{children}</div>
</div>
);
};

export default SidebarItemLabel;
6 changes: 2 additions & 4 deletions packages/appChrome/components/SidebarSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ import { useTheme } from "@emotion/react";
import { AppChromeTheme } from "../types";

export interface SidebarSectionProps {
children:
| React.ReactElement<HTMLElement>
| Array<React.ReactElement<HTMLElement>>;
children: React.ReactNode | React.ReactNode[];
label?: React.ReactElement<HTMLElement> | string;
}

const SidebarSection: React.FC<SidebarSectionProps> = ({ label, children }) => {
const SidebarSection = ({ label, children }: SidebarSectionProps) => {
const theme: AppChromeTheme = useTheme();

return (
Expand Down
5 changes: 3 additions & 2 deletions packages/appChrome/components/SidebarSubMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface SidebarSubMenuProps {
iconWidth?: IconSize;
theme?: AppChromeTheme;
disabled?: boolean;
children?: React.ReactNode | React.ReactNode[];
}

export const getSubItemList = (items: React.ReactNode[] | React.ReactNode) => (
Expand All @@ -27,13 +28,13 @@ export const getSubItemList = (items: React.ReactNode[] | React.ReactNode) => (
</ul>
);

export const SidebarSubMenuComponent: React.FC<SidebarSubMenuProps> = ({
export const SidebarSubMenuComponent = ({
children,
label,
isOpen,
disabled,
menuHasIcon
}) => {
}: SidebarSubMenuProps) => {
const theme: AppChromeTheme = useTheme();

const dataCy = [
Expand Down
15 changes: 11 additions & 4 deletions packages/appChrome/components/SidebarSubMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ import { pickReadableTextColor } from "../../shared/styles/color";
import { AppChromeTheme, SidebarNavItemProps } from "../types";
import { IconSize } from "../../shared/types/iconSize";

const SidebarSubMenuItemText: React.FC<{
export interface SidebarSubMenuItemTextProps {
menuHasIcon: boolean;
iconContainerWidth: IconSize;
}> = ({ children, menuHasIcon, iconContainerWidth }) => (
children?: React.ReactNode;
}

const SidebarSubMenuItemText = ({
children,
menuHasIcon,
iconContainerWidth
}: SidebarSubMenuItemTextProps) => (
<span
className={cx(subMenuItemText, {
[spaceMenuIcon(iconContainerWidth)]: menuHasIcon
Expand All @@ -36,14 +43,14 @@ const SidebarSubMenuItemText: React.FC<{
</span>
);

const SidebarSubMenuItem: React.FC<SidebarNavItemProps> = ({
const SidebarSubMenuItem = ({
children,
disabled,
isActive,
onClick,
openInNewTab,
url
}) => {
}: SidebarNavItemProps) => {
const theme: AppChromeTheme & { menuHasIcon: boolean } = useTheme();
const iconContainerWidth = theme.iconWidth || "s";
const sidebarBgColor = theme?.sidebarBackgroundColor
Expand Down
Loading

0 comments on commit fa57957

Please sign in to comment.