Skip to content

Commit

Permalink
feat(react): add Popover component
Browse files Browse the repository at this point in the history
  • Loading branch information
brionmario committed Aug 4, 2023
1 parent 45779cc commit 42125d2
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/react/.storybook/story-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum StorybookCategories {
Theme = 'Theme',
Typography = 'Typography',
Surfaces = 'Surfaces',
Utils = 'Utils'
}

export type Stories =
Expand Down Expand Up @@ -93,6 +94,7 @@ export type Stories =
| 'NavbarItem'
| 'OutlinedInput'
| 'Paper'
| 'Popover'
| 'PhoneNumberInput'
| 'Radio'
| 'RadioGroup'
Expand Down Expand Up @@ -318,6 +320,9 @@ const StoryConfig: StorybookConfig = {
PhoneNumberInput: {
hierarchy: `${StorybookCategories.Inputs}/Phone Number Input`,
},
Popover: {
hierarchy: `${StorybookCategories.Utils}/Popover`,
},
Radio: {
hierarchy: `${StorybookCategories.ComponentAPI}/Radio`,
},
Expand Down
84 changes: 84 additions & 0 deletions packages/react/src/components/Popover/Popover.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs';
import dedent from 'ts-dedent';
import StoryConfig from '../../../.storybook/story-config.ts';
import Button from '../Button/Button.tsx';
import Typography from '../Typography/Typography.tsx';
import Popover from './Popover.tsx';
import {useArgs} from '@storybook/client-api';

export const meta = {
component: Popover,
title: StoryConfig.Popover.hierarchy,
};

<Meta title={meta.title} component={meta.component} />

export const Template = args => {
const [runtimeArgs, updateArgs] = useArgs();
const id = 'simple-popover';
const handleClick = (event) => {
updateArgs({
open: !runtimeArgs.open,
anchorEl: event.currentTarget
});
};
const handleClose = () => {
updateArgs({
open: false,
anchorEl: null
})
};
return (
<div>
<Button aria-describedby={id} variant="contained" onClick={handleClick}>
Open Popover
</Button>
<Popover
id={id}
open={runtimeArgs.open}
anchorEl={runtimeArgs.anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
{...args}
>
<Typography sx={{ p: 2 }}>The content of the Popover.</Typography>
</Popover>
</div>
);
};

# Popover

- [Overview](#overview)
- [Props](#props)
- [Usage](#usage)

## Overview

A Popover can be used to display some content on top of another.

<Canvas>
<Story
name="Overview"
>
{Template.bind({})}
</Story>
</Canvas>

## Props

<ArgsTable story="Overview" />

## Usage

Import and use the `Popover` component in your components as follows.

<Source
language="jsx"
dark
format
code={dedent`import Popover from '@oxygen-ui/react/Popover';\n`}
/>
43 changes: 43 additions & 0 deletions packages/react/src/components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* 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 MuiPopover, {PopoverProps as MuiPopoverProps} from '@mui/material/Popover';
import clsx from 'clsx';
import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react';
import {WithWrapperProps} from '../../models';
import {composeComponentDisplayName} from '../../utils';

export type PopoverProps = MuiPopoverProps;

const COMPONENT_NAME: string = 'Popover';

const Popover: ForwardRefExoticComponent<PopoverProps> & WithWrapperProps = forwardRef(
(props: PopoverProps, ref: MutableRefObject<HTMLDivElement>): ReactElement => {
const {className, ...rest} = props;

const classes: string = clsx('oxygen-popover', className);

return <MuiPopover className={classes} {...rest} ref={ref} />;
},
) as unknown as ForwardRefExoticComponent<PopoverProps> & WithWrapperProps;

Popover.displayName = composeComponentDisplayName(COMPONENT_NAME);
Popover.muiName = COMPONENT_NAME;
Popover.defaultProps = {};

export default Popover;
32 changes: 32 additions & 0 deletions packages/react/src/components/Popover/__tests__/Popover.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 Popover from '../Popover';

describe('Popover', () => {
it('should render successfully', () => {
const {baseElement} = render(<Popover open />);
expect(baseElement).toBeTruthy();
});

it('should match the snapshot', () => {
const {baseElement} = render(<Popover open />);
expect(baseElement).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Popover should match the snapshot 1`] = `
<body
style="padding-right: 1024px; overflow: hidden;"
>
<div
aria-hidden="true"
/>
<div
class="MuiPopover-root oxygen-popover MuiModal-root css-wpwlzh-MuiModal-root-MuiPopover-root"
role="presentation"
>
<div
aria-hidden="true"
class="MuiBackdrop-root MuiBackdrop-invisible MuiModal-backdrop css-g3hgs1-MuiBackdrop-root-MuiModal-backdrop"
style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
/>
<div
data-testid="sentinelStart"
tabindex="0"
/>
<div
class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation8 MuiPopover-paper css-52dy00-MuiPaper-root-MuiPopover-paper"
style="opacity: 1; transform: scale(1, 1); transition: opacity 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; top: 16px; left: 16px; transform-origin: -16px -16px;"
tabindex="-1"
/>
<div
data-testid="sentinelEnd"
tabindex="0"
/>
</div>
</body>
`;
20 changes: 20 additions & 0 deletions packages/react/src/components/Popover/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 './Popover';
export type {PopoverProps} from './Popover';
3 changes: 3 additions & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ export * from './Paper';
export {default as PhoneNumberInput} from './PhoneNumberInput';
export * from './PhoneNumberInput';

export {default as Popover} from './Popover';
export * from './Popover';

export {default as Radio} from './Radio';
export * from './Radio';

Expand Down

0 comments on commit 42125d2

Please sign in to comment.