diff --git a/docs/migration.md b/docs/migration.md
index 7bbed356f40..448a6f0f992 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -44,6 +44,20 @@ consider additional positioning prop support on a case-by-case basis.
#### @zendeskgarden/react-chrome
- Removed `PRODUCT` type export. Use `IHeaderItemProps['product']` instead.
+- Renamed `ICollapsibleSubNavItemProps` type export to `ISubNavCollapsibleItemProps`.
+- Subcomponent exports have been deprecated and will be removed in a future major version. Update
+ to subcomponent properties:
+ - `FooterItem` -> `Footer.Item`
+ - `HeaderItem` -> `Header.Item`
+ - `HeaderItemIcon` -> `Header.ItemIcon`
+ - `HeaderItemText` -> `Header.ItemText`
+ - `HeaderItemWrapper` -> `Header.ItemWrapper`
+ - `NavItem` -> `Nav.Item`
+ - `NavItemIcon` -> `Nav.ItemIcon`
+ - `NavItemText` -> `Nav.ItemText`
+ - `CollapsibleSubNavItem` -> `SubNav.CollapsibleItem`
+ - `SubNavItem` -> `SubNav.Item`
+ - `SubNavItemText` -> `SubNav.ItemText`
#### @zendeskgarden/react-colorpickers
diff --git a/packages/chrome/README.md b/packages/chrome/README.md
index 974f1480668..bb297d81503 100644
--- a/packages/chrome/README.md
+++ b/packages/chrome/README.md
@@ -15,41 +15,37 @@ npm install react react-dom styled-components @zendeskgarden/react-theming
```jsx
import { ThemeProvider } from '@zendeskgarden/react-theming';
-import { Chrome, Nav, NavItem, ... } from '@zendeskgarden/react-chrome';
+import { Chrome, Nav, SubNav, Body, Header, Content, Main } from '@zendeskgarden/react-chrome';
import ConnectIcon from '@zendeskgarden/icons/src/26/relationshape-connect.svg';
-
- Subnav 1
-
+
+ Subnav 1
+
...
-
+
-
- Lorem ipsum...
-
+ Lorem ipsum...
-
+;
```
diff --git a/packages/chrome/demo/chrome.stories.mdx b/packages/chrome/demo/chrome.stories.mdx
index 9e98b769a23..cd52bb14a27 100644
--- a/packages/chrome/demo/chrome.stories.mdx
+++ b/packages/chrome/demo/chrome.stories.mdx
@@ -1,28 +1,17 @@
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
import { useArgs } from '@storybook/client-api';
import {
- Chrome,
- CollapsibleSubNavItem,
Body,
+ Chrome,
Content,
Footer,
- FooterItem,
Header,
- HeaderItem,
- HeaderItemIcon,
- HeaderItemText,
- HeaderItemWrapper,
Main,
Nav,
- NavItem,
- NavItemIcon,
- NavItemText,
Sheet,
Sidebar,
SkipNav,
SubNav,
- SubNavItem,
- SubNavItemText,
PRODUCTS
} from '@zendeskgarden/react-chrome';
import { ChromeStory } from './stories/ChromeStory';
@@ -44,27 +33,27 @@ import README from '../README.md';
title="Packages/Chrome/Chrome"
component={Chrome}
subcomponents={{
- CollapsibleSubNavItem,
Body,
Content,
Footer,
- FooterItem,
+ 'Footer.Item': Footer.Item,
Header,
- HeaderItem,
- HeaderItemIcon,
- HeaderItemText,
- HeaderItemWrapper,
+ 'Item.HeaderItem': Header.Item,
+ 'Item.HeaderItemIcon': Header.ItemIcon,
+ 'Item.HeaderItemText': Header.ItemText,
+ 'Item.HeaderItemWrapper': Header.ItemWrapper,
Main,
Nav,
- NavItem,
- NavItemIcon,
- NavItemText,
+ 'Nav.Item': Nav.Item,
+ 'Nav.ItemIcon': Nav.ItemIcon,
+ 'Nav.ItemText': Nav.ItemText,
Sheet,
Sidebar,
SkipNav,
SubNav,
- SubNavItem,
- SubNavItemText
+ 'SubNav.CollapsibleItem': SubNav.CollapsibleItem,
+ 'SubNav.Item': SubNav.Item,
+ 'SubNav.ItemText': SubNav.ItemText
}}
/>
@@ -108,17 +97,17 @@ import README from '../README.md';
isExpanded: { name: 'Nav isExpanded', table: { category: 'Story' } },
isWrapped: { name: 'Nav/SubNav isWrapped', table: { category: 'Story' } },
hasNav: { name: 'Nav', table: { category: 'Story' } },
- navItems: { name: 'NavItem[]', table: { category: 'Story' } },
+ navItems: { name: 'Nav.Item[]', table: { category: 'Story' } },
hasLogo: { name: 'Nav hasLogo', table: { category: 'Story' } },
hasBrandmark: { name: 'Nav hasBrandmark', table: { category: 'Story' } },
hasSubNav: { name: 'SubNav', table: { category: 'Story' } },
- subNavItems: { name: 'SubNavItem[]', table: { category: 'Story' } },
+ subNavItems: { name: 'SubNav.Item[]', table: { category: 'Story' } },
subNavMaxWidth: { name: 'SubNav max-width', control: 'number', table: { category: 'Story' } },
hasHeader: { name: 'Header', table: { category: 'Story' } },
- headerItems: { name: 'HeaderItem[]', table: { category: 'Story' } },
+ headerItems: { name: 'Header.Item[]', table: { category: 'Story' } },
hasSidebar: { name: 'Sidebar', table: { category: 'Story' } },
hasFooter: { name: 'Footer', table: { category: 'Story' } },
- footerItems: { name: 'FooterItem[]', table: { category: 'Story' } },
+ footerItems: { name: 'Footer.Item[]', table: { category: 'Story' } },
product: {
name: 'Nav product',
control: { type: 'select', options: PRODUCTS },
diff --git a/packages/chrome/demo/stories/ChromeStory.tsx b/packages/chrome/demo/stories/ChromeStory.tsx
index 38c5178b1ae..17d9af6be0e 100644
--- a/packages/chrome/demo/stories/ChromeStory.tsx
+++ b/packages/chrome/demo/stories/ChromeStory.tsx
@@ -32,27 +32,16 @@ import { DEFAULT_THEME } from '@zendeskgarden/react-theming';
import {
Body,
Chrome,
- CollapsibleSubNavItem,
Content,
Footer,
- FooterItem,
Header,
- HeaderItem,
- HeaderItemIcon,
- HeaderItemText,
- HeaderItemWrapper,
IChromeProps,
INavItemProps,
Main,
Nav,
- NavItem,
- NavItemIcon,
- NavItemText,
Sidebar,
SkipNav,
- SubNav,
- SubNavItem,
- SubNavItemText
+ SubNav
} from '@zendeskgarden/react-chrome';
import { Button } from '@zendeskgarden/react-buttons';
import { IFooterItem, IHeaderItem, INavItem, ISubNavItem } from './types';
@@ -150,13 +139,13 @@ export const ChromeStory: Story = ({
{hasNav && (
)}
@@ -183,25 +172,25 @@ export const ChromeStory: Story = ({
{subNavItems.map((item, index) =>
item.items ? (
-
+
{item.items.map((subItem, subIndex) => (
- setCurrentSubNav(parseFloat(`${index}.${subIndex}`))}
>
- {subItem}
-
+ {subItem}
+
))}
-
+
) : (
- setCurrentSubNav(index)}
>
- {item.text}
-
+ {item.text}
+
)
)}
@@ -210,41 +199,41 @@ export const ChromeStory: Story = ({
{hasHeader && (
{hasLogo && (
-
-
+
+
-
- Header Logo
-
+
+ Header Logo
+
)}
{headerItems.map((item, index) =>
item.isWrapper ? (
-
{item.hasIcon && (
-
+
{HEADER_ICONS[HEADER_ICONS.length - headerItems.length + index] || (
)}
-
+
)}
- {item.text}
-
+ {item.text}
+
) : (
-
+
{item.hasIcon && (
-
+
{HEADER_ICONS[HEADER_ICONS.length - headerItems.length + index] || (
)}
-
+
)}
- {item.text}
-
+ {item.text}
+
)
)}
@@ -271,11 +260,11 @@ export const ChromeStory: Story = ({
)}
diff --git a/packages/chrome/demo/stories/CollapsibleSubNavItemStory.tsx b/packages/chrome/demo/stories/SubNavCollapsibleItem.tsx
similarity index 68%
rename from packages/chrome/demo/stories/CollapsibleSubNavItemStory.tsx
rename to packages/chrome/demo/stories/SubNavCollapsibleItem.tsx
index 1dd0fa654af..7c3af150362 100644
--- a/packages/chrome/demo/stories/CollapsibleSubNavItemStory.tsx
+++ b/packages/chrome/demo/stories/SubNavCollapsibleItem.tsx
@@ -6,37 +6,33 @@
*/
import React, { useState } from 'react';
-import { Story } from '@storybook/react';
+import { StoryFn } from '@storybook/react';
import { Col, Grid, Row } from '@zendeskgarden/react-grid';
-import {
- CollapsibleSubNavItem,
- ICollapsibleSubNavItemProps,
- SubNavItem
-} from '@zendeskgarden/react-chrome';
+import { SubNav, ICollapsibleSubNavItemProps } from '@zendeskgarden/react-chrome';
import { COLLAPSIBLE_SUB_NAV_ITEM } from './types';
interface IArgs extends ICollapsibleSubNavItemProps {
items: COLLAPSIBLE_SUB_NAV_ITEM[];
}
-export const CollapsibleSubNavItemStory: Story = ({ items, ...args }) => {
+export const SubNavCollapsibleItem: StoryFn = ({ items, ...args }) => {
const [current, setCurrent] = useState();
return (
-
+
{items.map((item, index) => (
- setCurrent(index)}
>
{item}
-
+
))}
-
+
diff --git a/packages/chrome/demo/collapsibleSubNavItem.stories.mdx b/packages/chrome/demo/subNavCollapsibleItem.stories.mdx
similarity index 73%
rename from packages/chrome/demo/collapsibleSubNavItem.stories.mdx
rename to packages/chrome/demo/subNavCollapsibleItem.stories.mdx
index afa5a507703..b82c61ad3a0 100644
--- a/packages/chrome/demo/collapsibleSubNavItem.stories.mdx
+++ b/packages/chrome/demo/subNavCollapsibleItem.stories.mdx
@@ -1,11 +1,11 @@
import { Meta, ArgsTable, Canvas, Story, Markdown } from '@storybook/addon-docs';
import { useArgs } from '@storybook/client-api';
import { CollapsibleSubNavItem } from '@zendeskgarden/react-chrome';
-import { CollapsibleSubNavItemStory } from './stories/CollapsibleSubNavItemStory';
+import { SubNavCollapsibleItem } from './stories/SubNavCollapsibleItem';
import { COLLAPSIBLE_SUB_NAV_ITEMS as ITEMS } from './stories/data';
import README from '../README.md';
-
+
# API
@@ -21,7 +21,7 @@ import README from '../README.md';
args={{ header: 'Header', items: ITEMS }}
argTypes={{ items: { name: 'children' }, isExpanded: { control: false } }}
>
- {({ onChange, ...args }) => }
+ {({ onChange, ...args }) => }
@@ -36,7 +36,7 @@ import README from '../README.md';
{args => {
const updateArgs = useArgs()[1];
const handleChange = () => updateArgs({ isExpanded: !args.isExpanded });
- return ;
+ return ;
}}
diff --git a/packages/chrome/src/elements/footer/Footer.tsx b/packages/chrome/src/elements/footer/Footer.tsx
index 1bd456e0752..87c13745748 100644
--- a/packages/chrome/src/elements/footer/Footer.tsx
+++ b/packages/chrome/src/elements/footer/Footer.tsx
@@ -7,12 +7,22 @@
import React, { HTMLAttributes } from 'react';
import { StyledFooter } from '../../styled';
+import { FooterItem } from './FooterItem';
/**
* @extends HTMLAttributes
*/
-export const Footer = React.forwardRef>((props, ref) => (
-
-));
+export const FooterComponent = React.forwardRef>(
+ (props, ref) =>
+);
-Footer.displayName = 'Footer';
+FooterComponent.displayName = 'Footer';
+
+/**
+ * @extends HTMLAttributes
+ */
+export const Footer = FooterComponent as typeof FooterComponent & {
+ Item: typeof FooterItem;
+};
+
+Footer.Item = FooterItem;
diff --git a/packages/chrome/src/elements/header/Header.tsx b/packages/chrome/src/elements/header/Header.tsx
index 7478a42b3f9..1c01ed5e0cf 100644
--- a/packages/chrome/src/elements/header/Header.tsx
+++ b/packages/chrome/src/elements/header/Header.tsx
@@ -9,16 +9,32 @@ import React from 'react';
import PropTypes from 'prop-types';
import { IHeaderProps } from '../../types';
import { StyledHeader } from '../../styled';
+import { HeaderItem } from './HeaderItem';
+import { HeaderItemIcon } from './HeaderItemIcon';
+import { HeaderItemText } from './HeaderItemText';
+import { HeaderItemWrapper } from './HeaderItemWrapper';
-/**
- * @extends HTMLAttributes
- */
-export const Header = React.forwardRef((props, ref) => (
+export const HeaderComponent = React.forwardRef((props, ref) => (
));
-Header.displayName = 'Header';
+HeaderComponent.displayName = 'Header';
-Header.propTypes = {
+HeaderComponent.propTypes = {
isStandalone: PropTypes.bool
};
+
+/**
+ * @extends HTMLAttributes
+ */
+export const Header = HeaderComponent as typeof HeaderComponent & {
+ Item: typeof HeaderItem;
+ ItemIcon: typeof HeaderItemIcon;
+ ItemText: typeof HeaderItemText;
+ ItemWrapper: typeof HeaderItemWrapper;
+};
+
+Header.Item = HeaderItem;
+Header.ItemIcon = HeaderItemIcon;
+Header.ItemText = HeaderItemText;
+Header.ItemWrapper = HeaderItemWrapper;
diff --git a/packages/chrome/src/elements/nav/Nav.tsx b/packages/chrome/src/elements/nav/Nav.tsx
index a4c58113d6d..b3e5bc1e054 100644
--- a/packages/chrome/src/elements/nav/Nav.tsx
+++ b/packages/chrome/src/elements/nav/Nav.tsx
@@ -11,11 +11,11 @@ import { INavProps } from '../../types';
import { useChromeContext } from '../../utils/useChromeContext';
import { NavContext } from '../../utils/useNavContext';
import { StyledNav } from '../../styled';
+import { NavItem } from './NavItem';
+import { NavItemIcon } from './NavItemIcon';
+import { NavItemText } from './NavItemText';
-/**
- * @extends HTMLAttributes
- */
-export const Nav = React.forwardRef((props, ref) => {
+export const NavComponent = React.forwardRef((props, ref) => {
const { hue, isLight, isDark } = useChromeContext();
const navContextValue = useMemo(() => ({ isExpanded: !!props.isExpanded }), [props.isExpanded]);
@@ -26,8 +26,21 @@ export const Nav = React.forwardRef((props, ref) => {
);
});
-Nav.displayName = 'Nav';
+NavComponent.displayName = 'Nav';
-Nav.propTypes = {
+NavComponent.propTypes = {
isExpanded: PropTypes.bool
};
+
+/**
+ * @extends HTMLAttributes
+ */
+export const Nav = NavComponent as typeof NavComponent & {
+ Item: typeof NavItem;
+ ItemIcon: typeof NavItemIcon;
+ ItemText: typeof NavItemText;
+};
+
+Nav.Item = NavItem;
+Nav.ItemIcon = NavItemIcon;
+Nav.ItemText = NavItemText;
diff --git a/packages/chrome/src/elements/subnav/SubNav.tsx b/packages/chrome/src/elements/subnav/SubNav.tsx
index fcc2280c6a8..f0b3ff0c36d 100644
--- a/packages/chrome/src/elements/subnav/SubNav.tsx
+++ b/packages/chrome/src/elements/subnav/SubNav.tsx
@@ -8,14 +8,29 @@
import React, { HTMLAttributes } from 'react';
import { StyledSubNav } from '../../styled';
import { useChromeContext } from '../../utils/useChromeContext';
+import { SubNavItem } from './SubNavItem';
+import { SubNavItemText } from './SubNavItemText';
+import { CollapsibleSubNavItem } from './CollapsibleSubNavItem';
+
+export const SubNavComponent = React.forwardRef>(
+ (props, ref) => {
+ const { hue, isLight, isDark } = useChromeContext();
+
+ return ;
+ }
+);
+
+SubNavComponent.displayName = 'SubNav';
/**
* @extends HTMLAttributes
*/
-export const SubNav = React.forwardRef>((props, ref) => {
- const { hue, isLight, isDark } = useChromeContext();
-
- return ;
-});
+export const SubNav = SubNavComponent as typeof SubNavComponent & {
+ Item: typeof SubNavItem;
+ ItemText: typeof SubNavItemText;
+ CollapsibleItem: typeof CollapsibleSubNavItem;
+};
-SubNav.displayName = 'SubNav';
+SubNav.Item = SubNavItem;
+SubNav.ItemText = SubNavItemText;
+SubNav.CollapsibleItem = CollapsibleSubNavItem;
diff --git a/packages/chrome/src/index.ts b/packages/chrome/src/index.ts
index 229ff7a0e87..23fb88e88f6 100644
--- a/packages/chrome/src/index.ts
+++ b/packages/chrome/src/index.ts
@@ -5,27 +5,39 @@
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/
-export { Chrome } from './elements/Chrome';
-export { SkipNav } from './elements/SkipNav';
-export { Body } from './elements/body/Body';
-export { Content } from './elements/body/Content';
-export { Main } from './elements/body/Main';
-export { Sidebar } from './elements/body/Sidebar';
-export { Header } from './elements/header/Header';
+/** @deprecated use `Header.Item` instead */
export { HeaderItem } from './elements/header/HeaderItem';
+/** @deprecated use `Header.ItemIcon` instead */
export { HeaderItemIcon } from './elements/header/HeaderItemIcon';
+/** @deprecated use `Header.ItemText` instead */
export { HeaderItemText } from './elements/header/HeaderItemText';
+/** @deprecated use `Header.ItemWrapper` instead */
export { HeaderItemWrapper } from './elements/header/HeaderItemWrapper';
-export { Footer } from './elements/footer/Footer';
+/** @deprecated use `Footer.Item` instead */
export { FooterItem } from './elements/footer/FooterItem';
-export { Nav } from './elements/nav/Nav';
+/** @deprecated use `Nav.Item` instead */
export { NavItem } from './elements/nav/NavItem';
+/** @deprecated use `Nav.ItemIcon` instead */
export { NavItemIcon } from './elements/nav/NavItemIcon';
+/** @deprecated use `Nav.ItemText` instead */
export { NavItemText } from './elements/nav/NavItemText';
-export { SubNav } from './elements/subnav/SubNav';
+/** @deprecated use `SubNav.Item` instead */
export { SubNavItem } from './elements/subnav/SubNavItem';
+/** @deprecated use `SubNav.ItemText` instead */
export { SubNavItemText } from './elements/subnav/SubNavItemText';
+/** @deprecated use `SubNav.CollapsibleItem` instead */
export { CollapsibleSubNavItem } from './elements/subnav/CollapsibleSubNavItem';
+
+export { Chrome } from './elements/Chrome';
+export { SkipNav } from './elements/SkipNav';
+export { Body } from './elements/body/Body';
+export { Content } from './elements/body/Content';
+export { Main } from './elements/body/Main';
+export { Sidebar } from './elements/body/Sidebar';
+export { Header } from './elements/header/Header';
+export { Footer } from './elements/footer/Footer';
+export { Nav } from './elements/nav/Nav';
+export { SubNav } from './elements/subnav/SubNav';
export { Sheet } from './elements/sheet/Sheet';
export {