Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ConfigProvider): add icons config #6587

Merged
merged 42 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bb9b8c4
feat(ConfigProvider): add icons config
guoyunhe Apr 12, 2024
884deac
refactor: use util
zombieJ Apr 16, 2024
bb866f1
test: update testcase
zombieJ Apr 16, 2024
ac64c95
test: update testcase
zombieJ Apr 16, 2024
46acb8a
refactor: use util
zombieJ Apr 17, 2024
06075cd
chore: merge master
zombieJ Apr 17, 2024
48aa12b
test: add test case
zombieJ Apr 17, 2024
40f7a3f
chore: rename
zombieJ Apr 17, 2024
b327bfd
refactor: props -> mergedProps, p -> props
guoyunhe Apr 17, 2024
5bd18db
test(CenterPopup): closeIcon
guoyunhe Apr 17, 2024
9361e9b
test(Popup): closeIcon
guoyunhe Apr 17, 2024
049cb73
test(CheckList): activeIcon
guoyunhe Apr 17, 2024
8286555
test(Form): helpIcon and arrowIcon
guoyunhe Apr 17, 2024
0c1fd22
test(Input): clearIcon
guoyunhe Apr 17, 2024
684d910
test(NavBar): backIcon
guoyunhe Apr 17, 2024
cea8c00
test(NoticeBar): closeIcon
guoyunhe Apr 17, 2024
c2a2388
test(useResultIcon): icon
guoyunhe Apr 17, 2024
250e591
test(useResultIcon): icon
guoyunhe Apr 17, 2024
ece574b
test(CenterPopup): props override context
guoyunhe Apr 18, 2024
970fd7e
test(CheckList): props override context
guoyunhe Apr 18, 2024
bee6535
test(Form): props override context
guoyunhe Apr 18, 2024
2b898bc
test(Input): props override context
guoyunhe Apr 18, 2024
2da0a95
test(List): props override context
guoyunhe Apr 18, 2024
de85019
test(NavBar): props override context
guoyunhe Apr 18, 2024
56d3474
test(NoticeBar): props override context
guoyunhe Apr 18, 2024
48dd7a5
test(Popup): props override context
guoyunhe Apr 18, 2024
b8940b0
chore: re-order
zombieJ Apr 18, 2024
b9d28f6
feat(Toast): revert context
guoyunhe Apr 18, 2024
dc7fbbc
Merge branch 'config-provider-icons' of github.com:ant-design/ant-des…
guoyunhe Apr 18, 2024
e392f44
chore: fix ts
zombieJ Apr 18, 2024
8b624b7
Merge branch 'config-provider-icons' of https://github.com/ant-design…
zombieJ Apr 23, 2024
48fdd9f
refactor: decoupling
zombieJ Apr 23, 2024
beded34
refactor: decoupling
zombieJ Apr 23, 2024
5694d42
fix(notice-bar): icon class
guoyunhe Apr 25, 2024
963fcb7
fix(dropdown): mergeProp
guoyunhe Apr 25, 2024
e1419f7
fix(notice-bar): icon class
guoyunhe Apr 25, 2024
d33fb4b
test(nav-bar): override
guoyunhe Apr 25, 2024
13a899d
test(search-bar): override
guoyunhe Apr 25, 2024
ca23bad
chore: fix default
zombieJ Jun 12, 2024
18ddc6c
chore: merge master
zombieJ Jun 12, 2024
92cb960
chore: rollback
zombieJ Jun 12, 2024
cefc14a
fix: virtualInput icon
zombieJ Jun 12, 2024
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
94 changes: 49 additions & 45 deletions src/components/center-popup/center-popup.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import React, { useRef, useState } from 'react'
import type { FC, PropsWithChildren } from 'react'
import { renderToContainer } from '../../utils/render-to-container'
import Mask from '../mask'
import { withStopPropagation } from '../../utils/with-stop-propagation'
import { mergeProps } from '../../utils/with-default-props'
import { useIsomorphicLayoutEffect, useUnmountedRef } from 'ahooks'
import { animated, useSpring } from '@react-spring/web'
import { useInnerVisible } from '../../utils/use-inner-visible'
import { useIsomorphicLayoutEffect, useUnmountedRef } from 'ahooks'
import classNames from 'classnames'
import type { FC, PropsWithChildren } from 'react'
import React, { useRef, useState } from 'react'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import { renderToContainer } from '../../utils/render-to-container'
import { ShouldRender } from '../../utils/should-render'
import { useInnerVisible } from '../../utils/use-inner-visible'
import { useLockScroll } from '../../utils/use-lock-scroll'
import { CloseOutline } from 'antd-mobile-icons'
import { mergeProps } from '../../utils/with-default-props'
import { withStopPropagation } from '../../utils/with-stop-propagation'
import { useConfig } from '../config-provider'
import Mask from '../mask'
import {
defaultPopupBaseProps,
PopupBaseProps,
defaultPopupBaseProps,
} from '../popup/popup-base-props'

const classPrefix = 'adm-center-popup'
Expand All @@ -37,13 +37,14 @@ const defaultProps = {
getContainer: null,
}

export const CenterPopup: FC<CenterPopupProps> = p => {
const props = mergeProps(defaultProps, p)
export const CenterPopup: FC<CenterPopupProps> = props => {
const { popup: componentConfig = {} } = useConfig()
const mergedProps = mergeProps(defaultProps, componentConfig, props)

guoyunhe marked this conversation as resolved.
Show resolved Hide resolved
const unmountedRef = useUnmountedRef()
const style = useSpring({
scale: props.visible ? 1 : 0.8,
opacity: props.visible ? 1 : 0,
scale: mergedProps.visible ? 1 : 0.8,
opacity: mergedProps.visible ? 1 : 0,
config: {
mass: 1.2,
tension: 200,
Expand All @@ -52,68 +53,71 @@ export const CenterPopup: FC<CenterPopupProps> = p => {
},
onRest: () => {
if (unmountedRef.current) return
setActive(props.visible)
if (props.visible) {
props.afterShow?.()
setActive(mergedProps.visible)
if (mergedProps.visible) {
mergedProps.afterShow?.()
} else {
props.afterClose?.()
mergedProps.afterClose?.()
}
},
})

const [active, setActive] = useState(props.visible)
const [active, setActive] = useState(mergedProps.visible)
useIsomorphicLayoutEffect(() => {
if (props.visible) {
if (mergedProps.visible) {
setActive(true)
}
}, [props.visible])
}, [mergedProps.visible])

const ref = useRef<HTMLDivElement>(null)
useLockScroll(ref, props.disableBodyScroll && active)
useLockScroll(ref, mergedProps.disableBodyScroll && active)

const maskVisible = useInnerVisible(active && props.visible)
const maskVisible = useInnerVisible(active && mergedProps.visible)

const body = (
<div
className={classNames(`${classPrefix}-body`, props.bodyClassName)}
style={props.bodyStyle}
className={classNames(`${classPrefix}-body`, mergedProps.bodyClassName)}
style={mergedProps.bodyStyle}
>
{props.children}
{mergedProps.children}
</div>
)

const node = withStopPropagation(
props.stopPropagation,
mergedProps.stopPropagation,
withNativeProps(
props,
mergedProps,
<div
className={classPrefix}
style={{
display: active ? undefined : 'none',
pointerEvents: active ? undefined : 'none',
}}
>
{props.mask && (
{mergedProps.mask && (
<Mask
visible={maskVisible}
forceRender={props.forceRender}
destroyOnClose={props.destroyOnClose}
forceRender={mergedProps.forceRender}
destroyOnClose={mergedProps.destroyOnClose}
onMaskClick={e => {
props.onMaskClick?.(e)
if (props.closeOnMaskClick) {
props.onClose?.()
mergedProps.onMaskClick?.(e)
if (mergedProps.closeOnMaskClick) {
mergedProps.onClose?.()
}
}}
style={props.maskStyle}
className={classNames(`${classPrefix}-mask`, props.maskClassName)}
style={mergedProps.maskStyle}
className={classNames(
`${classPrefix}-mask`,
mergedProps.maskClassName
)}
disableBodyScroll={false}
stopPropagation={props.stopPropagation}
stopPropagation={mergedProps.stopPropagation}
/>
)}
<div
className={`${classPrefix}-wrap`}
role={props.role}
aria-label={props['aria-label']}
role={mergedProps.role}
aria-label={mergedProps['aria-label']}
>
<animated.div
style={{
Expand All @@ -124,17 +128,17 @@ export const CenterPopup: FC<CenterPopupProps> = p => {
}}
ref={ref}
>
{props.showCloseButton && (
{mergedProps.showCloseButton && (
<a
className={classNames(
`${classPrefix}-close`,
'adm-plain-anchor'
)}
onClick={() => {
props.onClose?.()
mergedProps.onClose?.()
}}
>
<CloseOutline />
{mergedProps.closeIcon}
</a>
)}
{body}
Expand All @@ -147,10 +151,10 @@ export const CenterPopup: FC<CenterPopupProps> = p => {
return (
<ShouldRender
active={active}
forceRender={props.forceRender}
destroyOnClose={props.destroyOnClose}
forceRender={mergedProps.forceRender}
destroyOnClose={mergedProps.destroyOnClose}
>
{renderToContainer(props.getContainer, node)}
{renderToContainer(mergedProps.getContainer, node)}
</ShouldRender>
)
}
54 changes: 54 additions & 0 deletions src/components/center-popup/tests/center-popup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
import { render, screen, testA11y } from 'testing'
import ConfigProvider from '../../config-provider'
import { CenterPopup } from '../center-popup'

describe('center-popup', () => {
test('a11y', async () => {
await testA11y(<CenterPopup visible>foobar</CenterPopup>)
})

describe('closeIcon', () => {
it('default', () => {
const { baseElement } = render(
<CenterPopup visible showCloseButton>
foobar
</CenterPopup>
)
expect(baseElement.querySelector('.antd-mobile-icon')).toBeTruthy()
})

it('props', () => {
render(
<CenterPopup visible showCloseButton closeIcon='bamboo'>
foobar
</CenterPopup>
)
expect(screen.getByText('bamboo')).toBeVisible()
})

it('context', () => {
render(
<ConfigProvider popup={{ closeIcon: 'little' }}>
<CenterPopup visible showCloseButton>
foobar
</CenterPopup>
</ConfigProvider>
)

expect(screen.getByText('little')).toBeVisible()
})

it('props override context', () => {
render(
<ConfigProvider popup={{ closeIcon: 'little' }}>
<CenterPopup visible showCloseButton closeIcon='bamboo'>
foobar
</CenterPopup>
</ConfigProvider>
)

expect(screen.getByText('bamboo')).toBeVisible()
})
})
})
26 changes: 14 additions & 12 deletions src/components/check-list/check-list.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react'
import { CheckOutline } from 'antd-mobile-icons'
import type { FC, ReactNode } from 'react'
import React from 'react'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import List, { ListProps } from '../list'
import { usePropsValue } from '../../utils/use-props-value'
import { mergeProps } from '../../utils/with-default-props'
import { useConfig } from '../config-provider'
import List, { ListProps } from '../list'
import { CheckListContext } from './context'
import { usePropsValue } from '../../utils/use-props-value'
import { CheckOutline } from 'antd-mobile-icons'

const classPrefix = 'adm-check-list'

Expand All @@ -29,13 +30,14 @@ const defaultProps = {
activeIcon: <CheckOutline />,
}

export const CheckList: FC<CheckListProps> = p => {
const props = mergeProps(defaultProps, p)
export const CheckList: FC<CheckListProps> = props => {
const { checkList: componentConfig = {} } = useConfig()
const mergedProps = mergeProps(defaultProps, componentConfig, props)
guoyunhe marked this conversation as resolved.
Show resolved Hide resolved

const [value, setValue] = usePropsValue(props)
const [value, setValue] = usePropsValue(mergedProps)

function check(val: CheckListValue) {
if (props.multiple) {
if (mergedProps.multiple) {
setValue([...value, val])
} else {
setValue([val])
Expand All @@ -46,7 +48,7 @@ export const CheckList: FC<CheckListProps> = p => {
setValue(value.filter(item => item !== val))
}

const { activeIcon, extra, disabled, readOnly } = props
const { activeIcon, extra, disabled, readOnly } = mergedProps

return (
<CheckListContext.Provider
Expand All @@ -61,9 +63,9 @@ export const CheckList: FC<CheckListProps> = p => {
}}
>
{withNativeProps(
props,
<List mode={props.mode} className={classPrefix}>
{props.children}
mergedProps,
<List mode={mergedProps.mode} className={classPrefix}>
{mergedProps.children}
</List>
)}
</CheckListContext.Provider>
Expand Down
51 changes: 50 additions & 1 deletion src/components/check-list/tests/check-list.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { fireEvent, render, testA11y } from 'testing'
import { fireEvent, render, screen, testA11y } from 'testing'
import CheckList from '../'
import ConfigProvider from '../../config-provider'

const classPrefix = `adm-check-list`

Expand Down Expand Up @@ -74,4 +75,52 @@ describe('CheckList', () => {
expect(getByText('YES')).toBeVisible()
expect(getByText('NO')).toBeVisible()
})

describe('closeIcon', () => {
it('default', () => {
const { baseElement } = render(
<CheckList defaultValue={['B']}>
<CheckList.Item value='A'>A</CheckList.Item>
<CheckList.Item value='B'>B</CheckList.Item>
</CheckList>
)
expect(baseElement.querySelector('.antd-mobile-icon')).toBeTruthy()
})

it('props', () => {
render(
<CheckList defaultValue={['B']} activeIcon='bamboo'>
<CheckList.Item value='A'>A</CheckList.Item>
<CheckList.Item value='B'>B</CheckList.Item>
</CheckList>
)
expect(screen.getByText('bamboo')).toBeVisible()
})

it('context', () => {
render(
<ConfigProvider checkList={{ activeIcon: 'little' }}>
<CheckList defaultValue={['B']}>
<CheckList.Item value='A'>A</CheckList.Item>
<CheckList.Item value='B'>B</CheckList.Item>
</CheckList>
</ConfigProvider>
)

expect(screen.getByText('little')).toBeVisible()
})

it('props override context', () => {
render(
<ConfigProvider checkList={{ activeIcon: 'little' }}>
<CheckList defaultValue={['B']} activeIcon='bamboo'>
<CheckList.Item value='A'>A</CheckList.Item>
<CheckList.Item value='B'>B</CheckList.Item>
</CheckList>
</ConfigProvider>
)

expect(screen.getByText('bamboo')).toBeVisible()
})
})
})
Loading
Loading