Skip to content

Commit

Permalink
Merge pull request #29 from brionmario/feat-app-shell
Browse files Browse the repository at this point in the history
feat(react): add `AppShell` component
  • Loading branch information
brionmario authored Feb 16, 2023
2 parents df54656 + 0b2fc6d commit a84290d
Show file tree
Hide file tree
Showing 15 changed files with 516 additions and 99 deletions.
4 changes: 4 additions & 0 deletions packages/react/.storybook/story-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum StorybookCategories {
export type Stories =
| 'ActionCard'
| 'AppBar'
| 'AppShell'
| 'Avatar'
| 'Badge'
| 'Box'
Expand Down Expand Up @@ -101,6 +102,9 @@ const StoryConfig: StorybookConfig = {
AppBar: {
hierarchy: `${StorybookCategories.Surfaces}/App Bar`,
},
AppShell: {
hierarchy: `${StorybookCategories.Layout}/App Shell`,
},
Avatar: {
hierarchy: `${StorybookCategories.DataDisplay}/Avatar`,
},
Expand Down
166 changes: 166 additions & 0 deletions packages/react/src/components/AppShell/AppShell.stories.mdx
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>
68 changes: 68 additions & 0 deletions packages/react/src/components/AppShell/AppShell.tsx
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 packages/react/src/components/AppShell/__tests__/AppShell.test.tsx
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();
});
});
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>
`;
49 changes: 49 additions & 0 deletions packages/react/src/components/AppShell/app-shell.scss
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);
}
}
}
}
20 changes: 20 additions & 0 deletions packages/react/src/components/AppShell/index.ts
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';
Loading

0 comments on commit a84290d

Please sign in to comment.