Browse Source
* feat : new components app * feat: update app * feat: update app * feat: update app * feat: update app * feat: update app * feat: update app * feat: update app * feat: update style * feat: update style * feat: update style * feat: add style * chore: code clean * feat: add prefixCls * chore: update snapshot * chore: update snapshot * chore: update snapshot * test: image test * Update components/app/index.zh-CN.md Co-authored-by: afc163 <afc163@gmail.com> * feat : update for reviewer * feat: update * feat: update * feat: update snap Co-authored-by: MadCcc <1075746765@qq.com> Co-authored-by: afc163 <afc163@gmail.com>pull/39356/head
黑雨
2 years ago
committed by
GitHub
25 changed files with 453 additions and 7 deletions
@ -0,0 +1,46 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`renders ./components/app/demo/message.tsx extend context correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open message |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/app/demo/modal.tsx extend context correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open modal |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/app/demo/notification.tsx extend context correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open notification |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
@ -0,0 +1,46 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`renders ./components/app/demo/message.tsx correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open message |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/app/demo/modal.tsx correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open modal |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
|||
|
|||
exports[`renders ./components/app/demo/notification.tsx correctly 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<button |
|||
class="ant-btn ant-btn-primary" |
|||
type="button" |
|||
> |
|||
<span> |
|||
Open notification |
|||
</span> |
|||
</button> |
|||
</div> |
|||
`; |
@ -0,0 +1,17 @@ |
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
|||
|
|||
exports[`App rtl render component should be rendered correctly in RTL direction 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
/> |
|||
`; |
|||
|
|||
exports[`App single 1`] = ` |
|||
<div |
|||
class="ant-app" |
|||
> |
|||
<div> |
|||
Hello World |
|||
</div> |
|||
</div> |
|||
`; |
@ -0,0 +1,3 @@ |
|||
import { extendTest } from '../../../tests/shared/demoTest'; |
|||
|
|||
extendTest('app'); |
@ -0,0 +1,3 @@ |
|||
import demoTest from '../../../tests/shared/demoTest'; |
|||
|
|||
demoTest('app'); |
@ -0,0 +1,5 @@ |
|||
import { imageDemoTest } from '../../../tests/shared/imageTest'; |
|||
|
|||
describe('app', () => { |
|||
imageDemoTest('app'); |
|||
}); |
@ -0,0 +1,33 @@ |
|||
import React from 'react'; |
|||
import App from '..'; |
|||
import mountTest from '../../../tests/shared/mountTest'; |
|||
import rtlTest from '../../../tests/shared/rtlTest'; |
|||
import { render } from '../../../tests/utils'; |
|||
|
|||
describe('App', () => { |
|||
mountTest(App); |
|||
rtlTest(App); |
|||
|
|||
it('single', () => { |
|||
// Sub page
|
|||
const MyPage = () => { |
|||
const { message } = App.useApp(); |
|||
React.useEffect(() => { |
|||
message.success('Good!'); |
|||
}, [message]); |
|||
|
|||
return <div>Hello World</div>; |
|||
}; |
|||
|
|||
// Entry component
|
|||
const MyApp = () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
|||
|
|||
const { getByText, container } = render(<MyApp />); |
|||
expect(getByText('Hello World')).toBeTruthy(); |
|||
expect(container.firstChild).toMatchSnapshot(); |
|||
}); |
|||
}); |
@ -0,0 +1,19 @@ |
|||
import React from 'react'; |
|||
import type { MessageInstance } from '../message/interface'; |
|||
import type { NotificationInstance } from '../notification/interface'; |
|||
import type { ModalStaticFunctions } from '../modal/confirm'; |
|||
|
|||
type ModalType = Omit<ModalStaticFunctions, 'warn'>; |
|||
export interface useAppProps { |
|||
message: MessageInstance; |
|||
notification: NotificationInstance; |
|||
modal: ModalType; |
|||
} |
|||
|
|||
const AppContext = React.createContext<useAppProps>({ |
|||
message: {} as MessageInstance, |
|||
notification: {} as NotificationInstance, |
|||
modal: {} as ModalType, |
|||
}); |
|||
|
|||
export default AppContext; |
@ -0,0 +1,7 @@ |
|||
## zh-CN |
|||
|
|||
获取 `message` 静态方法. |
|||
|
|||
## en-US |
|||
|
|||
Static method for `message`. |
@ -0,0 +1,24 @@ |
|||
import React from 'react'; |
|||
import { App, Button } from 'antd'; |
|||
|
|||
// Sub page
|
|||
const MyPage = () => { |
|||
const { message } = App.useApp(); |
|||
|
|||
const showMessage = () => { |
|||
message.success('Success!'); |
|||
}; |
|||
|
|||
return ( |
|||
<Button type="primary" onClick={showMessage}> |
|||
Open message |
|||
</Button> |
|||
); |
|||
}; |
|||
|
|||
// Entry component
|
|||
export default () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
@ -0,0 +1,7 @@ |
|||
## zh-CN |
|||
|
|||
获取 `modal` 静态方法. |
|||
|
|||
## en-US |
|||
|
|||
Static method for `modal`. |
@ -0,0 +1,27 @@ |
|||
import React from 'react'; |
|||
import { App, Button } from 'antd'; |
|||
|
|||
// Sub page
|
|||
const MyPage = () => { |
|||
const { modal } = App.useApp(); |
|||
|
|||
const showModal = () => { |
|||
modal.warning({ |
|||
title: 'This is a warning message', |
|||
content: 'some messages...some messages...', |
|||
}); |
|||
}; |
|||
|
|||
return ( |
|||
<Button type="primary" onClick={showModal}> |
|||
Open modal |
|||
</Button> |
|||
); |
|||
}; |
|||
|
|||
// Entry component
|
|||
export default () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
@ -0,0 +1,7 @@ |
|||
## zh-CN |
|||
|
|||
获取 `notification` 静态方法. |
|||
|
|||
## en-US |
|||
|
|||
Static method for `notification`. |
@ -0,0 +1,28 @@ |
|||
import React from 'react'; |
|||
import { App, Button } from 'antd'; |
|||
|
|||
// Sub page
|
|||
const MyPage = () => { |
|||
const { notification } = App.useApp(); |
|||
|
|||
const showNotification = () => { |
|||
notification.info({ |
|||
message: `Notification topLeft`, |
|||
description: 'Hello, Ant Design!!', |
|||
placement: 'topLeft', |
|||
}); |
|||
}; |
|||
|
|||
return ( |
|||
<Button type="primary" onClick={showNotification}> |
|||
Open notification |
|||
</Button> |
|||
); |
|||
}; |
|||
|
|||
// Entry component
|
|||
export default () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
@ -0,0 +1,43 @@ |
|||
--- |
|||
category: Components |
|||
group: Other |
|||
title: App |
|||
cover: https://gw.alipayobjects.com/zos/bmw-prod/cc3fcbfa-bf5b-4c8c-8a3d-c3f8388c75e8.svg |
|||
demo: |
|||
cols: 2 |
|||
--- |
|||
|
|||
New App Component which provide global style & static function replacement. |
|||
|
|||
## When To Use |
|||
|
|||
Static function in React 18 concurrent mode will not well support. In v5, we recommend to use hooks for the static replacement. But it will make user manual work on define this. |
|||
|
|||
## Examples |
|||
|
|||
<!-- prettier-ignore --> |
|||
<code src="./demo/message.tsx">message</code> |
|||
<code src="./demo/notification.tsx">notification</code> |
|||
<code src="./demo/modal.tsx">modal</code> |
|||
|
|||
## How to use |
|||
|
|||
```javascript |
|||
import React from 'react'; |
|||
import { App } from 'antd'; |
|||
const MyPage = () => { |
|||
const { message, notification, modal } = App.useApp(); |
|||
message.success('Good!'); |
|||
notification.info({ message: 'Good' }); |
|||
modal.warning({ title: 'Good' }); |
|||
// .... |
|||
// other message,notification,modal static function |
|||
return <div>Hello word</div>; |
|||
}; |
|||
|
|||
const MyApp = () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
|||
``` |
@ -0,0 +1,60 @@ |
|||
import React, { useContext } from 'react'; |
|||
import type { ReactNode } from 'react'; |
|||
import classNames from 'classnames'; |
|||
import type { ConfigConsumerProps } from '../config-provider'; |
|||
import { ConfigContext } from '../config-provider'; |
|||
import useStyle from './style'; |
|||
import useMessage from '../message/useMessage'; |
|||
import useNotification from '../notification/useNotification'; |
|||
import useModal from '../modal/useModal'; |
|||
import AppContext from './context'; |
|||
import type { useAppProps } from './context'; |
|||
|
|||
export type AppProps = { |
|||
className?: string; |
|||
prefixCls?: string; |
|||
children?: ReactNode; |
|||
}; |
|||
|
|||
const useApp: () => useAppProps = () => React.useContext(AppContext); |
|||
|
|||
const App: React.ForwardRefRenderFunction<HTMLDivElement, AppProps> & { |
|||
useApp: () => useAppProps; |
|||
} = (props) => { |
|||
const { prefixCls: customizePrefixCls, children, className } = props; |
|||
const { getPrefixCls } = useContext<ConfigConsumerProps>(ConfigContext); |
|||
const prefixCls = getPrefixCls('app', customizePrefixCls); |
|||
const [wrapSSR, hashId] = useStyle(prefixCls); |
|||
const customClassName = classNames(hashId, prefixCls, className); |
|||
|
|||
const [messageApi, messageContextHolder] = useMessage(); |
|||
const [notificationApi, notificationContextHolder] = useNotification(); |
|||
const [ModalApi, ModalContextHolder] = useModal(); |
|||
|
|||
const memoizedContextValue = React.useMemo( |
|||
() => ({ |
|||
message: messageApi, |
|||
notification: notificationApi, |
|||
modal: ModalApi, |
|||
}), |
|||
[messageApi, notificationApi, ModalApi], |
|||
); |
|||
|
|||
return wrapSSR( |
|||
<AppContext.Provider value={memoizedContextValue}> |
|||
<div className={customClassName}> |
|||
{ModalContextHolder} |
|||
{messageContextHolder} |
|||
{notificationContextHolder} |
|||
{children} |
|||
</div> |
|||
</AppContext.Provider>, |
|||
); |
|||
}; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
App.displayName = 'App'; |
|||
} |
|||
|
|||
App.useApp = useApp; |
|||
export default App; |
@ -0,0 +1,45 @@ |
|||
--- |
|||
category: Components |
|||
subtitle: 包裹组件 |
|||
group: 其他 |
|||
title: App |
|||
cover: https://gw.alipayobjects.com/zos/bmw-prod/cc3fcbfa-bf5b-4c8c-8a3d-c3f8388c75e8.svg |
|||
demo: |
|||
cols: 2 |
|||
--- |
|||
|
|||
新的包裹组件,提供重置样式和提供消费上下文的默认环境。 |
|||
|
|||
## 何时使用 |
|||
|
|||
- 提供可消费 React context 的 `message.xxx`、`Modal.xxx`、`notification.xxx` 的静态方法,可以简化 useMessage 等方法需要手动植入 `contextHolder` 的问题。 |
|||
- 提供基于 `.ant-app` 的默认重置样式,解决原生元素没有 antd 规范样式的问题。 |
|||
|
|||
## 代码演示 |
|||
|
|||
<!-- prettier-ignore --> |
|||
<code src="./demo/message.tsx">message</code> |
|||
<code src="./demo/notification.tsx">notification</code> |
|||
<code src="./demo/modal.tsx">modal</code> |
|||
|
|||
## How to use |
|||
|
|||
```javascript |
|||
import React from 'react'; |
|||
import { App } from 'antd'; |
|||
const MyPage = () => { |
|||
const { message, notification, modal } = App.useApp(); |
|||
message.success('Good!'); |
|||
notification.info({ message: 'Good' }); |
|||
modal.warning({ title: 'Good' }); |
|||
// .... |
|||
// other message,notification,modal static function |
|||
return <div>Hello word</div>; |
|||
}; |
|||
|
|||
const MyApp = () => ( |
|||
<App> |
|||
<MyPage /> |
|||
</App> |
|||
); |
|||
``` |
@ -0,0 +1,22 @@ |
|||
import type { FullToken, GenerateStyle } from '../../theme/internal'; |
|||
import { genComponentStyleHook } from '../../theme/internal'; |
|||
|
|||
export type ComponentToken = {}; |
|||
|
|||
interface AppToken extends FullToken<'App'> {} |
|||
|
|||
// =============================== Base ===============================
|
|||
const genBaseStyle: GenerateStyle<AppToken> = (token) => { |
|||
const { componentCls, colorText, fontSize, lineHeight, fontFamily } = token; |
|||
return { |
|||
[componentCls]: { |
|||
color: colorText, |
|||
fontSize, |
|||
lineHeight, |
|||
fontFamily, |
|||
}, |
|||
}; |
|||
}; |
|||
|
|||
// ============================== Export ==============================
|
|||
export default genComponentStyleHook('App', (token) => [genBaseStyle(token)]); |
Loading…
Reference in new issue