diff --git a/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.spec.tsx b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.spec.tsx new file mode 100644 index 00000000000000..3c4203efa90693 --- /dev/null +++ b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.spec.tsx @@ -0,0 +1,9 @@ +import * as React from 'react'; +import TabsListUnstyled, { TabsListUnstyledRootSlotProps } from '@mui/base/TabsListUnstyled'; + +function Root(props: TabsListUnstyledRootSlotProps) { + const { ownerState, ...other } = props; + return
; +} + +const styledTabsList = ; diff --git a/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.tsx b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.tsx index 258af707e03e9e..348ca8bd6a78a1 100644 --- a/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.tsx +++ b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.tsx @@ -3,9 +3,13 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import { OverridableComponent } from '@mui/types'; import composeClasses from '../composeClasses'; -import { appendOwnerState } from '../utils'; +import { appendOwnerState, WithOptionalOwnerState } from '../utils'; import { getTabsListUnstyledUtilityClass } from './tabsListUnstyledClasses'; -import TabsListUnstyledProps, { TabsListUnstyledTypeMap } from './TabsListUnstyledProps'; +import { + TabsListUnstyledProps, + TabsListUnstyledRootSlotProps, + TabsListUnstyledTypeMap, +} from './TabsListUnstyled.types'; import useTabsList from './useTabsList'; const useUtilityClasses = (ownerState: { orientation: 'horizontal' | 'vertical' }) => { @@ -42,23 +46,20 @@ const TabsListUnstyled = React.forwardRef((props const classes = useUtilityClasses(ownerState); const TabsListRoot: React.ElementType = component ?? components.Root ?? 'div'; - const tabsListRootProps = appendOwnerState( + const tabsListRootProps: WithOptionalOwnerState = appendOwnerState( TabsListRoot, - { ...other, ...componentsProps.root }, + { + ...getRootProps(), + ...other, + ...componentsProps.root, + className: clsx(className, componentsProps.root?.className, classes.root), + }, ownerState, ); const processedChildren = processChildren(); - return ( - - {processedChildren} - - ); + return {processedChildren}; }) as OverridableComponent; TabsListUnstyled.propTypes /* remove-proptypes */ = { diff --git a/packages/mui-base/src/TabsListUnstyled/TabsListUnstyledProps.ts b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.types.ts similarity index 76% rename from packages/mui-base/src/TabsListUnstyled/TabsListUnstyledProps.ts rename to packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.types.ts index ff3d9b3593ef49..5297240debc2a1 100644 --- a/packages/mui-base/src/TabsListUnstyled/TabsListUnstyledProps.ts +++ b/packages/mui-base/src/TabsListUnstyled/TabsListUnstyled.types.ts @@ -1,5 +1,6 @@ import React from 'react'; import { OverrideProps } from '@mui/types'; +import { UseTabsListRootSlotProps } from './useTabsList.types'; interface TabsListUnstyledComponentsPropsOverrides {} @@ -31,7 +32,7 @@ export interface TabsListUnstyledTypeMap

= OverrideProps, D> & { @@ -43,4 +44,12 @@ type TabsListUnstyledProps< component?: D; }; -export default TabsListUnstyledProps; +export type TabsListUnstyledOwnerState = TabsListUnstyledProps & { + isRtl: boolean; + orientation: 'horizontal' | 'vertical'; +}; + +export type TabsListUnstyledRootSlotProps = UseTabsListRootSlotProps & { + className?: string; + ownerState: TabsListUnstyledOwnerState; +}; diff --git a/packages/mui-base/src/TabsListUnstyled/index.ts b/packages/mui-base/src/TabsListUnstyled/index.ts index 79c81b11865d85..9f71aea7ef255d 100644 --- a/packages/mui-base/src/TabsListUnstyled/index.ts +++ b/packages/mui-base/src/TabsListUnstyled/index.ts @@ -1,6 +1,8 @@ export { default } from './TabsListUnstyled'; +export * from './TabsListUnstyled.types'; + export { default as tabsListUnstyledClasses } from './tabsListUnstyledClasses'; export * from './tabsListUnstyledClasses'; -export type { default as TabsListUnstyledProps } from './TabsListUnstyledProps'; + export { default as useTabsList } from './useTabsList'; -export * from './useTabsList'; +export * from './useTabsList.types'; diff --git a/packages/mui-base/src/TabsListUnstyled/useTabsList.ts b/packages/mui-base/src/TabsListUnstyled/useTabsList.ts index 9792aaf51390cc..49895c6a5a3965 100644 --- a/packages/mui-base/src/TabsListUnstyled/useTabsList.ts +++ b/packages/mui-base/src/TabsListUnstyled/useTabsList.ts @@ -6,6 +6,8 @@ import { import { isFragment } from 'react-is'; import { useTabContext } from '../TabsUnstyled'; import extractEventHandlers from '../utils/extractEventHandlers'; +import { UseTabsListParameters, UseTabsListRootSlotProps } from './useTabsList.types'; +import { EventHandlers } from '../utils'; const nextItem = (list: Element | null, item: Element | null): Element | null => { if (!list) { @@ -66,18 +68,8 @@ const moveFocus = ( } }; -export interface UseTabsListProps { - 'aria-label'?: string; - 'aria-labelledby'?: string; - /** - * The content of the component. - */ - children?: React.ReactNode; - ref: React.Ref; -} - -const useTabsList = (props: UseTabsListProps) => { - const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, children, ref } = props; +const useTabsList = (parameters: UseTabsListParameters) => { + const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, children, ref } = parameters; const tabsListRef = React.createRef(); const handleRef = useForkRef(tabsListRef, ref); @@ -138,22 +130,24 @@ const useTabsList = (props: UseTabsListProps) => { otherHandlers.onKeyDown?.(event); }; - const getRootProps = (otherHandlers?: Record>) => { - const propsEventHandlers = extractEventHandlers(props); + const getRootProps = ( + otherHandlers: TOther = {} as TOther, + ): UseTabsListRootSlotProps => { + const propsEventHandlers = extractEventHandlers(parameters); const externalEventHandlers = { ...propsEventHandlers, ...otherHandlers }; const ownEventHandlers = { onKeyDown: createHandleKeyDown(externalEventHandlers), }; - const mergedEventHandlers: Record> = { + const mergedEventHandlers = { ...externalEventHandlers, ...ownEventHandlers, }; return { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, - 'aria-orientation': orientation === 'vertical' ? 'vertical' : null, + 'aria-orientation': orientation === 'vertical' ? 'vertical' : undefined, role: 'tablist', ref: handleRef, ...mergedEventHandlers, diff --git a/packages/mui-base/src/TabsListUnstyled/useTabsList.types.ts b/packages/mui-base/src/TabsListUnstyled/useTabsList.types.ts new file mode 100644 index 00000000000000..b4baa870e17b1c --- /dev/null +++ b/packages/mui-base/src/TabsListUnstyled/useTabsList.types.ts @@ -0,0 +1,20 @@ +import * as React from 'react'; + +export interface UseTabsListParameters { + 'aria-label'?: string; + 'aria-labelledby'?: string; + /** + * The content of the component. + */ + children?: React.ReactNode; + ref: React.Ref; +} + +export type UseTabsListRootSlotProps = TOther & { + 'aria-label'?: React.AriaAttributes['aria-label']; + 'aria-labelledby'?: React.AriaAttributes['aria-labelledby']; + 'aria-orientation'?: React.AriaAttributes['aria-orientation']; + role: React.AriaRole; + ref: React.Ref; + onKeyDown?: React.KeyboardEventHandler; +};