feat: App support style props (#40708)

* feat: App support style props and export props type

* test: add test case

* Conflicting
This commit is contained in:
lijianan 2023-02-15 18:32:40 +08:00 committed by GitHub
parent 9f98fc243e
commit c53330d90e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 16 deletions

View File

@ -21,7 +21,7 @@ describe('App', () => {
it('single', () => {
// Sub page
const MyPage = () => {
const MyPage: React.FC = () => {
const { message } = App.useApp();
React.useEffect(() => {
message.success('Good!');
@ -31,7 +31,7 @@ describe('App', () => {
};
// Entry component
const MyApp = () => (
const MyApp: React.FC = () => (
<App>
<MyPage />
</App>
@ -122,4 +122,22 @@ describe('App', () => {
expect(config?.message).toStrictEqual({ maxCount: 11, top: 20 });
expect(config?.notification).toStrictEqual({ maxCount: 30, bottom: 41 });
});
it('support className', () => {
const { container } = render(
<App className="test-class">
<div>test</div>
</App>,
);
expect(container.querySelector<HTMLDivElement>('.ant-app')).toHaveClass('test-class');
});
it('support style', () => {
const { container } = render(
<App style={{ color: 'blue' }}>
<div>test</div>
</App>,
);
expect(container.querySelector<HTMLDivElement>('.ant-app')).toHaveStyle('color: blue;');
});
});

View File

@ -6,18 +6,19 @@ import { ConfigContext } from '../config-provider';
import useMessage from '../message/useMessage';
import useModal from '../modal/useModal';
import useNotification from '../notification/useNotification';
import AppContext, { AppConfigContext } from './context';
import type { AppConfig, useAppProps } from './context';
import AppContext, { AppConfigContext } from './context';
import useStyle from './style';
export type AppProps = {
export interface AppProps extends AppConfig {
style?: React.CSSProperties;
className?: string;
rootClassName?: string;
prefixCls?: string;
children?: ReactNode;
} & AppConfig;
}
const useApp = () => React.useContext(AppContext);
const useApp = () => React.useContext<useAppProps>(AppContext);
const App: React.FC<AppProps> & { useApp: typeof useApp } = (props) => {
const {
@ -27,13 +28,15 @@ const App: React.FC<AppProps> & { useApp: typeof useApp } = (props) => {
rootClassName,
message,
notification,
style,
} = props;
const { getPrefixCls } = useContext<ConfigConsumerProps>(ConfigContext);
const prefixCls = getPrefixCls('app', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const customClassName = classNames(hashId, prefixCls, className, rootClassName);
const appConfig = useContext(AppConfigContext);
const appConfig = useContext<AppConfig>(AppConfigContext);
const mergedAppConfig = React.useMemo<AppConfig>(
() => ({
message: { ...appConfig.message, ...message },
@ -60,7 +63,7 @@ const App: React.FC<AppProps> & { useApp: typeof useApp } = (props) => {
return wrapSSR(
<AppContext.Provider value={memoizedContextValue}>
<AppConfigContext.Provider value={mergedAppConfig}>
<div className={customClassName}>
<div className={customClassName} style={style}>
{ModalContextHolder}
{messageContextHolder}
{notificationContextHolder}

View File

@ -1,16 +1,15 @@
export type { Breakpoint } from './_util/responsiveObserver';
export { default as Affix } from './affix';
export type { AffixProps } from './affix';
export { default as Alert } from './alert';
export type { AlertProps } from './alert';
export { default as Anchor } from './anchor';
export type { AnchorLinkProps, AnchorProps } from './anchor';
export { default as App } from './app';
export type { AppProps } from './app';
export { default as AutoComplete } from './auto-complete';
export type { AutoCompleteProps } from './auto-complete';
export { default as Avatar } from './avatar';
export type { AvatarProps } from './avatar';
export { default as FloatButton } from './float-button';
export type { FloatButtonProps, FloatButtonGroupProps } from './float-button/interface';
export { default as BackTop } from './back-top';
export type { BackTopProps } from './back-top';
export { default as Badge } from './badge';
@ -52,6 +51,8 @@ export type {
} from './dropdown';
export { default as Empty } from './empty';
export type { EmptyProps } from './empty';
export { default as FloatButton } from './float-button';
export type { FloatButtonGroupProps, FloatButtonProps } from './float-button/interface';
export { default as Form } from './form';
export type {
FormInstance,
@ -75,7 +76,7 @@ export type { ListProps } from './list';
export { default as Mentions } from './mentions';
export type { MentionProps } from './mentions';
export { default as Menu } from './menu';
export type { MenuItemProps, MenuProps, MenuTheme, SubMenuProps, MenuRef } from './menu';
export type { MenuItemProps, MenuProps, MenuRef, MenuTheme, SubMenuProps } from './menu';
export { default as message } from './message';
export type { ArgsProps as MessageArgsProps } from './message';
export { default as Modal } from './modal';
@ -89,6 +90,8 @@ export { default as Popover } from './popover';
export type { PopoverProps } from './popover';
export { default as Progress } from './progress';
export type { ProgressProps } from './progress';
export { default as QRCode } from './qrcode';
export type { QRCodeProps, QRPropsCanvas } from './qrcode/interface';
export { default as Radio } from './radio';
export type { RadioChangeEvent, RadioGroupProps, RadioProps } from './radio';
export { default as Rate } from './rate';
@ -138,7 +141,6 @@ export { default as Tooltip } from './tooltip';
export type { TooltipProps } from './tooltip';
export { default as Tour } from './tour';
export type { TourProps, TourStepProps } from './tour/interface';
export { default as App } from './app';
export { default as Transfer } from './transfer';
export type { TransferProps } from './transfer';
export { default as Tree } from './tree';
@ -153,8 +155,7 @@ export { default as Typography } from './typography';
export type { TypographyProps } from './typography';
export { default as Upload } from './upload';
export type { UploadFile, UploadProps } from './upload';
export { default as version } from './version';
export { default as Watermark } from './watermark';
export type { WatermarkProps } from './watermark';
export { default as QRCode } from './qrcode';
export type { QRCodeProps, QRPropsCanvas } from './qrcode/interface';
export { default as version } from './version';
export type { Breakpoint } from './_util/responsiveObserver';