Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import { defaultPopupBaseProps } from '../popup/popup-base-props'
import { IconContext } from './context'
import Item, { ItemChildrenWrap } from './item'

const classPrefix = `adm-dropdown`

export type DropdownProps = {
activeKey?: string | null
defaultActiveKey?: string | null
Expand All @@ -38,6 +36,7 @@ export type DropdownProps = {
*/
arrow?: ReactNode
getContainer?: PopupProps['getContainer']
prefixCls?: string
} & NativeProps

const defaultProps = {
Expand All @@ -53,7 +52,7 @@ export type DropdownRef = {

const Dropdown = forwardRef<DropdownRef, PropsWithChildren<DropdownProps>>(
(props, ref) => {
const { dropdown: componentConfig = {} } = useConfig()
const { dropdown: componentConfig = {}, getPrefixCls } = useConfig()
const mergedProps = mergeProps(defaultProps, componentConfig, props)
const arrowIcon = mergeProp(
componentConfig.arrowIcon,
Expand All @@ -65,7 +64,7 @@ const Dropdown = forwardRef<DropdownRef, PropsWithChildren<DropdownProps>>(
defaultValue: mergedProps.defaultActiveKey,
onChange: mergedProps.onChange,
})

const prefixCls = getPrefixCls('dropdown', mergedProps.prefixCls)
const navRef = useRef<HTMLDivElement>(null)
const contentRef = useRef<HTMLDivElement>(null)

Expand Down Expand Up @@ -128,23 +127,23 @@ const Dropdown = forwardRef<DropdownRef, PropsWithChildren<DropdownProps>>(
return withNativeProps(
mergedProps,
<div
className={classNames(classPrefix, {
[`${classPrefix}-open`]: !!value,
className={classNames(prefixCls, {
[`${prefixCls}-open`]: !!value,
})}
ref={containerRef}
>
<IconContext.Provider value={arrowIcon}>
<div className={`${classPrefix}-nav`} ref={navRef}>
<div className={`${prefixCls}-nav`} ref={navRef}>
{navs}
</div>
</IconContext.Provider>
<Popup
visible={!!value}
position='top'
getContainer={mergedProps.getContainer}
className={`${classPrefix}-popup`}
maskClassName={`${classPrefix}-popup-mask`}
bodyClassName={`${classPrefix}-popup-body`}
className={`${prefixCls}-popup`}
maskClassName={`${prefixCls}-popup-mask`}
bodyClassName={`${prefixCls}-popup-body`}
style={{ top }}
forceRender={popupForceRender}
onMaskClick={
Expand All @@ -164,6 +163,7 @@ const Dropdown = forwardRef<DropdownRef, PropsWithChildren<DropdownProps>>(
active={isActive}
forceRender={item.props.forceRender}
destroyOnClose={item.props.destroyOnClose}
prefixCls={prefixCls}
>
{item.props.children}
</ItemChildrenWrap>
Expand Down
27 changes: 14 additions & 13 deletions src/components/dropdown/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { mergeProp, mergeProps } from '../../utils/with-default-props'
import { useConfig } from '../config-provider'
import { IconContext } from './context'

const classPrefix = `adm-dropdown-item`

export type DropdownItemProps = {
key: string
title: ReactNode
Expand All @@ -24,15 +22,17 @@ export type DropdownItemProps = {
*/
arrow?: ReactNode
children?: ReactNode
prefixCls?: string
} & NativeProps

const Item: FC<DropdownItemProps> = props => {
const { dropdown: componentConfig = {} } = useConfig()
const { dropdown: componentConfig = {}, getPrefixCls } = useConfig()
const mergedProps = mergeProps(componentConfig, props)
const prefixCls = getPrefixCls('dropdown-item', mergedProps.prefixCls)
const { active, highlight, onClick, title } = mergedProps
const cls = classNames(classPrefix, {
[`${classPrefix}-active`]: active,
[`${classPrefix}-highlight`]: highlight ?? active,
const cls = classNames(prefixCls, {
[`${prefixCls}-active`]: active,
[`${prefixCls}-highlight`]: highlight ?? active,
})

const contextArrowIcon = React.useContext(IconContext)
Expand All @@ -46,11 +46,11 @@ const Item: FC<DropdownItemProps> = props => {
return withNativeProps(
props,
<div className={cls} onClick={onClick}>
<div className={`${classPrefix}-title`}>
<span className={`${classPrefix}-title-text`}>{title}</span>
<div className={`${prefixCls}-title`}>
<span className={`${prefixCls}-title-text`}>{title}</span>
<span
className={classNames(`${classPrefix}-title-arrow`, {
[`${classPrefix}-title-arrow-active`]: active,
className={classNames(`${prefixCls}-title-arrow`, {
[`${prefixCls}-title-arrow-active`]: active,
})}
>
{mergedArrowIcon}
Expand All @@ -64,19 +64,20 @@ export default Item

type DropdownItemChildrenWrapProps = {
onClick?: () => void
prefixCls: string
} & Pick<
DropdownItemProps,
'active' | 'forceRender' | 'destroyOnClose' | 'children'
>
export const ItemChildrenWrap: FC<DropdownItemChildrenWrapProps> = props => {
const { active = false } = props
const { active = false, prefixCls } = props
const shouldRender = useShouldRender(
active,
props.forceRender,
props.destroyOnClose
)
const cls = classNames(`${classPrefix}-content`, {
[`${classPrefix}-content-hidden`]: !active,
const cls = classNames(`${prefixCls}-content`, {
[`${prefixCls}-content-hidden`]: !active,
})

return shouldRender ? (
Expand Down
31 changes: 31 additions & 0 deletions src/components/dropdown/tests/dropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { fireEvent, render, screen, waitFor } from 'testing'
import Dropdown from '..'
import ConfigProvider from '../../config-provider'

const classPrefix = `adm-dropdown`

Expand Down Expand Up @@ -150,4 +151,34 @@ describe('Dropdown', () => {
expect(screen.getByText('bamboo')).toBeVisible()
})
})

test('should apply custom prefixCls(ConfigProvider)', () => {
render(
<ConfigProvider prefixCls='config-prefix'>
<Dropdown arrowIcon='ignore' arrow='ignore'>
<Dropdown.Item title='sorter' key='sorter' />
</Dropdown>
</ConfigProvider>
)
fireEvent.click(screen.getByText('sorter'))
expect(document.querySelector('.config-prefix-dropdown')).toBeTruthy()
expect(
document.querySelector('.config-prefix-dropdown-content')
).toBeTruthy()
expect(document.querySelector('.config-prefix-dropdown-item')).toBeTruthy()
})

test('should apply custom prefixCls(component)', () => {
render(
<ConfigProvider prefixCls='config-prefix'>
<Dropdown arrowIcon='ignore' prefixCls='component-prefix'>
<Dropdown.Item title='sorter' key='sorter' />
</Dropdown>
</ConfigProvider>
)
fireEvent.click(screen.getByText('sorter'))
expect(document.querySelector('.component-prefix')).toBeTruthy()
expect(document.querySelector('.component-prefix-content')).toBeTruthy()
expect(document.querySelector('.config-prefix-dropdown-item')).toBeTruthy()
})
})
Loading