diff --git a/src/PickerInput/RangePicker.tsx b/src/PickerInput/RangePicker.tsx index ab48627d2..db6d66fbe 100644 --- a/src/PickerInput/RangePicker.tsx +++ b/src/PickerInput/RangePicker.tsx @@ -693,8 +693,10 @@ function RangePicker( generateConfig, button: components.button, input: components.input, + styles, + classNames, }), - [prefixCls, locale, generateConfig, components.button, components.input], + [prefixCls, locale, generateConfig, components.button, components.input, classNames, styles], ); // ======================== Effect ======================== diff --git a/src/PickerInput/SinglePicker.tsx b/src/PickerInput/SinglePicker.tsx index c4568b864..652fbb1b7 100644 --- a/src/PickerInput/SinglePicker.tsx +++ b/src/PickerInput/SinglePicker.tsx @@ -577,8 +577,10 @@ function Picker( generateConfig, button: components.button, input: components.input, + styles, + classNames, }), - [prefixCls, locale, generateConfig, components.button, components.input], + [prefixCls, locale, generateConfig, components.button, components.input, styles, classNames], ); // ======================== Effect ======================== diff --git a/src/PickerInput/context.tsx b/src/PickerInput/context.tsx index fcbc581b5..97cf09f51 100644 --- a/src/PickerInput/context.tsx +++ b/src/PickerInput/context.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import type { GenerateConfig } from '../generate'; -import type { Components, Locale } from '../interface'; +import type { Components, Locale, SemanticStructure } from '../interface'; export interface PickerContextProps { prefixCls: string; @@ -9,7 +9,8 @@ export interface PickerContextProps { /** Customize button component */ button?: Components['button']; input?: Components['input']; - + styles?: Partial>; + classNames?: Partial>; } const PickerContext = React.createContext(null!); diff --git a/src/PickerPanel/PanelBody.tsx b/src/PickerPanel/PanelBody.tsx index 9eb4fb253..f8969aebb 100644 --- a/src/PickerPanel/PanelBody.tsx +++ b/src/PickerPanel/PanelBody.tsx @@ -63,7 +63,11 @@ export default function PanelBody(props: PanelBod const cellPrefixCls = `${prefixCls}-cell`; // ============================= Context ============================== - const { onCellDblClick } = React.useContext(PickerHackContext); + const { + onCellDblClick, + classNames: pickerClassNames, + styles, + } = React.useContext(PickerHackContext); // ============================== Value =============================== const matchValues = (date: DateType) => @@ -181,8 +185,14 @@ export default function PanelBody(props: PanelBod // ============================== Render ============================== return ( -
- +
+
{headerCells && ( {headerCells} diff --git a/src/PickerPanel/context.ts b/src/PickerPanel/context.ts index 28f3713fe..ff61e444c 100644 --- a/src/PickerPanel/context.ts +++ b/src/PickerPanel/context.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { PanelMode, SharedPanelProps } from '../interface'; +import type { PanelMode, SemanticStructure, SharedPanelProps } from '../interface'; export interface PanelContextProps extends Pick< @@ -106,6 +106,8 @@ export interface PickerHackContextProps { hideNext?: boolean; hideHeader?: boolean; onCellDblClick?: () => void; + styles?: Partial>; + classNames?: Partial>; } /** diff --git a/src/PickerPanel/index.tsx b/src/PickerPanel/index.tsx index ed141ebf1..7cfb3ce2a 100644 --- a/src/PickerPanel/index.tsx +++ b/src/PickerPanel/index.tsx @@ -183,7 +183,15 @@ function PickerPanel( hideHeader, } = props; - const mergedPrefixCls = React.useContext(PickerContext)?.prefixCls || prefixCls || 'rc-picker'; + // ======================== Context ======================== + const { + prefixCls: contextPrefixCls, + classNames: pickerClassNames, + styles, + } = React.useContext(PickerContext) || {}; + + // ======================== prefixCls ======================== + const mergedPrefixCls = contextPrefixCls || prefixCls || 'rc-picker'; // ========================== Refs ========================== const rootRef = React.useRef(); @@ -366,8 +374,8 @@ function PickerPanel( // ======================== Context ========================= const parentHackContext = React.useContext(PickerHackContext); const pickerPanelContext = React.useMemo( - () => ({ ...parentHackContext, hideHeader }), - [parentHackContext, hideHeader], + () => ({ ...parentHackContext, hideHeader, classNames: pickerClassNames, styles }), + [parentHackContext, hideHeader, pickerClassNames, styles], ); // ======================== Warnings ======================== diff --git a/src/interface.tsx b/src/interface.tsx index 8938da9bd..570698114 100644 --- a/src/interface.tsx +++ b/src/interface.tsx @@ -281,7 +281,7 @@ export type Components = Partial< >; // ========================= Picker ========================= -export type SemanticStructure = 'popup'; +export type SemanticStructure = 'popup' | 'popupBody' | 'popupContent'; export type CustomFormat = (value: DateType) => string; diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index 5cd6f54af..e5044fd95 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -1349,17 +1349,27 @@ describe('Picker.Basic', () => { ); }); - it('classNames.popup', () => { - render( - , - ); - - expect(document.querySelector('.rc-picker-dropdown')).toHaveClass('bamboo'); + it('support classNames and styles', () => { + const customClassNames = { + popup: 'custom-popup', + popupBody: 'custom-body', + popupContent: 'custom-content', + }; + const customStyles = { + popup: { color: 'red' }, + popupBody: { color: 'green' }, + popupContent: { color: 'blue' }, + }; + render(); + + expect(document.querySelector('.rc-picker-dropdown')).toHaveClass(customClassNames.popup); + expect(document.querySelector('.rc-picker-dropdown')).toHaveStyle(customStyles.popup); + const content = document.querySelector('.rc-picker-content'); + const body = document.querySelector('.rc-picker-body'); + expect(content).toHaveClass(customClassNames.popupContent); + expect(content).toHaveStyle(customStyles.popupContent); + expect(body).toHaveClass(customClassNames.popupBody); + expect(body).toHaveStyle(customStyles.popupBody); }); it('showTime config should have format', () => {