-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from brionmario/feat-app-shell
feat(react): add `AppShell` component
- Loading branch information
Showing
15 changed files
with
516 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
packages/react/src/components/AppShell/AppShell.stories.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs'; | ||
import {useArgs} from '@storybook/client-api'; | ||
import dedent from 'ts-dedent'; | ||
import StoryConfig from '../../../.storybook/story-config.ts'; | ||
import AppShell from './AppShell.tsx'; | ||
import Footer from '../Footer/Footer.tsx'; | ||
import Header from '../Header/Header.tsx'; | ||
import Navbar from '../Navbar/Navbar.tsx'; | ||
import Typography from '../Typography/Typography.tsx'; | ||
import {basicFooterVariationOptions} from '../Footer/Footer.stories.mdx'; | ||
import {basicHeaderVariationOptions} from '../Header/Header.stories.mdx'; | ||
import {ConsoleUserThickIcon, HomeFilledIcon, LockIcon, PreferencesIcon, LanguagesIcon} from '@oxygen-ui/react-icons'; | ||
|
||
export const meta = { | ||
component: AppShell, | ||
title: StoryConfig.AppShell.hierarchy, | ||
}; | ||
|
||
<Meta title={meta.title} component={meta.component} /> | ||
|
||
export const NavbarItems = [ | ||
[ | ||
{ | ||
icon: <HomeFilledIcon />, | ||
name: 'Overview', | ||
selected: true, | ||
}, | ||
{ | ||
icon: <ConsoleUserThickIcon />, | ||
name: 'Profile Info', | ||
}, | ||
{ | ||
icon: <LockIcon />, | ||
name: 'Security', | ||
}, | ||
], | ||
[ | ||
{ | ||
icon: <LanguagesIcon />, | ||
name: 'Language', | ||
}, | ||
{ | ||
icon: <PreferencesIcon />, | ||
name: 'Preferences', | ||
}, | ||
], | ||
]; | ||
|
||
export const Template = ({fill, ...rest}) => { | ||
const [runtimeArgs, updateArgs] = useArgs(); | ||
const {open} = runtimeArgs; | ||
return ( | ||
<AppShell | ||
footer={<Footer {...basicFooterVariationOptions} />} | ||
header={ | ||
<Header | ||
{...basicHeaderVariationOptions} | ||
showCollapsibleHamburger | ||
position="fixed" | ||
open={open} | ||
onCollapsibleHamburgerClick={() => updateArgs({...runtimeArgs, open: !open})} | ||
/> | ||
} | ||
navigation={<Navbar fill={fill} open={open} items={NavbarItems} />} | ||
{...rest} | ||
> | ||
<Typography paragraph> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore | ||
magna aliqua. Rhoncus dolor purus non enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus | ||
imperdiet. Semper risus in hendrerit gravida rutrum quisque non tellus. Convallis convallis tellus id interdum | ||
velit laoreet id donec ultrices. Odio morbi quis commodo odio aenean sed adipiscing. Amet nisl suscipit | ||
adipiscing bibendum est ultricies integer quis. Cursus euismod quis viverra nibh cras. Metus vulputate eu | ||
scelerisque felis imperdiet proin fermentum leo. Mauris commodo quis imperdiet massa tincidunt. Cras tincidunt | ||
lobortis feugiat vivamus at augue. At augue eget arcu dictum varius duis at consectetur lorem. Velit sed | ||
ullamcorper morbi tincidunt. Lorem donec massa sapien faucibus et molestie ac. | ||
</Typography> | ||
<Typography paragraph> | ||
Consequat mauris nunc congue nisi vitae suscipit. Fringilla est ullamcorper eget nulla facilisi etiam dignissim | ||
diam. Pulvinar elementum integer enim neque volutpat ac tincidunt. Ornare suspendisse sed nisi lacus sed viverra | ||
tellus. Purus sit amet volutpat consequat mauris. Elementum eu facilisis sed odio morbi. Euismod lacinia at quis | ||
risus sed vulputate odio. Morbi tincidunt ornare massa eget egestas purus viverra accumsan in. In hendrerit | ||
gravida rutrum quisque non tellus orci ac. Pellentesque nec nam aliquam sem et tortor. Habitant morbi tristique | ||
senectus et. Adipiscing elit duis tristique sollicitudin nibh sit. Ornare aenean euismod elementum nisi quis | ||
eleifend. Commodo viverra maecenas accumsan lacus vel facilisis. Nulla posuere sollicitudin aliquam ultrices | ||
sagittis orci a. | ||
</Typography> | ||
</AppShell> | ||
); | ||
}; | ||
|
||
# App Shell | ||
|
||
- [Overview](#overview) | ||
- [Props](#props) | ||
- [Usage](#usage) | ||
- [Variants](#variants) | ||
|
||
## Overview | ||
|
||
AppShell is a layout component that can be used to create a common Header - Navbar - Footer - Aside - Content layout | ||
pattern. | ||
|
||
<Canvas> | ||
<Story | ||
name="Overview" | ||
parameters={{ | ||
docs: {iframeHeight: 476}, | ||
}} | ||
> | ||
{Template.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
## Props | ||
|
||
<ArgsTable story="Overview" /> | ||
|
||
## Usage | ||
|
||
Import and use the `AppShell` component in your components as follows. | ||
|
||
<Source | ||
language="jsx" | ||
dark | ||
format | ||
code={dedent` | ||
import AppShell from '@oxygen-ui/react/AppShell';\n | ||
function Demo() { | ||
return ( | ||
<AppShell /> | ||
); | ||
}`} | ||
/> | ||
|
||
## Variants | ||
|
||
### Basic | ||
|
||
Basic app shell with `Header`, `Navigation` & `Footer`. | ||
|
||
<Canvas> | ||
<Story | ||
name="Basic" | ||
parameters={{ | ||
docs: {iframeHeight: 476}, | ||
}} | ||
> | ||
{Template.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
### Gradient | ||
|
||
Basic app shell with `Header`, gradient variation of `Navigation` & `Footer`. | ||
|
||
<Canvas> | ||
<Story | ||
name="Gradient" | ||
args={{fill: 'gradient'}} | ||
parameters={{ | ||
docs: {iframeHeight: 476}, | ||
}} | ||
> | ||
{Template.bind({})} | ||
</Story> | ||
</Canvas> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. licenses this file to you under the Apache License, | ||
* Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
import clsx from 'clsx'; | ||
import {FC, ReactElement, ReactNode} from 'react'; | ||
import {WithWrapperProps} from '../../models'; | ||
import {composeComponentDisplayName} from '../../utils'; | ||
import Box, {BoxProps} from '../Box'; | ||
import './app-shell.scss'; | ||
|
||
export interface AppShellProps extends BoxProps { | ||
/** | ||
* Footer component. | ||
*/ | ||
footer?: ReactNode; | ||
/** | ||
* Header component. | ||
*/ | ||
header?: ReactNode; | ||
/** | ||
* Navigation component. | ||
*/ | ||
navigation?: ReactNode; | ||
} | ||
|
||
const COMPONENT_NAME: string = 'AppShell'; | ||
|
||
const AppShell: FC<AppShellProps> & WithWrapperProps = (props: AppShellProps): ReactElement => { | ||
const {className, children, footer, header, navigation, ...rest} = props; | ||
|
||
const classes: string = clsx('oxygen-app-shell', className); | ||
|
||
return ( | ||
<Box className={classes} {...rest}> | ||
{header} | ||
<Box className="oxygen-app-shell-content"> | ||
{navigation} | ||
<Box className="oxygen-app-shell-main-wrapper"> | ||
<Box component="main" className="oxygen-app-shell-main"> | ||
{children} | ||
</Box> | ||
{footer} | ||
</Box> | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
AppShell.displayName = composeComponentDisplayName(COMPONENT_NAME); | ||
AppShell.muiName = COMPONENT_NAME; | ||
AppShell.defaultProps = {}; | ||
|
||
export default AppShell; |
32 changes: 32 additions & 0 deletions
32
packages/react/src/components/AppShell/__tests__/AppShell.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. licenses this file to you under the Apache License, | ||
* Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
import {render} from '@unit-testing'; | ||
import AppShell from '../AppShell'; | ||
|
||
describe('AppShell', () => { | ||
it('should render successfully', () => { | ||
const {baseElement} = render(<AppShell />); | ||
expect(baseElement).toBeTruthy(); | ||
}); | ||
|
||
it('should match the snapshot', () => { | ||
const {baseElement} = render(<AppShell />); | ||
expect(baseElement).toMatchSnapshot(); | ||
}); | ||
}); |
23 changes: 23 additions & 0 deletions
23
packages/react/src/components/AppShell/__tests__/__snapshots__/AppShell.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`AppShell should match the snapshot 1`] = ` | ||
<body> | ||
<div> | ||
<div | ||
class="oxygen-box oxygen-app-shell MuiBox-root css-0" | ||
> | ||
<div | ||
class="oxygen-box oxygen-app-shell-content MuiBox-root css-0" | ||
> | ||
<div | ||
class="oxygen-box oxygen-app-shell-main-wrapper MuiBox-root css-0" | ||
> | ||
<main | ||
class="oxygen-box oxygen-app-shell-main MuiBox-root css-0" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. licenses this file to you under the Apache License, | ||
* Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
.oxygen-app-shell { | ||
width: 100%; | ||
display: flex; | ||
overflow: hidden; | ||
flex-grow: 1; | ||
flex-direction: column; | ||
|
||
.oxygen-header { | ||
z-index: 1201; | ||
} | ||
|
||
.oxygen-app-shell-content { | ||
display: flex; | ||
overflow: auto; | ||
flex-grow: 1; | ||
transition: all 0.5s; | ||
|
||
.oxygen-app-shell-main-wrapper { | ||
display: flex; | ||
overflow: auto; | ||
flex-grow: 1; | ||
flex-direction: column; | ||
|
||
.oxygen-app-shell-main { | ||
flex-grow: 1; | ||
padding: var(--oxygen-customComponents-AppShell-properties-padding); | ||
margin-top: var(--oxygen-customComponents-Header-properties-min-height); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. | ||
* | ||
* WSO2 LLC. licenses this file to you under the Apache License, | ||
* Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export {default} from './AppShell'; | ||
export type {AppShellProps} from './AppShell'; |
Oops, something went wrong.