From e432d254f6b3fb24b62222e9a0f37f519a57c9cb Mon Sep 17 00:00:00 2001 From: Brion Date: Thu, 10 Oct 2024 14:44:05 +0530 Subject: [PATCH] fix(react): update composition pattern --- .../src/components/Accordion/Accordion.tsx | 48 ++- .../react/src/components/Accordion/index.ts | 2 +- .../AccordionDetails/AccordionDetails.tsx | 29 +- .../src/components/AccordionDetails/index.ts | 2 +- .../AccordionSummary/AccordionSummary.tsx | 50 ++- .../src/components/AccordionSummary/index.ts | 4 +- .../AccountOverview/AccountOverview.tsx | 122 ++++--- .../src/components/AccountOverview/index.ts | 2 +- .../src/components/ActionCard/ActionCard.tsx | 79 +++-- .../react/src/components/ActionCard/index.ts | 2 +- packages/react/src/components/Alert/Alert.tsx | 43 ++- packages/react/src/components/Alert/index.ts | 4 +- .../src/components/AlertTitle/AlertTitle.tsx | 43 ++- .../react/src/components/AlertTitle/index.ts | 2 +- .../react/src/components/AppBar/AppBar.tsx | 53 ++- packages/react/src/components/AppBar/index.ts | 2 + .../src/components/AppShell/AppShell.tsx | 72 ++-- .../components/Autocomplete/Autocomplete.tsx | 36 +- .../src/components/Autocomplete/index.ts | 17 +- .../react/src/components/Avatar/Avatar.tsx | 89 +++-- packages/react/src/components/Avatar/index.ts | 4 +- .../src/components/Backdrop/Backdrop.tsx | 53 ++- .../react/src/components/Backdrop/index.ts | 5 +- packages/react/src/components/Badge/Badge.tsx | 54 ++- packages/react/src/components/Badge/index.ts | 5 +- packages/react/src/components/Box/Box.tsx | 47 ++- packages/react/src/components/Box/index.ts | 4 +- .../components/Breadcrumbs/Breadcrumbs.tsx | 65 +++- .../react/src/components/Breadcrumbs/index.ts | 4 +- .../react/src/components/Button/Button.tsx | 53 ++- packages/react/src/components/Button/index.ts | 4 +- packages/react/src/components/Card/Card.tsx | 40 ++- packages/react/src/components/Card/index.ts | 4 +- .../components/CardActions/CardActions.tsx | 38 ++- .../react/src/components/CardActions/index.ts | 2 +- .../components/CardContent/CardContent.tsx | 39 ++- .../react/src/components/CardContent/index.ts | 4 +- .../src/components/CardHeader/CardHeader.tsx | 54 ++- .../react/src/components/CardHeader/index.ts | 4 +- .../src/components/Carousel/Carousel.tsx | 264 ++++++++------- .../react/src/components/Carousel/index.ts | 3 +- .../src/components/Checkbox/Checkbox.tsx | 45 ++- .../react/src/components/Checkbox/index.ts | 4 +- packages/react/src/components/Chip/Chip.tsx | 52 ++- packages/react/src/components/Chip/index.ts | 9 +- .../CircularProgress/CircularProgress.tsx | 53 ++- .../src/components/CircularProgress/index.ts | 4 +- .../CircularProgressAvatar.tsx | 120 ++++--- .../CircularProgressAvatar/index.ts | 2 +- packages/react/src/components/Code/Code.tsx | 62 ++-- packages/react/src/components/Code/index.ts | 2 +- .../CollapsibleNavbarItem.tsx | 60 +++- .../CollapsibleNavbarItem/index.tsx | 2 +- .../ColorModeToggle/ColorModeToggle.tsx | 89 +++-- .../src/components/ColorModeToggle/index.ts | 2 +- .../src/components/Container/Container.tsx | 55 ++- .../react/src/components/Container/index.ts | 4 +- .../components/CountryFlag/CountryFlag.tsx | 46 ++- .../react/src/components/CountryFlag/index.ts | 2 +- .../src/components/DataGrid/DataGrid.tsx | 41 ++- .../react/src/components/DataGrid/index.ts | 29 +- .../react/src/components/Divider/Divider.tsx | 54 ++- .../react/src/components/Divider/index.ts | 4 +- .../react/src/components/Drawer/Drawer.tsx | 49 ++- packages/react/src/components/Drawer/index.ts | 2 +- packages/react/src/components/Fab/Fab.tsx | 42 ++- packages/react/src/components/Fab/index.ts | 9 +- .../react/src/components/Footer/Footer.tsx | 113 ++++--- packages/react/src/components/Footer/index.ts | 2 +- .../components/FormControl/FormControl.tsx | 61 +++- .../react/src/components/FormControl/index.ts | 9 +- .../FormControlLabel/FormControlLabel.tsx | 31 +- .../src/components/FormControlLabel/index.ts | 2 +- .../src/components/FormGroup/FormGroup.tsx | 30 +- .../react/src/components/FormGroup/index.ts | 2 +- .../FormHelperText/FormHelperText.tsx | 55 ++- .../src/components/FormHelperText/index.ts | 4 +- .../src/components/FormLabel/FormLabel.tsx | 45 ++- .../react/src/components/FormLabel/index.ts | 10 +- packages/react/src/components/Grid/Grid.tsx | 51 ++- packages/react/src/components/Grid/index.ts | 4 +- .../react/src/components/Header/Header.tsx | 267 ++++++++------- packages/react/src/components/Header/index.ts | 3 +- .../src/components/IconButton/IconButton.tsx | 67 +++- .../react/src/components/IconButton/index.ts | 8 +- packages/react/src/components/Image/Image.tsx | 29 +- packages/react/src/components/Image/index.ts | 2 +- packages/react/src/components/Input/Input.tsx | 38 ++- packages/react/src/components/Input/index.ts | 2 +- .../InputAdornment/InputAdornment.tsx | 57 +++- .../src/components/InputAdornment/index.ts | 4 +- .../src/components/InputLabel/InputLabel.tsx | 53 ++- .../react/src/components/InputLabel/index.ts | 4 +- .../LinearProgress/LinearProgress.tsx | 41 ++- .../src/components/LinearProgress/index.ts | 4 +- packages/react/src/components/Link/Link.tsx | 55 ++- packages/react/src/components/Link/index.ts | 2 + packages/react/src/components/List/List.tsx | 54 ++- packages/react/src/components/List/index.ts | 4 +- .../src/components/ListItem/ListItem.tsx | 41 ++- .../react/src/components/ListItem/index.ts | 4 +- .../ListItemAvatar/ListItemAvatar.tsx | 40 ++- .../src/components/ListItemAvatar/index.ts | 2 +- .../ListItemButton/ListItemButton.tsx | 47 ++- .../components/ListItemIcon/ListItemIcon.tsx | 40 ++- .../src/components/ListItemIcon/index.ts | 2 +- .../components/ListItemText/ListItemText.tsx | 40 ++- .../src/components/ListItemText/index.ts | 2 +- packages/react/src/components/Menu/Menu.tsx | 48 ++- packages/react/src/components/Menu/index.ts | 2 +- .../src/components/MenuItem/MenuItem.tsx | 53 ++- .../react/src/components/MenuItem/index.tsx | 4 +- .../react/src/components/Navbar/Navbar.tsx | 276 ++++++++------- packages/react/src/components/Navbar/index.ts | 2 +- .../src/components/NavbarItem/NavbarItem.tsx | 87 +++-- .../react/src/components/NavbarItem/index.tsx | 2 +- .../OutlinedInput/OutlinedInput.tsx | 41 ++- .../src/components/OutlinedInput/index.ts | 2 +- packages/react/src/components/Paper/Paper.tsx | 46 ++- packages/react/src/components/Paper/index.ts | 4 +- .../PhoneNumberInput/PhoneNumberInput.tsx | 57 +++- .../src/components/PhoneNumberInput/index.ts | 2 +- .../react/src/components/Popover/Popover.tsx | 43 ++- .../react/src/components/Popover/index.ts | 5 +- packages/react/src/components/Radio/Radio.tsx | 41 ++- packages/react/src/components/Radio/index.ts | 4 +- .../src/components/RadioGroup/RadioGroup.tsx | 30 +- .../react/src/components/RadioGroup/index.ts | 4 +- .../react/src/components/Select/Select.tsx | 35 +- packages/react/src/components/Select/index.ts | 4 +- .../react/src/components/SignIn/SignIn.tsx | 161 +++++---- packages/react/src/components/SignIn/index.ts | 2 +- .../src/components/Skeleton/Skeleton.tsx | 55 ++- .../react/src/components/Skeleton/index.ts | 4 +- .../src/components/Snackbar/Snackbar.tsx | 27 +- .../react/src/components/Snackbar/index.ts | 4 +- .../react/src/components/Stepper/Stepper.tsx | 150 +++++---- .../react/src/components/Stepper/index.ts | 2 +- .../react/src/components/Switch/Switch.tsx | 44 ++- packages/react/src/components/Switch/index.ts | 4 +- packages/react/src/components/Tab/Tab.tsx | 45 ++- packages/react/src/components/Tab/index.ts | 4 +- .../src/components/TabPanel/TabPanel.tsx | 37 +- .../react/src/components/TabPanel/index.ts | 2 +- packages/react/src/components/Tabs/Tabs.tsx | 43 ++- packages/react/src/components/Tabs/index.ts | 4 +- .../src/components/TextField/TextField.tsx | 78 +++-- .../components/TextField/constants/index.ts | 19 -- .../components/TextField/constants/types.ts | 22 -- .../react/src/components/TextField/index.ts | 12 +- .../react/src/components/Toolbar/Toolbar.tsx | 52 ++- .../react/src/components/Toolbar/index.ts | 4 +- .../react/src/components/Tooltip/Tooltip.tsx | 29 +- .../src/components/Typography/Typography.tsx | 57 +++- .../react/src/components/Typography/index.ts | 4 +- .../UserDropdownMenu/UserDropdownMenu.tsx | 318 ++++++++++-------- .../src/components/UserDropdownMenu/index.ts | 4 +- .../react/src/components/Wizard/Wizard.tsx | 195 ++++++----- packages/react/src/components/Wizard/index.ts | 2 +- 159 files changed, 4207 insertions(+), 1594 deletions(-) delete mode 100644 packages/react/src/components/TextField/constants/index.ts delete mode 100644 packages/react/src/components/TextField/constants/types.ts diff --git a/packages/react/src/components/Accordion/Accordion.tsx b/packages/react/src/components/Accordion/Accordion.tsx index 39022d3e..df3c6be0 100644 --- a/packages/react/src/components/Accordion/Accordion.tsx +++ b/packages/react/src/components/Accordion/Accordion.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * 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 @@ -18,20 +18,54 @@ import MuiAccordion, {AccordionProps as MuiAccordionProps} from '@mui/material/Accordion'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './accordion.scss'; -export type AccordionProps = MuiAccordionProps; +export type AccordionProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Accordion'; -const Accordion: FC & WithWrapperProps = ({className, ...rest}: AccordionProps): ReactElement => { - const classes: string = clsx('oxygen-accordion', className); +/** + * The Accordion component lets users show and hide sections of related content on a page. + * + * Demos: + * + * - [Accordion (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-accordion) + * - [Accordion (MUI)](https://mui.com/material-ui/react-accordion/) + * + * API: + * + * - [Accordion API](https://mui.com/material-ui/api/accordion/) + * - inherits [Paper API](https://mui.com/material-ui/api/paper/) + * + * @remarks + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/paper/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Accordion component. + * @param ref - The ref to be forwarded to the MuiAccordion component. + * @returns The rendered Accordion component. + */ +const Accordion: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AccordionProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-accordion', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Accordion.displayName = composeComponentDisplayName(COMPONENT_NAME); Accordion.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Accordion/index.ts b/packages/react/src/components/Accordion/index.ts index 1896ff61..29a1c979 100644 --- a/packages/react/src/components/Accordion/index.ts +++ b/packages/react/src/components/Accordion/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Accordion'; -export type {AccordionProps} from './Accordion'; +export * from './Accordion'; diff --git a/packages/react/src/components/AccordionDetails/AccordionDetails.tsx b/packages/react/src/components/AccordionDetails/AccordionDetails.tsx index 92389c8d..1e26b7b5 100644 --- a/packages/react/src/components/AccordionDetails/AccordionDetails.tsx +++ b/packages/react/src/components/AccordionDetails/AccordionDetails.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiAccordionDetails, {AccordionDetailsProps as MuiAccordionDetailsProps} from '@mui/material/AccordionDetails'; +import MuiAccordionDetails from '@mui/material/AccordionDetails'; +import type {AccordionDetailsProps as MuiAccordionDetailsProps} from '@mui/material/AccordionDetails'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,11 +28,32 @@ export type AccordionDetailsProps = MuiAccordionDetailsProps; const COMPONENT_NAME: string = 'AccordionDetails'; +/** + * The Accordion Details component is the wrapper for the Accordion content. + * + * Demos: + * + * - [Accordion (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-accordion) + * - [Accordion (MUI)](https://mui.com/material-ui/react-accordion/) + * + * API: + * + * - [AccordionDetails API](https://mui.com/material-ui/api/accordion-details/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the AccordionDetails component. + * @param ref - The ref to be forwarded to the MuiAccordionDetails component. + * @returns The rendered AccordionDetails component. + */ const AccordionDetails: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ({className, ...rest}: AccordionDetailsProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-accordion-details', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/AccordionDetails/index.ts b/packages/react/src/components/AccordionDetails/index.ts index f51b979f..c815ca9e 100644 --- a/packages/react/src/components/AccordionDetails/index.ts +++ b/packages/react/src/components/AccordionDetails/index.ts @@ -17,4 +17,4 @@ */ export {default} from './AccordionDetails'; -export type {AccordionDetailsProps} from './AccordionDetails'; +export * from './AccordionDetails'; diff --git a/packages/react/src/components/AccordionSummary/AccordionSummary.tsx b/packages/react/src/components/AccordionSummary/AccordionSummary.tsx index a735730d..46a5decd 100644 --- a/packages/react/src/components/AccordionSummary/AccordionSummary.tsx +++ b/packages/react/src/components/AccordionSummary/AccordionSummary.tsx @@ -16,21 +16,61 @@ * under the License. */ -import MuiAccordionSummary, {AccordionSummaryProps as MuiAccordionSummaryProps} from '@mui/material/AccordionSummary'; +import MuiAccordionSummary from '@mui/material/AccordionSummary'; +import type { + AccordionSummaryProps as MuiAccordionSummaryProps, + AccordionSummaryTypeMap, +} from '@mui/material/AccordionSummary'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type AccordionSummaryProps = MuiAccordionSummaryProps; +export type AccordionSummaryProps< + C extends ElementType = ElementType, + D extends ElementType = AccordionSummaryTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'AccordionSummary'; +/** + * The Accordion Summary component is the wrapper for the Accordion header, which expands or collapses the content when clicked. + * + * Demos: + * + * - [Accordion (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-accordion) + * - [Accordion (MUI)](https://mui.com/material-ui/react-accordion/) + * + * API: + * + * - [AccordionSummary API](https://mui.com/material-ui/api/accordion-summary/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the AccordionSummary component. + * @param ref - The ref to be forwarded to the MuiAccordionSummary component. + * @returns The rendered AccordionSummary component. + */ const AccordionSummary: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: AccordionSummaryProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: AccordionSummaryProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-accordion-summary', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/AccordionSummary/index.ts b/packages/react/src/components/AccordionSummary/index.ts index 7edb0e1f..a5e4bade 100644 --- a/packages/react/src/components/AccordionSummary/index.ts +++ b/packages/react/src/components/AccordionSummary/index.ts @@ -17,4 +17,6 @@ */ export {default} from './AccordionSummary'; -export type {AccordionSummaryProps} from './AccordionSummary'; +export * from './AccordionSummary'; + +export type {AccordionSummaryTypeMap} from '@mui/material/AccordionSummary'; diff --git a/packages/react/src/components/AccountOverview/AccountOverview.tsx b/packages/react/src/components/AccountOverview/AccountOverview.tsx index d3e1ab15..1bd95b5c 100644 --- a/packages/react/src/components/AccountOverview/AccountOverview.tsx +++ b/packages/react/src/components/AccountOverview/AccountOverview.tsx @@ -17,19 +17,27 @@ */ import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; -import Card, {CardProps} from '../Card'; -import CardHeader, {CardHeaderProps} from '../CardHeader'; -import Carousel, {CarouselStep} from '../Carousel'; +import Card from '../Card'; +import type {CardProps, CardTypeMap} from '../Card'; +import CardHeader from '../CardHeader'; +import type {CardHeaderProps} from '../CardHeader'; +import Carousel from '../Carousel'; +import type {CarouselStep} from '../Carousel'; import CircularProgressAvatar from '../CircularProgressAvatar'; import Divider from '../Divider'; -import {UserTemplate} from '../UserDropdownMenu'; +import type {UserTemplate} from '../UserDropdownMenu'; import './account-overview.scss'; -export interface AccountOverviewProps extends Omit { +export type AccountOverviewProps< + C extends ElementType = ElementType, + D extends ElementType = CardTypeMap['defaultComponent'], + P = {}, +> = Omit, 'title'> & { /** * Account completion steps. */ @@ -60,49 +68,77 @@ export interface AccountOverviewProps extends Omit { * Logged user information. */ user: UserTemplate; -} +}; export type AccountCompletionSteps = CarouselStep; const COMPONENT_NAME: string = 'AccountOverview'; -const AccountOverview: FC & WithWrapperProps = ({ - className, - title, - subheader, - accountCompletionStepsTitle, - accountCompletionSteps, - accountProgress, - user, - cardHeaderProps, - ...rest -}: AccountOverviewProps): ReactElement => { - const classes: string = clsx('oxygen-account-overview', className); +/** + * The Account Overview component lets you display the progress of the user's account. + * It includes the user's profile picture, name, email, account progress and account completion steps. + * + * Demos: + * + * - [Account Overview (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/patterns-account-overview) + * + * API: + * + * - inherits [Card API](https://mui.com/material-ui/api/card/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/card/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the AccountOverview component. + * @param ref - The ref to be forwarded to the Card component. + * @returns The rendered AccountOverview component. + */ +const AccountOverview: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + { + className, + title, + subheader, + accountCompletionStepsTitle, + accountCompletionSteps, + accountProgress, + user, + cardHeaderProps, + ...rest + }: AccountOverviewProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-account-overview', className); - return ( - - - } - title={title} - subheader={subheader} - {...cardHeaderProps} - /> - {accountCompletionSteps && ( - - - - - )} - - ); -}; + return ( + + + } + title={title} + subheader={subheader} + {...cardHeaderProps} + /> + {accountCompletionSteps && ( + + + + + )} + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; AccountOverview.displayName = composeComponentDisplayName(COMPONENT_NAME); AccountOverview.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/AccountOverview/index.ts b/packages/react/src/components/AccountOverview/index.ts index 2edf6a08..b469556e 100644 --- a/packages/react/src/components/AccountOverview/index.ts +++ b/packages/react/src/components/AccountOverview/index.ts @@ -17,4 +17,4 @@ */ export {default} from './AccountOverview'; -export type {AccountOverviewProps} from './AccountOverview'; +export * from './AccountOverview'; diff --git a/packages/react/src/components/ActionCard/ActionCard.tsx b/packages/react/src/components/ActionCard/ActionCard.tsx index cdb2626f..671dfcc2 100644 --- a/packages/react/src/components/ActionCard/ActionCard.tsx +++ b/packages/react/src/components/ActionCard/ActionCard.tsx @@ -17,17 +17,19 @@ */ import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Button from '../Button'; -import Card, {CardProps} from '../Card'; +import Card from '../Card'; +import type {CardProps} from '../Card'; import CardActions from '../CardActions'; import CardContent from '../CardContent'; import Typography from '../Typography'; import './action-card.scss'; -export interface ActionCardProps extends CardProps { +export type ActionCardProps = CardProps & { /** * The text to be displayed in the action button. */ @@ -48,36 +50,55 @@ export interface ActionCardProps extends CardProps { * The title of the card. */ title: string; -} +}; const COMPONENT_NAME: string = 'ActionCard'; -const ActionCard: FC & WithWrapperProps = ({ - className, - image, - title, - description, - actionText, - onActionClick, - ...rest -}: ActionCardProps): ReactElement => { - const classes: string = clsx('oxygen-action-card', className); +/** + * The Action Card component is an extended version of the` Card` component with an action button. + * + * Demos: + * + * - [Action Card (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-action-card) + * + * API: + * + * - inherits [Card API](https://mui.com/material-ui/api/card/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/card/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the ActionCard component. + * @param ref - The ref to be forwarded to the Card component. + * @returns The rendered ActionCard component. + */ +const ActionCard: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, image, title, description, actionText, onActionClick, ...rest}: ActionCardProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-action-card', className); - return ( - - - {image} - {title} - {description} - - - - - - ); -}; + return ( + + + {image} + {title} + {description} + + + + + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; ActionCard.displayName = composeComponentDisplayName(COMPONENT_NAME); ActionCard.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/ActionCard/index.ts b/packages/react/src/components/ActionCard/index.ts index 6cf2bb06..bf033e71 100644 --- a/packages/react/src/components/ActionCard/index.ts +++ b/packages/react/src/components/ActionCard/index.ts @@ -17,4 +17,4 @@ */ export {default} from './ActionCard'; -export type {ActionCardProps} from './ActionCard'; +export * from './ActionCard'; diff --git a/packages/react/src/components/Alert/Alert.tsx b/packages/react/src/components/Alert/Alert.tsx index 4b50fffe..1a472b69 100644 --- a/packages/react/src/components/Alert/Alert.tsx +++ b/packages/react/src/components/Alert/Alert.tsx @@ -16,22 +16,55 @@ * under the License. */ -import MuiAlert, {AlertProps as MuiAlertProps} from '@mui/material/Alert'; +import MuiAlert from '@mui/material/Alert'; +import type {AlertProps as MuiAlertProps} from '@mui/material/Alert'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './alert.scss'; -export type AlertProps = MuiAlertProps; +export type AlertProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Alert'; +/** + * The Alert component display brief messages for the user without interrupting their use of the app. + * + * Demos: + * + * - [Alert (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-alert) + * - [Alert (MUI)](https://mui.com/material-ui/react-alert/) + * + * API: + * + * - [Alert API](https://mui.com/material-ui/api/alert/) + * - inherits [Paper API](https://mui.com/material-ui/api/paper/) + * + * @remarks + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/paper/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Alert component. + * @param ref - The ref to be forwarded to the MuiAlert component. + * @returns The rendered Alert component. + */ const Alert: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: AlertProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: AlertProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-alert', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/Alert/index.ts b/packages/react/src/components/Alert/index.ts index dfca86d5..ee6a4340 100644 --- a/packages/react/src/components/Alert/index.ts +++ b/packages/react/src/components/Alert/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Alert'; -export type {AlertProps} from './Alert'; +export * from './Alert'; + +export type {AlertColor, AlertPropsVariantOverrides, AlertPropsColorOverrides} from '@mui/material/Alert'; diff --git a/packages/react/src/components/AlertTitle/AlertTitle.tsx b/packages/react/src/components/AlertTitle/AlertTitle.tsx index c3104370..8e1f0f2f 100644 --- a/packages/react/src/components/AlertTitle/AlertTitle.tsx +++ b/packages/react/src/components/AlertTitle/AlertTitle.tsx @@ -16,22 +16,55 @@ * under the License. */ -import MuiAlertTitle, {AlertTitleProps as MuiAlertProps} from '@mui/material/AlertTitle'; +import MuiAlertTitle from '@mui/material/AlertTitle'; +import type {AlertTitleProps as MuiAlertTitleProps} from '@mui/material/AlertTitle'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './alert-title.scss'; -export type AlertProps = MuiAlertProps; +export type AlertProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'AlertTitle'; +/** + * The Alert Title component can be used to display a title for the Alert component. + * + * Demos: + * + * - [Alert (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-alert) + * - [Alert (MUI)](https://mui.com/material-ui/react-alert/) + * + * API: + * + * - [AlertTitle API](https://mui.com/material-ui/api/alert-title/) + * - inherits [Typography API](https://mui.com/material-ui/api/typography/) + * + * @remarks + * - ✔️ Props of the [Typography](https://mui.com/material-ui/api/typography/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the AlertTitle component. + * @param ref - The ref to be forwarded to the MuiAlertTitle component. + * @returns The rendered AlertTitle component. + */ const AlertTitle: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: AlertProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: AlertProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-alert-title', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/AlertTitle/index.ts b/packages/react/src/components/AlertTitle/index.ts index c71b698f..b3381e1d 100644 --- a/packages/react/src/components/AlertTitle/index.ts +++ b/packages/react/src/components/AlertTitle/index.ts @@ -17,4 +17,4 @@ */ export {default} from './AlertTitle'; -export type {AlertProps} from './AlertTitle'; +export * from './AlertTitle'; diff --git a/packages/react/src/components/AppBar/AppBar.tsx b/packages/react/src/components/AppBar/AppBar.tsx index 4dbf9d6f..ae3ff877 100644 --- a/packages/react/src/components/AppBar/AppBar.tsx +++ b/packages/react/src/components/AppBar/AppBar.tsx @@ -16,22 +16,61 @@ * under the License. */ -import MuiAppBar, {AppBarProps as MuiAppBarProps} from '@mui/material/AppBar'; +import MuiAppBar from '@mui/material/AppBar'; +import type {AppBarTypeMap, AppBarProps as MuiAppBarProps} from '@mui/material/AppBar'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './app-bar.scss'; -export type AppBarProps = MuiAppBarProps; +export type AppBarProps< + C extends ElementType = ElementType, + D extends ElementType = AppBarTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'AppBar'; -const AppBar: FC & WithWrapperProps = ({className, ...rest}: AppBarProps): ReactElement => { - const classes: string = clsx('oxygen-app-bar', className); +/** + * The App Bar component displays information and actions relating to the current screen. + * + * Demos: + * + * - [App Bar (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-app-bar) + * - [App Bar (MUI)](https://mui.com/material-ui/react-app-bar/) + * + * API: + * + * - [AppBar API](https://mui.com/material-ui/api/app-bar/) + * - inherits [Paper API](https://mui.com/material-ui/api/paper/) + * + * @remarks + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/paper/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the AppBar component. + * @param ref - The ref to be forwarded to the MuiAppBar component. + * @returns The rendered AppBar component. + */ +const AppBar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AppBarProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-app-bar', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; AppBar.displayName = composeComponentDisplayName(COMPONENT_NAME); AppBar.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/AppBar/index.ts b/packages/react/src/components/AppBar/index.ts index c64c13e2..90e28d63 100644 --- a/packages/react/src/components/AppBar/index.ts +++ b/packages/react/src/components/AppBar/index.ts @@ -18,3 +18,5 @@ export {default} from './AppBar'; export type {AppBarProps} from './AppBar'; + +export type {AppBarPropsColorOverrides, AppBarTypeMap} from '@mui/material/AppBar'; diff --git a/packages/react/src/components/AppShell/AppShell.tsx b/packages/react/src/components/AppShell/AppShell.tsx index 327c153f..f6387362 100644 --- a/packages/react/src/components/AppShell/AppShell.tsx +++ b/packages/react/src/components/AppShell/AppShell.tsx @@ -17,13 +17,15 @@ */ import clsx from 'clsx'; -import {FC, PropsWithChildren, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import Box, {BoxProps} from '../Box'; +import Box from '../Box'; +import type {BoxProps} from '../Box'; import './app-shell.scss'; -export interface AppShellProps extends BoxProps { +export type AppShellProps = BoxProps & { /** * Footer component. */ @@ -36,35 +38,55 @@ export interface AppShellProps extends BoxProps { * Navigation component. */ navigation?: ReactNode; -} +}; const COMPONENT_NAME: string = 'AppShell'; -const AppShell: FC> & WithWrapperProps = ({ - className, - children, - footer, - header, - navigation, - ...rest -}: PropsWithChildren): ReactElement => { - const classes: string = clsx('oxygen-app-shell', className); +/** + * The App Shell component is a layout component that can be used to create a common Header - Navbar - Footer - Aside - Content layout pattern. + * + * Demos: + * + * - [App Shell (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/layout-app-shell) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the AppShell component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered AppShell component. + */ +const AppShell: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, children, footer, header, navigation, ...rest}: AppShellProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-app-shell', className); - return ( - - {header} - - {navigation} - - - {children} + return ( + + {header} + + {navigation} + + + {children} + + {footer} - {footer} - - ); -}; + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; AppShell.displayName = composeComponentDisplayName(COMPONENT_NAME); AppShell.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Autocomplete/Autocomplete.tsx b/packages/react/src/components/Autocomplete/Autocomplete.tsx index c64440dc..e6fd4bd4 100644 --- a/packages/react/src/components/Autocomplete/Autocomplete.tsx +++ b/packages/react/src/components/Autocomplete/Autocomplete.tsx @@ -16,19 +16,47 @@ * under the License. */ -import MuiAutocomplete, {AutocompleteProps as MuiAutocompleteProps} from '@mui/material/Autocomplete'; +import MuiAutocomplete from '@mui/material/Autocomplete'; +import type {AutocompleteProps as MuiAutocompleteProps} from '@mui/material/Autocomplete'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {ChipTypeMap} from '../Chip'; import './autocomplete.scss'; -export type AutocompleteProps = MuiAutocompleteProps; +export type AutocompleteProps< + T, + Multiple extends boolean | undefined = boolean | undefined, + DisableClearable extends boolean | undefined = boolean | undefined, + FreeSolo extends boolean | undefined = boolean | undefined, + ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'], +> = MuiAutocompleteProps; const COMPONENT_NAME: string = 'Autocomplete'; /** - * @remarks `any` is used as the generic type for the props because the generic type is not used in the component. + * The Autocomplete is a normal text input enhanced by a panel of suggested options. + * + * Demos: + * + * - [Autocomplete (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-autocomplete) + * - [Autocomplete (MUI)](https://mui.com/material-ui/react-autocomplete/) + * + * API: + * + * - [Autocomplete API](https://mui.com/material-ui/api/autocomplete/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ❌ The component cannot hold a `ref`. + * + * @template C - The type of the component. + * @param props - The props for the Accordion component. + * @param ref - The ref to be forwarded to the MuiAccordion component. + * @returns The rendered Accordion component. */ const Autocomplete: ForwardRefExoticComponent> & WithWrapperProps = forwardRef( ({className, ...rest}: AutocompleteProps, ref: MutableRefObject): ReactElement => { diff --git a/packages/react/src/components/Autocomplete/index.ts b/packages/react/src/components/Autocomplete/index.ts index b9d71d10..095d58ce 100644 --- a/packages/react/src/components/Autocomplete/index.ts +++ b/packages/react/src/components/Autocomplete/index.ts @@ -17,5 +17,18 @@ */ export {default} from './Autocomplete'; -export type {AutocompleteProps} from './Autocomplete'; -export type {AutocompleteRenderGetTagProps, AutocompleteRenderInputParams} from '@mui/material/Autocomplete'; +export * from './Autocomplete'; + +export {createFilterOptions} from '@mui/material/Autocomplete'; +export type { + AutocompleteChangeDetails, + AutocompleteChangeReason, + AutocompleteCloseReason, + AutocompleteInputChangeReason, + AutocompleteOwnerState, + AutocompleteRenderGetTagProps, + AutocompleteRenderOptionState, + AutocompleteRenderGroupParams, + AutocompleteRenderInputParams, + AutocompletePropsSizeOverrides, +} from '@mui/material/Autocomplete'; diff --git a/packages/react/src/components/Avatar/Avatar.tsx b/packages/react/src/components/Avatar/Avatar.tsx index 6fafaf31..389f35e9 100644 --- a/packages/react/src/components/Avatar/Avatar.tsx +++ b/packages/react/src/components/Avatar/Avatar.tsx @@ -16,15 +16,21 @@ * under the License. */ -import MuiAvatar, {AvatarProps as MuiAvatarProps} from '@mui/material/Avatar'; +import MuiAvatar from '@mui/material/Avatar'; +import type {AvatarProps as MuiAvatarProps, AvatarTypeMap} from '@mui/material/Avatar'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement, useMemo} from 'react'; +import {forwardRef, useMemo} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import usePastelColorGenerator from '../../hooks/use-pastel-color-generator'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './avatar.scss'; -export type AvatarProps = { +export type AvatarProps< + C extends ElementType = ElementType, + D extends ElementType = AvatarTypeMap['defaultComponent'], + P = {}, +> = { /** * Text for the random background color generator. */ @@ -37,45 +43,60 @@ export type AvatarProps = { * If `true`, the background color will be randomly generated. */ randomBackgroundColor?: boolean; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Avatar'; -const Avatar: FC & WithWrapperProps = ({ - className, - children, - component, - randomBackgroundColor, - backgroundColorRandomizer, - ...rest -}: AvatarProps): ReactElement => { - const colorRandomizer: string = useMemo(() => { - if (backgroundColorRandomizer) { - return backgroundColorRandomizer; - } +/** + * The Alert component display brief messages for the user without interrupting their use of the app. + * + * Demos: + * + * - [Avatar (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-avatar) + * - [Avatar (MUI)](https://mui.com/material-ui/react-avatar/) + * + * API: + * + * - [Avatar API](https://mui.com/material-ui/api/avatar/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Avatar component. + * @param ref - The ref to be forwarded to the MuiAvatar component. + * @returns The rendered Avatar component. + */ +const Avatar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, children, randomBackgroundColor, backgroundColorRandomizer, ...rest}: AvatarProps, + ref: MutableRefObject, + ): ReactElement => { + const colorRandomizer: string = useMemo(() => { + if (backgroundColorRandomizer) { + return backgroundColorRandomizer; + } - if (typeof children === 'string') { - return children; - } + if (typeof children === 'string') { + return children; + } - return ''; - }, [children, backgroundColorRandomizer]); + return ''; + }, [children, backgroundColorRandomizer]); - const {color} = usePastelColorGenerator(colorRandomizer); + const {color} = usePastelColorGenerator(colorRandomizer); - const classes: string = clsx('oxygen-avatar', className); + const classes: string = clsx('oxygen-avatar', className); - return ( - - {children} - - ); -}; + return ( + + {children} + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Avatar.displayName = composeComponentDisplayName(COMPONENT_NAME); Avatar.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Avatar/index.ts b/packages/react/src/components/Avatar/index.ts index ed378b1d..26c4986b 100644 --- a/packages/react/src/components/Avatar/index.ts +++ b/packages/react/src/components/Avatar/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Avatar'; -export type {AvatarProps} from './Avatar'; +export * from './Avatar'; + +export type {AvatarPropsVariantOverrides, AvatarTypeMap} from '@mui/material/Avatar'; diff --git a/packages/react/src/components/Backdrop/Backdrop.tsx b/packages/react/src/components/Backdrop/Backdrop.tsx index 74f90a53..bcedc736 100644 --- a/packages/react/src/components/Backdrop/Backdrop.tsx +++ b/packages/react/src/components/Backdrop/Backdrop.tsx @@ -16,22 +16,61 @@ * under the License. */ -import MuiBackdrop, {BackdropProps as MuiBackdropProps} from '@mui/material/Backdrop'; +import MuiBackdrop from '@mui/material/Backdrop'; +import type {BackdropProps as MuiBackdropProps, BackdropTypeMap} from '@mui/material/Backdrop'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './backdrop.scss'; -export type BackdropProps = MuiBackdropProps; +export type BackdropProps< + C extends ElementType = ElementType, + D extends ElementType = BackdropTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Backdrop'; -const Backdrop: FC & WithWrapperProps = ({className, ...rest}: BackdropProps): ReactElement => { - const classes: string = clsx('oxygen-backdrop', className); +/** + * The Backdrop component narrows the user's focus to a particular element on the screen. + * + * Demos: + * + * - [Backdrop (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-backdrop) + * - [Backdrop (MUI)](https://mui.com/material-ui/react-backdrop/) + * + * API: + * + * - [Backdrop API](https://mui.com/material-ui/api/backdrop/) + * - inherits [Fade API](https://mui.com/material-ui/api/fade/) + * + * @remarks + * - ✔️ Props of the [Fade](https://mui.com/material-ui/api/fade/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Backdrop component. + * @param ref - The ref to be forwarded to the MuiBackdrop component. + * @returns The rendered Backdrop component. + */ +const Backdrop: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: BackdropProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-backdrop', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Backdrop.displayName = composeComponentDisplayName(COMPONENT_NAME); Backdrop.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Backdrop/index.ts b/packages/react/src/components/Backdrop/index.ts index ca508f8e..c992ac72 100644 --- a/packages/react/src/components/Backdrop/index.ts +++ b/packages/react/src/components/Backdrop/index.ts @@ -17,4 +17,7 @@ */ export {default} from './Backdrop'; -export type {BackdropProps} from './Backdrop'; +export * from './Backdrop'; + +export {BackdropRoot} from '@mui/material/Backdrop'; +export type {BackdropComponentsPropsOverrides, BackdropTypeMap} from '@mui/material/Backdrop'; diff --git a/packages/react/src/components/Badge/Badge.tsx b/packages/react/src/components/Badge/Badge.tsx index 8d45dd24..8a976ed4 100644 --- a/packages/react/src/components/Badge/Badge.tsx +++ b/packages/react/src/components/Badge/Badge.tsx @@ -16,22 +16,62 @@ * under the License. */ -import MuiBadge, {BadgeProps as MuiBadgeProps} from '@mui/material/Badge'; +import MuiBadge from '@mui/material/Badge'; +import type {BadgeProps as MuiBadgeProps, BadgeTypeMap} from '@mui/material/Badge'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './badge.scss'; -export type BadgeProps = MuiBadgeProps; +export type BadgeProps< + C extends ElementType = ElementType, + D extends ElementType = BadgeTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Badge'; -const Badge: FC & WithWrapperProps = ({className, ...rest}: BadgeProps): ReactElement => { - const classes: string = clsx('oxygen-badge', className); +/** + * The Badge component generates a small badge to the top-right of its child(ren). + * + * Demos: + * + * - [Avatar (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-avatar) + * - [Badge (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-badge/) + * - [Avatar (MUI)](https://mui.com/material-ui/react-avatar/) + * - [Badge (MUI)](https://mui.com/material-ui/react-badge/) + * + * API: + * + * - [Badge API](https://mui.com/material-ui/api/badge/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Badge component. + * @param ref - The ref to be forwarded to the MuiBadge component. + * @returns The rendered Badge component. + */ +const Badge: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: BadgeProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-badge', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Badge.displayName = composeComponentDisplayName(COMPONENT_NAME); Badge.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Badge/index.ts b/packages/react/src/components/Badge/index.ts index d01c35d7..f0f7774d 100644 --- a/packages/react/src/components/Badge/index.ts +++ b/packages/react/src/components/Badge/index.ts @@ -17,4 +17,7 @@ */ export {default} from './Badge'; -export type {BadgeProps} from './Badge'; +export * from './Badge'; + +export {BadgeRoot, BadgeMark} from '@mui/material/Badge'; +export type {BadgePropsVariantOverrides, BadgePropsColorOverrides, BadgeOrigin} from '@mui/material/Badge'; diff --git a/packages/react/src/components/Box/Box.tsx b/packages/react/src/components/Box/Box.tsx index 4e75f991..159bbec2 100644 --- a/packages/react/src/components/Box/Box.tsx +++ b/packages/react/src/components/Box/Box.tsx @@ -16,23 +16,58 @@ * under the License. */ -import MuiBox, {BoxProps as MuiBoxProps} from '@mui/material/Box'; +import MuiBox from '@mui/material/Box'; +import type {BoxProps as MuiBoxProps} from '@mui/material/Box'; +import {BoxTypeMap} from '@mui/system'; import clsx from 'clsx'; -import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type BoxProps = { +export type BoxProps< + C extends ElementType = ElementType, + D extends ElementType = BoxTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Box'; +/** + * The Box component is a generic, theme-aware container with access to CSS utilities from MUI System. + * + * Demos: + * + * - [Box (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/layout-box) + * - [Box (MUI)](https://mui.com/material-ui/react-box/) + * + * API: + * + * - [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Badge component. + * @param ref - The ref to be forwarded to the MuiBadge component. + * @returns The rendered Badge component. + */ const Box: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: BoxProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: BoxProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-box', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/Box/index.ts b/packages/react/src/components/Box/index.ts index cd76e3f7..d3e04e14 100644 --- a/packages/react/src/components/Box/index.ts +++ b/packages/react/src/components/Box/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Box'; -export type {BoxProps} from './Box'; +export * from './Box'; + +export {BoxTypeMap} from '@mui/system/Box'; diff --git a/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx b/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx index 9e43ea0d..dd93a278 100644 --- a/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx +++ b/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx @@ -16,30 +16,65 @@ * under the License. */ -import MuiBreadcrumbs, {BreadcrumbsProps as MuiBreadcrumbsProps} from '@mui/material/Breadcrumbs'; +import MuiBreadcrumbs from '@mui/material/Breadcrumbs'; +import type {BreadcrumbsProps as MuiBreadcrumbsProps, BreadcrumbsTypeMap} from '@mui/material/Breadcrumbs'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './breadcrumbs.scss'; -export type BreadcrumbsProps = MuiBreadcrumbsProps; +export type BreadcrumbsProps< + C extends ElementType = ElementType, + D extends ElementType = BreadcrumbsTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Breadcrumbs'; -const Breadcrumbs: FC & WithWrapperProps = ({ - className, - children, - ...rest -}: BreadcrumbsProps): ReactElement => { - const classes: string = clsx('oxygen-breadcrumbs', className); +/** + * The Breadcrumbs component is a list of links that help visualize a page's location within + * a site's hierarchical structure, it allows navigation up to any of the ancestors. + * + * Demos: + * + * - [Breadcrumbs (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-breadcrumbs) + * - [Breadcrumbs (MUI)](https://mui.com/material-ui/react-breadcrumbs/) + * + * API: + * + * - [Breadcrumbs API](https://mui.com/material-ui/api/breadcrumbs/) + * + * @remarks + * - ✔️ Props of the [Typography](https://mui.com/material-ui/api/typography/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Breadcrumbs component. + * @param ref - The ref to be forwarded to the MuiBreadcrumbs component. + * @returns The rendered Breadcrumbs component. + */ +const Breadcrumbs: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, children, ...rest}: BreadcrumbsProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-breadcrumbs', className); - return ( - - {children} - - ); -}; + return ( + + {children} + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Breadcrumbs.displayName = composeComponentDisplayName(COMPONENT_NAME); Breadcrumbs.muiName = 'Breadcrumbs'; diff --git a/packages/react/src/components/Breadcrumbs/index.ts b/packages/react/src/components/Breadcrumbs/index.ts index b2114fc0..cd144ade 100644 --- a/packages/react/src/components/Breadcrumbs/index.ts +++ b/packages/react/src/components/Breadcrumbs/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Breadcrumbs'; -export type {BreadcrumbsProps} from './Breadcrumbs'; +export * from './Breadcrumbs'; + +export {BreadcrumbsTypeMap} from '@mui/material/Breadcrumbs'; diff --git a/packages/react/src/components/Button/Button.tsx b/packages/react/src/components/Button/Button.tsx index 133f3b48..9fb06d76 100644 --- a/packages/react/src/components/Button/Button.tsx +++ b/packages/react/src/components/Button/Button.tsx @@ -16,22 +16,61 @@ * under the License. */ -import MuiButton, {LoadingButtonProps as MuiButtonProps} from '@mui/lab/LoadingButton'; +import MuiButton from '@mui/lab/LoadingButton'; +import type {LoadingButtonTypeMap, LoadingButtonProps as MuiButtonProps} from '@mui/lab/LoadingButton'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './button.scss'; -export type ButtonProps = MuiButtonProps; +export type ButtonProps< + C extends ElementType = ElementType, + D extends ElementType = LoadingButtonTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Button'; -const Button: FC & WithWrapperProps = ({className, ...rest}: ButtonProps): ReactElement => { - const classes: string = clsx('oxygen-button', className); +/** + * The Button component allow users to take actions, and make choices, with a single tap. + * + * Demos: + * + * - [Button (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-button) + * - [Button (MUI)](https://mui.com/material-ui/react-button/) + * + * API: + * + * - [LoadingButton API](https://mui.com/material-ui/api/loading-button/) + * - inherits [Button API](https://mui.com/material-ui/api/button/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Button component. + * @param ref - The ref to be forwarded to the MuiButton component. + * @returns The rendered Button component. + */ +const Button: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, children, ...rest}: ButtonProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-button', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Button.displayName = composeComponentDisplayName(COMPONENT_NAME); Button.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Button/index.ts b/packages/react/src/components/Button/index.ts index 3fef8878..9e0afec9 100644 --- a/packages/react/src/components/Button/index.ts +++ b/packages/react/src/components/Button/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Button'; -export type {ButtonProps} from './Button'; +export * from './Button'; + +export type {LoadingButtonTypeMap} from '@mui/lab/LoadingButton'; diff --git a/packages/react/src/components/Card/Card.tsx b/packages/react/src/components/Card/Card.tsx index 53a39df1..bcf4bbb4 100644 --- a/packages/react/src/components/Card/Card.tsx +++ b/packages/react/src/components/Card/Card.tsx @@ -16,19 +16,51 @@ * under the License. */ -import MuiCard, {CardProps as MuiCardProps} from '@mui/material/Card'; +import MuiCard from '@mui/material/Card'; +import type {CardProps as MuiCardProps, CardTypeMap} from '@mui/material/Card'; import clsx from 'clsx'; -import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './card.scss'; -export type CardProps = { +export type CardProps< + C extends ElementType = ElementType, + D extends ElementType = CardTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Card'; +/** + * The Card component contain content and actions about a single subject. + * + * Demos: + * + * - [Card (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-card) + * - [Card (MUI)](https://mui.com/material-ui/react-card/) + * + * API: + * + * - [Card API](https://mui.com/material-ui/api/card/) + * - inherits [Paper API](https://mui.com/material-ui/api/paper/) + * + * @remarks + * - ✔️ Props of the [Paper](https://mui.com/material-ui/api/paper/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Card component. + * @param ref - The ref to be forwarded to the MuiCard component. + * @returns The rendered Card component. + */ const Card: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ( {className, component, onClick, elevation = 0, variant = 'outlined', ...rest}: CardProps, diff --git a/packages/react/src/components/Card/index.ts b/packages/react/src/components/Card/index.ts index ac35e13e..061442ef 100644 --- a/packages/react/src/components/Card/index.ts +++ b/packages/react/src/components/Card/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Card'; -export type {CardProps} from './Card'; +export * from './Card'; + +export type {CardPropsColorOverrides, CardTypeMap} from '@mui/material/Card'; diff --git a/packages/react/src/components/CardActions/CardActions.tsx b/packages/react/src/components/CardActions/CardActions.tsx index f48f2271..96f255f8 100644 --- a/packages/react/src/components/CardActions/CardActions.tsx +++ b/packages/react/src/components/CardActions/CardActions.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiCardActions, {CardActionsProps as MuiCardActionsProps} from '@mui/material/CardActions'; +import MuiCardActions from '@mui/material/CardActions'; +import type {CardActionsProps as MuiCardActionsProps} from '@mui/material/CardActions'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './card-actions.scss'; @@ -27,11 +29,35 @@ export type CardActionsProps = MuiCardActionsProps; const COMPONENT_NAME: string = 'CardActions'; -const CardActions: FC & WithWrapperProps = ({className, ...rest}: CardActionsProps): ReactElement => { - const classes: string = clsx('oxygen-card-actions', className); +/** + * The Card Actions component is an optional wrapper that groups a set of buttons. + * + * Demos: + * + * - [Card (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-card) + * - [Card (MUI)](https://mui.com/material-ui/react-card/) + * + * API: + * + * - [CardActions API](https://mui.com/material-ui/api/card-actions/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CardActions component. + * @param ref - The ref to be forwarded to the MuiCardActions component. + * @returns The rendered CardActions component. + */ +const CardActions: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: CardActionsProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-card-actions', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; CardActions.displayName = composeComponentDisplayName(COMPONENT_NAME); CardActions.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/CardActions/index.ts b/packages/react/src/components/CardActions/index.ts index 4f48e301..54117332 100644 --- a/packages/react/src/components/CardActions/index.ts +++ b/packages/react/src/components/CardActions/index.ts @@ -17,4 +17,4 @@ */ export {default} from './CardActions'; -export type {CardActionsProps} from './CardActions'; +export * from './CardActions'; diff --git a/packages/react/src/components/CardContent/CardContent.tsx b/packages/react/src/components/CardContent/CardContent.tsx index 6ac42d40..cffbffda 100644 --- a/packages/react/src/components/CardContent/CardContent.tsx +++ b/packages/react/src/components/CardContent/CardContent.tsx @@ -16,17 +16,50 @@ * under the License. */ -import MuiCardContent, {CardContentProps as MuiCardContentProps} from '@mui/material/CardContent'; +import MuiCardContent from '@mui/material/CardContent'; +import type {CardContentProps as MuiCardContentProps, CardContentTypeMap} from '@mui/material/CardContent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './card-content.scss'; -export type CardContentProps = MuiCardContentProps; +export type CardContentProps< + C extends ElementType = ElementType, + D extends React.ElementType = CardContentTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'CardContent'; +/** + * The Card Content component is the wrapper for the Card content. + * + * Demos: + * + * - [Card (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-card) + * - [Card (MUI)](https://mui.com/material-ui/react-card/) + * + * API: + * + * - [CardContent API](https://mui.com/material-ui/api/card-content/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CardContent component. + * @param ref - The ref to be forwarded to the MuiCardContent component. + * @returns The rendered CardContent component. + */ const CardContent: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ({className, ...rest}: CardContentProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-card-content', className); diff --git a/packages/react/src/components/CardContent/index.ts b/packages/react/src/components/CardContent/index.ts index e4e0bc88..21baaaa5 100644 --- a/packages/react/src/components/CardContent/index.ts +++ b/packages/react/src/components/CardContent/index.ts @@ -17,4 +17,6 @@ */ export {default} from './CardContent'; -export type {CardContentProps} from './CardContent'; +export * from './CardContent'; + +export type {CardContentTypeMap} from '@mui/material/CardContent'; diff --git a/packages/react/src/components/CardHeader/CardHeader.tsx b/packages/react/src/components/CardHeader/CardHeader.tsx index c71804db..8d03d830 100644 --- a/packages/react/src/components/CardHeader/CardHeader.tsx +++ b/packages/react/src/components/CardHeader/CardHeader.tsx @@ -16,22 +16,62 @@ * under the License. */ -import MuiCardHeader, {CardHeaderProps as MuiCardHeaderProps} from '@mui/material/CardHeader'; +import MuiCardHeader from '@mui/material/CardHeader'; +import type {CardHeaderProps as MuiCardHeaderProps, CardHeaderTypeMap} from '@mui/material/CardHeader'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './card-header.scss'; -export type CardHeaderProps = MuiCardHeaderProps; +export type CardHeaderProps< + C extends ElementType = ElementType, + D extends ElementType = CardHeaderTypeMap['defaultComponent'], + P = {}, + T extends ElementType = 'span', + S extends ElementType = 'span', +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'CardHeader'; -const CardHeader: FC & WithWrapperProps = ({className, ...rest}: CardHeaderProps): ReactElement => { - const classes: string = clsx('oxygen-card-header', className); +/** + * The Card Header component is an optional wrapper for the Card header. + * + * Demos: + * + * - [Card (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-card) + * - [Card (MUI)](https://mui.com/material-ui/react-card/) + * + * API: + * + * - [CardHeader API](https://mui.com/material-ui/api/card-header/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CardHeader component. + * @param ref - The ref to be forwarded to the MuiCardHeader component. + * @returns The rendered CardHeader component. + */ +const CardHeader: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: CardHeaderProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-card-header', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; CardHeader.displayName = composeComponentDisplayName(COMPONENT_NAME); CardHeader.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/CardHeader/index.ts b/packages/react/src/components/CardHeader/index.ts index f32ca5ce..20566f34 100644 --- a/packages/react/src/components/CardHeader/index.ts +++ b/packages/react/src/components/CardHeader/index.ts @@ -17,4 +17,6 @@ */ export {default} from './CardHeader'; -export type {CardHeaderProps} from './CardHeader'; +export * from './CardHeader'; + +export type {CardHeaderTypeMap, OverridableCardHeader, CardHeaderPropsWithComponent} from '@mui/material/CardHeader'; diff --git a/packages/react/src/components/Carousel/Carousel.tsx b/packages/react/src/components/Carousel/Carousel.tsx index 0935792a..b9e6bae6 100644 --- a/packages/react/src/components/Carousel/Carousel.tsx +++ b/packages/react/src/components/Carousel/Carousel.tsx @@ -18,23 +18,24 @@ import {ChevronLeftIcon, ChevronRightIcon} from '@oxygen-ui/react-icons'; import clsx from 'clsx'; -import {FC, HTMLAttributes, ReactElement, ReactNode, useEffect, useMemo, useState} from 'react'; -import {useIsMobile} from '../../hooks'; +import {forwardRef, useEffect, useMemo, useState} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; +import {useIsMobile} from '../../hooks/use-is-mobile'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; +import type {BoxProps, BoxTypeMap} from '../Box'; import Button from '../Button'; import Card from '../Card'; import CardContent from '../CardContent'; -import IconButton from '../IconButton'; -import {IconButtonVariants} from '../IconButton/IconButton'; +import IconButton, {IconButtonVariants} from '../IconButton'; import ListItem from '../ListItem'; import ListItemIcon from '../ListItemIcon'; import ListItemText from '../ListItemText'; import Stepper from '../Stepper'; import './carousel.scss'; -export interface CarouselStep { +export type CarouselStep = { /** * Action to be performed on the step. * @example @@ -55,9 +56,13 @@ export interface CarouselStep { * @example title */ title: ReactNode; -} +}; -export interface CarouselProps extends Omit, 'title'> { +export type CarouselProps< + C extends ElementType = ElementType, + D extends ElementType = BoxTypeMap['defaultComponent'], + P = {}, +> = Omit, 'title'> & { /** * Specifies whether to auto play the carousel. */ @@ -83,123 +88,150 @@ export interface CarouselProps extends Omit, 'tit * @example title */ title?: ReactNode; -} +}; const COMPONENT_NAME: string = 'Carousel'; -const Carousel: FC & WithWrapperProps = ({ - autoPlay = false, - autoPlayInterval = 5000, - className, - nextButtonText = 'Next', - previousButtonText = 'Previous', - steps, - title, - ...rest -}: CarouselProps): ReactElement => { - const [currentStep, setCurrentStep] = useState(0); - - const isLastStep: boolean = useMemo(() => currentStep === steps.length - 1, [steps, currentStep]); - const isFirstStep: boolean = useMemo(() => currentStep === 0, [currentStep]); - const isMobile: boolean = useIsMobile(); - - const classes: string = clsx('oxygen-carousel', {mobile: isMobile}, className); - - useEffect(() => { - if (!autoPlay) { - return () => {}; - } - - const interval: NodeJS.Timer = setInterval(() => { +/** + * The Carousel component can be used to slide through content. + * + * Demos: + * + * - [Carousel(Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/patterns-carousel) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Carousel component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered Carousel component. + */ +const Carousel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + { + autoPlay = false, + autoPlayInterval = 5000, + className, + nextButtonText = 'Next', + previousButtonText = 'Previous', + steps, + title, + ...rest + }: CarouselProps, + ref: MutableRefObject, + ): ReactElement => { + const [currentStep, setCurrentStep] = useState(0); + + const isLastStep: boolean = useMemo(() => currentStep === steps.length - 1, [steps, currentStep]); + const isFirstStep: boolean = useMemo(() => currentStep === 0, [currentStep]); + const isMobile: boolean = useIsMobile(); + + const classes: string = clsx('oxygen-carousel', {mobile: isMobile}, className); + + useEffect(() => { + if (!autoPlay) { + return () => {}; + } + + const interval: NodeJS.Timer = setInterval(() => { + if (isLastStep) { + setCurrentStep(0); + } else { + setCurrentStep(currentStep + 1); + } + }, autoPlayInterval); + + return () => clearInterval(interval); + }, [autoPlay, autoPlayInterval, currentStep, isLastStep]); + + const handleNextButtonClick = (): void => { if (isLastStep) { - setCurrentStep(0); - } else { - setCurrentStep(currentStep + 1); + return; } - }, autoPlayInterval); - - return () => clearInterval(interval); - }, [autoPlay, autoPlayInterval, currentStep, isLastStep]); - - const handleNextButtonClick = (): void => { - if (isLastStep) { - return; - } - setCurrentStep(currentStep + 1); - }; - - const handlePreviousButtonClick = (): void => { - if (isFirstStep) { - return; - } - setCurrentStep(currentStep - 1); - }; - - const generateCarouselSteps = (): ReactElement[] => - steps?.map((step: CarouselStep) => { - const {title: stepTitle, description, illustration, action} = step; - return ( - - - - {illustration && {illustration}} - - - - {action && {action}} - - ); - }); - - return ( - - - {title} - - - - - - - + setCurrentStep(currentStep + 1); + }; + + const handlePreviousButtonClick = (): void => { + if (isFirstStep) { + return; + } + setCurrentStep(currentStep - 1); + }; + + const generateCarouselSteps = (): ReactElement[] => + steps?.map((step: CarouselStep) => { + const {title: stepTitle, description, illustration, action} = step; + return ( + + + + {illustration && {illustration}} + + + + {action && {action}} + + ); + }); + + return ( + + + {title} + + + + + + + + + + + + - - - + + - - - - - ); -}; + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Carousel.displayName = composeComponentDisplayName(COMPONENT_NAME); Carousel.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Carousel/index.ts b/packages/react/src/components/Carousel/index.ts index a91d7b31..a9261f98 100644 --- a/packages/react/src/components/Carousel/index.ts +++ b/packages/react/src/components/Carousel/index.ts @@ -17,5 +17,4 @@ */ export {default} from './Carousel'; -export type {CarouselProps} from './Carousel'; -export type {CarouselStep} from './Carousel'; +export * from './Carousel'; diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx index dad65555..688c4eff 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -16,21 +16,56 @@ * under the License. */ -import MuiCheckbox, {CheckboxProps as MuiCheckboxProps} from '@mui/material/Checkbox'; +import MuiCheckbox from '@mui/material/Checkbox'; +import type {CheckboxProps as MuiCheckboxProps} from '@mui/material/Checkbox'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type CheckboxProps = MuiCheckboxProps; +export type CheckboxProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Checkbox'; +/** + * The Checkboxes allow the user to select one or more items from a set. + * + * Demos: + * + * - [Checkbox (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-checkbox) + * - [Checkbox (MUI)](https://mui.com/material-ui/react-checkbox/) + * - [Transfer List (Oxygen UI)](TODO: Add a link after implementing: Tracker: https://github.com/wso2/oxygen-ui/issues/2) + * - [Transfer List (MUI)](https://mui.com/material-ui/react-transfer-list/) + * + * API: + * + * - [Checkbox API](https://mui.com/material-ui/api/checkbox/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Checkbox component. + * @param ref - The ref to be forwarded to the MuiCheckbox component. + * @returns The rendered Checkbox component. + */ const Checkbox: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: CheckboxProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: CheckboxProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-checkbox', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/Checkbox/index.ts b/packages/react/src/components/Checkbox/index.ts index 005edc36..db23cb91 100644 --- a/packages/react/src/components/Checkbox/index.ts +++ b/packages/react/src/components/Checkbox/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Checkbox'; -export type {CheckboxProps} from './Checkbox'; +export * from './Checkbox'; + +export {CheckboxPropsSizeOverrides, CheckboxPropsColorOverrides} from '@mui/material/Checkbox'; diff --git a/packages/react/src/components/Chip/Chip.tsx b/packages/react/src/components/Chip/Chip.tsx index 8dbbdd38..289bbd23 100644 --- a/packages/react/src/components/Chip/Chip.tsx +++ b/packages/react/src/components/Chip/Chip.tsx @@ -16,27 +16,57 @@ * under the License. */ -import MuiChip, {ChipProps as MuiChipProps} from '@mui/material/Chip'; +import MuiChip from '@mui/material/Chip'; +import type {ChipProps as MuiChipProps, ChipTypeMap} from '@mui/material/Chip'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './chip.scss'; -export type ChipProps = { +export type ChipProps< + C extends ElementType = ElementType, + D extends ElementType = ChipTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Chip'; -const Chip: FC & WithWrapperProps = ({ - className, - ...rest -}: ChipProps): ReactElement => { - const classes: string = clsx('oxygen-chip', className); +/** + * The Chips are compact elements that represent an input, attribute, or action. + * + * Demos: + * + * - [Chip (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-chip) + * - [Chip (MUI)](https://mui.com/material-ui/react-chip/) + * + * API: + * + * - [Chip API](https://mui.com/material-ui/api/chip/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Chip component. + * @param ref - The ref to be forwarded to the MuiChip component. + * @returns The rendered Chip component. + */ +const Chip: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: ChipProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-chip', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Chip.displayName = composeComponentDisplayName(COMPONENT_NAME); Chip.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Chip/index.ts b/packages/react/src/components/Chip/index.ts index f799b576..ad4f8257 100644 --- a/packages/react/src/components/Chip/index.ts +++ b/packages/react/src/components/Chip/index.ts @@ -17,4 +17,11 @@ */ export {default} from './Chip'; -export type {ChipProps} from './Chip'; +export * from './Chip'; + +export type { + ChipPropsVariantOverrides, + ChipPropsSizeOverrides, + ChipPropsColorOverrides, + ChipTypeMap, +} from '@mui/material/Chip'; diff --git a/packages/react/src/components/CircularProgress/CircularProgress.tsx b/packages/react/src/components/CircularProgress/CircularProgress.tsx index 4d28a481..64f822dc 100644 --- a/packages/react/src/components/CircularProgress/CircularProgress.tsx +++ b/packages/react/src/components/CircularProgress/CircularProgress.tsx @@ -16,25 +16,58 @@ * under the License. */ -import MuiCircularProgress, {CircularProgressProps as MuiCircularProgressProps} from '@mui/material/CircularProgress'; +import MuiCircularProgress from '@mui/material/CircularProgress'; +import type {CircularProgressProps as MuiCircularProgressProps} from '@mui/material/CircularProgress'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './circular-progress.scss'; -export type CircularProgressProps = MuiCircularProgressProps; +export type CircularProgressProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'CircularProgress'; -const CircularProgress: FC & WithWrapperProps = ({ - className, - ...rest -}: CircularProgressProps): ReactElement => { - const classes: string = clsx('oxygen-circular-progress', className); +/** + * The Circular Progress indicators commonly known as spinners, express an unspecified wait + * time or display the length of a process. + * + * Demos: + * + * TODO: Merge two progress components into one. + * - [Progress (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-circular-progress) + * - [Progress (MUI)](https://mui.com/material-ui/react-progress/) + * + * API: + * + * - [CircularProgress API](https://mui.com/material-ui/api/circular-progress/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CircularProgress component. + * @param ref - The ref to be forwarded to the MuiCircularProgress component. + * @returns The rendered CircularProgress component. + */ +const CircularProgress: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: CircularProgressProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-circular-progress', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; CircularProgress.displayName = composeComponentDisplayName(COMPONENT_NAME); CircularProgress.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/CircularProgress/index.ts b/packages/react/src/components/CircularProgress/index.ts index addbec06..bb9b77b2 100644 --- a/packages/react/src/components/CircularProgress/index.ts +++ b/packages/react/src/components/CircularProgress/index.ts @@ -17,4 +17,6 @@ */ export {default} from './CircularProgress'; -export type {CircularProgressProps} from './CircularProgress'; +export * from './CircularProgress'; + +export {CircularProgressPropsColorOverrides} from '@mui/material/CircularProgress'; diff --git a/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx b/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx index 1b1cb6f4..15262258 100644 --- a/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx +++ b/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx @@ -16,16 +16,24 @@ * under the License. */ -import {Badge, BadgeProps, CircularProgress, CircularProgressProps} from '@mui/material'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import Avatar, {AvatarProps} from '../Avatar'; +import Avatar from '../Avatar'; +import type {AvatarProps} from '../Avatar'; +import type {BadgeProps} from '../Badge'; +import Badge from '../Badge'; import Box from '../Box'; +import type {CircularProgressProps} from '../CircularProgress'; +import CircularProgress from '../CircularProgress'; import './circular-progress-avatar.scss'; -export interface CircularProgressAvatarProps extends Omit { +export type CircularProgressAvatarProps = Omit< + CircularProgressProps, + 'value' +> & { /** * Props sent to the Avatar component. */ @@ -38,51 +46,73 @@ export interface CircularProgressAvatarProps extends Omit & WithWrapperProps = ({ - className, - progress, - badgeOptions, - avatarOptions, - ...rest -}: CircularProgressAvatarProps): ReactElement => { - const classes: string = clsx('oxygen-circular-progress-avatar', className); +/** + * The Circular Progress Avatar is a Avatar variant with a circular progress and a badge. + * + * Demos: + * + * // TODO: Move this demo to the Progress demo. + * - [Circular Progress Avatar (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-circular-progress-avatar) + * + * API: + * + * - [CircularProgress API](https://mui.com/material-ui/api/circular-progress/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CircularProgressAvatar component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered CircularProgressAvatar component. + */ +const CircularProgressAvatar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, progress, badgeOptions, avatarOptions, ...rest}: CircularProgressAvatarProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-circular-progress-avatar', className); - return ( - - - - - - - - ); -}; + return ( + + + + + + + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; CircularProgressAvatar.displayName = composeComponentDisplayName(COMPONENT_NAME); CircularProgressAvatar.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/CircularProgressAvatar/index.ts b/packages/react/src/components/CircularProgressAvatar/index.ts index 1be26dc8..8662fab9 100644 --- a/packages/react/src/components/CircularProgressAvatar/index.ts +++ b/packages/react/src/components/CircularProgressAvatar/index.ts @@ -17,4 +17,4 @@ */ export {default} from './CircularProgressAvatar'; -export type {CircularProgressAvatarProps} from './CircularProgressAvatar'; +export * from './CircularProgressAvatar'; diff --git a/packages/react/src/components/Code/Code.tsx b/packages/react/src/components/Code/Code.tsx index 611f65a0..b81600b9 100644 --- a/packages/react/src/components/Code/Code.tsx +++ b/packages/react/src/components/Code/Code.tsx @@ -16,18 +16,15 @@ * under the License. */ -import MuiTypography, {TypographyProps as MuiTypographyProps} from '@mui/material/Typography'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import Typography, {TypographyProps} from '../Typography/Typography'; import './code.scss'; -export type CodeProps = { - /** - * The component used for the root node. Either a string to use a HTML element or a component. - */ - component?: C; +export type CodeProps = TypographyProps & { /** * Shows the code block with a filled background. * @default true @@ -38,25 +35,46 @@ export type CodeProps = { * @default false */ outlined?: boolean; -} & Omit; +}; const COMPONENT_NAME: string = 'Code'; -const Code: FC & WithWrapperProps = ({ - className, - children, - filled = true, - outlined = false, - ...rest -}: CodeProps): ReactElement => { - const classes: string = clsx('oxygen-code', {filled, outlined}, className); +/** + * The Code can represent an inline or block code without syntax highlight. + * + * Demos: + * + * - [Code (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-code) + * + * API: + * + * - inherits [Typography API](https://mui.com/material-ui/api/typography/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Typography](https://mui.com/material-ui/api/typography/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Code component. + * @param ref - The ref to be forwarded to the Typography component. + * @returns The rendered Code component. + */ +const Code: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, children, filled = true, outlined = false, ...rest}: CodeProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-code', {filled, outlined}, className); - return ( - - {children} - - ); -}; + return ( + + {children} + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Code.displayName = composeComponentDisplayName(COMPONENT_NAME); Code.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Code/index.ts b/packages/react/src/components/Code/index.ts index 477314ff..dbeac608 100644 --- a/packages/react/src/components/Code/index.ts +++ b/packages/react/src/components/Code/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Code'; -export type {CodeProps} from './Code'; +export * from './Code'; diff --git a/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx b/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx index 389a9807..5ccdfe29 100644 --- a/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx +++ b/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx @@ -19,7 +19,8 @@ import MuiCollapse from '@mui/material/Collapse'; import {ChevronDownIcon, ChevronUpIcon} from '@oxygen-ui/react-icons'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement, useState} from 'react'; +import {forwardRef, useState} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MouseEvent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; @@ -28,29 +29,51 @@ import List from '../List'; import ListItemButton from '../ListItemButton'; import ListItemIcon from '../ListItemIcon'; import ListItemText from '../ListItemText'; -import type {NavbarProps} from '../Navbar/Navbar'; +import type {NavbarProps} from '../Navbar'; import type {NavbarItemProps} from '../NavbarItem'; import Tooltip from '../Tooltip'; import './collapsible-navbar-item.scss'; -export interface CollapsibleNavbarItemProps extends NavbarItemProps, Pick { - /** - * Is the item expanded. - */ - expanded?: boolean; - /** - * Set of sub items. - */ - items: NavbarItemProps[]; -} +export type CollapsibleNavbarItemProps = NavbarItemProps & + Pick & { + /** + * Is the item expanded. + */ + expanded?: boolean; + /** + * Set of sub items. + */ + items: NavbarItemProps[]; + }; const COMPONENT_NAME: string = 'CollapsibleNavbarItem'; +/** + * The Collapsible Navbar Item is a custom component that is used to render a collapsible item in the Navbar. + * + * Demos: + * + * - [Collapsible Navbar Item (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-collapsible-navbar-item) + * + * API: + * + * - inherits [ListItemButton API](https://mui.com/material-ui/api/list-item-button/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the CollapsibleNavbarItem component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered CollapsibleNavbarItem component. + */ const CollapsibleNavbarItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ( + ( { className, - component, expanded, fill, icon, @@ -62,7 +85,7 @@ const CollapsibleNavbarItem: ForwardRefExoticComponent, ref: MutableRefObject, ): ReactElement => { const classes: string = clsx( @@ -77,10 +100,11 @@ const CollapsibleNavbarItem: ForwardRefExoticComponent(expanded || false); - const handleItemClick = (): void => { + const handleItemClick = (e: MouseEvent): void => { if (onClick) { - onClick(); + onClick(e); } + setItemExpanded((prevState: boolean) => !prevState); }; @@ -89,7 +113,7 @@ const CollapsibleNavbarItem: ForwardRefExoticComponent (itemExpanded ? : ); return ( - + = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ColorModeToggle'; @@ -66,28 +84,53 @@ const CrescentIcon = (props: PropsWithChildren>): ReactE ); -const ColorModeToggle: FC & WithWrapperProps = ({ - className, - ...rest -}: ColorModeToggleProps): ReactElement => { - const {mode, setMode} = useColorScheme(); +/** + * The Toggle to switch between the two palette modes: light (the default) and dark. + * + * Demos: + * + * - [Color Mode Toggle (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/theme-color-mode-toggle--overview) + * + * API: + * + * - [IconButton API](https://mui.com/material-ui/api/icon-button/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the ColorModeToggle component. + * @param ref - The ref to be forwarded to the IconButton component. + * @returns The rendered ColorModeToggle component. + */ +const ColorModeToggle: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ColorModeToggleProps, + ref: MutableRefObject, + ): ReactElement => { + const {mode, setMode} = useColorScheme(); - const classes: string = clsx('oxygen-color-mode-toggle', className); + const classes: string = clsx('oxygen-color-mode-toggle', className); - return ( - { - setMode(mode === 'light' ? 'dark' : 'light'); - }} - color="inherit" - className={classes} - {...rest} - > - {mode === 'light' ? : } - - ); -}; + return ( + { + setMode(mode === 'light' ? 'dark' : 'light'); + }} + color="inherit" + className={classes} + {...rest} + > + {mode === 'light' ? : } + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; ColorModeToggle.displayName = composeComponentDisplayName(COMPONENT_NAME); ColorModeToggle.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/ColorModeToggle/index.ts b/packages/react/src/components/ColorModeToggle/index.ts index a048e05b..5ff1db43 100644 --- a/packages/react/src/components/ColorModeToggle/index.ts +++ b/packages/react/src/components/ColorModeToggle/index.ts @@ -17,4 +17,4 @@ */ export {default} from './ColorModeToggle'; -export type {ColorModeToggleProps} from './ColorModeToggle'; +export * from './ColorModeToggle'; diff --git a/packages/react/src/components/Container/Container.tsx b/packages/react/src/components/Container/Container.tsx index a668ce21..4654efb6 100644 --- a/packages/react/src/components/Container/Container.tsx +++ b/packages/react/src/components/Container/Container.tsx @@ -16,27 +16,60 @@ * under the License. */ -import MuiContainer, {ContainerProps as MuiContainerProps} from '@mui/material/Container'; +import MuiContainer from '@mui/material/Container'; +import type {ContainerProps as MuiContainerProps, ContainerTypeMap} from '@mui/material/Container'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './container.scss'; -export type ContainerProps = { +export type ContainerProps< + C extends ElementType = ElementType, + D extends ElementType = ContainerTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Container'; -const Container: FC & WithWrapperProps = ({ - className, - ...rest -}: ContainerProps): ReactElement => { - const classes: string = clsx('oxygen-container', className); +/** + * The container centers your content horizontally. It's the most basic layout element. + * + * Demos: + * + * - [Container (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/layout-container) + * - [Container (MUI)](https://mui.com/material-ui/react-container/) + * + * API: + * + * - [Container API](https://mui.com/material-ui/api/container/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Container component. + * @param ref - The ref to be forwarded to the MuiContainer component. + * @returns The rendered Container component. + */ +const Container: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ContainerProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-container', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Container.displayName = composeComponentDisplayName(COMPONENT_NAME); Container.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Container/index.ts b/packages/react/src/components/Container/index.ts index e65a0906..6016c087 100644 --- a/packages/react/src/components/Container/index.ts +++ b/packages/react/src/components/Container/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Container'; -export type {ContainerProps} from './Container'; +export * from './Container'; + +export {ContainerTypeMap} from '@mui/material/Container'; diff --git a/packages/react/src/components/CountryFlag/CountryFlag.tsx b/packages/react/src/components/CountryFlag/CountryFlag.tsx index f7489431..fcd56a5d 100644 --- a/packages/react/src/components/CountryFlag/CountryFlag.tsx +++ b/packages/react/src/components/CountryFlag/CountryFlag.tsx @@ -16,13 +16,14 @@ * under the License. */ -import {Typography} from '@mui/material'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, HTMLAttributes, MutableRefObject, ReactElement} from 'react'; import WorldFlag from 'react-world-flags'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import Typography from '../Typography'; -export interface CountryFlagsProps extends React.HTMLAttributes { +export type CountryFlagProps = { /** * The two-letter/three-letter/three-digit country code of the flag. */ @@ -31,17 +32,38 @@ export interface CountryFlagsProps extends React.HTMLAttributes; -const COMPONENT_NAME: string = 'Flag'; +const COMPONENT_NAME: string = 'CountryFlag'; -const CountryFlag: FC & WithWrapperProps = ({ - countryCode, - height = '16', - ...rest -}: CountryFlagsProps): ReactElement => ( - {countryCode}} {...rest} /> -); +/** + * The Toggle to switch between the two palette modes: light (the default) and dark. + * + * Demos: + * + * - [Country Flag (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/icons-country-flags) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the CountryFlag component. + * @param ref - The ref to be forwarded to the WorldFlag component. + * @returns The rendered CountryFlag component. + */ +const CountryFlag: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({countryCode, height = '16', ...rest}: CountryFlagProps, ref: MutableRefObject): ReactElement => ( + {countryCode}} + {...rest} + /> + ), +) as ForwardRefExoticComponent & WithWrapperProps; CountryFlag.displayName = composeComponentDisplayName(COMPONENT_NAME); CountryFlag.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/CountryFlag/index.ts b/packages/react/src/components/CountryFlag/index.ts index f9f59eba..1362398e 100644 --- a/packages/react/src/components/CountryFlag/index.ts +++ b/packages/react/src/components/CountryFlag/index.ts @@ -17,4 +17,4 @@ */ export {default} from './CountryFlag'; -export type {CountryFlagsProps} from './CountryFlag'; +export * from './CountryFlag'; diff --git a/packages/react/src/components/DataGrid/DataGrid.tsx b/packages/react/src/components/DataGrid/DataGrid.tsx index 81245176..d1be7689 100644 --- a/packages/react/src/components/DataGrid/DataGrid.tsx +++ b/packages/react/src/components/DataGrid/DataGrid.tsx @@ -16,22 +16,49 @@ * under the License. */ -import {DataGrid as MuiDataGrid, DataGridProps as MuiDataGridProps} from '@mui/x-data-grid'; +import {DataGrid as MuiXDataGrid} from '@mui/x-data-grid'; +import type {GridValidRowModel as MuiXGridValidRowModel, DataGridProps as MuiXDataGridProps} from '@mui/x-data-grid'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './data-grid.scss'; -export type DataGridProps = MuiDataGridProps; +export type DataGridProps = MuiXDataGridProps; const COMPONENT_NAME: string = 'DataGrid'; -const DataGrid: FC & WithWrapperProps = ({className, ...rest}: DataGridProps): ReactElement => { - const classes: string = clsx('oxygen-data-grid', className); +/** + * The Data Grid component is built with React and TypeScript to provide a smooth UX for manipulating + * an unlimited set of data. It features an intuitive API for real-time updates as well as theming + * and custom templates—all with blazing-fast performance. + * + * Demos: + * + * - [Data Grid (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-datagrid) + * - [Data Grid (MUI X)](https://mui.com/x/react-data-grid/) + * + * API: + * + * - [DataGrid API](https://mui.com/x/api/data-grid/data-grid/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the DataGrid component. + * @param ref - The ref to be forwarded to the MuiDataGrid component. + * @returns The rendered DataGrid component. + */ +const DataGrid: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: DataGridProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-data-grid', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; DataGrid.displayName = composeComponentDisplayName(COMPONENT_NAME); DataGrid.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/DataGrid/index.ts b/packages/react/src/components/DataGrid/index.ts index 0580fc48..6af665e3 100644 --- a/packages/react/src/components/DataGrid/index.ts +++ b/packages/react/src/components/DataGrid/index.ts @@ -17,4 +17,31 @@ */ export {default} from './DataGrid'; -export type {DataGridProps} from './DataGrid'; +export * from './DataGrid'; + +export * from '@mui/x-data-grid/components'; +export * from '@mui/x-data-grid/constants'; +export * from '@mui/x-data-grid/hooks'; +export * from '@mui/x-data-grid/locales'; +export * from '@mui/x-data-grid/models'; +export * from '@mui/x-data-grid/context'; +export * from '@mui/x-data-grid/colDef'; +export * from '@mui/x-data-grid/utils'; +export { + useGridRootProps, + useGridApiRef, + useGridApiContext, + GridColumnHeaders, + GridColumnMenu, + GRID_COLUMN_MENU_SLOTS, + GRID_COLUMN_MENU_SLOT_PROPS, +} from '@mui/x-data-grid'; +export type { + GridApi, + GridState, + GridInitialState, + GridExportFormat, + GridExportExtension, + GridToolbarExportProps, + GridExperimentalFeatures, +} from '@mui/x-data-grid'; diff --git a/packages/react/src/components/Divider/Divider.tsx b/packages/react/src/components/Divider/Divider.tsx index 831a6bf6..c74b6658 100644 --- a/packages/react/src/components/Divider/Divider.tsx +++ b/packages/react/src/components/Divider/Divider.tsx @@ -16,22 +16,62 @@ * under the License. */ -import MuiDivider, {DividerProps as MuiDividerProps} from '@mui/material/Divider'; +import MuiDivider from '@mui/material/Divider'; +import type {DividerProps as MuiDividerProps, DividerTypeMap as MuiDividerTypeMap} from '@mui/material/Divider'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './divider.scss'; -export type DividerProps = MuiDividerProps; +export type DividerProps< + C extends ElementType = ElementType, + D extends ElementType = MuiDividerTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Divider'; -const Divider: FC & WithWrapperProps = ({className, ...rest}: DividerProps): ReactElement => { - const classes: string = clsx('oxygen-divider', className); +/** + * The Divider provides a thin, unobtrusive line for grouping elements to reinforce visual hierarchy. + * + * Demos: + * + * - [Divider (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-divider) + * - [Divider (MUI)](https://mui.com/material-ui/react-divider/) + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * + * API: + * + * - [Divider API](https://mui.com/material-ui/api/divider/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Divider component. + * @param ref - The ref to be forwarded to the MuiDivider component. + * @returns The rendered Divider component. + */ +const Divider: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: DividerProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-divider', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Divider.displayName = composeComponentDisplayName(COMPONENT_NAME); Divider.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Divider/index.ts b/packages/react/src/components/Divider/index.ts index 29f4138e..480521cb 100644 --- a/packages/react/src/components/Divider/index.ts +++ b/packages/react/src/components/Divider/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Divider'; -export type {DividerProps} from './Divider'; +export * from './Divider'; + +export type {DividerPropsVariantOverrides, DividerTypeMap} from '@mui/material/Divider'; diff --git a/packages/react/src/components/Drawer/Drawer.tsx b/packages/react/src/components/Drawer/Drawer.tsx index 1bc11823..bdefaf56 100644 --- a/packages/react/src/components/Drawer/Drawer.tsx +++ b/packages/react/src/components/Drawer/Drawer.tsx @@ -16,22 +16,57 @@ * under the License. */ -import MuiDrawer, {DrawerProps as MuiDrawerProps} from '@mui/material/Drawer'; +import MuiDrawer from '@mui/material/Drawer'; +import type {DrawerProps as MuiDrawerProps} from '@mui/material/Drawer'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './drawer.scss'; -export type DrawerProps = MuiDrawerProps; +export type DrawerProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Drawer'; -const Drawer: FC & WithWrapperProps = ({className, ...rest}: DrawerProps): ReactElement => { - const classes: string = clsx('oxygen-drawer', className); +/** + * The navigation drawers (or "sidebars") provide ergonomic access to destinations in a site or + * app functionality such as switching accounts. + * + * Demos: + * + * - [Drawer (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-drawer) + * - [Drawer (MUI)](https://mui.com/material-ui/react-drawer/) + * + * API: + * + * - [Drawer API](https://mui.com/material-ui/api/drawer/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Drawer component. + * @param ref - The ref to be forwarded to the MuiDrawer component. + * @returns The rendered Drawer component. + */ +const Drawer: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: DrawerProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-drawer', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Drawer.displayName = composeComponentDisplayName(COMPONENT_NAME); Drawer.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Drawer/index.ts b/packages/react/src/components/Drawer/index.ts index 41d950f9..11d00665 100644 --- a/packages/react/src/components/Drawer/index.ts +++ b/packages/react/src/components/Drawer/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Drawer'; -export type {DrawerProps} from './Drawer'; +export * from './Drawer'; diff --git a/packages/react/src/components/Fab/Fab.tsx b/packages/react/src/components/Fab/Fab.tsx index 19feb9bf..c2e9c596 100644 --- a/packages/react/src/components/Fab/Fab.tsx +++ b/packages/react/src/components/Fab/Fab.tsx @@ -16,18 +16,50 @@ * under the License. */ -import MuiFab, {FabProps as MuiFabProps} from '@mui/material/Fab'; +import MuiFab from '@mui/material/Fab'; +import type {FabProps as MuiFabProps, FabTypeMap as MuiFabTypeMap} from '@mui/material/Fab'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type FabProps = { +export type FabProps< + C extends ElementType = ElementType, + D extends ElementType = MuiFabTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Fab'; +/** + * A Floating Action Button (FAB) performs the primary, or most common, action on a screen. + * + * Demos: + * + * - [Floating Action Button (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-fab) + * - [Floating Action Button (MUI)](https://mui.com/material-ui/react-floating-action-button/) + * + * API: + * + * - [Fab API](https://mui.com/material-ui/api/fab/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Fab component. + * @param ref - The ref to be forwarded to the MuiFab component. + * @returns The rendered Fab component. + */ const Fab: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ( {className, ...rest}: FabProps, @@ -35,7 +67,7 @@ const Fab: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ): ReactElement => { const classes: string = clsx('oxygen-fab', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/Fab/index.ts b/packages/react/src/components/Fab/index.ts index 5aaaf4a7..e57c8110 100644 --- a/packages/react/src/components/Fab/index.ts +++ b/packages/react/src/components/Fab/index.ts @@ -17,4 +17,11 @@ */ export {default} from './Fab'; -export type {FabProps} from './Fab'; +export * from './Fab'; + +export type { + FabPropsVariantOverrides, + FabPropsSizeOverrides, + FabPropsColorOverrides, + FabTypeMap, +} from '@mui/material/Fab'; diff --git a/packages/react/src/components/Footer/Footer.tsx b/packages/react/src/components/Footer/Footer.tsx index d90c760f..cd5ceace 100644 --- a/packages/react/src/components/Footer/Footer.tsx +++ b/packages/react/src/components/Footer/Footer.tsx @@ -17,17 +17,21 @@ */ import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; -import {useIsMobile} from '../../hooks'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; +import {useIsMobile} from '../../hooks/use-is-mobile'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import Box, {BoxProps} from '../Box'; -import Container, {ContainerProps} from '../Container'; -import Link, {LinkProps} from '../Link'; +import Box from '../Box'; +import type {BoxProps} from '../Box'; +import Container from '../Container'; +import type {ContainerProps} from '../Container'; +import Link from '../Link'; +import type {LinkProps} from '../Link'; import Typography from '../Typography'; import './footer.scss'; -export interface FooterProps extends BoxProps { +export type FooterProps = BoxProps & { /** * Copyright to display. */ @@ -40,52 +44,69 @@ export interface FooterProps extends BoxProps { * Determine the max-width of the footer container. */ maxWidth?: ContainerProps['maxWidth']; -} +}; const COMPONENT_NAME: string = 'Footer'; -const Footer: FC & WithWrapperProps = ({ - className, - copyright, - links, - maxWidth, - ...rest -}: FooterProps): ReactElement => { - const isMobile: boolean = useIsMobile(); +/** + * The Footers display a set of links and a copyright at the bottom of the application. + * + * Demos: + * + * - [Footer (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-footer) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Footer component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered Footer component. + */ +const Footer: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, copyright, component = 'footer' as C, links, maxWidth, ...rest}: FooterProps, + ref: MutableRefObject, + ): ReactElement => { + const isMobile: boolean = useIsMobile(); - const classes: string = clsx('oxygen-footer', {mobile: isMobile}, className); + const classes: string = clsx('oxygen-footer', {mobile: isMobile}, className); - return ( - - - {links !== undefined && Array.isArray(links) && links.length > 0 && ( - - {links.map((link: LinkProps) => ( - - ))} - - )} - {copyright && ( - - - - {copyright} - + return ( + + + {links !== undefined && Array.isArray(links) && links.length > 0 && ( + + {links.map((link: LinkProps) => ( + + ))} - - )} - - - ); -}; + )} + {copyright && ( + + + + {copyright} + + + + )} + + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Footer.displayName = composeComponentDisplayName(COMPONENT_NAME); Footer.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Footer/index.ts b/packages/react/src/components/Footer/index.ts index f998389c..e3eb0bb8 100644 --- a/packages/react/src/components/Footer/index.ts +++ b/packages/react/src/components/Footer/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Footer'; -export type {FooterProps} from './Footer'; +export * from './Footer'; diff --git a/packages/react/src/components/FormControl/FormControl.tsx b/packages/react/src/components/FormControl/FormControl.tsx index b8e60c52..a577b494 100644 --- a/packages/react/src/components/FormControl/FormControl.tsx +++ b/packages/react/src/components/FormControl/FormControl.tsx @@ -16,27 +16,66 @@ * under the License. */ -import MuiFormControl, {FormControlProps as MuiFormControlProps} from '@mui/material/FormControl'; +import MuiFormControl from '@mui/material/FormControl'; +import type {FormControlProps as MuiFormControlProps, FormControlTypeMap} from '@mui/material/FormControl'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './form-control.scss'; -export type FormControlProps = { +export type FormControlProps< + C extends ElementType = ElementType, + D extends ElementType = FormControlTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormControl'; -const FormControl: FC & WithWrapperProps = ({ - className, - ...rest -}: FormControlProps): ReactElement => { - const classes: string = clsx('oxygen-form-control', className); +/** + * The Form Control apply a common state to form inputs; FormLabel, FormHelperText, Input, InputLabel. + * + * Demos: + * + * - [Checkbox (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-checkbox) + * - [Checkbox (MUI)](https://mui.com/material-ui/react-checkbox/) + * - [Radio Group (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-radio-group) + * - [Radio Group (MUI)](https://mui.com/material-ui/react-radio-button/) + * - [Switch (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-switch) + * - [Switch (MUI)](https://mui.com/material-ui/react-switch/) + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [FormControl API](https://mui.com/material-ui/api/form-control/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the FormControl component. + * @param ref - The ref to be forwarded to the MuiFormControl component. + * @returns The rendered FormControl component. + */ +const FormControl: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FormControlProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-form-control', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; FormControl.displayName = composeComponentDisplayName(COMPONENT_NAME); FormControl.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/FormControl/index.ts b/packages/react/src/components/FormControl/index.ts index f89bb9c6..60aac7e0 100644 --- a/packages/react/src/components/FormControl/index.ts +++ b/packages/react/src/components/FormControl/index.ts @@ -17,4 +17,11 @@ */ export {default} from './FormControl'; -export type {FormControlProps} from './FormControl'; +export * from './FormControl'; + +export {useFormControl, FormControlState} from '@mui/material/FormControl'; +export type { + FormControlPropsSizeOverrides, + FormControlPropsColorOverrides, + FormControlTypeMap, +} from '@mui/material/FormControl'; diff --git a/packages/react/src/components/FormControlLabel/FormControlLabel.tsx b/packages/react/src/components/FormControlLabel/FormControlLabel.tsx index 334fc848..71c97739 100644 --- a/packages/react/src/components/FormControlLabel/FormControlLabel.tsx +++ b/packages/react/src/components/FormControlLabel/FormControlLabel.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiFormControlLabel, {FormControlLabelProps as MuiFormControlLabelProps} from '@mui/material/FormControlLabel'; +import MuiFormControlLabel from '@mui/material/FormControlLabel'; +import type {FormControlLabelProps as MuiFormControlLabelProps} from '@mui/material/FormControlLabel'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,6 +28,31 @@ export type FormControlLabelProps = MuiFormControlLabelProps; const COMPONENT_NAME: string = 'FormControlLabel'; +/** + * The Form Control Label can be used to display a label for a form control. + * + * Demos: + * + * - [Checkbox (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-checkbox) + * - [Checkbox (MUI)](https://mui.com/material-ui/react-checkbox/) + * - [Radio Group (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-radio-group) + * - [Radio Group (MUI)](https://mui.com/material-ui/react-radio-button/) + * - [Switch (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-switch) + * - [Switch (MUI)](https://mui.com/material-ui/react-switch/) + * + * API: + * + * - [FormControlLabel API](https://mui.com/material-ui/api/form-control-label/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the FormControlLabel component. + * @param ref - The ref to be forwarded to the MuiFormControlLabel component. + * @returns The rendered FormControlLabel component. + */ const FormControlLabel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ({className, ...rest}: FormControlLabelProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-form-control-label', className); diff --git a/packages/react/src/components/FormControlLabel/index.ts b/packages/react/src/components/FormControlLabel/index.ts index b2adcbcf..09030c95 100644 --- a/packages/react/src/components/FormControlLabel/index.ts +++ b/packages/react/src/components/FormControlLabel/index.ts @@ -17,4 +17,4 @@ */ export {default} from './FormControlLabel'; -export type {FormControlLabelProps} from './FormControlLabel'; +export * from './FormControlLabel'; diff --git a/packages/react/src/components/FormGroup/FormGroup.tsx b/packages/react/src/components/FormGroup/FormGroup.tsx index ec7bac63..c6f8a11f 100644 --- a/packages/react/src/components/FormGroup/FormGroup.tsx +++ b/packages/react/src/components/FormGroup/FormGroup.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiFormGroup, {FormGroupProps as MuiFormGroupProps} from '@mui/material/FormGroup'; +import MuiFormGroup from '@mui/material/FormGroup'; +import type {FormGroupProps as MuiFormGroupProps} from '@mui/material/FormGroup'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,11 +28,33 @@ export type FormGroupProps = MuiFormGroupProps; const COMPONENT_NAME: string = 'FormGroup'; +/** + * The Form Group is a helpful wrapper used to group selection control components. + * + * Demos: + * + * - [Checkbox (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-checkbox) + * - [Checkbox (MUI)](https://mui.com/material-ui/react-checkbox/) + * - [Switch (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-switch) + * - [Switch (MUI)](https://mui.com/material-ui/react-switch/) + * + * API: + * + * - [FormGroup API](https://mui.com/material-ui/api/form-group/) + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the FormGroup component. + * @param ref - The ref to be forwarded to the MuiFormGroup component. + * @returns The rendered FormGroup component. + */ const FormGroup: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ({className, ...rest}: FormGroupProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-form-group', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/FormGroup/index.ts b/packages/react/src/components/FormGroup/index.ts index 825627b8..48780e1d 100644 --- a/packages/react/src/components/FormGroup/index.ts +++ b/packages/react/src/components/FormGroup/index.ts @@ -17,4 +17,4 @@ */ export {default} from './FormGroup'; -export type {FormGroupProps} from './FormGroup'; +export * from './FormGroup'; diff --git a/packages/react/src/components/FormHelperText/FormHelperText.tsx b/packages/react/src/components/FormHelperText/FormHelperText.tsx index 180b4af1..233aff58 100644 --- a/packages/react/src/components/FormHelperText/FormHelperText.tsx +++ b/packages/react/src/components/FormHelperText/FormHelperText.tsx @@ -16,27 +16,60 @@ * under the License. */ -import MuiFormHelperText, {FormHelperTextProps as MuiFormHelperTextProps} from '@mui/material/FormHelperText'; +import MuiFormHelperText from '@mui/material/FormHelperText'; +import type {FormHelperTextProps as MuiFormHelperTextProps, FormHelperTextTypeMap} from '@mui/material/FormHelperText'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './form-helper-text.scss'; -export type FormHelperTextProps = { +export type FormHelperTextProps< + C extends ElementType = ElementType, + D extends ElementType = FormHelperTextTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormHelperText'; -const FormHelperText: FC & WithWrapperProps = ({ - className, - ...rest -}: FormHelperTextProps): ReactElement => { - const classes: string = clsx('oxygen-form-helper-text', className); +/** + * A Form Helper Text component is used to provide additional information about the form inputs. + * + * Demos: + * + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [FormHelperText API](https://mui.com/material-ui/api/form-helper-text/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Fab component. + * @param ref - The ref to be forwarded to the MuiFab component. + * @returns The rendered Fab component. + */ +const FormHelperText: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FormHelperTextProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-form-helper-text', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; FormHelperText.displayName = composeComponentDisplayName(COMPONENT_NAME); FormHelperText.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/FormHelperText/index.ts b/packages/react/src/components/FormHelperText/index.ts index 028cbfeb..28678a4c 100644 --- a/packages/react/src/components/FormHelperText/index.ts +++ b/packages/react/src/components/FormHelperText/index.ts @@ -17,4 +17,6 @@ */ export {default} from './FormHelperText'; -export type {FormHelperTextProps} from './FormHelperText'; +export * from './FormHelperText'; + +export type {FormHelperTextPropsVariantOverrides, FormHelperTextTypeMap} from '@mui/material/FormHelperText'; diff --git a/packages/react/src/components/FormLabel/FormLabel.tsx b/packages/react/src/components/FormLabel/FormLabel.tsx index 1de0aa56..9e5d45e1 100644 --- a/packages/react/src/components/FormLabel/FormLabel.tsx +++ b/packages/react/src/components/FormLabel/FormLabel.tsx @@ -16,18 +16,53 @@ * under the License. */ -import MuiFormLabel, {FormLabelProps as MuiFormLabelProps} from '@mui/material/FormLabel'; +import MuiFormLabel from '@mui/material/FormLabel'; +import type {FormLabelTypeMap, FormLabelProps as MuiFormLabelProps} from '@mui/material/FormLabel'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type FormLabelProps = { +export type FormLabelProps< + C extends ElementType = ElementType, + D extends ElementType = FormLabelTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormLabel'; +/** + * A Form Label component is used to provide a label for the form inputs. + * + * Demos: + * + * - [Checkbox (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-checkbox) + * - [Checkbox (MUI)](https://mui.com/material-ui/react-checkbox/) + * - [Radio Group (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-radio-group) + * - [Radio Group (MUI)](https://mui.com/material-ui/react-radio-button/) + * - [Switch (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-switch) + * - [Switch (MUI)](https://mui.com/material-ui/react-switch/) + * + * API: + * + * - [FormLabel API](https://mui.com/material-ui/api/form-label/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Fab component. + * @param ref - The ref to be forwarded to the MuiFab component. + * @returns The rendered Fab component. + */ const FormLabel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ( {className, ...rest}: FormLabelProps, @@ -35,7 +70,7 @@ const FormLabel: ForwardRefExoticComponent & WithWrapperProps = ): ReactElement => { const classes: string = clsx('oxygen-form-label', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/FormLabel/index.ts b/packages/react/src/components/FormLabel/index.ts index 51abd52b..21f04ada 100644 --- a/packages/react/src/components/FormLabel/index.ts +++ b/packages/react/src/components/FormLabel/index.ts @@ -17,4 +17,12 @@ */ export {default} from './FormLabel'; -export type {FormLabelProps} from './FormLabel'; +export * from './FormLabel'; + +export type { + FormLabelPropsColorOverrides, + FormLabelOwnProps, + FormLabelTypeMap, + FormLabelBaseProps, + ExtendFormLabelTypeMap, +} from '@mui/material/FormLabel'; diff --git a/packages/react/src/components/Grid/Grid.tsx b/packages/react/src/components/Grid/Grid.tsx index 91a8b932..7beb5959 100644 --- a/packages/react/src/components/Grid/Grid.tsx +++ b/packages/react/src/components/Grid/Grid.tsx @@ -16,22 +16,59 @@ * under the License. */ -import MuiGrid, {Grid2Props as MuiGridProps} from '@mui/material/Unstable_Grid2'; +import MuiGrid from '@mui/material/Unstable_Grid2'; +import type {Grid2TypeMap, Grid2Props as MuiGridProps} from '@mui/material/Unstable_Grid2'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './grid.scss'; -export type GridProps = MuiGridProps; +export type GridProps< + C extends ElementType = ElementType, + D extends React.ElementType = Grid2TypeMap['defaultComponent'], + P = { + component?: React.ElementType; + }, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Grid'; -const Grid: FC & WithWrapperProps = ({className, ...rest}: GridProps): ReactElement => { - const classes: string = clsx('oxygen-grid', className); +/** + * The Grid adapts to screen size and orientation, ensuring consistency across layouts. + * + * Demos: + * + * - [Grid (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/layout-grid) + * - [Grid (MUI)](https://mui.com/material-ui/react-grid2/) + * + * API: + * + * - [Grid API](https://mui.com/material-ui/api/grid-2/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the FormControl component. + * @param ref - The ref to be forwarded to the MuiFormControl component. + * @returns The rendered FormControl component. + */ +const Grid: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: GridProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-grid', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Grid.displayName = composeComponentDisplayName(COMPONENT_NAME); Grid.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Grid/index.ts b/packages/react/src/components/Grid/index.ts index b79c636d..b35f54d3 100644 --- a/packages/react/src/components/Grid/index.ts +++ b/packages/react/src/components/Grid/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Grid'; -export type {GridProps} from './Grid'; +export * from './Grid'; + +export type {Grid2Slot, Grid2TypeMap} from '@mui/material/Unstable_Grid2'; diff --git a/packages/react/src/components/Header/Header.tsx b/packages/react/src/components/Header/Header.tsx index 07a4bf52..30c35385 100644 --- a/packages/react/src/components/Header/Header.tsx +++ b/packages/react/src/components/Header/Header.tsx @@ -20,22 +20,25 @@ import {useColorScheme} from '@mui/material/styles'; import {Mode} from '@mui/system/cssVars/useCurrentColorScheme'; import {ChevronDownIcon, BarsIcon, ArrowRightToBracketIcon} from '@oxygen-ui/react-icons'; import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; import {useIsMobile} from '../../hooks/use-is-mobile'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import './header.scss'; -import AppBar, {AppBarProps} from '../AppBar'; +import AppBar from '../AppBar'; +import type {AppBarProps} from '../AppBar'; import Avatar from '../Avatar'; import Box from '../Box'; -import {ButtonProps} from '../Button'; +import type {ButtonProps} from '../Button'; import IconButton from '../IconButton'; import Link from '../Link'; import Toolbar from '../Toolbar'; import Typography from '../Typography'; -import UserDropdownMenu, {ModeList, UserTemplate} from '../UserDropdownMenu'; +import UserDropdownMenu from '../UserDropdownMenu'; +import type {ModeList, UserTemplate} from '../UserDropdownMenu'; +import './header.scss'; -export interface HeaderProps extends AppBarProps { +export type HeaderProps = AppBarProps & { /** * Brand information. */ @@ -74,9 +77,9 @@ export interface HeaderProps extends AppBarProps { * Props to modify the action menu item in the user dropdown menu. */ userDropdownMenu?: UserDropdownMenuHeaderProps; -} +}; -export interface UserDropdownMenuHeaderProps { +export type UserDropdownMenuHeaderProps = { /** * Action icon for the user dropdown menu. */ @@ -98,9 +101,9 @@ export interface UserDropdownMenuHeaderProps { */ onActionClick?: () => void; triggerOptions?: Omit & Record; -} +}; -export interface BrandTemplate { +export type BrandTemplate = { /** * Logo for the brand template. */ @@ -122,7 +125,7 @@ export interface BrandTemplate { * Title of the brand, portal name or company. */ title?: ReactNode; -} +}; const userDropdownMenuDefaultProps: UserDropdownMenuHeaderProps = { actionIcon: , @@ -132,119 +135,147 @@ const userDropdownMenuDefaultProps: UserDropdownMenuHeaderProps = { const COMPONENT_NAME: string = 'Header'; -const Header: FC & WithWrapperProps = ({ - brand, - className, - modes, - showCollapsibleHamburger, - leftAlignedElements, - navbarToggleIcon = , - onCollapsibleHamburgerClick, - rightAlignedElements, - user, - userDropdownMenu = userDropdownMenuDefaultProps, - ...rest -}: HeaderProps): ReactElement => { - const userDropdownMenuProps: UserDropdownMenuHeaderProps = {...userDropdownMenuDefaultProps, ...userDropdownMenu}; +/** + * The Header displays the brand, left aligned elements, right aligned elements, and the user dropdown menu. + * + * Demos: + * + * - [Header (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-header) + * + * API: + * + * - [AppBar API](https://mui.com/material-ui/api/app-bar/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [AppBar](https://mui.com/material-ui/api/app-bar//) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Header component. + * @param ref - The ref to be forwarded to the AppBar component. + * @returns The rendered Header component. + */ +const Header: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + { + brand, + className, + modes, + showCollapsibleHamburger, + leftAlignedElements, + navbarToggleIcon = , + onCollapsibleHamburgerClick, + rightAlignedElements, + user, + userDropdownMenu = userDropdownMenuDefaultProps, + ...rest + }: HeaderProps, + ref: MutableRefObject, + ): ReactElement => { + const userDropdownMenuProps: UserDropdownMenuHeaderProps = {...userDropdownMenuDefaultProps, ...userDropdownMenu}; - const {mode, setMode} = useColorScheme(); - const isMobile: boolean = useIsMobile(); + const {mode, setMode} = useColorScheme(); + const isMobile: boolean = useIsMobile(); - const classes: string = clsx( - 'oxygen-header', - { - mobile: isMobile, - 'with-hamburger': showCollapsibleHamburger, - }, - className, - ); + const classes: string = clsx( + 'oxygen-header', + { + mobile: isMobile, + 'with-hamburger': showCollapsibleHamburger, + }, + className, + ); - const onModeChange = (selectedMode: Mode): void => { - setMode(selectedMode); - }; + const onModeChange = (selectedMode: Mode): void => { + setMode(selectedMode); + }; - return ( - - - {showCollapsibleHamburger && ( -
- null)}> - {navbarToggleIcon} - -
- )} - {brand && ( - - - {isMobile ? brand.logo.mobile ?? brand.logo.desktop : brand.logo.desktop} + return ( + + + {showCollapsibleHamburger && ( +
+ null)}> + {navbarToggleIcon} + +
+ )} + {brand && ( + + + {isMobile ? brand.logo.mobile ?? brand.logo.desktop : brand.logo.desktop} + + + {brand.title} + - - {brand.title} - -
- )} - {(leftAlignedElements || rightAlignedElements) && ( - - {leftAlignedElements?.length > 0 && ( - {leftAlignedElements} - )} - {rightAlignedElements?.length > 0 && ( - {rightAlignedElements} - )} + )} + {(leftAlignedElements || rightAlignedElements) && ( + + {leftAlignedElements?.length > 0 && ( + {leftAlignedElements} + )} + {rightAlignedElements?.length > 0 && ( + {rightAlignedElements} + )} + + )} + + , + startIcon: ( + + {user?.name?.split('')[0]} + + ), + ...userDropdownMenuProps.triggerOptions, + }} + modesHeading="Theme" + modes={modes} + onActionTrigger={userDropdownMenuProps.onActionClick} + actionText={userDropdownMenuProps.actionText} + actionIcon={userDropdownMenuProps.actionIcon} + mode={mode} + onModeChange={onModeChange} + menuItems={userDropdownMenuProps.menuItems} + footerContent={userDropdownMenu.footerContent} + /> - )} - - , - startIcon: ( - - {user?.name?.split('')[0]} - - ), - ...userDropdownMenuProps.triggerOptions, - }} - modesHeading="Theme" - modes={modes} - onActionTrigger={userDropdownMenuProps.onActionClick} - actionText={userDropdownMenuProps.actionText} - actionIcon={userDropdownMenuProps.actionIcon} - mode={mode} - onModeChange={onModeChange} - menuItems={userDropdownMenuProps.menuItems} - footerContent={userDropdownMenu.footerContent} - /> - -
-
- ); -}; + + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Header.displayName = composeComponentDisplayName(COMPONENT_NAME); Header.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Header/index.ts b/packages/react/src/components/Header/index.ts index 40eca574..3240c0ca 100644 --- a/packages/react/src/components/Header/index.ts +++ b/packages/react/src/components/Header/index.ts @@ -17,5 +17,4 @@ */ export {default} from './Header'; -export type {HeaderProps} from './Header'; -export type {BrandTemplate} from './Header'; +export * from './Header'; diff --git a/packages/react/src/components/IconButton/IconButton.tsx b/packages/react/src/components/IconButton/IconButton.tsx index b8170737..609737fd 100644 --- a/packages/react/src/components/IconButton/IconButton.tsx +++ b/packages/react/src/components/IconButton/IconButton.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiIconButton, {IconButtonProps as MuiIconButtonProps} from '@mui/material/IconButton'; +import MuiIconButton from '@mui/material/IconButton'; +import type {IconButtonTypeMap, IconButtonProps as MuiIconButtonProps} from '@mui/material/IconButton'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './icon-button.scss'; @@ -28,23 +30,58 @@ export enum IconButtonVariants { TEXT = 'text', } -export interface IconButtonProps extends MuiIconButtonProps { +export type IconButtonProps< + C extends ElementType = ElementType, + D extends ElementType = IconButtonTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; + /** + * The variant of the icon button. + */ variant?: IconButtonVariants; -} +} & Omit, 'component'>; const COMPONENT_NAME: string = 'IconButton'; -const IconButton: FC & WithWrapperProps = ({ - className, - variant = IconButtonVariants.TEXT, - ...rest -}: IconButtonProps): ReactElement => { - const classes: string = clsx('oxygen-icon-button', className, { - 'oxygen-icon-button-contained': variant === IconButtonVariants.CONTAINED, - }); - - return ; -}; +/** + * The Icon Button component is used to render a button with an icon. + * + * Demos: + * + * - [Button (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-button) + * - [Button (MUI)](https://mui.com/material-ui/react-button/) + * + * API: + * + * - [IconButton API](https://mui.com/material-ui/api/icon-button/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the FormControl component. + * @param ref - The ref to be forwarded to the MuiFormControl component. + * @returns The rendered FormControl component. + */ +const IconButton: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, variant = IconButtonVariants.TEXT, ...rest}: IconButtonProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-icon-button', className, { + 'oxygen-icon-button-contained': variant === IconButtonVariants.CONTAINED, + }); + + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; IconButton.displayName = composeComponentDisplayName(COMPONENT_NAME); IconButton.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/IconButton/index.ts b/packages/react/src/components/IconButton/index.ts index 5349e9af..18cd7c8c 100644 --- a/packages/react/src/components/IconButton/index.ts +++ b/packages/react/src/components/IconButton/index.ts @@ -17,4 +17,10 @@ */ export {default} from './IconButton'; -export type {IconButtonProps} from './IconButton'; +export * from './IconButton'; + +export type { + IconButtonPropsColorOverrides, + IconButtonPropsSizeOverrides, + IconButtonTypeMap, +} from '@mui/material/IconButton'; diff --git a/packages/react/src/components/Image/Image.tsx b/packages/react/src/components/Image/Image.tsx index e51781e2..0f5e8de9 100644 --- a/packages/react/src/components/Image/Image.tsx +++ b/packages/react/src/components/Image/Image.tsx @@ -17,7 +17,8 @@ */ import clsx from 'clsx'; -import {FC, ImgHTMLAttributes, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ImgHTMLAttributes, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,14 +27,32 @@ export type ImageProps = ImgHTMLAttributes; const COMPONENT_NAME: string = 'Image'; /** + * The Footers display a set of links and a copyright at the bottom of the application. + * * TODO: Refer improvement issue if this Image component is required. * @see {@link https://github.com/wso2/oxygen-ui/issues/65} + * + * Demos: + * + * - [Image (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-image) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the Image component. + * @param ref - The ref to be forwarded to the img component. + * @returns The rendered Image component. */ -const Image: FC & WithWrapperProps = ({className, alt, ...rest}: ImageProps): ReactElement => { - const classes: string = clsx('oxygen-image', className); +const Image: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, alt, ...rest}: ImageProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-image', className); - return {alt}; -}; + return {alt}; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Image.displayName = composeComponentDisplayName(COMPONENT_NAME); Image.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Image/index.ts b/packages/react/src/components/Image/index.ts index cc1ea89f..8dce47a6 100644 --- a/packages/react/src/components/Image/index.ts +++ b/packages/react/src/components/Image/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Image'; -export type {ImageProps} from './Image'; +export * from './Image'; diff --git a/packages/react/src/components/Input/Input.tsx b/packages/react/src/components/Input/Input.tsx index 1370e33d..d2f7a7d9 100644 --- a/packages/react/src/components/Input/Input.tsx +++ b/packages/react/src/components/Input/Input.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiInput, {InputProps as MuiInputProps} from '@mui/material/Input'; +import MuiInput from '@mui/material/Input'; +import type {InputProps as MuiInputProps} from '@mui/material/Input'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './input.scss'; @@ -27,11 +29,35 @@ export type InputProps = MuiInputProps; const COMPONENT_NAME: string = 'Input'; -const Input: FC & WithWrapperProps = ({className, ...rest}: InputProps): ReactElement => { - const classes: string = clsx('oxygen-input', className); +/** + * The Input component is used to render a text input field. + * + * Demos: + * + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [Input API](https://mui.com/material-ui/api/input/) + * - inherits [InputBase API](https://mui.com/material-ui/api/input-base/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the Input component. + * @param ref - The ref to be forwarded to the MuiInput component. + * @returns The rendered Input component. + */ +const Input: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: InputProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-input', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Input.displayName = composeComponentDisplayName(COMPONENT_NAME); Input.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Input/index.ts b/packages/react/src/components/Input/index.ts index 82bf89f9..3677abeb 100644 --- a/packages/react/src/components/Input/index.ts +++ b/packages/react/src/components/Input/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Input'; -export type {InputProps} from './Input'; +export * from './Input'; diff --git a/packages/react/src/components/InputAdornment/InputAdornment.tsx b/packages/react/src/components/InputAdornment/InputAdornment.tsx index e542577d..1496f509 100644 --- a/packages/react/src/components/InputAdornment/InputAdornment.tsx +++ b/packages/react/src/components/InputAdornment/InputAdornment.tsx @@ -16,27 +16,60 @@ * under the License. */ -import MuiInputAdornment, {InputAdornmentProps as MuiInputAdornmentProps} from '@mui/material/InputAdornment'; +import MuiInputAdornment from '@mui/material/InputAdornment'; +import type {InputAdornmentTypeMap, InputAdornmentProps as MuiInputAdornmentProps} from '@mui/material/InputAdornment'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type InputAdornmentProps = { +export type InputAdornmentProps< + C extends ElementType = ElementType, + D extends ElementType = InputAdornmentTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'InputAdornment'; -const InputAdornment: FC & WithWrapperProps = ({ - className, - position, - ...rest -}: InputAdornmentProps): ReactElement => { - const classes: string = clsx('oxygen-input-adornment', className); +/** + * The Input Adornment can be used to add a prefix, a suffix, or an action to an input. For instance, + * you can use an icon button to hide or reveal the password. + * + * Demos: + * + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [InputAdornment API](https://mui.com/material-ui/api/input-adornment/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the InputAdornment component. + * @param ref - The ref to be forwarded to the MuiInputAdornment component. + * @returns The rendered InputAdornment component. + */ +const InputAdornment: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, position, ...rest}: InputAdornmentProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-input-adornment', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; InputAdornment.displayName = composeComponentDisplayName(COMPONENT_NAME); InputAdornment.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/InputAdornment/index.ts b/packages/react/src/components/InputAdornment/index.ts index 572ab11d..811fa7c9 100644 --- a/packages/react/src/components/InputAdornment/index.ts +++ b/packages/react/src/components/InputAdornment/index.ts @@ -17,4 +17,6 @@ */ export {default} from './InputAdornment'; -export type {InputAdornmentProps} from './InputAdornment'; +export * from './InputAdornment'; + +export {InputAdornmentTypeMap} from '@mui/material/InputAdornment'; diff --git a/packages/react/src/components/InputLabel/InputLabel.tsx b/packages/react/src/components/InputLabel/InputLabel.tsx index 378ae84f..ecc8b4c6 100644 --- a/packages/react/src/components/InputLabel/InputLabel.tsx +++ b/packages/react/src/components/InputLabel/InputLabel.tsx @@ -16,22 +16,61 @@ * under the License. */ -import MuiInputLabel, {InputLabelProps as MuiInputLabelProps} from '@mui/material/InputLabel'; +import MuiInputLabel from '@mui/material/InputLabel'; +import type {InputLabelTypeMap, InputLabelProps as MuiInputLabelProps} from '@mui/material/InputLabel'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './input-label.scss'; -export type InputLabelProps = MuiInputLabelProps; +export type InputLabelProps< + C extends ElementType = ElementType, + D extends React.ElementType = InputLabelTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'InputLabel'; -const InputLabel: FC & WithWrapperProps = ({className, ...rest}: InputLabelProps): ReactElement => { - const classes: string = clsx('oxygen-input-label', className); +/** + * The Form Label component is used to provide a label for the form inputs. + * + * Demos: + * + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [InputLabel API](https://mui.com/material-ui/api/input-label/) + * - inherits [FormLabel API](https://mui.com/material-ui/api/form-label/) + * + * @remarks + * - ✔️ Props of the [FormLabel](https://mui.com/material-ui/api/form-label/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the InputLabel component. + * @param ref - The ref to be forwarded to the MuiInputLabel component. + * @returns The rendered InputLabel component. + */ +const InputLabel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: InputLabelProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-input-label', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; InputLabel.displayName = composeComponentDisplayName(COMPONENT_NAME); InputLabel.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/InputLabel/index.ts b/packages/react/src/components/InputLabel/index.ts index b81a120a..e484081c 100644 --- a/packages/react/src/components/InputLabel/index.ts +++ b/packages/react/src/components/InputLabel/index.ts @@ -17,4 +17,6 @@ */ export {default} from './InputLabel'; -export type {InputLabelProps} from './InputLabel'; +export * from './InputLabel'; + +export type {InputLabelPropsSizeOverrides, InputLabelTypeMap} from '@mui/material/InputLabel'; diff --git a/packages/react/src/components/LinearProgress/LinearProgress.tsx b/packages/react/src/components/LinearProgress/LinearProgress.tsx index 34a09a24..a63b548d 100644 --- a/packages/react/src/components/LinearProgress/LinearProgress.tsx +++ b/packages/react/src/components/LinearProgress/LinearProgress.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiLinearProgress, {LinearProgressProps as MuiLinearProgressProps} from '@mui/material/LinearProgress'; +import MuiLinearProgress from '@mui/material/LinearProgress'; +import type {LinearProgressProps as MuiLinearProgressProps} from '@mui/material/LinearProgress'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,14 +28,35 @@ export type LinearProgressProps = MuiLinearProgressProps; const COMPONENT_NAME: string = 'LinearProgress'; -const LinearProgress: FC & WithWrapperProps = ({ - className, - ...rest -}: LinearProgressProps): ReactElement => { - const classes: string = clsx('oxygen-linear-progress', className); +/** + * The Linear Progress component is used to show the progress of a task in a linear fashion. + * + * Demos: + * + * TODO: Merge two progress components into one. + * - [Progress (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-circular-progress) + * - [Progress (MUI)](https://mui.com/material-ui/react-progress/) + * + * API: + * + * - [LinearProgress API](https://mui.com/material-ui/api/linear-progress/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the LinearProgress component. + * @param ref - The ref to be forwarded to the MuiLinearProgress component. + * @returns The rendered LinearProgress component. + */ +const LinearProgress: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: LinearProgressProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-linear-progress', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; LinearProgress.displayName = composeComponentDisplayName(COMPONENT_NAME); LinearProgress.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/LinearProgress/index.ts b/packages/react/src/components/LinearProgress/index.ts index 717d377d..139b485d 100644 --- a/packages/react/src/components/LinearProgress/index.ts +++ b/packages/react/src/components/LinearProgress/index.ts @@ -17,4 +17,6 @@ */ export {default} from './LinearProgress'; -export type {LinearProgressProps} from './LinearProgress'; +export * from './LinearProgress'; + +export {LinearProgressPropsColorOverrides} from '@mui/material/LinearProgress'; diff --git a/packages/react/src/components/Link/Link.tsx b/packages/react/src/components/Link/Link.tsx index 8e0da0c4..3a1eaa52 100644 --- a/packages/react/src/components/Link/Link.tsx +++ b/packages/react/src/components/Link/Link.tsx @@ -16,22 +16,63 @@ * under the License. */ -import MuiLink, {LinkProps as MuiLinkProps} from '@mui/material/Link'; +import MuiLink from '@mui/material/Link'; +import type {LinkTypeMap, LinkProps as MuiLinkProps} from '@mui/material/Link'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './link.scss'; -export type LinkProps = MuiLinkProps; +export type LinkProps< + C extends ElementType = ElementType, + D extends ElementType = LinkTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Link'; -const Link: FC & WithWrapperProps = ({className, ...rest}: LinkProps): ReactElement => { - const classes: string = clsx('oxygen-link', className); +/** + * A Link allows you to easily customize anchor elements with your theme colors and typography styles. + * + * Demos: + * + * - [Breadcrumbs (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-breadcrumbs) + * - [Breadcrumbs (MUI)](https://mui.com/material-ui/react-breadcrumbs/) + * - [Links (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-link) + * - [Links (MUI)](https://mui.com/material-ui/react-link/) + * + * API: + * + * - [Link API](https://mui.com/material-ui/api/link/) + * - inherits [Typography API](https://mui.com/material-ui/api/typography/) + * + * @remarks + * - ✔️ Props of the [Typography](https://mui.com/material-ui/api/typography/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Link component. + * @param ref - The ref to be forwarded to the MuiLink component. + * @returns The rendered Link component. + */ +const Link: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: LinkProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-link', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Link.displayName = composeComponentDisplayName(COMPONENT_NAME); Link.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Link/index.ts b/packages/react/src/components/Link/index.ts index f21831fa..7601761c 100644 --- a/packages/react/src/components/Link/index.ts +++ b/packages/react/src/components/Link/index.ts @@ -18,3 +18,5 @@ export {default} from './Link'; export type {LinkProps} from './Link'; + +export type {LinkTypeMap, LinkBaseProps} from '@mui/material/Link'; diff --git a/packages/react/src/components/List/List.tsx b/packages/react/src/components/List/List.tsx index b0084d21..885d1c10 100644 --- a/packages/react/src/components/List/List.tsx +++ b/packages/react/src/components/List/List.tsx @@ -16,22 +16,62 @@ * under the License. */ -import MuiList, {ListProps as MuiListProps} from '@mui/material/List'; +import MuiList from '@mui/material/List'; +import type {ListTypeMap, ListProps as MuiListProps} from '@mui/material/List'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list.scss'; -export type ListProps = MuiListProps; +export type ListProps< + C extends ElementType = ElementType, + D extends ElementType = ListTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'List'; -const List: FC & WithWrapperProps = ({className, ...rest}: ListProps): ReactElement => { - const classes: string = clsx('oxygen-list', className); +/** + * A Lists is a continuous, vertical index of text or images. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * - [Transfer List (Oxygen UI)](TODO: Add a link after implementing: Tracker: https://github.com/wso2/oxygen-ui/issues/2) + * - [Transfer List (MUI)](https://mui.com/material-ui/react-transfer-list/) + * + * API: + * + * - [List API](https://mui.com/material-ui/api/list/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the List component. + * @param ref - The ref to be forwarded to the MuiList component. + * @returns The rendered List component. + */ +const List: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ListProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-list', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; List.displayName = composeComponentDisplayName(COMPONENT_NAME); List.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/List/index.ts b/packages/react/src/components/List/index.ts index fe765bd4..05bf674d 100644 --- a/packages/react/src/components/List/index.ts +++ b/packages/react/src/components/List/index.ts @@ -17,4 +17,6 @@ */ export {default} from './List'; -export type {ListProps} from './List'; +export * from './List'; + +export type {ListTypeMap, ExtendListTypeMap, ExtendList} from '@mui/material/List'; diff --git a/packages/react/src/components/ListItem/ListItem.tsx b/packages/react/src/components/ListItem/ListItem.tsx index f942c978..7afdf691 100644 --- a/packages/react/src/components/ListItem/ListItem.tsx +++ b/packages/react/src/components/ListItem/ListItem.tsx @@ -16,27 +16,56 @@ * under the License. */ -import MuiListItem, {ListItemProps as MuiListItemProps} from '@mui/material/ListItem'; +import MuiListItem from '@mui/material/ListItem'; +import type {ListItemProps as MuiListItemProps} from '@mui/material/ListItem'; import clsx from 'clsx'; -import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item.scss'; -export type ListItemProps = { +export type ListItemProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ListItem'; +/** + * The List Item is a common list item that renders as an
  • by default. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Transfer List (Oxygen UI)](TODO: Add a link after implementing: Tracker: https://github.com/wso2/oxygen-ui/issues/2) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * - [Transfer List (MUI)](https://mui.com/material-ui/react-transfer-list/) + * + * API: + * + * - [ListItem API](https://mui.com/material-ui/api/list-item/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the ListItem component. + * @param ref - The ref to be forwarded to the MuiListItem component. + * @returns The rendered ListItem component. + */ const ListItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ( + ( {className, ...rest}: ListItemProps, ref: MutableRefObject, ): ReactElement => { const classes: string = clsx('oxygen-list-item', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/ListItem/index.ts b/packages/react/src/components/ListItem/index.ts index 773f905a..8e3f5404 100644 --- a/packages/react/src/components/ListItem/index.ts +++ b/packages/react/src/components/ListItem/index.ts @@ -17,4 +17,6 @@ */ export {default} from './ListItem'; -export type {ListItemProps} from './ListItem'; +export * from './ListItem'; + +export type {ListItemComponentsPropsOverrides, ListItemBaseProps, ListItemTypeMap} from '@mui/material/ListItem'; diff --git a/packages/react/src/components/ListItemAvatar/ListItemAvatar.tsx b/packages/react/src/components/ListItemAvatar/ListItemAvatar.tsx index 6a81378e..c9bd6218 100644 --- a/packages/react/src/components/ListItemAvatar/ListItemAvatar.tsx +++ b/packages/react/src/components/ListItemAvatar/ListItemAvatar.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiListItemAvatar, {ListItemAvatarProps as MuiListItemAvatarProps} from '@mui/material/ListItemAvatar'; +import MuiListItemAvatar from '@mui/material/ListItemAvatar'; +import type {ListItemAvatarProps as MuiListItemAvatarProps} from '@mui/material/ListItemAvatar'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-avatar.scss'; @@ -27,14 +29,34 @@ export type ListItemAvatarProps = MuiListItemAvatarProps; const COMPONENT_NAME: string = 'ListItemAvatar'; -const ListItemAvatar: FC & WithWrapperProps = ({ - className, - ...rest -}: ListItemAvatarProps): ReactElement => { - const classes: string = clsx('oxygen-list-item-avatar', className); +/** + * The List Item Avatar component is used to display an avatar in a list item. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * + * API: + * + * - [ListItemAvatar API](https://mui.com/material-ui/api/list-item-avatar/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the ListItemAvatar component. + * @param ref - The ref to be forwarded to the MuiListItemAvatar component. + * @returns The rendered ListItemAvatar component. + */ +const ListItemAvatar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: ListItemAvatarProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-list-item-avatar', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemAvatar.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemAvatar.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/ListItemAvatar/index.ts b/packages/react/src/components/ListItemAvatar/index.ts index a104803a..a457aee2 100644 --- a/packages/react/src/components/ListItemAvatar/index.ts +++ b/packages/react/src/components/ListItemAvatar/index.ts @@ -17,4 +17,4 @@ */ export {default} from './ListItemAvatar'; -export type {ListItemAvatarProps} from './ListItemAvatar'; +export * from './ListItemAvatar'; diff --git a/packages/react/src/components/ListItemButton/ListItemButton.tsx b/packages/react/src/components/ListItemButton/ListItemButton.tsx index 55726bd6..e88e49a1 100644 --- a/packages/react/src/components/ListItemButton/ListItemButton.tsx +++ b/packages/react/src/components/ListItemButton/ListItemButton.tsx @@ -16,24 +16,59 @@ * under the License. */ -import MuiListItemButton, {ListItemButtonProps as MuiListItemButtonProps} from '@mui/material/ListItemButton'; +import MuiListItemButton from '@mui/material/ListItemButton'; +import type {ListItemButtonProps as MuiListItemButtonProps, ListItemButtonTypeMap} from '@mui/material/ListItemButton'; import clsx from 'clsx'; -import {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, forwardRef} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-button.scss'; -export type ListItemButtonProps = { +export type ListItemButtonProps< + C extends ElementType = ElementType, + D extends ElementType = ListItemButtonTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ListItemButton'; +/** + * The List Item Button an action element to be used inside a list item. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * + * API: + * + * - [ListItemButton API](https://mui.com/material-ui/api/list-item-button/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the ListItemButton component. + * @param ref - The ref to be forwarded to the MuiListItemButton component. + * @returns The rendered ListItemButton component. + */ const ListItemButton: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: ListItemButtonProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: ListItemButtonProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-list-item-button', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/ListItemIcon/ListItemIcon.tsx b/packages/react/src/components/ListItemIcon/ListItemIcon.tsx index 2dab02ca..7638cf78 100644 --- a/packages/react/src/components/ListItemIcon/ListItemIcon.tsx +++ b/packages/react/src/components/ListItemIcon/ListItemIcon.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiListItemIcon, {ListItemIconProps as MuiListItemIconProps} from '@mui/material/ListItemIcon'; +import MuiListItemIcon from '@mui/material/ListItemIcon'; +import type {ListItemIconProps as MuiListItemIconProps} from '@mui/material/ListItemIcon'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-icon.scss'; @@ -27,14 +29,34 @@ export type ListItemIconProps = MuiListItemIconProps; const COMPONENT_NAME: string = 'ListItemIcon'; -const ListItemIcon: FC & WithWrapperProps = ({ - className, - ...rest -}: ListItemIconProps): ReactElement => { - const classes: string = clsx('oxygen-list-item-icon', className); +/** + * The List Item Icon component is used to display an icon in a list item. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * + * API: + * + * - [ListItemIcon API](https://mui.com/material-ui/api/list-item-icon/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the ListItemIcon component. + * @param ref - The ref to be forwarded to the MuiListItemIcon component. + * @returns The rendered ListItemIcon component. + */ +const ListItemIcon: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: ListItemIconProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-list-item-icon', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemIcon.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemIcon.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/ListItemIcon/index.ts b/packages/react/src/components/ListItemIcon/index.ts index f759e992..da191b73 100644 --- a/packages/react/src/components/ListItemIcon/index.ts +++ b/packages/react/src/components/ListItemIcon/index.ts @@ -17,4 +17,4 @@ */ export {default} from './ListItemIcon'; -export type {ListItemIconProps} from './ListItemIcon'; +export * from './ListItemIcon'; diff --git a/packages/react/src/components/ListItemText/ListItemText.tsx b/packages/react/src/components/ListItemText/ListItemText.tsx index f4e3b928..7d1b427f 100644 --- a/packages/react/src/components/ListItemText/ListItemText.tsx +++ b/packages/react/src/components/ListItemText/ListItemText.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiListItemText, {ListItemTextProps as MuiListItemTextProps} from '@mui/material/ListItemText'; +import MuiListItemText from '@mui/material/ListItemText'; +import type {ListItemTextProps as MuiListItemTextProps} from '@mui/material/ListItemText'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-text.scss'; @@ -27,14 +29,34 @@ export type ListItemTextProps = MuiListItemTextProps; const COMPONENT_NAME: string = 'ListItemText'; -const ListItemText: FC & WithWrapperProps = ({ - className, - ...rest -}: ListItemTextProps): ReactElement => { - const classes: string = clsx('oxygen-list-item-text', className); +/** + * The List Item Text component is used to display text in a list item. + * + * Demos: + * + * - [Lists (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/data-display-list) + * - [Lists (MUI)](https://mui.com/material-ui/react-list/) + * + * API: + * + * - [ListItemText API](https://mui.com/material-ui/api/list-item-text/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the ListItemText component. + * @param ref - The ref to be forwarded to the MuiListItemText component. + * @returns The rendered ListItemText component. + */ +const ListItemText: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: ListItemTextProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-list-item-text', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemText.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemText.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/ListItemText/index.ts b/packages/react/src/components/ListItemText/index.ts index 90fdd71c..85e3c763 100644 --- a/packages/react/src/components/ListItemText/index.ts +++ b/packages/react/src/components/ListItemText/index.ts @@ -17,4 +17,4 @@ */ export {default} from './ListItemText'; -export type {ListItemTextProps} from './ListItemText'; +export * from './ListItemText'; diff --git a/packages/react/src/components/Menu/Menu.tsx b/packages/react/src/components/Menu/Menu.tsx index e05acdc5..84945b2f 100644 --- a/packages/react/src/components/Menu/Menu.tsx +++ b/packages/react/src/components/Menu/Menu.tsx @@ -16,22 +16,56 @@ * under the License. */ -import MuiMenu, {MenuProps as MuiMenuProps} from '@mui/material/Menu'; +import MuiMenu from '@mui/material/Menu'; +import type {MenuProps as MuiMenuProps} from '@mui/material/Menu'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './menu.scss'; -export type MenuProps = MuiMenuProps; +export type MenuProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Menu'; -const Menu: FC & WithWrapperProps = ({className, ...rest}: MenuProps): ReactElement => { - const classes: string = clsx('oxygen-menu', className); +/** + * A Menus display a list of choices on temporary surfaces. + * + * Demos: + * + * - [App Bar (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-app-bar) + * - [App Bar (MUI)](https://mui.com/material-ui/react-app-bar/) + * - [Menu (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-menu) + * - [Menu (MUI)](https://mui.com/material-ui/react-menu/) + * + * API: + * + * - [Menu API](https://mui.com/material-ui/api/menu/) + * - inherits [Popover API](https://mui.com/material-ui/api/popover/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the List component. + * @param ref - The ref to be forwarded to the MuiList component. + * @returns The rendered List component. + */ +const Menu: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: MenuProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-menu', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Menu.displayName = composeComponentDisplayName(COMPONENT_NAME); Menu.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Menu/index.ts b/packages/react/src/components/Menu/index.ts index 7683b4e7..f480dd7c 100644 --- a/packages/react/src/components/Menu/index.ts +++ b/packages/react/src/components/Menu/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Menu'; -export type {MenuProps} from './Menu'; +export * from './Menu'; diff --git a/packages/react/src/components/MenuItem/MenuItem.tsx b/packages/react/src/components/MenuItem/MenuItem.tsx index 32cd214d..bea5bde6 100644 --- a/packages/react/src/components/MenuItem/MenuItem.tsx +++ b/packages/react/src/components/MenuItem/MenuItem.tsx @@ -16,22 +16,61 @@ * under the License. */ -import MuiMenuItem, {MenuItemProps as MuiMenuItemProps} from '@mui/material/MenuItem'; +import MuiMenuItem from '@mui/material/MenuItem'; +import type {MenuItemTypeMap, MenuItemProps as MuiMenuItemProps} from '@mui/material/MenuItem'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './menu-item.scss'; -export type MenuItemProps = MuiMenuItemProps; +export type MenuItemProps< + C extends ElementType = ElementType, + D extends ElementType = MenuItemTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'MenuItem'; -const MenuItem: FC & WithWrapperProps = ({className, ...rest}: MenuItemProps): ReactElement => { - const classes: string = clsx('oxygen-menu-item', className); +/** + * The Menu Item component is used to display a single item inside a menu. + * + * Demos: + * + * - [Menu (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-menu) + * - [Menu (MUI)](https://mui.com/material-ui/react-menu/) + * + * API: + * + * - [MenuItem API](https://mui.com/material-ui/api/menu-item/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the MenuItem component. + * @param ref - The ref to be forwarded to the MuiMenuItem component. + * @returns The rendered MenuItem component. + */ +const MenuItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: MenuItemProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-menu-item', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; MenuItem.displayName = composeComponentDisplayName(COMPONENT_NAME); MenuItem.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/MenuItem/index.tsx b/packages/react/src/components/MenuItem/index.tsx index 611f25f1..21637447 100644 --- a/packages/react/src/components/MenuItem/index.tsx +++ b/packages/react/src/components/MenuItem/index.tsx @@ -17,4 +17,6 @@ */ export {default} from './MenuItem'; -export type {MenuItemProps} from './MenuItem'; +export * from './MenuItem'; + +export {MenuItemTypeMap} from '@mui/material/MenuItem'; diff --git a/packages/react/src/components/Navbar/Navbar.tsx b/packages/react/src/components/Navbar/Navbar.tsx index 6da5023a..ac94b7ed 100644 --- a/packages/react/src/components/Navbar/Navbar.tsx +++ b/packages/react/src/components/Navbar/Navbar.tsx @@ -18,11 +18,20 @@ import {BarsIcon} from '@oxygen-ui/react-icons'; import clsx from 'clsx'; -import {FC, ReactElement, MouseEvent, Fragment, ReactNode} from 'react'; +import {forwardRef, Fragment} from 'react'; +import type { + ReactElement, + MouseEvent, + ReactNode, + ElementType, + ForwardRefExoticComponent, + MutableRefObject, +} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; import CollapsibleNavbarItem from '../CollapsibleNavbarItem'; +import type {CollapsibleNavbarItemProps} from '../CollapsibleNavbarItem'; import Divider from '../Divider'; import Drawer, {DrawerProps} from '../Drawer'; import IconButton from '../IconButton'; @@ -32,7 +41,7 @@ import type {NavbarItemProps} from '../NavbarItem'; import Typography from '../Typography'; import './navbar.scss'; -export interface NavbarProps extends DrawerProps { +export type NavbarProps = DrawerProps & { /** * Is the Navbar collapsible. If `true`, a hamburger will be shown. */ @@ -54,7 +63,7 @@ export interface NavbarProps extends DrawerProps { * @default */ toggleIcon?: ReactNode; -} +}; export type NavbarItems = { /** @@ -73,130 +82,157 @@ export type NavbarItems = { const COMPONENT_NAME: string = 'Navbar'; -const Navbar: FC & WithWrapperProps = ({ - className, - fill, - onClose, - items, - collapsible = true, - open = true, - onOpen, - toggleIcon = , - ...rest -}: NavbarProps): ReactElement => { - const classes: string = clsx( - 'oxygen-navbar', +/** + * The Navbar component is used to provide a navigation bar for the application. + * + * Demos: + * + * - [Navvar (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-navbar) + * + * API: + * + * - inherits [Drawer API](https://mui.com/material-ui/api/drawer/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Drawer](https://mui.com/material-ui/api/drawer/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Navbar component. + * @param ref - The ref to be forwarded to the Drawer component. + * @returns The rendered Navbar component. + */ +const Navbar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( { - collapsible, - [`${fill}`]: fill, + className, fill, - open, - }, - className, - ); + onClose, + items, + collapsible = true, + open = true, + onOpen, + toggleIcon = , + ...rest + }: NavbarProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx( + 'oxygen-navbar', + { + collapsible, + [`${fill}`]: fill, + fill, + open, + }, + className, + ); - const handleCollapsibleHamburgerClick = (e: MouseEvent): void => { - if (open && onClose && typeof onClose === 'function') { - onClose(e, null); - return; - } + const handleCollapsibleHamburgerClick = (e: MouseEvent): void => { + if (open && onClose && typeof onClose === 'function') { + onClose(e, null); + return; + } - if (onOpen && typeof onOpen === 'function') { - onOpen(); - } - }; + if (onOpen && typeof onOpen === 'function') { + onOpen(); + } + }; - const renderDivider = (itemSetIndex: number, heading: string): ReactElement => { - if (itemSetIndex !== 0 && !heading) { - return ; - } - if (heading) { - return ( - - {heading} - - ); - } - return null; - }; + const renderDivider = (itemSetIndex: number, heading: string): ReactElement => { + if (itemSetIndex !== 0 && !heading) { + return ; + } + if (heading) { + return ( + + {heading} + + ); + } + return null; + }; - return ( - - {collapsible && ( - <> -
    - - {toggleIcon} - -
    - - - )} - - {items?.map((navbarItems: NavbarItems, itemsIndex: number) => { - const navBarListClass: string = clsx('oxygen-navbar-list', {'no-heading': !navbarItems.label}); + return ( + + {collapsible && ( + <> +
    + + {toggleIcon} + +
    + + + )} + + {items?.map((navbarItems: NavbarItems, itemsIndex: number) => { + const navBarListClass: string = clsx('oxygen-navbar-list', {'no-heading': !navbarItems.label}); - return ( - -
    {renderDivider(itemsIndex, navbarItems.label)}
    - - {navbarItems?.items?.map( - ({ - expanded, - icon, - id, - selected, - items: navbarSubItems, - label, - onClick, - tag, - tagClassName, - ...otherListItemProps - }: NavbarItemProps) => - navbarSubItems ? ( - - ) : ( - - ), - )} - -
    - ); - })} -
    -
    - ); -}; + return ( + +
    {renderDivider(itemsIndex, navbarItems.label)}
    + + {navbarItems?.items?.map( + ({ + expanded, + icon, + id, + selected, + items: navbarSubItems, + label, + onClick, + tag, + tagClassName, + ...otherListItemProps + }: CollapsibleNavbarItemProps) => + navbarSubItems ? ( + + ) : ( + + ), + )} + +
    + ); + })} +
    +
    + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; Navbar.displayName = composeComponentDisplayName(COMPONENT_NAME); Navbar.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Navbar/index.ts b/packages/react/src/components/Navbar/index.ts index 60745cbd..045a5cc0 100644 --- a/packages/react/src/components/Navbar/index.ts +++ b/packages/react/src/components/Navbar/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Navbar'; -export type {NavbarItems} from './Navbar'; +export * from './Navbar'; diff --git a/packages/react/src/components/NavbarItem/NavbarItem.tsx b/packages/react/src/components/NavbarItem/NavbarItem.tsx index fa847cba..670583e5 100644 --- a/packages/react/src/components/NavbarItem/NavbarItem.tsx +++ b/packages/react/src/components/NavbarItem/NavbarItem.tsx @@ -17,53 +17,76 @@ */ import clsx from 'clsx'; -import {ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode, forwardRef} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; import Chip from '../Chip'; -import type {ListItemProps} from '../ListItem'; +import type {ListItemButtonProps} from '../ListItemButton'; import ListItemButton from '../ListItemButton'; import ListItemIcon from '../ListItemIcon'; import ListItemText from '../ListItemText'; -import type {NavbarProps} from '../Navbar/Navbar'; +import type {NavbarProps} from '../Navbar'; import Tooltip from '../Tooltip'; import './navbar-item.scss'; -export interface NavbarItemProps extends ListItemProps, Pick { - /** - * Icon for the Navbar item. - * @example - */ - icon?: ReactNode; - /** - * Unique id for the item. - */ - id?: string; - /** - * Label to display on the UI. - * @example Overview - */ - label: ReactNode; - /** - * Tag to display on the UI. - * @example Beta - */ - tag?: string; - /** - * Tag color variant. - */ - tagClassName?: 'premium' | 'beta' | 'new' | 'experimental'; -} +export type NavbarItemProps = ListItemButtonProps & + Pick & { + /** + * Icon for the Navbar item. + * @example + */ + icon?: ReactNode; + /** + * Unique id for the item. + */ + id?: string; + /** + * Label to display on the UI. + * @example Overview + */ + label: ReactNode; + /** + * Tag to display on the UI. + * @example Beta + */ + tag?: string; + /** + * Tag color variant. + */ + tagClassName?: 'premium' | 'beta' | 'new' | 'experimental'; + }; const COMPONENT_NAME: string = 'NavbarItem'; +/** + * The Navbar Item component is used to represent an item in the Navbar. + * + * Demos: + * + * - [Navbar Item (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-navbar-item) + * + * API: + * + * - inherits [ListItemButton API](https://mui.com/material-ui/api/list-item-button/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [ListItemButton](https://mui.com/material-ui/api/list-item-button/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the NavbarItem component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered NavbarItem component. + */ const NavbarItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ( + ( { className, collapsible = true, - component, fill, icon, id, @@ -75,7 +98,7 @@ const NavbarItem: ForwardRefExoticComponent & WithWrapperProps tagClassName, open = true, ...rest - }: NavbarItemProps, + }: NavbarItemProps, ref: MutableRefObject, ): ReactElement => { const classes: string = clsx( @@ -89,7 +112,7 @@ const NavbarItem: ForwardRefExoticComponent & WithWrapperProps ); return ( - + & WithWrapperProps = ({ - className, - ...rest -}: OutlinedInputProps): ReactElement => { - const classes: string = clsx('oxygen-outlined-input', className); +/** + * The Outlined Input component is used to render a text input field with an outlined border. + * + * Demos: + * + * - [Text Field (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-text-field) + * - [Text Field (MUI)](https://mui.com/material-ui/react-text-field/) + * + * API: + * + * - [OutlinedInput API](https://mui.com/material-ui/api/outlined-input/) + * - inherits [InputBase API](https://mui.com/material-ui/api/input-base/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the OutlinedInput component. + * @param ref - The ref to be forwarded to the MuiOutlinedInput component. + * @returns The rendered OutlinedInput component. + */ +const OutlinedInput: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, ...rest}: OutlinedInputProps, ref: MutableRefObject): ReactElement => { + const classes: string = clsx('oxygen-outlined-input', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; OutlinedInput.displayName = composeComponentDisplayName(COMPONENT_NAME); OutlinedInput.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/OutlinedInput/index.ts b/packages/react/src/components/OutlinedInput/index.ts index f0beb81a..cd840b65 100644 --- a/packages/react/src/components/OutlinedInput/index.ts +++ b/packages/react/src/components/OutlinedInput/index.ts @@ -17,4 +17,4 @@ */ export {default} from './OutlinedInput'; -export type {OutlinedInputProps} from './OutlinedInput'; +export * from './OutlinedInput'; diff --git a/packages/react/src/components/Paper/Paper.tsx b/packages/react/src/components/Paper/Paper.tsx index 533c60a1..5d429d0f 100644 --- a/packages/react/src/components/Paper/Paper.tsx +++ b/packages/react/src/components/Paper/Paper.tsx @@ -16,20 +16,56 @@ * under the License. */ -import MuiPaper, {PaperProps as MuiPaperProps} from '@mui/material/Paper'; +import MuiPaper from '@mui/material/Paper'; +import type {PaperProps as MuiPaperProps, PaperTypeMap} from '@mui/material/Paper'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type PaperProps = { +export type PaperProps< + C extends ElementType = ElementType, + D extends ElementType = PaperTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Paper'; +/** + * The Paper component is a container for displaying content on an elevated surface. + * + * Demos: + * + * - [Card (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-card) + * - [Card (MUI)](https://mui.com/material-ui/react-card/) + * - [Paper (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-paper) + * - [Paper](https://mui.com/material-ui/react-paper/) + * + * API: + * + * - [Paper API](https://mui.com/material-ui/api/paper/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Paper component. + * @param ref - The ref to be forwarded to the MuiPaper component. + * @returns The rendered Paper component. + */ const Paper: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: PaperProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: PaperProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-paper', className); return ; diff --git a/packages/react/src/components/Paper/index.ts b/packages/react/src/components/Paper/index.ts index cff0130e..2251b4e8 100644 --- a/packages/react/src/components/Paper/index.ts +++ b/packages/react/src/components/Paper/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Paper'; -export type {PaperProps} from './Paper'; +export * from './Paper'; + +export type {PaperPropsVariantOverrides, PaperTypeMap} from '@mui/material/Paper'; diff --git a/packages/react/src/components/PhoneNumberInput/PhoneNumberInput.tsx b/packages/react/src/components/PhoneNumberInput/PhoneNumberInput.tsx index 91f071f2..3854aaf4 100644 --- a/packages/react/src/components/PhoneNumberInput/PhoneNumberInput.tsx +++ b/packages/react/src/components/PhoneNumberInput/PhoneNumberInput.tsx @@ -17,28 +17,39 @@ */ import {FlagOutlined} from '@mui/icons-material'; +// TODO: Refactor to use the `Select` from local. import Select, {SelectChangeEvent, SelectProps as MuiSelectProps} from '@mui/material/Select'; import clsx from 'clsx'; -import {ChangeEvent, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement, useState} from 'react'; +import {forwardRef, useState} from 'react'; +import type {ChangeEvent, ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import Flag from 'react-world-flags'; -import {countries, Country} from './constants'; +import {countries, Country} from './constants/countries'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import Box, {BoxProps} from '../Box'; +import Box from '../Box'; +import type {BoxProps} from '../Box'; import InputLabel from '../InputLabel'; +import type {InputLabelProps} from '../InputLabel'; import ListItemIcon from '../ListItemIcon'; import MenuItem from '../MenuItem'; -import './phone-number-input.scss'; -import OutlinedInput, {OutlinedInputProps as MuiOutlinedInputProps} from '../OutlinedInput'; +import OutlinedInput from '../OutlinedInput'; +import type {OutlinedInputProps} from '../OutlinedInput'; import Typography from '../Typography'; +import './phone-number-input.scss'; -export interface PhoneNumberInputProps extends BoxProps { +export type PhoneNumberInputProps = BoxProps & { + /** + * Props sent to the InputLabel component. + * + * Refer props: {@link https://mui.com/material-ui/api/input-label/} + */ + InputLabelProps?: InputLabelProps; /** * Props sent to the OutlinedInput component. * * Refer props: {@link https://mui.com/material-ui/api/outlined-input/} */ - OutlinedInputProps?: Omit; + OutlinedInputProps?: Omit; /** * Props sent to the Select component. * @@ -51,6 +62,10 @@ export interface PhoneNumberInputProps extends BoxProps { * @example '+94' */ dialCodeValue?: string; + /** + * Label for the phone number input. + */ + label: string; /** * Callback function to be called when the dialCode or phoneNumber changes. */ @@ -65,12 +80,34 @@ export interface PhoneNumberInputProps extends BoxProps { * Placeholder text for the phone number input. */ placeholder?: string; -} +}; const COMPONENT_NAME: string = 'PhoneNumberInput'; +/** + * The Phone Number Input component is used to get the phone number input from the user. + * + * Demos: + * + * - [Phone Number Input (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-phone-number-input) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the PhoneNumberInput component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered PhoneNumberInput component. + */ const PhoneNumberInput: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ( + ( { className, dialCodeValue, @@ -82,7 +119,7 @@ const PhoneNumberInput: ForwardRefExoticComponent & WithW placeholder, SelectProps, ...rest - }: PhoneNumberInputProps, + }: PhoneNumberInputProps, ref: MutableRefObject, ): ReactElement => { const classes: string = clsx('oxygen-phone-number-input', className); diff --git a/packages/react/src/components/PhoneNumberInput/index.ts b/packages/react/src/components/PhoneNumberInput/index.ts index d8320007..f2025c60 100644 --- a/packages/react/src/components/PhoneNumberInput/index.ts +++ b/packages/react/src/components/PhoneNumberInput/index.ts @@ -17,4 +17,4 @@ */ export {default} from './PhoneNumberInput'; -export type {PhoneNumberInputProps} from './PhoneNumberInput'; +export * from './PhoneNumberInput'; diff --git a/packages/react/src/components/Popover/Popover.tsx b/packages/react/src/components/Popover/Popover.tsx index 533008ee..fb490dbb 100644 --- a/packages/react/src/components/Popover/Popover.tsx +++ b/packages/react/src/components/Popover/Popover.tsx @@ -16,18 +16,53 @@ * under the License. */ -import MuiPopover, {PopoverProps as MuiPopoverProps} from '@mui/material/Popover'; +import MuiPopover from '@mui/material/Popover'; +import type {PopoverProps as MuiPopoverProps} from '@mui/material/Popover'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type PopoverProps = MuiPopoverProps; +export type PopoverProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Popover'; +/** + * A Popover can be used to display some content on top of another. + * + * Demos: + * + * - [Menu (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-menu) + * - [Menu (MUI)](https://mui.com/material-ui/react-menu/) + * - [Popover (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/utils-popover) + * - [Popover (MUI)](https://mui.com/material-ui/react-popover/) + * + * API: + * + * - [Popover API](https://mui.com/material-ui/api/popover/) + * - inherits [Modal API](https://mui.com/material-ui/api/modal/) + * + * @remarks + * - ✔️ Props of the [Modal](https://mui.com/material-ui/api/modal/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Popover component. + * @param ref - The ref to be forwarded to the MuiPopover component. + * @returns The rendered Popover component. + */ const Popover: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: PopoverProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: PopoverProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-popover', className); return ; diff --git a/packages/react/src/components/Popover/index.ts b/packages/react/src/components/Popover/index.ts index e6be37bf..a9513f52 100644 --- a/packages/react/src/components/Popover/index.ts +++ b/packages/react/src/components/Popover/index.ts @@ -17,4 +17,7 @@ */ export {default} from './Popover'; -export type {PopoverProps} from './Popover'; +export * from './Popover'; + +export type {PopoverActions, PopoverReference, PopoverPosition, PopoverOrigin} from '@mui/material/Popover'; +export {getOffsetTop, getOffsetLeft} from '@mui/material/Popover'; diff --git a/packages/react/src/components/Radio/Radio.tsx b/packages/react/src/components/Radio/Radio.tsx index 32fb979e..ac4034a5 100644 --- a/packages/react/src/components/Radio/Radio.tsx +++ b/packages/react/src/components/Radio/Radio.tsx @@ -16,18 +16,51 @@ * under the License. */ -import MuiRadio, {RadioProps as MuiRadioProps} from '@mui/material/Radio'; +import MuiRadio from '@mui/material/Radio'; +import type {RadioProps as MuiRadioProps} from '@mui/material/Radio'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type RadioProps = MuiRadioProps; +export type RadioProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Radio'; +/** + * A Radio component is used to allow users to select a single option from a list of options. + * + * Demos: + * + * - [Radio Group (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-radio-group) + * - [Radio Group (MUI)](https://mui.com/material-ui/react-radio-button/) + * + * API: + * + * - [Radio API](https://mui.com/material-ui/api/radio/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Radio component. + * @param ref - The ref to be forwarded to the MuiRadio component. + * @returns The rendered Radio component. + */ const Radio: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: RadioProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: RadioProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-radio', className); return ; diff --git a/packages/react/src/components/Radio/index.ts b/packages/react/src/components/Radio/index.ts index c7f7cb81..67a36a3a 100644 --- a/packages/react/src/components/Radio/index.ts +++ b/packages/react/src/components/Radio/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Radio'; -export type {RadioProps} from './Radio'; +export * from './Radio'; + +export type {RadioPropsSizeOverrides, RadioPropsColorOverrides} from '@mui/material/Radio'; diff --git a/packages/react/src/components/RadioGroup/RadioGroup.tsx b/packages/react/src/components/RadioGroup/RadioGroup.tsx index 8c928589..ecd5b1bd 100644 --- a/packages/react/src/components/RadioGroup/RadioGroup.tsx +++ b/packages/react/src/components/RadioGroup/RadioGroup.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiRadioGroup, {RadioGroupProps as MuiRadioGroupProps} from '@mui/material/RadioGroup'; +import MuiRadioGroup from '@mui/material/RadioGroup'; +import type {RadioGroupProps as MuiRadioGroupProps} from '@mui/material/RadioGroup'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,8 +28,30 @@ export type RadioGroupProps = MuiRadioGroupProps; const COMPONENT_NAME: string = 'RadioGroup'; +/** + * The Radio Group allows the user to select one option from a set. + * + * Demos: + * + * - [Radio Group (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-radio-group) + * - [Radio Group (MUI)](https://mui.com/material-ui/react-radio-button/) + * + * API: + * + * - [RadioGroup API](https://mui.com/material-ui/api/radio-group/) + * - inherits [FormGroup API](https://mui.com/material-ui/api/form-group/) + * + * @remarks + * - ✔️ Props of the [FormGroup](https://mui.com/material-ui/api/form-group/) component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the RadioGroup component. + * @param ref - The ref to be forwarded to the MuiRadioGroup component. + * @returns The rendered RadioGroup component. + */ const RadioGroup: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: RadioGroupProps, ref: MutableRefObject): ReactElement => { + ({className, ...rest}: RadioGroupProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-radio-group', className); return ; diff --git a/packages/react/src/components/RadioGroup/index.ts b/packages/react/src/components/RadioGroup/index.ts index 4e384eff..e4703030 100644 --- a/packages/react/src/components/RadioGroup/index.ts +++ b/packages/react/src/components/RadioGroup/index.ts @@ -17,4 +17,6 @@ */ export {default} from './RadioGroup'; -export type {RadioGroupProps} from './RadioGroup'; +export * from './RadioGroup'; + +export {RadioGroupClassKey} from '@mui/material/RadioGroup'; diff --git a/packages/react/src/components/Select/Select.tsx b/packages/react/src/components/Select/Select.tsx index 2f4489ba..0b5eec87 100644 --- a/packages/react/src/components/Select/Select.tsx +++ b/packages/react/src/components/Select/Select.tsx @@ -16,23 +16,48 @@ * under the License. */ -import MuiSelect, {SelectProps as MuiSelectProps} from '@mui/material/Select'; +import MuiSelect from '@mui/material/Select'; +import type {SelectProps as MuiSelectProps} from '@mui/material/Select'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -import InputLabel, {InputLabelProps as MuiInputLabelProps} from '../InputLabel'; +import InputLabel from '../InputLabel'; +import type {InputLabelProps as MuiInputLabelProps} from '../InputLabel'; import './select.scss'; -export interface SelectProps extends MuiSelectProps { +export type SelectProps = MuiSelectProps & { /** * Props for the `InputLabel` component. */ InputLabelProps?: MuiInputLabelProps; -} +}; const COMPONENT_NAME: string = 'Select'; +/** + * The Select components are used for collecting user provided information from a list of options. + * + * Demos: + * + * - [Select (Oxygen UI)](https://mui.com/material-ui/react-select/) + * - [Select (MUI)](https://mui.com/material-ui/react-select/) + * + * API: + * + * - [Select API](https://mui.com/material-ui/api/select/) + * - inherits [OutlinedInput API](https://mui.com/material-ui/api/outlined-input/) + * + * @remarks + * - ✔️ Props of the [OutlinedInput](https://mui.com/material-ui/api/outlined-input/) component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the Select component. + * @param ref - The ref to be forwarded to the MuiSelect component. + * @returns The rendered Select component. + */ const Select: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ( { diff --git a/packages/react/src/components/Select/index.ts b/packages/react/src/components/Select/index.ts index 99547d5c..f9c11f7d 100644 --- a/packages/react/src/components/Select/index.ts +++ b/packages/react/src/components/Select/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Select'; -export type {SelectProps} from './Select'; +export * from './Select'; + +export {SelectChangeEvent} from '@mui/material/Select'; diff --git a/packages/react/src/components/SignIn/SignIn.tsx b/packages/react/src/components/SignIn/SignIn.tsx index 933d71af..7f436e37 100644 --- a/packages/react/src/components/SignIn/SignIn.tsx +++ b/packages/react/src/components/SignIn/SignIn.tsx @@ -16,18 +16,26 @@ * under the License. */ -import {Box, FormGroup, FormControlLabel, Typography, Grid, BoxProps, Paper, Checkbox} from '@mui/material'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; -import {MuiWrapperProps} from '../../models/component'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {BoxProps} from '../Box'; +import Box from '../Box'; import Button from '../Button'; +import Checkbox from '../Checkbox'; import Divider from '../Divider'; +import FormControlLabel from '../FormControlLabel'; +import FormGroup from '../FormGroup'; +import Grid from '../Grid'; import Link from '../Link'; +import Paper from '../Paper'; import TextField from '../TextField'; +import Typography from '../Typography'; import './sign-in.scss'; -export interface SignInProps extends BoxProps { +export type SignInProps = BoxProps & { /** * URL for the login box logo. */ @@ -40,73 +48,94 @@ export interface SignInProps extends BoxProps { * URL for the sign up. */ signUpUrl?: string; -} +}; const COMPONENT_NAME: string = 'SignIn'; -const SignIn: FC & MuiWrapperProps = ({ - className, - signUpUrl, - logoUrl, - signInOptions, - ...rest -}: SignInProps): ReactElement => { - const classes: string = clsx('oxygen-sign-in', className); +/** + * The Sign In component is a custom component that is used to render a sign-in form. + * + * Demos: + * + * - [Sign In (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/patterns-sign-in--overview) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the SignIn component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered SignIn component. + */ +const SignIn: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, signUpUrl, logoUrl, signInOptions, ...rest}: SignInProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-sign-in', className); - return ( - - {logoUrl && } - - - Sign in - - null} noValidate sx={{mt: 1}}> - - - - } label="Remember me on this computer" /> - - - {signInOptions && ( -
    - OR -
    {signInOptions}
    -
    - )} - {signUpUrl && ( - - Don't have an account? - - - Sign up - + return ( + + {logoUrl && } + + + Sign in + + null} noValidate sx={{mt: 1}}> + + + + } label="Remember me on this computer" /> + + + {signInOptions && ( +
    + OR +
    {signInOptions}
    +
    + )} + {signUpUrl && ( + + Don't have an account? + + + Sign up + + -
    - )} -
    -
    -
    - ); -}; + )} +
    + +
    + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; SignIn.displayName = composeComponentDisplayName(COMPONENT_NAME); SignIn.muiName = 'SignIn'; diff --git a/packages/react/src/components/SignIn/index.ts b/packages/react/src/components/SignIn/index.ts index bf5f76e8..c90a3aef 100644 --- a/packages/react/src/components/SignIn/index.ts +++ b/packages/react/src/components/SignIn/index.ts @@ -17,4 +17,4 @@ */ export {default} from './SignIn'; -export type {SignInProps} from './SignIn'; +export * from './SignIn'; diff --git a/packages/react/src/components/Skeleton/Skeleton.tsx b/packages/react/src/components/Skeleton/Skeleton.tsx index 258b8958..476e6fca 100644 --- a/packages/react/src/components/Skeleton/Skeleton.tsx +++ b/packages/react/src/components/Skeleton/Skeleton.tsx @@ -16,26 +16,59 @@ * under the License. */ -import MuiSkeleton, {SkeletonProps as MuiSkeletonProps} from '@mui/material/Skeleton'; +import MuiSkeleton from '@mui/material/Skeleton'; +import type {SkeletonProps as MuiSkeletonProps, SkeletonTypeMap} from '@mui/material/Skeleton'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; -export type SkeletonProps = { +export type SkeletonProps< + C extends ElementType = ElementType, + D extends ElementType = SkeletonTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Skeleton'; -const Skeleton: FC & WithWrapperProps = ({ - className, - ...rest -}: SkeletonProps): ReactElement => { - const classes: string = clsx('oxygen-skeleton', className); +/** + * The Skeleton displays a placeholder preview of your content before the data gets loaded to reduce load-time frustration. + * + * Demos: + * + * - [Skeleton (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-skeleton) + * - [Skeleton (MUI)](https://mui.com/material-ui/react-skeleton/) + * + * API: + * + * - [Skeleton API](https://mui.com/material-ui/api/skeleton/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Skeleton component. + * @param ref - The ref to be forwarded to the MuiSkeleton component. + * @returns The rendered Skeleton component. + */ +const Skeleton: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {className, ...rest}: SkeletonProps, + ref: MutableRefObject, + ): ReactElement => { + const classes: string = clsx('oxygen-skeleton', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Skeleton.displayName = composeComponentDisplayName(COMPONENT_NAME); Skeleton.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Skeleton/index.ts b/packages/react/src/components/Skeleton/index.ts index 40e010aa..d7c1a671 100644 --- a/packages/react/src/components/Skeleton/index.ts +++ b/packages/react/src/components/Skeleton/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Skeleton'; -export type {SkeletonProps} from './Skeleton'; +export * from './Skeleton'; + +export type {SkeletonPropsVariantOverrides, SkeletonTypeMap} from '@mui/material/Skeleton'; diff --git a/packages/react/src/components/Snackbar/Snackbar.tsx b/packages/react/src/components/Snackbar/Snackbar.tsx index df895ed4..f53af5df 100644 --- a/packages/react/src/components/Snackbar/Snackbar.tsx +++ b/packages/react/src/components/Snackbar/Snackbar.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiSnackbar, {SnackbarProps as MuiSnackbarProps} from '@mui/material/Snackbar'; +import MuiSnackbar from '@mui/material/Snackbar'; +import type {SnackbarProps as MuiSnackbarProps} from '@mui/material/Snackbar'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './snackbar.scss'; @@ -27,6 +29,27 @@ export type SnackbarProps = MuiSnackbarProps; const COMPONENT_NAME: string = 'Snackbar'; +/** + * The Snackbar (also known as toasts) is used for brief notifications of processes that have been or will be performed. + * + * Demos: + * + * - [Snackbar (Oxygen UI)]](https://wso2.github.io/oxygen-ui/react/?path=/docs/feedback-snackbar--overview) + * - [Snackbar (MUI)](https://mui.com/material-ui/react-snackbar/) + * + * API: + * + * - [Snackbar API](https://mui.com/material-ui/api/snackbar/) + * + * @remarks + * - ✔️ Props of the native component are also available. + * - ❌ `component` prop is not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @param props - The props for the Snackbar component. + * @param ref - The ref to be forwarded to the MuiSnackbar component. + * @returns The rendered Snackbar component. + */ const Snackbar: ForwardRefExoticComponent & WithWrapperProps = forwardRef( ({className, ...rest}: SnackbarProps, ref: MutableRefObject): ReactElement => { const classes: string = clsx('oxygen-snackbar', className); diff --git a/packages/react/src/components/Snackbar/index.ts b/packages/react/src/components/Snackbar/index.ts index 76a168a1..1ac3f36a 100644 --- a/packages/react/src/components/Snackbar/index.ts +++ b/packages/react/src/components/Snackbar/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Snackbar'; -export type {SnackbarProps} from './Snackbar'; +export * from './Snackbar'; + +export type {SnackbarCloseReason, SnackbarOrigin} from '@mui/material/Snackbar'; diff --git a/packages/react/src/components/Stepper/Stepper.tsx b/packages/react/src/components/Stepper/Stepper.tsx index fc3ced33..88c93f4b 100644 --- a/packages/react/src/components/Stepper/Stepper.tsx +++ b/packages/react/src/components/Stepper/Stepper.tsx @@ -17,13 +17,15 @@ */ import clsx from 'clsx'; -import {FC, HTMLAttributes, MutableRefObject, ReactElement, useCallback, useEffect, useRef, useState} from 'react'; +import {forwardRef, useCallback, useEffect, useRef, useState} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import Box from '../Box'; +import type {BoxProps} from '../Box'; import './stepper.scss'; -export interface StepperProps extends HTMLAttributes { +export type StepperProps = BoxProps & { /** * Animate the slide transition. */ @@ -36,75 +38,97 @@ export interface StepperProps extends HTMLAttributes { * Steps to be rendered. */ steps: ReactElement[]; -} +}; const COMPONENT_NAME: string = 'Stepper'; -const Stepper: FC & WithWrapperProps = ({ - animateOnSlide, - className, - currentStep = 0, - steps, -}: StepperProps): ReactElement => { - const [slideLeftPosition, setSlideLeftPosition] = useState(0); - const [slideContainerWidth, setSlideContainerWidth] = useState(0); - - const slideContainerRef: MutableRefObject = useRef(null); - - const classes: string = clsx('oxygen-stepper', className); +/** + * The Stepper can be used to compose wizards and carousels. + * + * Demos: + * + * - [Stepper (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/surfaces-stepper--overview) + * + * API: + * + * - inherits [Box API](https://mui.com/material-ui/api/box/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Stepper component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered Stepper component. + */ +const Stepper: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ( + {animateOnSlide, className, currentStep = 0, steps}: StepperProps, + ref: MutableRefObject, + ): ReactElement => { + const [slideLeftPosition, setSlideLeftPosition] = useState(0); + const [slideContainerWidth, setSlideContainerWidth] = useState(0); + + const slideContainerRef: MutableRefObject = useRef(null); + + const classes: string = clsx('oxygen-stepper', className); + + const slideContainer: (position: number) => void = useCallback( + (position: number): void => { + if (!animateOnSlide) { + return; + } + + const slideBy: number = position; + setSlideLeftPosition(slideBy * -1 * currentStep); + }, + [currentStep, animateOnSlide], + ); - const slideContainer: (position: number) => void = useCallback( - (position: number): void => { - if (!animateOnSlide) { - return; + useEffect(() => { + if (!slideContainerRef?.current || !animateOnSlide) { + return () => {}; } - const slideBy: number = position; - setSlideLeftPosition(slideBy * -1 * currentStep); - }, - [currentStep, animateOnSlide], - ); - - useEffect(() => { - if (!slideContainerRef?.current || !animateOnSlide) { - return () => {}; - } - - setSlideContainerWidth(slideContainerRef.current.offsetWidth); - - const handleResize = (): void => { - const width: number = slideContainerRef.current.offsetWidth; - setSlideContainerWidth(width); - slideContainer(width); - }; - - window.addEventListener('resize', handleResize); - - return (): void => { - window.removeEventListener('resize', handleResize); - }; - }, [animateOnSlide, slideContainer]); - - useEffect(() => { - slideContainer(slideContainerWidth); - }, [slideContainerWidth, slideContainer]); - - if (animateOnSlide) { - return ( - - - {steps.map((step: ReactElement) => ( - - {step} - - ))} + setSlideContainerWidth(slideContainerRef.current.offsetWidth); + + const handleResize = (): void => { + const width: number = slideContainerRef.current.offsetWidth; + setSlideContainerWidth(width); + slideContainer(width); + }; + + window.addEventListener('resize', handleResize); + + return (): void => { + window.removeEventListener('resize', handleResize); + }; + }, [animateOnSlide, slideContainer]); + + useEffect(() => { + slideContainer(slideContainerWidth); + }, [slideContainerWidth, slideContainer]); + + if (animateOnSlide) { + return ( + + + {steps.map((step: ReactElement) => ( + + {step} + + ))} + - - ); - } + ); + } - return steps[currentStep]; -}; + return steps[currentStep]; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Stepper.displayName = composeComponentDisplayName(COMPONENT_NAME); Stepper.muiName = COMPONENT_NAME; diff --git a/packages/react/src/components/Stepper/index.ts b/packages/react/src/components/Stepper/index.ts index 31cef048..c0ca389c 100644 --- a/packages/react/src/components/Stepper/index.ts +++ b/packages/react/src/components/Stepper/index.ts @@ -17,4 +17,4 @@ */ export {default} from './Stepper'; -export type {StepperProps} from './Stepper'; +export * from './Stepper'; diff --git a/packages/react/src/components/Switch/Switch.tsx b/packages/react/src/components/Switch/Switch.tsx index d0ca1ec6..6a0bb4c2 100644 --- a/packages/react/src/components/Switch/Switch.tsx +++ b/packages/react/src/components/Switch/Switch.tsx @@ -16,25 +16,57 @@ * under the License. */ -import MuiSwitch, {SwitchProps as MuiSwitchProps} from '@mui/material/Switch'; +import MuiSwitch from '@mui/material/Switch'; +import type {SwitchProps as MuiSwitchProps} from '@mui/material/Switch'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './switch.scss'; -export type SwitchProps = MuiSwitchProps; +export type SwitchProps = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit; const COMPONENT_NAME: string = 'Switch'; /** - * @remarks `any` is used as the generic type for the props because the generic type is not used in the component. + * The Switch toggles the state of a single setting on or off. + * + * Demos: + * + * - [Switch (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/inputs-switch) + * - [Switch (MUI)](https://mui.com/material-ui/react-switch/) + * - [Transfer List (Oxygen UI)](TODO: Add a link after implementing: Tracker: https://github.com/wso2/oxygen-ui/issues/2) + * - [Transfer List (MUI)](https://mui.com/material-ui/react-transfer-list/) + * + * API: + * + * - [Switch API](https://mui.com/material-ui/api/switch/) + * - inherits [IconButton API](https://mui.com/material-ui/api/icon-button/) + * + * @remarks + * - ✔️ Props of the [IconButton](https://mui.com/material-ui/api/icon-button/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Switch component. + * @param ref - The ref to be forwarded to the MuiSwitch component. + * @returns The rendered Switch component. */ const Switch: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: SwitchProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: SwitchProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-switch', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; diff --git a/packages/react/src/components/Switch/index.ts b/packages/react/src/components/Switch/index.ts index 47deb744..9c151c75 100644 --- a/packages/react/src/components/Switch/index.ts +++ b/packages/react/src/components/Switch/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Switch'; -export type {SwitchProps} from './Switch'; +export * from './Switch'; + +export type {SwitchPropsSizeOverrides, SwitchPropsColorOverrides} from '@mui/material/Switch'; diff --git a/packages/react/src/components/Tab/Tab.tsx b/packages/react/src/components/Tab/Tab.tsx index a63d439f..61770178 100644 --- a/packages/react/src/components/Tab/Tab.tsx +++ b/packages/react/src/components/Tab/Tab.tsx @@ -16,19 +16,56 @@ * under the License. */ -import MuiTab, {TabProps as MuiTabProps} from '@mui/material/Tab'; +import MuiTab from '@mui/material/Tab'; +import type {TabProps as MuiTabProps, TabTypeMap} from '@mui/material/Tab'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './tab.scss'; -export type TabProps = MuiTabProps; +export type TabProps< + C extends ElementType = ElementType, + D extends ElementType = TabTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ + component?: C; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Tab'; +/** + * The Tab component is used to create a tab in a tab list. + * + * Demos: + * + * - [Tabs (Oxygen UI)](https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-tab) + * - [Tabs (MUI)](https://mui.com/material-ui/react-tabs/) + * + * API: + * + * - [Tab API](https://mui.com/material-ui/api/tab/) + * - inherits [ButtonBase API](https://mui.com/material-ui/api/button-base/) + * + * @remarks + * - ✔️ Props of the [ButtonBase](https://mui.com/material-ui/api/button-base/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the Tab component. + * @param ref - The ref to be forwarded to the MuiTab component. + * @returns The rendered Tab component. + */ const Tab: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ({className, ...rest}: TabProps, ref: MutableRefObject): ReactElement => { + ( + {className, ...rest}: TabProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-tab', className); return ; diff --git a/packages/react/src/components/Tab/index.ts b/packages/react/src/components/Tab/index.ts index b42963d6..31602781 100644 --- a/packages/react/src/components/Tab/index.ts +++ b/packages/react/src/components/Tab/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Tab'; -export type {TabProps} from './Tab'; +export * from './Tab'; + +export {TabTypeMap} from '@mui/material/Tab'; diff --git a/packages/react/src/components/TabPanel/TabPanel.tsx b/packages/react/src/components/TabPanel/TabPanel.tsx index ab168917..84acb90c 100644 --- a/packages/react/src/components/TabPanel/TabPanel.tsx +++ b/packages/react/src/components/TabPanel/TabPanel.tsx @@ -16,15 +16,16 @@ * under the License. */ -import {BoxProps as MuiBoxProps} from '@mui/material'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {BoxProps} from '../Box'; import Box from '../Box'; import './tab-panel.scss'; -export interface TabPanelProps extends MuiBoxProps { +export type TabPanelProps = BoxProps & { /* * The index of the corresponding `TabPanel`. */ @@ -33,19 +34,41 @@ export interface TabPanelProps extends MuiBoxProps { * The value of the selected `TabPanel`. */ value: number; -} +}; const COMPONENT_NAME: string = 'TabPanel'; +/** + * TabPanel component can be used with Tabs component to implement the content of the tab views. + * + * Demos: + * + * - [TabPanel (Oxygen UI)] (https://wso2.github.io/oxygen-ui/react/?path=/docs/navigation-tab-panel--overview) + * + * API: + * + * - inherits [Card API](https://mui.com/material-ui/api/card/) + * + * @remarks + * - ✨ This is a custom component that is not available in the Material-UI library. + * - ✔️ Props of the [Box](https://mui.com/material-ui/api/box/) component are also available. + * - ✅ `component` prop is supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @template C - The type of the component. + * @param props - The props for the TabPanel component. + * @param ref - The ref to be forwarded to the Box component. + * @returns The rendered TabPanel component. + */ const TabPanel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - ( - {className, children, value, index, ...rest}: TabPanelProps, + ( + {className, children, value, index, ...rest}: TabPanelProps, ref: MutableRefObject, ): ReactElement => { const classes: string = clsx('oxygen-tab-panel', className); return ( -