From 202a69510f00d7fbafff85f2a958277a51437ad8 Mon Sep 17 00:00:00 2001 From: Will McVay Date: Sat, 14 Oct 2023 11:49:47 +0100 Subject: [PATCH 1/2] feat: #9761 page heading and layout tweaks --- packages/elements/package.json | 2 +- .../src/components/grid/grid.stories.mdx | 2 +- .../src/components/layout/__styles__/index.ts | 23 +- .../__snapshots__/layout.test.tsx.snap | 77 --- .../layout/__tests__/layout.test.tsx | 20 +- .../src/components/layout/layout.stories.mdx | 294 ++++++++-- .../elements/src/components/layout/layout.tsx | 38 +- .../page-header/__styles__/index.ts | 30 +- .../__snapshots__/page-header.test.tsx.snap | 512 ++++++++++++------ .../__tests__/page-header.test.tsx | 25 + .../page-header/page-header.stories.mdx | 27 + .../components/page-header/page-header.tsx | 88 +-- .../src/components/tabs/__styles__/index.ts | 9 +- .../elements/src/components/tabs/tabs.tsx | 6 +- .../src/components/tile/tile.stories.mdx | 6 +- .../src/storybook/changelog.stories.mdx | 5 +- 16 files changed, 812 insertions(+), 352 deletions(-) diff --git a/packages/elements/package.json b/packages/elements/package.json index 9e22ff0cbf..3ad891ed8e 100644 --- a/packages/elements/package.json +++ b/packages/elements/package.json @@ -1,6 +1,6 @@ { "name": "@reapit/elements", - "version": "3.12.0", + "version": "4.0.0-beta.4", "description": "A collection of React components and utilities for building apps for Reapit Marketplace", "homepage": "https://github.com/reapit/foundations#readme", "bugs": { diff --git a/packages/elements/src/components/grid/grid.stories.mdx b/packages/elements/src/components/grid/grid.stories.mdx index b10e90e9ed..a171c98a5c 100644 --- a/packages/elements/src/components/grid/grid.stories.mdx +++ b/packages/elements/src/components/grid/grid.stories.mdx @@ -122,7 +122,7 @@ Below 1024px the grid will have a single item per column, above, the screen will ## Basic Usage - Split Screen Grid Thirds -For a sidebar and main colum view, you can use a `GridThirds` grid, with `ColSplitThird` and `ColSplitTwoThirds` grid items - this is best combined with a `PageContainerMaxWidth` - see layouts for more on this. +For a sidebar and main colum view, you can use a `GridThirds` grid, with `ColSplitThird` and `ColSplitTwoThirds` grid items - this is best combined with a `hasMaxWidth` Container - see layouts for more on this. In mobile and tablet, these columns stack then break at destop view and above. diff --git a/packages/elements/src/components/layout/__styles__/index.ts b/packages/elements/src/components/layout/__styles__/index.ts index a824959947..7dd889b79a 100644 --- a/packages/elements/src/components/layout/__styles__/index.ts +++ b/packages/elements/src/components/layout/__styles__/index.ts @@ -4,11 +4,12 @@ import { elHFull } from '../../../styles/sizing' import { css } from '@linaria/core' export const elHasGreyBackground = css`` +export const elHasMaxWidth = css`` export const ElMainContainer = styled.main` display: flex; flex-direction: column; - width: 100vw; + width: 100%; height: 100vh; overflow-y: visible; overflow-x: hidden; @@ -17,6 +18,11 @@ export const ElMainContainer = styled.main` &.${elHasGreyBackground} { background: var(--color-grey-50); } + + &.${elHasMaxWidth} { + max-width: 1200px; + margin: 0 auto; + } ` export const ElPageContainer = styled.section` @@ -29,7 +35,7 @@ export const ElPageContainer = styled.section` background-color: var(--color-white); ${isTablet} { - padding: 2rem 1.5rem; + padding: 2.5rem 1.5rem; } &.${elHFull} { @@ -39,11 +45,11 @@ export const ElPageContainer = styled.section` &.${elHasGreyBackground} { background: var(--color-grey-50); } -` -export const ElPageContainerMaxWidth = styled(ElPageContainer)` - max-width: 1200px; - margin: 0 auto; + &.${elHasMaxWidth} { + max-width: 1200px; + margin: 0 auto; + } ` export const ElSecondaryNavContainer = styled.aside` @@ -81,4 +87,9 @@ export const ElFlexContainer = styled.div` &.${elHasGreyBackground} { background: var(--color-grey-50); } + + &.${elHasMaxWidth} { + max-width: 1200px; + margin: 0 auto; + } ` diff --git a/packages/elements/src/components/layout/__tests__/__snapshots__/layout.test.tsx.snap b/packages/elements/src/components/layout/__tests__/__snapshots__/layout.test.tsx.snap index d9fc572e7c..4294a49abd 100644 --- a/packages/elements/src/components/layout/__tests__/__snapshots__/layout.test.tsx.snap +++ b/packages/elements/src/components/layout/__tests__/__snapshots__/layout.test.tsx.snap @@ -465,83 +465,6 @@ exports[`PageContainer should match a snapshot and render children 1`] = ` } `; -exports[`PageContainerMaxWidth should match a snapshot and render children 1`] = ` -{ - "asFragment": [Function], - "baseElement": -
- -

- I am child -

-
-
- , - "container":
- -

- I am child -

-
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - exports[`SecondaryNavContainer should match a snapshot and render children 1`] = ` { "asFragment": [Function], diff --git a/packages/elements/src/components/layout/__tests__/layout.test.tsx b/packages/elements/src/components/layout/__tests__/layout.test.tsx index e9ba7202b1..216d7e0ea0 100644 --- a/packages/elements/src/components/layout/__tests__/layout.test.tsx +++ b/packages/elements/src/components/layout/__tests__/layout.test.tsx @@ -1,13 +1,6 @@ import React from 'react' import { render } from '@testing-library/react' -import { - MainContainer, - PageContainer, - SecondaryNavContainer, - Molecule, - FlexContainer, - PageContainerMaxWidth, -} from '../index' +import { MainContainer, PageContainer, SecondaryNavContainer, Molecule, FlexContainer } from '../index' describe('MainContainer', () => { it('should match a snapshot and render children', () => { @@ -31,17 +24,6 @@ describe('PageContainer', () => { }) }) -describe('PageContainerMaxWidth', () => { - it('should match a snapshot and render children', () => { - const wrapper = render( - -

I am child

-
, - ) - expect(wrapper).toMatchSnapshot() - }) -}) - describe('SecondaryNavContainer', () => { it('should match a snapshot and render children', () => { const wrapper = render( diff --git a/packages/elements/src/components/layout/layout.stories.mdx b/packages/elements/src/components/layout/layout.stories.mdx index cbc756f686..ab0e0bb068 100644 --- a/packages/elements/src/components/layout/layout.stories.mdx +++ b/packages/elements/src/components/layout/layout.stories.mdx @@ -1,11 +1,12 @@ import { useState } from 'react' import { Story, Canvas, Meta, ArgsTable } from '@storybook/addon-docs' -import { MainContainer, PageContainer, SecondaryNavContainer, FlexContainer, PageContainerMaxWidth } from './index' +import { MainContainer, PageContainer, SecondaryNavContainer, FlexContainer } from './index' import { GridDemoBlock } from '../../storybook/demo-block' import { RenderHtmlMarkup } from '../../storybook/render-html-markup' import { NavStateProvider } from '../../hooks/use-nav-state' import { MediaStateProvider } from '../../hooks/use-media-query' import { SecondaryNav, SecondaryNavItem } from '../secondary-nav' +import { PageHeader } from '../page-header' import { NavResponsive } from '../nav' import { Grid, Col, ColSplitThird, ColSplitTwoThirds, GridThirds } from '../grid' @@ -88,15 +89,15 @@ The `PageContainer` should be the body of your content, it will typically contai -## PageContainerMaxWidth +## Page Container Max Width -The `PageContainerMaxWidth` should be the body of your content but maxes out at 1200px width in Desktop and is centered on the page. +The `PageContainer` should be the body of your content but maxes out at 1200px width when the `hasMaxWidth` prop is applied in Desktop and is centered on the page. - + - + @@ -108,9 +109,9 @@ All containers accept a `hasGreyBackground` prop which will add a grey backgroun - + - + @@ -168,7 +169,7 @@ These booleans map 1:1 to the flexbox helpers you can see here on [Github](https ## Combined Layout -For a complete example of how to lay out a page, see below where we have combined a number of other stories including `Nav`, `SecondaryNav` and `Grid` to give a full page layout. +For a complete example of how to lay out a page, see below where we have combined a number of other stories including `Nav`, `PageHeader`, `SecondaryNav` and `Grid` to give a full page layout. @@ -180,7 +181,33 @@ For a complete example of how to lay out a page, see below where we have combine console.log('Navigating'), + iconUrl: , + }, + { + text: 'DevPortal', + callback: () => console.log('Navigating'), + iconUrl: , + }, + ]} + avatarText="JD" + avatarOptions={[ + { + text: 'Settings', + callback: () => console.log('Navigating'), + }, + { + text: 'Profile', + callback: () => console.log('Navigating'), + }, + { + text: 'Log Out', + callback: () => console.log('Navigating'), + }, + ]} options={[ { itemIndex: 0, @@ -225,13 +252,6 @@ For a complete example of how to lay out a page, see below where we have combine href: 'https://marketplace.reapit.cloud', text: 'Marketplace', }, - { - itemIndex: 4, - callback: () => console.log('Logging out'), - iconId: 'profileMenu', - isSecondary: true, - text: 'Logout', - }, ]} /> @@ -246,6 +266,97 @@ For a complete example of how to lay out a page, see below where we have combine + console.log('Home clicked'), + }, + { + text: 'Level 1', + onClick: () => console.log('1 clicked'), + }, + { + text: 'Level 2', + onClick: () => console.log('2 clicked'), + }, + { + text: 'Level 3', + onClick: () => console.log('3 clicked'), + }, + ], + }} + avatar={{ + type: 'image', + src: 'https://picsum.photos/200/300', + }} + pageTitle={{ + children: 'Page Title', + hasBoldText: true, + }} + tags={[ + { + intent: 'primary', + children: 'Tag 1', + }, + { + intent: 'primary', + children: 'Tag 2', + }, + ]} + pageSubtitle={{ + children: 'Page Sub Title', + hasBoldText: true, + }} + pageInfo={[ + { + children: 'Page Info 1', + }, + { + children: 'Page Info 2', + }, + { + children: 'Page Info 3', + }, + ]} + buttons={[ + { + children: 'Button 1', + intent: 'default', + }, + { + children: 'Button 2', + intent: 'default', + }, + ]} + tabs={{ + name: 'my-cool-tabs-full-width', + isFullWidth: true, + hasNoBorder: true, + options: [ + { + id: 'tab-1-fw', + value: 'tab-1-fw', + text: 'Tab Content 1', + isChecked: true, + }, + { + id: 'tab-2-fw', + value: 'tab-2-fw', + text: 'Tab Content 2', + isChecked: false, + }, + { + id: 'tab-3-fw', + value: 'tab-3-fw', + text: 'Tab Content 3', + isChecked: false, + }, + ], + }} + /> @@ -299,10 +410,36 @@ Variant on the complete layout but using a max width container in desktop, a sid return ( - + console.log('Navigating'), + iconUrl: , + }, + { + text: 'DevPortal', + callback: () => console.log('Navigating'), + iconUrl: , + }, + ]} + avatarText="JD" + avatarOptions={[ + { + text: 'Settings', + callback: () => console.log('Navigating'), + }, + { + text: 'Profile', + callback: () => console.log('Navigating'), + }, + { + text: 'Log Out', + callback: () => console.log('Navigating'), + }, + ]} options={[ { itemIndex: 0, @@ -347,25 +484,112 @@ Variant on the complete layout but using a max width container in desktop, a sid href: 'https://marketplace.reapit.cloud', text: 'Marketplace', }, - { - itemIndex: 4, - callback: () => console.log('Logging out'), - iconId: 'profileMenu', - isSecondary: true, - text: 'Logout', - }, ]} /> - - - - - - - - - - + + console.log('Home clicked'), + }, + { + text: 'Level 1', + onClick: () => console.log('1 clicked'), + }, + { + text: 'Level 2', + onClick: () => console.log('2 clicked'), + }, + { + text: 'Level 3', + onClick: () => console.log('3 clicked'), + }, + ], + }} + avatar={{ + type: 'image', + src: 'https://picsum.photos/200/300', + }} + pageTitle={{ + children: 'Page Title', + hasBoldText: true, + }} + tags={[ + { + intent: 'primary', + children: 'Tag 1', + }, + { + intent: 'primary', + children: 'Tag 2', + }, + ]} + pageSubtitle={{ + children: 'Page Sub Title', + hasBoldText: true, + }} + pageInfo={[ + { + children: 'Page Info 1', + }, + { + children: 'Page Info 2', + }, + { + children: 'Page Info 3', + }, + ]} + buttons={[ + { + children: 'Button 1', + intent: 'default', + }, + { + children: 'Button 2', + intent: 'default', + }, + ]} + tabs={{ + name: 'my-cool-tabs-max-width', + isFullWidth: true, + hasNoBorder: true, + options: [ + { + id: 'tab-1-mw', + value: 'tab-1-mw', + text: 'Tab Content 1', + isChecked: true, + }, + { + id: 'tab-2-mw', + value: 'tab-2-mw', + text: 'Tab Content 2', + isChecked: false, + }, + { + id: 'tab-3-mw', + value: 'tab-3-mw', + text: 'Tab Content 3', + isChecked: false, + }, + ], + }} + /> + + + + + + + + + + + diff --git a/packages/elements/src/components/layout/layout.tsx b/packages/elements/src/components/layout/layout.tsx index bd03e715ab..3148dd1b96 100644 --- a/packages/elements/src/components/layout/layout.tsx +++ b/packages/elements/src/components/layout/layout.tsx @@ -6,8 +6,8 @@ import { ElSecondaryNavContainer, ElMolecule, ElFlexContainer, - ElPageContainerMaxWidth, elHasGreyBackground, + elHasMaxWidth, } from './__styles__' import { elFlexRow, @@ -37,6 +37,7 @@ import { useDeprecateComponent } from '../../storybook/deprecate-var' export interface ContainerProps extends HTMLAttributes { hasGreyBackground?: boolean + hasMaxWidth?: boolean } export interface ContainerFlexProps extends ContainerProps { @@ -65,26 +66,35 @@ export interface ContainerFlexProps extends ContainerProps { hasGreyBackground?: boolean } -export const MainContainer: FC = ({ children, className, hasGreyBackground, ...rest }) => ( - +export const MainContainer: FC = ({ children, className, hasGreyBackground, hasMaxWidth, ...rest }) => ( + {children} ) -export const PageContainer: FC = ({ children, className, hasGreyBackground, ...rest }) => ( - +export const PageContainer: FC = ({ children, className, hasGreyBackground, hasMaxWidth, ...rest }) => ( + {children} ) -export const PageContainerMaxWidth: FC = ({ children, className, hasGreyBackground, ...rest }) => ( - - {children} - -) - -export const SecondaryNavContainer: FC = ({ children, className, hasGreyBackground, ...rest }) => ( - +export const SecondaryNavContainer: FC = ({ + children, + className, + hasGreyBackground, + hasMaxWidth, + ...rest +}) => ( + {children} ) @@ -119,6 +129,7 @@ export const FlexContainer: FC = ({ isFlexAlignStart, isFlexAlignEnd, hasGreyBackground, + hasMaxWidth, className, ...rest }) => { @@ -146,6 +157,7 @@ export const FlexContainer: FC = ({ isFlexAlignStart && elFlexAlignStart, isFlexAlignEnd && elFlexAlignEnd, hasGreyBackground && elHasGreyBackground, + hasMaxWidth && elHasMaxWidth, className, ) diff --git a/packages/elements/src/components/page-header/__styles__/index.ts b/packages/elements/src/components/page-header/__styles__/index.ts index cdc2467c5a..e8e46579cb 100644 --- a/packages/elements/src/components/page-header/__styles__/index.ts +++ b/packages/elements/src/components/page-header/__styles__/index.ts @@ -2,12 +2,15 @@ import { styled } from '@linaria/react' import { isTablet } from '../../../styles/media' import { ElAvatar, ElAvatarImage } from '../../avatar' import { ElText2XL, ElTextBase } from '../../typography' +import { css } from '@linaria/core' const dot = `data:image/svg+xml;utf8, ` +export const elPageHeaderMaxWidth = css`` + export const ElPageHeaderContainer = styled.div` display: flex; flex-direction: column; @@ -20,6 +23,7 @@ export const ElPageHeaderContainer = styled.div` ${isTablet} { flex-direction: row; justify-content: space-between; + margin-bottom: 1.25rem; ${ElTextBase} { margin-bottom: 0; @@ -47,10 +51,31 @@ export const ElPageHeaderTitleContainer = styled.div` } ` +export const ElPageHeaderWrapInner = styled.div` + width: 100%; + height: 100%; + padding: 0.5rem 0 0 0; + + &.${elPageHeaderMaxWidth} { + max-width: 1200px; + margin: 0 auto; + } + + ${isTablet} { + padding: 2.5rem 1.5rem 0 1.5rem; + } +` + export const ElPageHeaderWrap = styled.div` width: 100%; display: flex; flex-direction: column; + background-color: var(--color-white); + width: calc(100% + 2.5rem); + translate: -1.25rem -0.5rem; + padding: 0 1.25rem; + border-bottom: 1px solid var(--color-grey-100); + margin-bottom: 0.5rem; ${ElAvatarImage} { border-radius: 0.25rem; @@ -61,7 +86,10 @@ export const ElPageHeaderWrap = styled.div` } ${isTablet} { - padding: 0 1rem; + padding: 0; + margin-bottom: 0; + width: calc(100% + 3rem); + translate: -1.5rem -2.5rem; ${ElAvatar} { width: 48px; diff --git a/packages/elements/src/components/page-header/__tests__/__snapshots__/page-header.test.tsx.snap b/packages/elements/src/components/page-header/__tests__/__snapshots__/page-header.test.tsx.snap index 0511a5b51a..f7cdd4c128 100644 --- a/packages/elements/src/components/page-header/__tests__/__snapshots__/page-header.test.tsx.snap +++ b/packages/elements/src/components/page-header/__tests__/__snapshots__/page-header.test.tsx.snap @@ -5,6 +5,284 @@ exports[`PageHeader component should match a snapshot 1`] = ` "asFragment": [Function], "baseElement":
+ + + + + + Home + + + + + + + + Level 1 + + + + + + + + Level 2 + + + + + + + + Level 3 + + + + + + + https://picsum.photos/200/300 + + + + + Page Title + + + + + Tag 1 + + + Tag 2 + + + + + + Page Sub Title + + + + Page Info 1 + + + + Page Info 2 + + + + Page Info 3 + + + + + + + + + Button 1 + + + + Button 2 + + + + + + + + + + Tab Content 1 + + + + + + Tab Content 2 + + + + + + Tab Content 3 + + + + + + + +
+ , + "container":
+ @@ -173,176 +451,104 @@ exports[`PageHeader component should match a snapshot 1`] = ` - -
- , - "container":
- - - Home - - - + + - - + Tab Content 1 + + + - - - Level 1 - - - + - - + Tab Content 2 + + + - - - Level 2 - - - + - - - - - Level 3 + > + Tab Content 3 + + - - - - - - https://picsum.photos/200/300 - - - - Page Title - - - - - Tag 1 - - - Tag 2 - - - - - - Page Sub Title - - - - Page Info 1 - - - - Page Info 2 - - - - Page Info 3 - - - - - - - - - Button 1 - - - - Button 2 - - + /> diff --git a/packages/elements/src/components/page-header/__tests__/page-header.test.tsx b/packages/elements/src/components/page-header/__tests__/page-header.test.tsx index f3b31fa535..9b4c9e89f3 100644 --- a/packages/elements/src/components/page-header/__tests__/page-header.test.tsx +++ b/packages/elements/src/components/page-header/__tests__/page-header.test.tsx @@ -70,6 +70,31 @@ describe('PageHeader component', () => { intent: 'default', }, ]} + tabs={{ + name: 'my-cool-tabs-full-width', + isFullWidth: true, + hasNoBorder: true, + options: [ + { + id: 'tab-1-fw', + value: 'tab-1-fw', + text: 'Tab Content 1', + isChecked: true, + }, + { + id: 'tab-2-fw', + value: 'tab-2-fw', + text: 'Tab Content 2', + isChecked: false, + }, + { + id: 'tab-3-fw', + value: 'tab-3-fw', + text: 'Tab Content 3', + isChecked: false, + }, + ], + }} />, ) expect(wrapper).toMatchSnapshot() diff --git a/packages/elements/src/components/page-header/page-header.stories.mdx b/packages/elements/src/components/page-header/page-header.stories.mdx index 37db98e80c..34c96dc55a 100644 --- a/packages/elements/src/components/page-header/page-header.stories.mdx +++ b/packages/elements/src/components/page-header/page-header.stories.mdx @@ -8,6 +8,8 @@ import { RenderHtmlMarkup } from '../../storybook/render-html-markup' Really a collecation of previously defined components, but exported as a React shorthand for a best practice pattern to display at the top of each page. Should always sit within a `PageContainer` see layout for more details. +If you want the page header to have a max width and center on the page in desktop, add the `hasMaxWidth` prop to the `PageHeader` component. + All props are optional, with the exception of `pageTitle` - see the individual component docs for more information on the available options however, we advise sticking largely to the template below. @@ -81,6 +83,31 @@ All props are optional, with the exception of `pageTitle` - see the individual c intent: 'default', }, ]} + tabs={{ + name: 'my-cool-tabs-full-width', + isFullWidth: true, + hasNoBorder: true, + options: [ + { + id: 'tab-1-fw', + value: 'tab-1-fw', + text: 'Tab Content 1', + isChecked: true, + }, + { + id: 'tab-2-fw', + value: 'tab-2-fw', + text: 'Tab Content 2', + isChecked: false, + }, + { + id: 'tab-3-fw', + value: 'tab-3-fw', + text: 'Tab Content 3', + isChecked: false, + }, + ], + }} /> diff --git a/packages/elements/src/components/page-header/page-header.tsx b/packages/elements/src/components/page-header/page-header.tsx index d721cc67f2..cb6ae8707c 100644 --- a/packages/elements/src/components/page-header/page-header.tsx +++ b/packages/elements/src/components/page-header/page-header.tsx @@ -5,6 +5,8 @@ import { ElPageHeaderSeparator, ElPageHeaderTitleContainer, ElPageHeaderWrap, + ElPageHeaderWrapInner, + elPageHeaderMaxWidth, } from './__styles__' import { Text2XL, TextL, TextBase, TypographyProps } from '../typography' import { FlexContainer } from '../layout' @@ -13,6 +15,7 @@ import { Tag, TagGroup, TagProps } from '../tag' import { Button, ButtonGroup, ButtonProps } from '../button' import { BreadCrumb, BreadCrumbProps } from '../breadcrumb' import { elMb6, elMr3 } from '../../styles/spacing' +import { Tabs, TabsProps } from '../tabs' export interface PageHeaderProps extends HTMLAttributes { avatar?: AvatarProps @@ -22,6 +25,8 @@ export interface PageHeaderProps extends HTMLAttributes { breadcrumb?: BreadCrumbProps tags?: TagProps[] buttons?: ButtonProps[] + tabs?: TabsProps + hasMaxWidth?: boolean } export const PageHeaderWrap: FC> = ({ children, className, ...rest }) => ( @@ -30,6 +35,12 @@ export const PageHeaderWrap: FC> = ({ children, c ) +export const PageHeaderWrapInner: FC> = ({ children, className, ...rest }) => ( + + {children} + +) + export const PageHeaderContainer: FC> = ({ children, className, ...rest }) => ( {children} @@ -50,50 +61,55 @@ export const PageHeader: FC = ({ breadcrumb, tags, buttons, + tabs, + hasMaxWidth, ...rest }) => { return ( - {breadcrumb && } - + + {breadcrumb && } - {avatar && } - - - {pageTitle && } - {tags && ( - - {tags.map(({ children, ...rest }, index) => ( - - {children} - + + {avatar && } + + + {pageTitle && } + {tags && ( + + {tags.map(({ children, ...rest }, index) => ( + + {children} + + ))} + + )} + + {pageSubtitle && } + {pageInfo && ( + + {pageInfo.map(({ ...rest }, index) => ( + + + {index !== pageInfo.length - 1 && } + ))} - + )} - - {pageSubtitle && } - {pageInfo && ( - - {pageInfo.map(({ ...rest }, index) => ( - - - {index !== pageInfo.length - 1 && } - - ))} - - )} - + + + {buttons && ( + + {buttons.map(({ children, ...rest }, index) => ( + + ))} + + )} - {buttons && ( - - {buttons.map(({ children, ...rest }, index) => ( - - ))} - - )} - + {tabs && } + ) } diff --git a/packages/elements/src/components/tabs/__styles__/index.ts b/packages/elements/src/components/tabs/__styles__/index.ts index f734b79c0e..568261aa18 100644 --- a/packages/elements/src/components/tabs/__styles__/index.ts +++ b/packages/elements/src/components/tabs/__styles__/index.ts @@ -21,6 +21,8 @@ export const elTabsFullWidth = css` justify-content: space-evenly; ` +export const elTabsHasNoBorder = css`` + export const ElTabs = styled.input` height: 0; width: 0; @@ -62,9 +64,8 @@ export const ElTabsWrap = styled.div` display: flex; flex-direction: column; background: var(--color-white); - border-radius: 1rem; + /* border-radius: 1rem; */ overflow: hidden; - padding: 0.25rem 0; width: fit-content; align-items: flex-start; height: auto; @@ -93,4 +94,8 @@ export const ElTabsFooter = styled.div` &.${elTabsFullWidth} { width: 100%; } + + &.${elTabsHasNoBorder} { + display: none; + } ` diff --git a/packages/elements/src/components/tabs/tabs.tsx b/packages/elements/src/components/tabs/tabs.tsx index e6010f09a8..3b71f9df00 100644 --- a/packages/elements/src/components/tabs/tabs.tsx +++ b/packages/elements/src/components/tabs/tabs.tsx @@ -2,6 +2,7 @@ import React, { FC, Fragment, HTMLAttributes } from 'react' import { cx } from '@linaria/core' import { elTabsFullWidth, + elTabsHasNoBorder, ElTabs, elTabsItem, ElTabsLabel, @@ -21,9 +22,10 @@ export interface TabsProps extends HTMLAttributes { options: TabsOption[] name: string isFullWidth?: boolean + hasNoBorder?: boolean } -export const Tabs: FC = ({ className, isFullWidth, name, options, ...rest }) => { +export const Tabs: FC = ({ className, isFullWidth, hasNoBorder, name, options, ...rest }) => { return ( @@ -36,7 +38,7 @@ export const Tabs: FC = ({ className, isFullWidth, name, options, ... ))} - + ) } diff --git a/packages/elements/src/components/tile/tile.stories.mdx b/packages/elements/src/components/tile/tile.stories.mdx index 2cff7a86a4..7f6780beef 100644 --- a/packages/elements/src/components/tile/tile.stories.mdx +++ b/packages/elements/src/components/tile/tile.stories.mdx @@ -1,6 +1,6 @@ import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs' import { Tile } from './' -import { PageContainerMaxWidth } from '../layout' +import { PageContainer } from '../layout' import { Grid, Col, ColSplitThird, ColSplitTwoThirds, GridThirds } from '../grid' import { elMb7 } from '../../styles/spacing' import { RenderHtmlMarkup } from './../../storybook/render-html-markup' @@ -41,7 +41,7 @@ The below illustration shows two kinds of tile layouts with different grids to g - + Some Content Here @@ -70,7 +70,7 @@ The below illustration shows two kinds of tile layouts with different grids to g Some Content Here - + diff --git a/packages/elements/src/storybook/changelog.stories.mdx b/packages/elements/src/storybook/changelog.stories.mdx index 6209096f13..7093ca3ed0 100644 --- a/packages/elements/src/storybook/changelog.stories.mdx +++ b/packages/elements/src/storybook/changelog.stories.mdx @@ -52,10 +52,9 @@ No functions, CSS classes or React props have been removed however, many have be - `Tag` - visual indicator tag to alert users to status of actions or items. - `Badge` - low impact visual indicator. - `Chip` - like a standalone version of `MultiSelct`, a checkbox chip for toggling state or filters. -- `PageContainerMaxWidth` - when not using a `SecondaryNav` it may be desireable to restrict the max width of the desktop page. This container fulfils this requirement - see layout docs for more info. -- `Grid` - adds `GridThirds`, `ColSplitThird` && `ColSplitTwoThirds` components to allow for side bar and main content layouts. See above, best paired with a `PageContainerMaxWidth` view. +- `ContainerProps` and `ContainerFlexProps` now support both `hasGreyBackground` and `hasMaxWidth` modifiers to support white tile on grey background UIs. Also, when not using a `SecondaryNav` it may be desireable to restrict the max width of the desktop page. This container prop fulfils this requirement - see layout docs for more info. See `Layout` stories for more detail. +- `Grid` - adds `GridThirds`, `ColSplitThird` && `ColSplitTwoThirds` components to allow for side bar and main content layouts. See above, best paired with a `hasMaxWidth` container. - `Grid` - adds `ColHalf` and `ColQuarter` components to allow for more flexible granular layouts. -- `ContainerProps` and `ContainerFlexProps` now support a `hasGreyBackground` modifier to support white tile on grey background UIs. See `Layout` stories for more detail. - `Tile` component added as an alternative to `Card` for laying out page sections. Works in conjunction with new container and grid items above. - `Typography` extended with a much larger range of text sizes, addtional modifiers and supports the concept of intent across all text options. - `Avatar` component added to support user profile images in `Card`, `Nav` and `Table` components. Has an image variant to allow property images and similar in thumbnails. From b66449a3f4c7aa42fe68b952a1746243c198d3a6 Mon Sep 17 00:00:00 2001 From: Will McVay Date: Sat, 14 Oct 2023 11:56:23 +0100 Subject: [PATCH 2/2] feat: #9761 page heading and layout tweaks --- packages/elements/src/components/tabs/__styles__/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/elements/src/components/tabs/__styles__/index.ts b/packages/elements/src/components/tabs/__styles__/index.ts index 568261aa18..18ad185341 100644 --- a/packages/elements/src/components/tabs/__styles__/index.ts +++ b/packages/elements/src/components/tabs/__styles__/index.ts @@ -64,7 +64,6 @@ export const ElTabsWrap = styled.div` display: flex; flex-direction: column; background: var(--color-white); - /* border-radius: 1rem; */ overflow: hidden; width: fit-content; align-items: flex-start;