diff --git a/packages/react/src/components/Accordion/Accordion.tsx b/packages/react/src/components/Accordion/Accordion.tsx index a39a470f..944be0be 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) 2024, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -17,23 +17,57 @@ */ import MuiAccordion, {AccordionProps as MuiAccordionProps} from '@mui/material/Accordion'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {PaperTypeMap} from '../Paper'; 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 = (props: AccordionProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AccordionProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-accordion', className); - return ; -}; + return ; + }, +) as OverridableComponent> & 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 1774181d..36f6668c 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, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,18 +28,36 @@ 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( - (props: AccordionDetailsProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ({className, ...rest}: AccordionDetailsProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-accordion-details', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; AccordionDetails.displayName = composeComponentDisplayName(COMPONENT_NAME); AccordionDetails.muiName = COMPONENT_NAME; -AccordionDetails.defaultProps = {}; export default AccordionDetails; 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 37cc13b0..0cbe52cc 100644 --- a/packages/react/src/components/AccordionSummary/AccordionSummary.tsx +++ b/packages/react/src/components/AccordionSummary/AccordionSummary.tsx @@ -16,28 +16,67 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, ElementType, Ref} 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'; -const AccordionSummary: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: AccordionSummaryProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - - const classes: string = clsx('oxygen-accordion-summary', className); +/** + * 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: OverridableComponent> & WithWrapperProps = + forwardRef( + ( + {className, ...rest}: AccordionSummaryProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-accordion-summary', className); - return ; - }, -) as ForwardRefExoticComponent & WithWrapperProps; + return ; + }, + ) as OverridableComponent> & WithWrapperProps; AccordionSummary.displayName = composeComponentDisplayName(COMPONENT_NAME); AccordionSummary.muiName = COMPONENT_NAME; -AccordionSummary.defaultProps = {}; export default AccordionSummary; 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 f4645b91..a72e1f1a 100644 --- a/packages/react/src/components/AccountOverview/AccountOverview.tsx +++ b/packages/react/src/components/AccountOverview/AccountOverview.tsx @@ -16,20 +16,29 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, ReactNode, Ref} 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,51 +69,77 @@ export interface AccountOverviewProps extends Omit { * Logged user information. */ user: UserTemplate; -} +}; export type AccountCompletionSteps = CarouselStep; const COMPONENT_NAME: string = 'AccountOverview'; -const AccountOverview: FC & WithWrapperProps = (props: AccountOverviewProps): ReactElement => { - const { - className, - title, - subheader, - accountCompletionStepsTitle, - accountCompletionSteps, - accountProgress, - user, - cardHeaderProps, - ...rest - } = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + { + className, + title, + subheader, + accountCompletionStepsTitle, + accountCompletionSteps, + accountProgress, + user, + cardHeaderProps, + ...rest + }: AccountOverviewProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-account-overview', className); - return ( - - - } - title={title} - subheader={subheader} - {...cardHeaderProps} - /> - {accountCompletionSteps && ( - - - - - )} - - ); -}; + return ( + + + } + title={title} + subheader={subheader} + {...cardHeaderProps} + /> + {accountCompletionSteps && ( + + + + + )} + + ); + }, +) as OverridableComponent> & 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 515ef90c..5ec9788b 100644 --- a/packages/react/src/components/ActionCard/ActionCard.tsx +++ b/packages/react/src/components/ActionCard/ActionCard.tsx @@ -16,18 +16,21 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, ReactNode, Ref} 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, CardTypeMap} 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,33 +51,57 @@ export interface ActionCardProps extends CardProps { * The title of the card. */ title: string; -} +}; const COMPONENT_NAME: string = 'ActionCard'; -const ActionCard: FC & WithWrapperProps = (props: ActionCardProps): ReactElement => { - const {className, image, title, description, actionText, onActionClick, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, image, title, description, actionText, onActionClick, ...rest}: ActionCardProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-action-card', className); - return ( - - - {image} - {title} - {description} - - - - - - ); -}; + return ( + + + {image} + {title} + {description} + + + + + + ); + }, +) as OverridableComponent> & WithWrapperProps; ActionCard.displayName = composeComponentDisplayName(COMPONENT_NAME); ActionCard.muiName = COMPONENT_NAME; -ActionCard.defaultProps = {}; export default ActionCard; 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 43becf4e..3b2000d0 100644 --- a/packages/react/src/components/Alert/Alert.tsx +++ b/packages/react/src/components/Alert/Alert.tsx @@ -16,29 +16,61 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, ElementType, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {PaperTypeMap} from '../Paper'; 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'; -const Alert: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: AlertProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * The Alert component displays brief messages to 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AlertProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-alert', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Alert.displayName = composeComponentDisplayName(COMPONENT_NAME); Alert.muiName = COMPONENT_NAME; -Alert.defaultProps = {}; export default Alert; 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 2d5ed0fd..d6436ed8 100644 --- a/packages/react/src/components/AlertTitle/AlertTitle.tsx +++ b/packages/react/src/components/AlertTitle/AlertTitle.tsx @@ -16,29 +16,61 @@ * under the License. */ -import MuiAlertTitle, {AlertTitleProps as MuiAlertProps} from '@mui/material/AlertTitle'; +import MuiAlertTitle from '@mui/material/AlertTitle'; +import type {AlertTitleProps, AlertTitleProps as MuiAlertTitleProps} from '@mui/material/AlertTitle'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, ElementType, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {TypographyTypeMap} from '../Typography'; 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'; -const AlertTitle: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: AlertProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AlertProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-alert-title', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; AlertTitle.displayName = composeComponentDisplayName(COMPONENT_NAME); AlertTitle.muiName = COMPONENT_NAME; -AlertTitle.defaultProps = {}; export default AlertTitle; 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 f7be5ce1..91c22497 100644 --- a/packages/react/src/components/AppBar/AppBar.tsx +++ b/packages/react/src/components/AppBar/AppBar.tsx @@ -16,27 +16,64 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, Ref} 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 = (props: AppBarProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: AppBarProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-app-bar', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; AppBar.displayName = composeComponentDisplayName(COMPONENT_NAME); AppBar.muiName = COMPONENT_NAME; -AppBar.defaultProps = {}; export default AppBar; 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 1e7fc595..8a6d7196 100644 --- a/packages/react/src/components/AppShell/AppShell.tsx +++ b/packages/react/src/components/AppShell/AppShell.tsx @@ -16,14 +16,17 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, PropsWithChildren, ReactElement, ReactNode} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, BoxTypeMap} from '../Box'; import './app-shell.scss'; -export interface AppShellProps extends BoxProps { +export type AppShellProps = BoxProps & { /** * Footer component. */ @@ -36,35 +39,57 @@ export interface AppShellProps extends BoxProps { * Navigation component. */ navigation?: ReactNode; -} +}; const COMPONENT_NAME: string = 'AppShell'; -const AppShell: FC> & WithWrapperProps = ( - props: PropsWithChildren, -): ReactElement => { - const {className, children, footer, header, navigation, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, children, footer, header, navigation, ...rest}: AppShellProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-app-shell', className); - return ( - - {header} - - {navigation} - - - {children} + return ( + + {header} + + {navigation} + + + {children} + + {footer} - {footer} - - ); -}; + ); + }, +) as OverridableComponent> & WithWrapperProps; AppShell.displayName = composeComponentDisplayName(COMPONENT_NAME); AppShell.muiName = COMPONENT_NAME; -AppShell.defaultProps = {}; export default AppShell; diff --git a/packages/react/src/components/Autocomplete/Autocomplete.tsx b/packages/react/src/components/Autocomplete/Autocomplete.tsx index 684104e2..a25a9822 100644 --- a/packages/react/src/components/Autocomplete/Autocomplete.tsx +++ b/packages/react/src/components/Autocomplete/Autocomplete.tsx @@ -16,24 +16,49 @@ * 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, Ref} 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`. + * + * @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( - (props: AutocompleteProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ({className, ...rest}: AutocompleteProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-autocomplete', className); return ; @@ -42,6 +67,5 @@ const Autocomplete: ForwardRefExoticComponent> & WithWrap Autocomplete.displayName = composeComponentDisplayName(COMPONENT_NAME); Autocomplete.muiName = COMPONENT_NAME; -Autocomplete.defaultProps = {}; export default Autocomplete; 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 f1ad7f8a..28296948 100644 --- a/packages/react/src/components/Avatar/Avatar.tsx +++ b/packages/react/src/components/Avatar/Avatar.tsx @@ -16,15 +16,22 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement, useMemo} from 'react'; +import {forwardRef, useMemo} from 'react'; +import type {ElementType, Ref, 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,43 +44,62 @@ export type AvatarProps = { * If `true`, the background color will be randomly generated. */ randomBackgroundColor?: boolean; -} & Omit, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Avatar'; -const Avatar: FC & WithWrapperProps = (props: AvatarProps): ReactElement => { - const {className, children, component, randomBackgroundColor, backgroundColorRandomizer, ...rest} = props; - - const colorRandomizer: string = useMemo(() => { - if (backgroundColorRandomizer) { - return backgroundColorRandomizer; - } +/** + * Avatars are found throughout material design with uses in everything from tables to dialog menus. + * + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, children, randomBackgroundColor, backgroundColorRandomizer, ...rest}: AvatarProps, + ref: Ref, + ): 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 OverridableComponent> & WithWrapperProps; Avatar.displayName = composeComponentDisplayName(COMPONENT_NAME); Avatar.muiName = COMPONENT_NAME; -Avatar.defaultProps = {}; export default Avatar; 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 10078c07..629802ff 100644 --- a/packages/react/src/components/Backdrop/Backdrop.tsx +++ b/packages/react/src/components/Backdrop/Backdrop.tsx @@ -16,27 +16,64 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: BackdropProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: BackdropProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-backdrop', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Backdrop.displayName = composeComponentDisplayName(COMPONENT_NAME); Backdrop.muiName = COMPONENT_NAME; -Backdrop.defaultProps = {}; export default Backdrop; 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 b0c1264d..6ea9f976 100644 --- a/packages/react/src/components/Badge/Badge.tsx +++ b/packages/react/src/components/Badge/Badge.tsx @@ -16,24 +16,64 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: BadgeProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = + forwardRef( + ( + {className, ...rest}: BadgeProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-badge', className); - return ; -}; + return ; + }, + ) as OverridableComponent> & 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..d251c2e4 100644 --- a/packages/react/src/components/Badge/index.ts +++ b/packages/react/src/components/Badge/index.ts @@ -17,4 +17,6 @@ */ export {default} from './Badge'; -export type {BadgeProps} from './Badge'; +export * from './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 021f86eb..d2f80265 100644 --- a/packages/react/src/components/Box/Box.tsx +++ b/packages/react/src/components/Box/Box.tsx @@ -16,30 +16,60 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; +import type {BoxTypeMap} from '@mui/system/Box'; import clsx from 'clsx'; -import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, Ref} 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Box'; -const Box: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: BoxProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ({className, ...rest}: BoxProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-box', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Box.displayName = composeComponentDisplayName(COMPONENT_NAME); Box.muiName = COMPONENT_NAME; -Box.defaultProps = {}; export default Box; 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 e318f29f..d69d0d31 100644 --- a/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx +++ b/packages/react/src/components/Breadcrumbs/Breadcrumbs.tsx @@ -16,31 +16,68 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: BreadcrumbsProps): ReactElement => { - const {className, children, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, children, ...rest}: BreadcrumbsProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-breadcrumbs', className); - return ( - - {children} - - ); -}; + return ( + + {children} + + ); + }, +) as OverridableComponent> & WithWrapperProps; Breadcrumbs.displayName = composeComponentDisplayName(COMPONENT_NAME); Breadcrumbs.muiName = 'Breadcrumbs'; -Breadcrumbs.defaultProps = {}; export default 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 2151e7ea..74214983 100644 --- a/packages/react/src/components/Button/Button.tsx +++ b/packages/react/src/components/Button/Button.tsx @@ -16,24 +16,63 @@ * 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 type {ButtonTypeMap} from '@mui/material'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, ReactElement, Ref} 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 = (props: ButtonProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ButtonProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-button', className); - return ; -}; + return ; + }, +) as OverridableComponent> & 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 2d9fe935..bcf4bbb4 100644 --- a/packages/react/src/components/Card/Card.tsx +++ b/packages/react/src/components/Card/Card.tsx @@ -16,34 +16,65 @@ * 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, 'component'>; +} & 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( - (props: CardProps, ref: MutableRefObject): ReactElement => { - const {className, component, onClick, ...rest} = props; - + ( + {className, component, onClick, elevation = 0, variant = 'outlined', ...rest}: CardProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-card', {'with-hover': onClick}, className); - return ; + return ( + + ); }, ) as ForwardRefExoticComponent & WithWrapperProps; Card.displayName = composeComponentDisplayName(COMPONENT_NAME); Card.muiName = COMPONENT_NAME; -Card.defaultProps = { - elevation: 0, - variant: 'outlined', -}; export default Card; 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 d7277e60..3a0e6897 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './card-actions.scss'; @@ -27,13 +29,34 @@ export type CardActionsProps = MuiCardActionsProps; const COMPONENT_NAME: string = 'CardActions'; -const CardActions: FC & WithWrapperProps = (props: CardActionsProps): ReactElement => { - const {className, ...rest} = props; - - 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. + * + * @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: Ref): 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 8c986059..5ff85eda 100644 --- a/packages/react/src/components/CardContent/CardContent.tsx +++ b/packages/react/src/components/CardContent/CardContent.tsx @@ -16,26 +16,61 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 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'; -const CardContent: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: CardContentProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: CardContentProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-card-content', className); return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; CardContent.displayName = composeComponentDisplayName(COMPONENT_NAME); CardContent.muiName = COMPONENT_NAME; 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 0fb6cab6..d9552a29 100644 --- a/packages/react/src/components/CardHeader/CardHeader.tsx +++ b/packages/react/src/components/CardHeader/CardHeader.tsx @@ -16,24 +16,63 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: CardHeaderProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: CardHeaderProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-card-header', className); - return ; -}; + return ; + }, +) as OverridableComponent> & 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 2daa9d08..24432cd9 100644 --- a/packages/react/src/components/Carousel/Carousel.tsx +++ b/packages/react/src/components/Carousel/Carousel.tsx @@ -16,25 +16,27 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; 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, Ref, 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 +57,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 +89,152 @@ export interface CarouselProps extends Omit, 'tit * @example title */ title?: ReactNode; -} +}; const COMPONENT_NAME: string = 'Carousel'; -const Carousel: FC & WithWrapperProps = (props: CarouselProps): ReactElement => { - const {autoPlay, autoPlayInterval, className, nextButtonText, previousButtonText, steps, title, ...rest} = props; - 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(); +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + { + autoPlay = false, + autoPlayInterval = 5000, + className, + nextButtonText = 'Next', + previousButtonText = 'Previous', + steps, + title, + ...rest + }: CarouselProps, + ref: Ref, + ): 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 classes: string = clsx('oxygen-carousel', {mobile: isMobile}, className); + const interval: NodeJS.Timer = setInterval(() => { + if (isLastStep) { + setCurrentStep(0); + } else { + setCurrentStep(currentStep + 1); + } + }, autoPlayInterval); - useEffect(() => { - if (!autoPlay) { - return () => {}; - } + return () => clearInterval(interval); + }, [autoPlay, autoPlayInterval, currentStep, isLastStep]); - const interval: NodeJS.Timer = setInterval(() => { + 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 OverridableComponent> & WithWrapperProps; Carousel.displayName = composeComponentDisplayName(COMPONENT_NAME); Carousel.muiName = COMPONENT_NAME; -Carousel.defaultProps = { - autoPlay: false, - autoPlayInterval: 5000, - nextButtonText: 'Next', - previousButtonText: 'Previous', -}; export default Carousel; 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 e5802409..fa253b38 100644 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ b/packages/react/src/components/Checkbox/Checkbox.tsx @@ -16,28 +16,62 @@ * under the License. */ -import MuiCheckbox, {CheckboxProps as MuiCheckboxProps} from '@mui/material/Checkbox'; +import type {ButtonBaseTypeMap} from '@mui/material/ButtonBase'; +import MuiCheckbox from '@mui/material/Checkbox'; +import type {CheckboxProps as MuiCheckboxProps} from '@mui/material/Checkbox'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, Ref, 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'; -const Checkbox: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: CheckboxProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: CheckboxProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-checkbox', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Checkbox.displayName = composeComponentDisplayName(COMPONENT_NAME); Checkbox.muiName = COMPONENT_NAME; -Checkbox.defaultProps = {}; export default Checkbox; 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 358005b6..bb5cc68e 100644 --- a/packages/react/src/components/Chip/Chip.tsx +++ b/packages/react/src/components/Chip/Chip.tsx @@ -16,29 +16,60 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Chip'; -const Chip: FC & WithWrapperProps = (props: ChipProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ({className, ...rest}: ChipProps, ref: Ref): ReactElement => { + const classes: string = clsx('oxygen-chip', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Chip.displayName = composeComponentDisplayName(COMPONENT_NAME); Chip.muiName = COMPONENT_NAME; -Chip.defaultProps = {}; export default Chip; 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 b139da8b..06587b63 100644 --- a/packages/react/src/components/CircularProgress/CircularProgress.tsx +++ b/packages/react/src/components/CircularProgress/CircularProgress.tsx @@ -16,9 +16,11 @@ * 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 {ForwardRefExoticComponent, ReactElement, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './circular-progress.scss'; @@ -27,16 +29,38 @@ export type CircularProgressProps = MuiCircularProgressProps; const COMPONENT_NAME: string = 'CircularProgress'; -const CircularProgress: FC & WithWrapperProps = (props: CircularProgressProps): ReactElement => { - const {className, ...rest} = props; - - 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 not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @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: Ref): ReactElement => { + const classes: string = clsx('oxygen-circular-progress', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; CircularProgress.displayName = composeComponentDisplayName(COMPONENT_NAME); CircularProgress.muiName = COMPONENT_NAME; -CircularProgress.defaultProps = {}; export default CircularProgress; 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 e570ce4c..ac4de3f6 100644 --- a/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx +++ b/packages/react/src/components/CircularProgressAvatar/CircularProgressAvatar.tsx @@ -16,16 +16,21 @@ * 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 {ForwardRefExoticComponent, Ref, 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 & { /** * Props sent to the Avatar component. */ @@ -38,52 +43,74 @@ export interface CircularProgressAvatarProps extends Omit & WithWrapperProps = ( - props: CircularProgressAvatarProps, -): ReactElement => { - const {className, progress, badgeOptions, avatarOptions, ...rest} = props; - - 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 not supported. + * - ✅ The `ref` is forwarded to the root element. + * + * @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: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-circular-progress-avatar', className); - return ( - - - - - - - - ); -}; + return ( + + + + + + + + ); + }, +) as ForwardRefExoticComponent & WithWrapperProps; CircularProgressAvatar.displayName = composeComponentDisplayName(COMPONENT_NAME); CircularProgressAvatar.muiName = COMPONENT_NAME; -CircularProgressAvatar.defaultProps = {}; export default CircularProgressAvatar; diff --git a/packages/react/src/components/CircularProgressAvatar/__tests__/__snapshots__/CircularProgressAvatar.test.tsx.snap b/packages/react/src/components/CircularProgressAvatar/__tests__/__snapshots__/CircularProgressAvatar.test.tsx.snap index 2719003a..8abcbc5b 100644 --- a/packages/react/src/components/CircularProgressAvatar/__tests__/__snapshots__/CircularProgressAvatar.test.tsx.snap +++ b/packages/react/src/components/CircularProgressAvatar/__tests__/__snapshots__/CircularProgressAvatar.test.tsx.snap @@ -8,7 +8,7 @@ exports[`CircularProgressAvatar should match the snapshot 1`] = ` role="presentation" >
@@ -50,7 +50,7 @@ exports[`CircularProgressAvatar should match the snapshot 1`] = ` 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 f181b398..b66f57f6 100644 --- a/packages/react/src/components/Code/Code.tsx +++ b/packages/react/src/components/Code/Code.tsx @@ -16,18 +16,17 @@ * under the License. */ -import MuiTypography, {TypographyProps as MuiTypographyProps} from '@mui/material/Typography'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {TypographyTypeMap} from '../Typography'; +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,27 +37,48 @@ export type CodeProps = { * @default false */ outlined?: boolean; -} & Omit, 'component'>; +}; const COMPONENT_NAME: string = 'Code'; -const Code: FC & WithWrapperProps = (props: CodeProps): ReactElement => { - const {className, children, filled, outlined, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, children, filled = true, outlined = false, ...rest}: CodeProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-code', {filled, outlined}, className); - return ( - - {children} - - ); -}; + return ( + + {children} + + ); + }, +) as OverridableComponent> & WithWrapperProps; Code.displayName = composeComponentDisplayName(COMPONENT_NAME); Code.muiName = COMPONENT_NAME; -Code.defaultProps = { - filled: true, - outlined: false, -}; export default Code; diff --git a/packages/react/src/components/Code/__tests__/__snapshots__/Code.test.tsx.snap b/packages/react/src/components/Code/__tests__/__snapshots__/Code.test.tsx.snap index 9419cce4..1cedb9b6 100644 --- a/packages/react/src/components/Code/__tests__/__snapshots__/Code.test.tsx.snap +++ b/packages/react/src/components/Code/__tests__/__snapshots__/Code.test.tsx.snap @@ -4,7 +4,7 @@ exports[`Code should match the snapshot 1`] = `
Code Block 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 370af69d..c6067fd2 100644 --- a/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx +++ b/packages/react/src/components/CollapsibleNavbarItem/CollapsibleNavbarItem.tsx @@ -17,40 +17,80 @@ */ import MuiCollapse from '@mui/material/Collapse'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; 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, Ref, MouseEvent, ReactElement} 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 List from '../List'; import ListItemButton from '../ListItemButton'; +import type {ListItemButtonTypeMap} 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'; -const CollapsibleNavbarItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: CollapsibleNavbarItemProps, ref: MutableRefObject): ReactElement => { - const {className, component, expanded, fill, icon, id, open, label, onClick, items, tag, tagClassName, ...rest} = - props; - +/** + * 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: OverridableComponent> & + WithWrapperProps = forwardRef( + ( + { + className, + expanded, + fill, + icon, + id, + open = true, + label, + onClick, + items, + tag, + tagClassName, + ...rest + }: CollapsibleNavbarItemProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx( 'oxygen-collapsible-navbar-item', { @@ -63,10 +103,11 @@ const CollapsibleNavbarItem: ForwardRefExoticComponent(expanded || false); - const handleItemClick = (): void => { + const handleItemClick = (e: MouseEvent): void => { if (onClick) { - onClick(); + onClick(e); } + setItemExpanded((prevState: boolean) => !prevState); }; @@ -75,7 +116,7 @@ const CollapsibleNavbarItem: ForwardRefExoticComponent (itemExpanded ? : ); return ( - + ); }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; CollapsibleNavbarItem.displayName = composeComponentDisplayName(COMPONENT_NAME); CollapsibleNavbarItem.muiName = COMPONENT_NAME; -CollapsibleNavbarItem.defaultProps = { - open: true, -}; export default CollapsibleNavbarItem; diff --git a/packages/react/src/components/CollapsibleNavbarItem/index.tsx b/packages/react/src/components/CollapsibleNavbarItem/index.tsx index 248f4086..7b1be20c 100644 --- a/packages/react/src/components/CollapsibleNavbarItem/index.tsx +++ b/packages/react/src/components/CollapsibleNavbarItem/index.tsx @@ -17,4 +17,4 @@ */ export {default} from './CollapsibleNavbarItem'; -export type {CollapsibleNavbarItemProps} from './CollapsibleNavbarItem'; +export * from './CollapsibleNavbarItem'; diff --git a/packages/react/src/components/ColorModeToggle/ColorModeToggle.tsx b/packages/react/src/components/ColorModeToggle/ColorModeToggle.tsx index 837e3ca4..fbe456c4 100644 --- a/packages/react/src/components/ColorModeToggle/ColorModeToggle.tsx +++ b/packages/react/src/components/ColorModeToggle/ColorModeToggle.tsx @@ -16,15 +16,27 @@ * under the License. */ -import IconButton, {IconButtonProps} from '@mui/material/IconButton'; +import IconButton from '@mui/material/IconButton'; +import type {IconButtonProps, IconButtonTypeMap} from '@mui/material/IconButton'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import {useColorScheme} from '@mui/material/styles'; import clsx from 'clsx'; -import {FC, PropsWithChildren, ReactElement, SVGProps} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, PropsWithChildren, ReactElement, SVGProps} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './color-mode-toggle.scss'; -export type ColorModeToggleProps = IconButtonProps; +export type ColorModeToggleProps< + 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; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ColorModeToggle'; @@ -66,30 +78,55 @@ const CrescentIcon = (props: PropsWithChildren>): ReactE ); -const ColorModeToggle: FC & WithWrapperProps = (props: ColorModeToggleProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ColorModeToggleProps, + ref: Ref, + ): 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 OverridableComponent> & WithWrapperProps; ColorModeToggle.displayName = composeComponentDisplayName(COMPONENT_NAME); ColorModeToggle.muiName = COMPONENT_NAME; -ColorModeToggle.defaultProps = {}; export default ColorModeToggle; 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 f42544a7..b68b4cb4 100644 --- a/packages/react/src/components/Container/Container.tsx +++ b/packages/react/src/components/Container/Container.tsx @@ -16,31 +16,63 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Container'; -const Container: FC & WithWrapperProps = ( - props: ContainerProps, -): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ContainerProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-container', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Container.displayName = composeComponentDisplayName(COMPONENT_NAME); Container.muiName = COMPONENT_NAME; -Container.defaultProps = {}; export default Container; 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 91e4e356..757ce45e 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, Ref, 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,20 +32,45 @@ export interface CountryFlagsProps extends React.HTMLAttributes; -const COMPONENT_NAME: string = 'Flag'; +/** + * @deprecated Use the {@link CountryFlagProps} instead. + */ +export type CountryFlagsProps = CountryFlagProps; -const CountryFlag: FC & WithWrapperProps = (props: CountryFlagsProps): ReactElement => { - const {countryCode, height, ...rest} = props; +const COMPONENT_NAME: string = 'CountryFlag'; - return {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: Ref): ReactElement => ( + {countryCode}} + {...rest} + /> + ), +) as ForwardRefExoticComponent & WithWrapperProps; CountryFlag.displayName = composeComponentDisplayName(COMPONENT_NAME); CountryFlag.muiName = COMPONENT_NAME; -CountryFlag.defaultProps = { - height: '16', -}; export default CountryFlag; 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 b4b59b1c..38f37391 100644 --- a/packages/react/src/components/DataGrid/DataGrid.tsx +++ b/packages/react/src/components/DataGrid/DataGrid.tsx @@ -16,27 +16,51 @@ * 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, Ref, 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 = (props: DataGridProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-data-grid', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; DataGrid.displayName = composeComponentDisplayName(COMPONENT_NAME); DataGrid.muiName = COMPONENT_NAME; -DataGrid.defaultProps = {}; export default DataGrid; 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 54019e4e..3f68f0fb 100644 --- a/packages/react/src/components/Divider/Divider.tsx +++ b/packages/react/src/components/Divider/Divider.tsx @@ -16,27 +16,65 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: DividerProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: DividerProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-divider', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Divider.displayName = composeComponentDisplayName(COMPONENT_NAME); Divider.muiName = COMPONENT_NAME; -Divider.defaultProps = {}; export default Divider; 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 d31c5c86..2b6e4987 100644 --- a/packages/react/src/components/Drawer/Drawer.tsx +++ b/packages/react/src/components/Drawer/Drawer.tsx @@ -16,27 +16,59 @@ * 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, Ref, ReactElement, ForwardRefExoticComponent} 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 = (props: DrawerProps): ReactElement => { - const {className, ...rest} = props; - - 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. + * - FIXME: ⚠️ `component` prop is temporarily not supported due to https://github.com/wso2/oxygen-ui/issues/283 + * - ✅ 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: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-drawer', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Drawer.displayName = composeComponentDisplayName(COMPONENT_NAME); Drawer.muiName = COMPONENT_NAME; -Drawer.defaultProps = {}; export default Drawer; 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 3c1d7780..10afc1a6 100644 --- a/packages/react/src/components/Fab/Fab.tsx +++ b/packages/react/src/components/Fab/Fab.tsx @@ -16,30 +16,63 @@ * under the License. */ -import MuiFab, {FabProps as MuiFabProps} from '@mui/material/Fab'; +import MuiFab from '@mui/material/Fab'; +import type {FabProps as MuiFabProps, FabTypeMap} from '@mui/material/Fab'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, Ref, 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 = FabTypeMap['defaultComponent'], + P = {}, +> = { + /** + * The component used for the root node. Either a string to use a HTML element or a component. + */ component?: C; -} & Omit, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Fab'; -const Fab: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: FabProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FabProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-fab', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Fab.displayName = composeComponentDisplayName(COMPONENT_NAME); Fab.muiName = COMPONENT_NAME; -Fab.defaultProps = {}; export default Fab; 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 a5b7f0cb..a61f8ee1 100644 --- a/packages/react/src/components/Footer/Footer.tsx +++ b/packages/react/src/components/Footer/Footer.tsx @@ -16,18 +16,23 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement, ReactNode} from 'react'; -import {useIsMobile} from '../../hooks'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, BoxTypeMap} 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,51 +45,71 @@ 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 = (props: FooterProps): ReactElement => { - const {className, copyright, links, maxWidth, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, copyright, component = 'footer' as C, links, maxWidth, ...rest}: FooterProps, + ref: Ref, + ): 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 OverridableComponent> & WithWrapperProps; Footer.displayName = composeComponentDisplayName(COMPONENT_NAME); Footer.muiName = COMPONENT_NAME; -Footer.defaultProps = {}; export default Footer; 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 9011cd17..62c96767 100644 --- a/packages/react/src/components/FormControl/FormControl.tsx +++ b/packages/react/src/components/FormControl/FormControl.tsx @@ -16,31 +16,69 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormControl'; -const FormControl: FC & WithWrapperProps = ( - props: FormControlProps, -): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FormControlProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-form-control', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; FormControl.displayName = composeComponentDisplayName(COMPONENT_NAME); FormControl.muiName = COMPONENT_NAME; -FormControl.defaultProps = {}; export default FormControl; 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 ce32930d..af2beb88 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, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,10 +28,33 @@ 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( - (props: FormControlLabelProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ({className, ...rest}: FormControlLabelProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-form-control-label', className); return ; @@ -38,6 +63,5 @@ const FormControlLabel: ForwardRefExoticComponent & WithW FormControlLabel.displayName = composeComponentDisplayName(COMPONENT_NAME); FormControlLabel.muiName = COMPONENT_NAME; -FormControlLabel.defaultProps = {}; export default FormControlLabel; 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 ce4c5550..09be13b1 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, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,18 +28,37 @@ 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( - (props: FormGroupProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ({className, ...rest}: FormGroupProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-form-group', className); - return ; + return ; }, ) as ForwardRefExoticComponent & WithWrapperProps; FormGroup.displayName = composeComponentDisplayName(COMPONENT_NAME); FormGroup.muiName = COMPONENT_NAME; -FormGroup.defaultProps = {}; export default FormGroup; 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 483a16da..3130bff4 100644 --- a/packages/react/src/components/FormHelperText/FormHelperText.tsx +++ b/packages/react/src/components/FormHelperText/FormHelperText.tsx @@ -16,31 +16,63 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormHelperText'; -const FormHelperText: FC & WithWrapperProps = ( - props: FormHelperTextProps, -): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FormHelperTextProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-form-helper-text', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; FormHelperText.displayName = composeComponentDisplayName(COMPONENT_NAME); FormHelperText.muiName = COMPONENT_NAME; -FormHelperText.defaultProps = {}; export default FormHelperText; 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 ba513fe7..41908ca6 100644 --- a/packages/react/src/components/FormLabel/FormLabel.tsx +++ b/packages/react/src/components/FormLabel/FormLabel.tsx @@ -16,30 +16,66 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {forwardRef, ForwardRefExoticComponent, ReactElement, MutableRefObject, ElementType} from 'react'; +import {forwardRef} from 'react'; +import type {ReactElement, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'FormLabel'; -const FormLabel: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: FormLabelProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: FormLabelProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-form-label', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; FormLabel.displayName = composeComponentDisplayName(COMPONENT_NAME); FormLabel.muiName = COMPONENT_NAME; -FormLabel.defaultProps = {}; export default FormLabel; 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 c81906cb..f61efd19 100644 --- a/packages/react/src/components/Grid/Grid.tsx +++ b/packages/react/src/components/Grid/Grid.tsx @@ -16,27 +16,62 @@ * under the License. */ -import MuiGrid, {Grid2Props as MuiGridProps} from '@mui/material/Unstable_Grid2'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; +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, Ref, 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 = (props: GridProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ({className, ...rest}: GridProps, ref: Ref): ReactElement => { + const classes: string = clsx('oxygen-grid', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Grid.displayName = composeComponentDisplayName(COMPONENT_NAME); Grid.muiName = COMPONENT_NAME; -Grid.defaultProps = {}; export default Grid; 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 da844e09..7e45b652 100644 --- a/packages/react/src/components/Header/Header.tsx +++ b/packages/react/src/components/Header/Header.tsx @@ -16,26 +16,30 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; 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, Ref, 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, AppBarTypeMap} 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 +78,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 +102,9 @@ export interface UserDropdownMenuHeaderProps { */ onActionClick?: () => void; triggerOptions?: Omit & Record; -} +}; -export interface BrandTemplate { +export type BrandTemplate = { /** * Logo for the brand template. */ @@ -122,7 +126,7 @@ export interface BrandTemplate { * Title of the brand, portal name or company. */ title?: ReactNode; -} +}; const userDropdownMenuDefaultProps: UserDropdownMenuHeaderProps = { actionIcon: , @@ -132,127 +136,149 @@ const userDropdownMenuDefaultProps: UserDropdownMenuHeaderProps = { const COMPONENT_NAME: string = 'Header'; -const Header: FC & WithWrapperProps = (props: HeaderProps): ReactElement => { - const { - brand, - className, - modes, - showCollapsibleHamburger, - leftAlignedElements, - navbarToggleIcon, - onCollapsibleHamburgerClick, - rightAlignedElements, - user, - userDropdownMenu, - ...rest - } = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + { + brand, + className, + modes, + showCollapsibleHamburger, + leftAlignedElements, + navbarToggleIcon = , + onCollapsibleHamburgerClick, + rightAlignedElements, + user, + userDropdownMenu = userDropdownMenuDefaultProps, + ...rest + }: HeaderProps, + ref: Ref, + ): 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 OverridableComponent> & WithWrapperProps; Header.displayName = composeComponentDisplayName(COMPONENT_NAME); Header.muiName = COMPONENT_NAME; -Header.defaultProps = { - navbarToggleIcon: , - userDropdownMenu: userDropdownMenuDefaultProps, -}; export default Header; 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 0cb1ce79..3dedb456 100644 --- a/packages/react/src/components/IconButton/IconButton.tsx +++ b/packages/react/src/components/IconButton/IconButton.tsx @@ -16,9 +16,12 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './icon-button.scss'; @@ -28,26 +31,60 @@ 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 = (props: IconButtonProps): ReactElement => { - const {className, variant, ...rest} = props; - - const classes: string = clsx('oxygen-icon-button', className, { - 'oxygen-icon-button-contained': variant === IconButtonVariants.CONTAINED, - }); +/** + * 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 IconButton component. + * @param ref - The ref to be forwarded to the MuiIconButton component. + * @returns The rendered IconButton component. + */ +const IconButton: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, variant = IconButtonVariants.TEXT, ...rest}: IconButtonProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-icon-button', className, { + 'oxygen-icon-button-contained': variant === IconButtonVariants.CONTAINED, + }); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; IconButton.displayName = composeComponentDisplayName(COMPONENT_NAME); IconButton.muiName = COMPONENT_NAME; -IconButton.defaultProps = { - variant: IconButtonVariants.TEXT, -}; export default IconButton; 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 b5d59f52..33851711 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,16 +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 not 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 = (props: ImageProps): ReactElement => { - const {className, alt, ...rest} = props; - - const classes: string = clsx('oxygen-image', className); +const Image: ForwardRefExoticComponent & WithWrapperProps = forwardRef( + ({className, alt, ...rest}: ImageProps, ref: Ref): 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 f56e359e..f5ab92bd 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './input.scss'; @@ -27,16 +29,37 @@ export type InputProps = MuiInputProps; const COMPONENT_NAME: string = 'Input'; -const Input: FC & WithWrapperProps = (props: InputProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-input', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; Input.displayName = composeComponentDisplayName(COMPONENT_NAME); Input.muiName = COMPONENT_NAME; -Input.defaultProps = {}; export default Input; 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 65850052..1d928d1c 100644 --- a/packages/react/src/components/InputAdornment/InputAdornment.tsx +++ b/packages/react/src/components/InputAdornment/InputAdornment.tsx @@ -16,30 +16,63 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'InputAdornment'; -const InputAdornment: FC & WithWrapperProps = ( - props: InputAdornmentProps, -): ReactElement => { - const {className, position, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, position, ...rest}: InputAdornmentProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-input-adornment', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; InputAdornment.displayName = composeComponentDisplayName(COMPONENT_NAME); InputAdornment.muiName = COMPONENT_NAME; -InputAdornment.defaultProps = {}; export default InputAdornment; 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 5ca0c4bd..a34e9df2 100644 --- a/packages/react/src/components/InputLabel/InputLabel.tsx +++ b/packages/react/src/components/InputLabel/InputLabel.tsx @@ -16,27 +16,64 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: InputLabelProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: InputLabelProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-input-label', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; InputLabel.displayName = composeComponentDisplayName(COMPONENT_NAME); InputLabel.muiName = COMPONENT_NAME; -InputLabel.defaultProps = {}; export default InputLabel; 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 ac90ab8d..8c088048 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,16 +28,37 @@ export type LinearProgressProps = MuiLinearProgressProps; const COMPONENT_NAME: string = 'LinearProgress'; -const LinearProgress: FC & WithWrapperProps = (props: LinearProgressProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-linear-progress', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; LinearProgress.displayName = composeComponentDisplayName(COMPONENT_NAME); LinearProgress.muiName = COMPONENT_NAME; -LinearProgress.defaultProps = {}; export default LinearProgress; 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 6b7e8a5b..a0192461 100644 --- a/packages/react/src/components/Link/Link.tsx +++ b/packages/react/src/components/Link/Link.tsx @@ -16,27 +16,66 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: LinkProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: LinkProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-link', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; Link.displayName = composeComponentDisplayName(COMPONENT_NAME); Link.muiName = COMPONENT_NAME; -Link.defaultProps = {}; export default Link; 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 fb7a57e7..dcc94fd6 100644 --- a/packages/react/src/components/List/List.tsx +++ b/packages/react/src/components/List/List.tsx @@ -16,27 +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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: ListProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ({className, ...rest}: ListProps, ref: Ref): ReactElement => { + const classes: string = clsx('oxygen-list', className); - return ; -}; + return ; + }, +) as OverridableComponent> & WithWrapperProps; List.displayName = composeComponentDisplayName(COMPONENT_NAME); List.muiName = COMPONENT_NAME; -List.defaultProps = {}; export default List; 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 05a6df70..9be4d2e5 100644 --- a/packages/react/src/components/ListItem/ListItem.tsx +++ b/packages/react/src/components/ListItem/ListItem.tsx @@ -16,31 +16,61 @@ * under the License. */ -import MuiListItem, {ListItemProps as MuiListItemProps} from '@mui/material/ListItem'; +import MuiListItem from '@mui/material/ListItem'; +import type {ListItemProps as MuiListItemProps, ListItemTypeMap} from '@mui/material/ListItem'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, forwardRef, ForwardRefExoticComponent, MutableRefObject, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ListItem'; -const ListItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: ListItemProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ListItemProps, + ref: MutableRefObject, + ): ReactElement => { const classes: string = clsx('oxygen-list-item', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; ListItem.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItem.muiName = COMPONENT_NAME; -ListItem.defaultProps = {}; export default ListItem; 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 0796d450..87f8be99 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-avatar.scss'; @@ -27,16 +29,36 @@ export type ListItemAvatarProps = MuiListItemAvatarProps; const COMPONENT_NAME: string = 'ListItemAvatar'; -const ListItemAvatar: FC & WithWrapperProps = (props: ListItemAvatarProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-list-item-avatar', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemAvatar.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemAvatar.muiName = COMPONENT_NAME; -ListItemAvatar.defaultProps = {}; export default ListItemAvatar; 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 b33f2dbc..18ccd998 100644 --- a/packages/react/src/components/ListItemButton/ListItemButton.tsx +++ b/packages/react/src/components/ListItemButton/ListItemButton.tsx @@ -16,31 +16,64 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ElementType, ForwardRefExoticComponent, MutableRefObject, ReactElement, forwardRef} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'ListItemButton'; -const ListItemButton: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: ListItemButtonProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: ListItemButtonProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-list-item-button', className); - return ; + return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; ListItemButton.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemButton.muiName = COMPONENT_NAME; -ListItemButton.defaultProps = {}; export default ListItemButton; diff --git a/packages/react/src/components/ListItemButton/index.ts b/packages/react/src/components/ListItemButton/index.ts index 8fdd8a3a..86b65c08 100644 --- a/packages/react/src/components/ListItemButton/index.ts +++ b/packages/react/src/components/ListItemButton/index.ts @@ -18,3 +18,5 @@ export {default} from './ListItemButton'; export type {ListItemButtonProps} from './ListItemButton'; + +export {ListItemButtonTypeMap, ListItemButtonBaseProps} from '@mui/material/ListItemButton'; diff --git a/packages/react/src/components/ListItemIcon/ListItemIcon.tsx b/packages/react/src/components/ListItemIcon/ListItemIcon.tsx index 3a95f9ee..94a931bd 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-icon.scss'; @@ -27,16 +29,36 @@ export type ListItemIconProps = MuiListItemIconProps; const COMPONENT_NAME: string = 'ListItemIcon'; -const ListItemIcon: FC & WithWrapperProps = (props: ListItemIconProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-list-item-icon', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemIcon.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemIcon.muiName = COMPONENT_NAME; -ListItemIcon.defaultProps = {}; export default ListItemIcon; 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 ffc88023..1ca95b76 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, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './list-item-text.scss'; @@ -27,16 +29,36 @@ export type ListItemTextProps = MuiListItemTextProps; const COMPONENT_NAME: string = 'ListItemText'; -const ListItemText: FC & WithWrapperProps = (props: ListItemTextProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-list-item-text', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; ListItemText.displayName = composeComponentDisplayName(COMPONENT_NAME); ListItemText.muiName = COMPONENT_NAME; -ListItemText.defaultProps = {}; export default ListItemText; 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 aea59089..57312173 100644 --- a/packages/react/src/components/Menu/Menu.tsx +++ b/packages/react/src/components/Menu/Menu.tsx @@ -16,24 +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, Ref, ReactElement, ForwardRefExoticComponent} 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 = (props: MenuProps): ReactElement => { - const {className, ...rest} = props; - - 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. + * - FIXME: ⚠️ `component` prop is temporarily not supported due to https://github.com/wso2/oxygen-ui/issues/283 + * - ✅ 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: Ref): 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 c3d0d7bd..4c7ed9ae 100644 --- a/packages/react/src/components/MenuItem/MenuItem.tsx +++ b/packages/react/src/components/MenuItem/MenuItem.tsx @@ -16,24 +16,62 @@ * 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 type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 = (props: MenuItemProps): ReactElement => { - const {className, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: MenuItemProps, + ref: Ref, + ): ReactElement => { + const classes: string = clsx('oxygen-menu-item', className); - return ; -}; + return ; + }, +) as OverridableComponent> & 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 62eddc22..8623c428 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,129 +82,159 @@ export type NavbarItems = { const COMPONENT_NAME: string = 'Navbar'; -const Navbar: FC & WithWrapperProps = (props: NavbarProps): ReactElement => { - const {className, fill, onClose, items, collapsible, open, onOpen, toggleIcon, ...rest} = props; - - 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; -Navbar.defaultProps = { - collapsible: true, - open: true, - toggleIcon: , -}; export default Navbar; 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 0a0ae311..ff1418e4 100644 --- a/packages/react/src/components/NavbarItem/NavbarItem.tsx +++ b/packages/react/src/components/NavbarItem/NavbarItem.tsx @@ -16,52 +16,78 @@ * under the License. */ +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {ForwardRefExoticComponent, MutableRefObject, ReactElement, ReactNode, forwardRef} from 'react'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, 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 ListItemButton from '../ListItemButton'; +import type {ListItemButtonProps, ListItemButtonTypeMap} 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'; -const NavbarItem: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: NavbarItemProps, ref: MutableRefObject): ReactElement => { - const {className, component, fill, icon, id, label, onClick, href, selected, tag, tagClassName, open, ...rest} = - props; +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, fill, icon, id, label, onClick, selected, tag, tagClassName, open = true, ...rest}: NavbarItemProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx( 'oxygen-navbar-item', { @@ -73,7 +99,7 @@ const NavbarItem: ForwardRefExoticComponent & WithWrapperProps ); return ( - + {icon} @@ -90,13 +116,9 @@ const NavbarItem: ForwardRefExoticComponent & WithWrapperProps ); }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; NavbarItem.displayName = composeComponentDisplayName(COMPONENT_NAME); NavbarItem.muiName = COMPONENT_NAME; -NavbarItem.defaultProps = { - collapsible: true, - open: true, -}; export default NavbarItem; diff --git a/packages/react/src/components/NavbarItem/index.tsx b/packages/react/src/components/NavbarItem/index.tsx index 84a89b72..6dad58a6 100644 --- a/packages/react/src/components/NavbarItem/index.tsx +++ b/packages/react/src/components/NavbarItem/index.tsx @@ -17,4 +17,4 @@ */ export {default} from './NavbarItem'; -export type {NavbarItemProps} from './NavbarItem'; +export * from './NavbarItem'; diff --git a/packages/react/src/components/OutlinedInput/OutlinedInput.tsx b/packages/react/src/components/OutlinedInput/OutlinedInput.tsx index 18d30705..49ebcfc8 100644 --- a/packages/react/src/components/OutlinedInput/OutlinedInput.tsx +++ b/packages/react/src/components/OutlinedInput/OutlinedInput.tsx @@ -16,9 +16,11 @@ * under the License. */ -import MuiOutlinedInput, {OutlinedInputProps as MuiOutlinedInputProps} from '@mui/material/OutlinedInput'; +import MuiOutlinedInput from '@mui/material/OutlinedInput'; +import type {OutlinedInputProps as MuiOutlinedInputProps} from '@mui/material/OutlinedInput'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; +import {forwardRef} from 'react'; +import type {ForwardRefExoticComponent, Ref, ReactElement} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; import './outlined-input.scss'; @@ -27,16 +29,37 @@ export type OutlinedInputProps = MuiOutlinedInputProps; const COMPONENT_NAME: string = 'OutlinedInput'; -const OutlinedInput: FC & WithWrapperProps = (props: OutlinedInputProps): ReactElement => { - const {className, ...rest} = props; - - 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: Ref): ReactElement => { + const classes: string = clsx('oxygen-outlined-input', className); - return ; -}; + return ; + }, +) as ForwardRefExoticComponent & WithWrapperProps; OutlinedInput.displayName = composeComponentDisplayName(COMPONENT_NAME); OutlinedInput.muiName = COMPONENT_NAME; -OutlinedInput.defaultProps = {}; export default OutlinedInput; 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 7bdc6d91..a2616101 100644 --- a/packages/react/src/components/Paper/Paper.tsx +++ b/packages/react/src/components/Paper/Paper.tsx @@ -16,30 +16,64 @@ * under the License. */ -import MuiPaper, {PaperProps as MuiPaperProps} from '@mui/material/Paper'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; +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 {ReactElement, Ref, 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, 'component'>; +} & Omit, 'component'>; const COMPONENT_NAME: string = 'Paper'; -const Paper: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: PaperProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: PaperProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-paper', className); return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Paper.displayName = composeComponentDisplayName(COMPONENT_NAME); Paper.muiName = COMPONENT_NAME; -Paper.defaultProps = {}; export default Paper; 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 54b7c8c9..88ffaf43 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'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; 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, Ref, 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, BoxTypeMap} 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,13 +80,35 @@ export interface PhoneNumberInputProps extends BoxProps { * Placeholder text for the phone number input. */ placeholder?: string; -} +}; const COMPONENT_NAME: string = 'PhoneNumberInput'; -const PhoneNumberInput: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: PhoneNumberInputProps, ref: MutableRefObject): ReactElement => { - const { +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + { className, dialCodeValue, label, @@ -82,8 +119,9 @@ const PhoneNumberInput: ForwardRefExoticComponent & WithW placeholder, SelectProps, ...rest - } = props; - + }: PhoneNumberInputProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-phone-number-input', className); const [dialCode, setDialCode] = useState(dialCodeValue ?? countries[0].dialCode); @@ -161,10 +199,9 @@ const PhoneNumberInput: ForwardRefExoticComponent & WithW ); }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; PhoneNumberInput.displayName = composeComponentDisplayName(COMPONENT_NAME); PhoneNumberInput.muiName = COMPONENT_NAME; -PhoneNumberInput.defaultProps = {}; export default PhoneNumberInput; 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 9331a27f..134f258a 100644 --- a/packages/react/src/components/Popover/Popover.tsx +++ b/packages/react/src/components/Popover/Popover.tsx @@ -16,28 +16,60 @@ * 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 {ReactElement, Ref, ElementType, ForwardRefExoticComponent} 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. + * - FIXME: ⚠️ `component` prop is temporarily not supported due to https://github.com/wso2/oxygen-ui/issues/283 + * - ✅ 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( - (props: PopoverProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ( + {className, ...rest}: PopoverProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-popover', className); return ; }, -) as unknown as ForwardRefExoticComponent & WithWrapperProps; +) as ForwardRefExoticComponent & WithWrapperProps; Popover.displayName = composeComponentDisplayName(COMPONENT_NAME); Popover.muiName = COMPONENT_NAME; -Popover.defaultProps = {}; export default Popover; 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 c2bba7e6..e2d85bc1 100644 --- a/packages/react/src/components/Radio/Radio.tsx +++ b/packages/react/src/components/Radio/Radio.tsx @@ -16,28 +16,60 @@ * under the License. */ -import MuiRadio, {RadioProps as MuiRadioProps} from '@mui/material/Radio'; +import {ButtonBaseTypeMap} from '@mui/material/ButtonBase'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; +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 {ReactElement, Ref, 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'; -const Radio: ForwardRefExoticComponent & WithWrapperProps = forwardRef( - (props: RadioProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - +/** + * 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, ...rest}: RadioProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-radio', className); return ; }, -) as ForwardRefExoticComponent & WithWrapperProps; +) as OverridableComponent> & WithWrapperProps; Radio.displayName = composeComponentDisplayName(COMPONENT_NAME); Radio.muiName = COMPONENT_NAME; -Radio.defaultProps = {}; export default Radio; 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 bb82ba6d..446e312a 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, Ref} from 'react'; import type {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; @@ -26,10 +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( - (props: RadioGroupProps, ref: MutableRefObject): ReactElement => { - const {className, ...rest} = props; - + ({className, ...rest}: RadioGroupProps, ref: Ref): ReactElement => { const classes: string = clsx('oxygen-radio-group', className); return ; @@ -38,6 +60,5 @@ const RadioGroup: ForwardRefExoticComponent & WithWrapperProps RadioGroup.displayName = composeComponentDisplayName(COMPONENT_NAME); RadioGroup.muiName = COMPONENT_NAME; -RadioGroup.defaultProps = {}; export default RadioGroup; 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 f43d47a0..3153b352 100644 --- a/packages/react/src/components/Select/Select.tsx +++ b/packages/react/src/components/Select/Select.tsx @@ -16,27 +16,64 @@ * 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, Ref, 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( - (props: SelectProps, ref: MutableRefObject): ReactElement => { - const {className, InputLabelProps, label, name, required, ...rest} = props; - + ( + { + className, + InputLabelProps = { + disableAnimation: true, + focused: false, + shrink: false, + }, + label, + name, + required, + ...rest + }: SelectProps, + ref: Ref, + ): ReactElement => { const classes: string = clsx('oxygen-select', className); const labelProps: MuiInputLabelProps = { @@ -69,12 +106,5 @@ const Select: ForwardRefExoticComponent & WithWrapperProps = forwar Select.displayName = composeComponentDisplayName(COMPONENT_NAME); Select.muiName = COMPONENT_NAME; -Select.defaultProps = { - InputLabelProps: { - disableAnimation: true, - focused: false, - shrink: false, - }, -}; export default Select; 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 7777cb98..cca1a846 100644 --- a/packages/react/src/components/SignIn/SignIn.tsx +++ b/packages/react/src/components/SignIn/SignIn.tsx @@ -16,18 +16,27 @@ * under the License. */ -import {Box, FormGroup, FormControlLabel, Typography, Grid, BoxProps, Paper, Checkbox} from '@mui/material'; +import type {OverridableComponent} from '@mui/material/OverridableComponent'; import clsx from 'clsx'; -import {FC, ReactElement} from 'react'; -import {MuiWrapperProps} from '../../models/component'; +import {forwardRef} from 'react'; +import type {ElementType, Ref, ReactElement} from 'react'; +import {WithWrapperProps} from '../../models/component'; import composeComponentDisplayName from '../../utils/compose-component-display-name'; +import type {BoxTypeMap, 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,72 +49,96 @@ export interface SignInProps extends BoxProps { * URL for the sign up. */ signUpUrl?: string; -} +}; const COMPONENT_NAME: string = 'SignIn'; -const SignIn: FC & MuiWrapperProps = (props: SignInProps): ReactElement => { - const {className, signUpUrl, logoUrl, signInOptions, ...rest} = props; - - 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: OverridableComponent> & WithWrapperProps = forwardRef( + ( + {className, signUpUrl, logoUrl, signInOptions, ...rest}: SignInProps, + ref: Ref, + ): 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 OverridableComponent> & WithWrapperProps; SignIn.displayName = composeComponentDisplayName(COMPONENT_NAME); SignIn.muiName = 'SignIn'; -SignIn.defaultProps = {}; export default SignIn; diff --git a/packages/react/src/components/SignIn/__tests__/__snapshots__/SignIn.test.tsx.snap b/packages/react/src/components/SignIn/__tests__/__snapshots__/SignIn.test.tsx.snap index 348b3272..9c3b4653 100644 --- a/packages/react/src/components/SignIn/__tests__/__snapshots__/SignIn.test.tsx.snap +++ b/packages/react/src/components/SignIn/__tests__/__snapshots__/SignIn.test.tsx.snap @@ -4,22 +4,22 @@ exports[`SignIn should match the snapshot 1`] = `