diff --git a/packages/react/.storybook/story-config.ts b/packages/react/.storybook/story-config.ts index c1a1b91f..05d792ca 100644 --- a/packages/react/.storybook/story-config.ts +++ b/packages/react/.storybook/story-config.ts @@ -33,7 +33,7 @@ enum StorybookCategories { export type Stories = | 'AppBar' | 'Avatar' - | 'ButtonDropdownMenu' + | 'UserDropdownMenu' | 'Header' | 'Box' | 'Button' @@ -103,8 +103,8 @@ const StoryConfig: StorybookConfig = { Button: { hierarchy: `${StorybookCategories.Inputs}/Button`, }, - ButtonDropdownMenu: { - hierarchy: `${StorybookCategories.Navigation}/Button Dropdown Menu`, + UserDropdownMenu: { + hierarchy: `${StorybookCategories.Navigation}/User Dropdown Menu`, }, ColorModeToggle: { hierarchy: `${StorybookCategories.Theme}/Color Mode Toggle`, diff --git a/packages/react/src/components/AppBar/AppBar.stories.mdx b/packages/react/src/components/AppBar/AppBar.stories.mdx index 22dffca3..bfccd282 100644 --- a/packages/react/src/components/AppBar/AppBar.stories.mdx +++ b/packages/react/src/components/AppBar/AppBar.stories.mdx @@ -17,6 +17,7 @@ export const Template = args => ; - [Overview](#overview) - [Props](#props) +- [Usage](#usage) ## Overview @@ -33,3 +34,14 @@ The top App bar provides content and actions related to the current screen. It's ## Props + +## Usage + +Import and use the `AppBar` component in your components as follows. + + diff --git a/packages/react/src/components/Avatar/Avatar.stories.mdx b/packages/react/src/components/Avatar/Avatar.stories.mdx index d6c22f69..3d33b80b 100644 --- a/packages/react/src/components/Avatar/Avatar.stories.mdx +++ b/packages/react/src/components/Avatar/Avatar.stories.mdx @@ -17,7 +17,6 @@ export const Template = args => ; - [Overview](#overview) - [Props](#props) - [Usage](#usage) -- [Variants](#variants) ## Overview @@ -35,3 +34,14 @@ The Avatar can be used to mainly display profile pictures of users and can be us ## Props + +## Usage + +Import and use the `Avatar` component in your components as follows. + + diff --git a/packages/react/src/components/Avatar/__tests__/Avatar.test.tsx b/packages/react/src/components/Avatar/__tests__/Avatar.test.tsx new file mode 100644 index 00000000..06e15327 --- /dev/null +++ b/packages/react/src/components/Avatar/__tests__/Avatar.test.tsx @@ -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 Avatar from '../Avatar'; + +describe('Avatar', () => { + it('should render successfully', () => { + const {baseElement} = render(); + expect(baseElement).toBeTruthy(); + }); + + it('should match the snapshot', () => { + const {baseElement} = render(); + expect(baseElement).toMatchSnapshot(); + }); +}); diff --git a/packages/react/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap b/packages/react/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap new file mode 100644 index 00000000..1e7c2e7d --- /dev/null +++ b/packages/react/src/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap @@ -0,0 +1,23 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Avatar should match the snapshot 1`] = ` + +
+
+ +
+
+ +`; diff --git a/packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.stories.mdx b/packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.stories.mdx deleted file mode 100644 index c36e6d44..00000000 --- a/packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.stories.mdx +++ /dev/null @@ -1,45 +0,0 @@ -import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs'; -import dedent from 'ts-dedent'; -import StoryConfig from '../../../.storybook/story-config.ts'; -import ButtonDropdownMenu from './ButtonDropdownMenu.tsx'; -import MenuItem from '../MenuItem'; - -export const meta = { - component: ButtonDropdownMenu, - title: StoryConfig.ButtonDropdownMenu.hierarchy, -}; - - - -export const Template = args => ; - -# Button Dropdown Menu - -- [Overview](#overview) -- [Props](#props) -- [Usage](#usage) - -## Overview - -Use Button Dropdown Menu to create a button with a dropdown menu for navigation, actions and to display information. - - - Sample Menu Item}}}> - {Template.bind({})} - - - -## Props - - - -## Usage - -Import and use the `ButtonDropdownMenu` component in your components as follows. - - diff --git a/packages/react/src/components/ButtonDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap b/packages/react/src/components/ButtonDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap deleted file mode 100644 index a340c494..00000000 --- a/packages/react/src/components/ButtonDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ButtonDropdownMenu should match the snapshot 1`] = ` - -
-
- -
-
- -`; diff --git a/packages/react/src/components/Header/Header.stories.mdx b/packages/react/src/components/Header/Header.stories.mdx index 54128386..cce8367a 100644 --- a/packages/react/src/components/Header/Header.stories.mdx +++ b/packages/react/src/components/Header/Header.stories.mdx @@ -19,7 +19,6 @@ export const Template = args =>
; - [Overview](#overview) - [Props](#props) - [Usage](#usage) -- [Variants](#variants) ## Overview @@ -75,3 +74,14 @@ The Header provides content and actions related to the current screen. It's used ## Props + +## Usage + +Import and use the `Header` component in your components as follows. + + diff --git a/packages/react/src/components/Header/Header.tsx b/packages/react/src/components/Header/Header.tsx index abd1999e..906db3ad 100644 --- a/packages/react/src/components/Header/Header.tsx +++ b/packages/react/src/components/Header/Header.tsx @@ -16,7 +16,7 @@ * under the License. */ -import {Box, IconButton, Toolbar, Typography, useMediaQuery} from '@mui/material'; +import {useMediaQuery} from '@mui/material'; import {useColorScheme, useTheme, Theme} from '@mui/material/styles'; import {Mode} from '@mui/system/cssVars/useCurrentColorScheme'; import {ChevronDownIcon, HamburgerIcon, PowerIcon} from '@oxygen-ui/react-icons'; @@ -27,13 +27,14 @@ import {composeComponentDisplayName} from '../../utils'; import './header.scss'; import AppBar, {AppBarProps} from '../AppBar'; import Avatar from '../Avatar'; +import Box from '../Box'; import Button, {ButtonProps} from '../Button'; -import ButtonDropdownMenu, {ModeListInterface} from '../ButtonDropdownMenu'; +import IconButton from '../IconButton'; import Link from '../Link'; +import Toolbar from '../Toolbar'; +import Typography from '../Typography'; +import UserDropdownMenu, {ModeList, UserTemplate} from '../UserDropdownMenu'; -/** - * Interface for the Header component props. - */ export interface HeaderProps extends AppBarProps { /** * Brand information. @@ -50,7 +51,7 @@ export interface HeaderProps extends AppBarProps { /** * List of modes. */ - modes?: ModeListInterface[]; + modes?: ModeList[]; /** * Function to handle left navigation bar button toggle. */ @@ -61,32 +62,32 @@ export interface HeaderProps extends AppBarProps { user?: UserTemplate; } -/** - * Interface for the brand template. - */ export interface BrandTemplate { + /** + * Logo for the brand template. + */ logo?: { + /** + * Desktop logo for the brand template. + */ desktop?: ReactNode; + /** + * Mobile logo for the brand template. + */ mobile?: ReactNode; }; + /** + * Function on clicking on the brand logo and name. + */ onClick?: () => void; + /** + * Title of the brand, portal name or company. + */ title?: ReactNode; } -/** - * Interface for the logged user template. - */ -export interface UserTemplate { - email?: string; - image?: string; - name?: string; -} - const COMPONENT_NAME: string = 'Header'; -/** - * Header component. - */ const Header: FC & WithWrapperProps = (props: HeaderProps): ReactElement => { const {className, children, isLeftNavigationActive, brand, user, links, modes, onLeftNavigationTrigger, ...rest} = props; @@ -114,7 +115,7 @@ const Header: FC & WithWrapperProps = (props: HeaderProps): ReactEl variant="outlined" elevation={0} className={classes} - role="navigation" + role="banner" {...rest} > @@ -126,16 +127,15 @@ const Header: FC & WithWrapperProps = (props: HeaderProps): ReactEl {brand && ( {isMobile ? brand.logo.mobile ?? brand.logo.desktop : brand.logo.desktop} - + {brand.title} @@ -165,9 +165,9 @@ const Header: FC & WithWrapperProps = (props: HeaderProps): ReactEl - , diff --git a/packages/react/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap b/packages/react/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap index f0fac1db..5726c746 100644 --- a/packages/react/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +++ b/packages/react/src/components/Header/__tests__/__snapshots__/Header.test.tsx.snap @@ -5,72 +5,69 @@ exports[`Header should match the snapshot 1`] = `
diff --git a/packages/react/src/components/Header/header.scss b/packages/react/src/components/Header/header.scss index e4e7f3f5..8fcb2aa1 100644 --- a/packages/react/src/components/Header/header.scss +++ b/packages/react/src/components/Header/header.scss @@ -25,6 +25,12 @@ margin-right: 1rem; } + .portal-name { + font-weight: 500; + font-size: 1.25rem; + line-height: 1.6; + } + .logo-box { display: flex; align-items: center; @@ -37,6 +43,7 @@ &.with-link { cursor: pointer; + text-decoration: none; } } diff --git a/packages/react/src/components/Header/index.ts b/packages/react/src/components/Header/index.ts index df1e97bd..64096448 100644 --- a/packages/react/src/components/Header/index.ts +++ b/packages/react/src/components/Header/index.ts @@ -19,4 +19,3 @@ export {default} from './Header'; export type {HeaderProps} from './Header'; export type {BrandTemplate} from './Header'; -export type {UserTemplate} from './Header'; diff --git a/packages/react/src/components/MenuItem/MenuItem.stories.mdx b/packages/react/src/components/MenuItem/MenuItem.stories.mdx index 7a74eb4d..db50fd95 100644 --- a/packages/react/src/components/MenuItem/MenuItem.stories.mdx +++ b/packages/react/src/components/MenuItem/MenuItem.stories.mdx @@ -2,6 +2,7 @@ import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs'; import dedent from 'ts-dedent'; import StoryConfig from '../../../.storybook/story-config.ts'; import MenuItem from './MenuItem.tsx'; +import Menu from '../Menu'; export const meta = { component: MenuItem, @@ -10,7 +11,13 @@ export const meta = { -export const Template = args => ; +export const Template = (args) => { + return ( + + + + ) +}; # Menu Item @@ -23,7 +30,7 @@ export const Template = args => ; A Menu Item. - + {Template.bind({})} diff --git a/packages/react/src/components/UserDropdownMenu/UserDropdownMenu.stories.mdx b/packages/react/src/components/UserDropdownMenu/UserDropdownMenu.stories.mdx new file mode 100644 index 00000000..8a51368c --- /dev/null +++ b/packages/react/src/components/UserDropdownMenu/UserDropdownMenu.stories.mdx @@ -0,0 +1,45 @@ +import {ArgsTable, Source, Story, Canvas, Meta} from '@storybook/addon-docs'; +import dedent from 'ts-dedent'; +import StoryConfig from '../../../.storybook/story-config.ts'; +import UserDropdownMenu from './UserDropdownMenu.tsx'; +import MenuItem from '../MenuItem'; + +export const meta = { + component: UserDropdownMenu, + title: StoryConfig.UserDropdownMenu.hierarchy, +}; + + + +export const Template = args => ; + +# User Dropdown Menu + +- [Overview](#overview) +- [Props](#props) +- [Usage](#usage) + +## Overview + +Use User Dropdown Menu to create a button with a dropdown menu for navigation, actions and to display information. + + + Sample Menu Item}}> + {Template.bind({})} + + + +## Props + + + +## Usage + +Import and use the `UserDropdownMenu` component in your components as follows. + + diff --git a/packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.tsx b/packages/react/src/components/UserDropdownMenu/UserDropdownMenu.tsx similarity index 75% rename from packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.tsx rename to packages/react/src/components/UserDropdownMenu/UserDropdownMenu.tsx index 8969023c..979cdb45 100644 --- a/packages/react/src/components/ButtonDropdownMenu/ButtonDropdownMenu.tsx +++ b/packages/react/src/components/UserDropdownMenu/UserDropdownMenu.tsx @@ -16,7 +16,7 @@ * under the License. */ -import {Divider, ListItemAvatar, ListSubheader, Radio} from '@mui/material'; +import {ListItemAvatar, ListSubheader, Radio} from '@mui/material'; import {capitalize} from '@mui/material/utils'; import clsx from 'clsx'; import {FC, MouseEvent, ReactElement, ReactNode, useState} from 'react'; @@ -24,17 +24,18 @@ import {WithWrapperProps} from 'src/models'; import {composeComponentDisplayName} from '../../utils'; import Avatar from '../Avatar'; import Button, {ButtonProps} from '../Button'; +import Divider from '../Divider'; import ListItem from '../ListItem'; import ListItemIcon from '../ListItemIcon'; import ListItemText from '../ListItemText'; import Menu, {MenuProps} from '../Menu'; import MenuItem from '../MenuItem'; -import './button-dropdown-menu.scss'; +import './user-dropdown-menu.scss'; /** * Interface for the Button Dropdown Menu component props. */ -export interface ButtonDropdownMenuProps { +export interface UserDropdownMenuProps extends Omit { /** * List item icon. */ @@ -43,14 +44,6 @@ export interface ButtonDropdownMenuProps { * List item button text. */ actionText?: string; - /** - * Props sent to the Button component; - */ - buttonProps?: Omit; - /** - * Props sent to the Menu component; - */ - menuProps?: Omit; /** * Current mode. */ @@ -58,7 +51,7 @@ export interface ButtonDropdownMenuProps { /** * Array list of modes */ - modes?: ModeListInterface[]; + modes?: ModeList[]; /** * Heading of the modes list. */ @@ -75,39 +68,51 @@ export interface ButtonDropdownMenuProps { * Callback function on navigation to logged user's profile. */ onUserProfileNavigation?: () => void; + /** + * Props sent to the menu trigger or Button component; + */ + triggerOptions?: Omit; /** * Logged user information. */ user?: UserTemplate; } -/** - * Interface for the modes list. - */ -export interface ModeListInterface { +export interface ModeList { + /** + * Icon of the mode. + */ icon?: string | ReactElement; + /** + * Display name of the mode. + */ name: string; } -/** - * Interface for the logged user template. - */ export interface UserTemplate { + /** + * Email of logged user. + */ email?: string; + /** + * Image link of logged user. + */ image?: string; + /** + * Display name of logged user. + */ name?: string; } const COMPONENT_NAME: string = 'UserDropdownMenu'; -/** - * Button Dropdown Menu component. - */ -const ButtonDropdownMenu: FC & WithWrapperProps = ( - props: ButtonDropdownMenuProps & WithWrapperProps, +const UserDropdownMenu: FC & WithWrapperProps = ( + props: UserDropdownMenuProps & WithWrapperProps, ) => { const { - buttonProps, + className, + children, + triggerOptions, user, modes, mode, @@ -117,11 +122,15 @@ const ButtonDropdownMenu: FC & WithWrapperProps = ( actionIcon, onModeChange, onActionTrigger, - menuProps, + ...rest } = props; + const classes: string = clsx('oxygen-user-dropdown-menu', className); + const [anchorEl, setAnchorEl] = useState(null); + const openMenu: boolean = Boolean(anchorEl); + const handleModeChange = (selectedMode: string): void => { onModeChange(selectedMode); }; @@ -132,36 +141,43 @@ const ButtonDropdownMenu: FC & WithWrapperProps = ( const handleUserProfileNavigation = (): void => { onCloseMenu(); - onUserProfileNavigation(); + if (onUserProfileNavigation) { + onUserProfileNavigation(); + } }; const handleActionTrigger = (): void => { onCloseMenu(); - onActionTrigger(); + if (onActionTrigger) { + onActionTrigger(); + } }; - const openMenu: boolean = Boolean(anchorEl); - const handleOpenUserMenu = (event: MouseEvent): void => { setAnchorEl(event.currentTarget); }; return ( -
-
+ ); }; -ButtonDropdownMenu.displayName = composeComponentDisplayName(COMPONENT_NAME); -ButtonDropdownMenu.muiName = COMPONENT_NAME; +UserDropdownMenu.displayName = composeComponentDisplayName(COMPONENT_NAME); +UserDropdownMenu.muiName = COMPONENT_NAME; -export default ButtonDropdownMenu; +export default UserDropdownMenu; diff --git a/packages/react/src/components/ButtonDropdownMenu/__tests__/UserDropdownMenu.test.tsx b/packages/react/src/components/UserDropdownMenu/__tests__/UserDropdownMenu.test.tsx similarity index 81% rename from packages/react/src/components/ButtonDropdownMenu/__tests__/UserDropdownMenu.test.tsx rename to packages/react/src/components/UserDropdownMenu/__tests__/UserDropdownMenu.test.tsx index 8e415901..51bd1759 100644 --- a/packages/react/src/components/ButtonDropdownMenu/__tests__/UserDropdownMenu.test.tsx +++ b/packages/react/src/components/UserDropdownMenu/__tests__/UserDropdownMenu.test.tsx @@ -17,16 +17,16 @@ */ import {render} from '@unit-testing'; -import ButtonDropdownMenu from '../ButtonDropdownMenu'; +import UserDropdownMenu from '../UserDropdownMenu'; -describe('ButtonDropdownMenu', () => { +describe('UserDropdownMenu', () => { it('should render successfully', () => { - const {baseElement} = render(); + const {baseElement} = render(); expect(baseElement).toBeTruthy(); }); it('should match the snapshot', () => { - const {baseElement} = render(); + const {baseElement} = render(); expect(baseElement).toMatchSnapshot(); }); }); diff --git a/packages/react/src/components/UserDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap b/packages/react/src/components/UserDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap new file mode 100644 index 00000000..090ac689 --- /dev/null +++ b/packages/react/src/components/UserDropdownMenu/__tests__/__snapshots__/UserDropdownMenu.test.tsx.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`UserDropdownMenu should match the snapshot 1`] = ` + +
+ +
+ +`; diff --git a/packages/react/src/components/ButtonDropdownMenu/index.ts b/packages/react/src/components/UserDropdownMenu/index.ts similarity index 76% rename from packages/react/src/components/ButtonDropdownMenu/index.ts rename to packages/react/src/components/UserDropdownMenu/index.ts index 6d62dc25..c15e0cce 100644 --- a/packages/react/src/components/ButtonDropdownMenu/index.ts +++ b/packages/react/src/components/UserDropdownMenu/index.ts @@ -16,6 +16,7 @@ * under the License. */ -export {default} from './ButtonDropdownMenu'; -export {ButtonDropdownMenuProps} from './ButtonDropdownMenu'; -export {ModeListInterface} from './ButtonDropdownMenu'; +export {default} from './UserDropdownMenu'; +export type {UserDropdownMenuProps} from './UserDropdownMenu'; +export type {ModeList} from './UserDropdownMenu'; +export type {UserTemplate} from './UserDropdownMenu'; diff --git a/packages/react/src/components/ButtonDropdownMenu/button-dropdown-menu.scss b/packages/react/src/components/UserDropdownMenu/user-dropdown-menu.scss similarity index 96% rename from packages/react/src/components/ButtonDropdownMenu/button-dropdown-menu.scss rename to packages/react/src/components/UserDropdownMenu/user-dropdown-menu.scss index 62b0da66..b278d069 100644 --- a/packages/react/src/components/ButtonDropdownMenu/button-dropdown-menu.scss +++ b/packages/react/src/components/UserDropdownMenu/user-dropdown-menu.scss @@ -16,7 +16,7 @@ * under the License. */ -.oxygen-button-dropdown-menu { +.oxygen-user-dropdown-menu { .dropdown-list-item { &.clickable { cursor: pointer;