Skip to content

Commit

Permalink
feat(ConfigProvider): add icons config
Browse files Browse the repository at this point in the history
  • Loading branch information
guoyunhe committed Apr 4, 2024
1 parent cf550e4 commit a10882d
Show file tree
Hide file tree
Showing 25 changed files with 353 additions and 81 deletions.
6 changes: 5 additions & 1 deletion src/components/center-popup/center-popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
defaultPopupBaseProps,
PopupBaseProps,
} from '../popup/popup-base-props'
import { useConfig } from '../config-provider'

const classPrefix = 'adm-center-popup'

Expand All @@ -39,6 +40,9 @@ const defaultProps = {

export const CenterPopup: FC<CenterPopupProps> = p => {
const props = mergeProps(defaultProps, p)
const {
icons: { PopupClose = CloseOutline },
} = useConfig()

const unmountedRef = useUnmountedRef()
const style = useSpring({
Expand Down Expand Up @@ -134,7 +138,7 @@ export const CenterPopup: FC<CenterPopupProps> = p => {
props.onClose?.()
}}
>
<CloseOutline />
<PopupClose />
</a>
)}
{body}
Expand Down
9 changes: 6 additions & 3 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 type { FC, ReactNode } from 'react'
import { CheckOutline } from 'antd-mobile-icons'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import List, { ListProps } from '../list'
import { mergeProps } from '../../utils/with-default-props'
import { CheckListContext } from './context'
import { usePropsValue } from '../../utils/use-props-value'
import { CheckOutline } from 'antd-mobile-icons'
import { useConfig } from '../config-provider'

const classPrefix = 'adm-check-list'

Expand All @@ -26,11 +27,13 @@ export type CheckListProps = Pick<ListProps, 'mode' | 'style'> & {
const defaultProps = {
multiple: false,
defaultValue: [],
activeIcon: <CheckOutline />,
}

export const CheckList: FC<CheckListProps> = p => {
const props = mergeProps(defaultProps, p)
const {
icons: { CheckListActive = CheckOutline },
} = useConfig()
const props = mergeProps({ activeIcon: <CheckListActive /> }, defaultProps, p)

const [value, setValue] = usePropsValue(props)

Expand Down
6 changes: 5 additions & 1 deletion src/components/collapse/collapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useMount } from 'ahooks'
import { useShouldRender } from '../../utils/should-render'
import { useIsomorphicUpdateLayoutEffect } from '../../utils/use-isomorphic-update-layout-effect'
import { traverseReactNode } from '../../utils/traverse-react-node'
import { useConfig } from '../config-provider'

const classPrefix = `adm-collapse`

Expand Down Expand Up @@ -121,6 +122,9 @@ export type CollapseProps = (
} & NativeProps

export const Collapse: FC<CollapseProps> = props => {
const {
icons: { CollapseArrow = DownOutline },
} = useConfig()
const panels: ReactElement<CollapsePanelProps>[] = []
traverseReactNode(props.children, child => {
if (!isValidElement<CollapsePanelProps>(child)) return
Expand Down Expand Up @@ -197,7 +201,7 @@ export const Collapse: FC<CollapseProps> = props => {
}

const renderArrow = () => {
let arrow: CollapseProps['arrow'] = <DownOutline />
let arrow: CollapseProps['arrow'] = <CollapseArrow />
if (props.arrow !== undefined) {
arrow = props.arrow
}
Expand Down
49 changes: 41 additions & 8 deletions src/components/config-provider/config-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,53 @@
import React, { useContext } from 'react'
import type { FC, ReactNode } from 'react'
import type { ComponentType, FC, ReactNode } from 'react'
import { Locale } from '../../locales/base'
import zhCN from '../../locales/zh-CN'
import { mergeProps } from '../../utils/with-default-props'

export type IconConfig = Partial<
Record<
| 'CheckListActive'
| 'CollapseArrow'
| 'DropdownItemArrow'
| 'FormItemHelp'
| 'ImageUploaderUpload'
| 'ImageUploaderDelete'
| 'InputClear'
| 'ListItemArrow'
| 'NavBarBackArrow'
| 'NoticeBarClose'
| 'NoticeBarNotice'
| 'NumberKeyboardClose'
| 'NumberKeyboardDelete'
| 'PopupClose'
| 'ResultSuccess'
| 'ResultError'
| 'ResultInfo'
| 'ResultWaiting'
| 'ResultWarning'
| 'SearchBarSearch'
| 'StepperPlus'
| 'StepperMinus'
| 'ToastSuccess'
| 'ToastFail'
| 'ToastLoading',
ComponentType<{ className?: string }>
>
>

const defaultIcons: IconConfig = {}

type Config = {
locale: Locale
icons: IconConfig
}

export const defaultConfigRef: {
current: Config
} = {
current: {
locale: zhCN,
icons: defaultIcons,
},
}

Expand All @@ -23,9 +59,9 @@ export function getDefaultConfig() {
return defaultConfigRef.current
}

const ConfigContext = React.createContext<Config | null>(null)
const ConfigContext = React.createContext<Config>(defaultConfigRef.current)

export type ConfigProviderProps = Config & {
export type ConfigProviderProps = Partial<Config> & {
children?: ReactNode
}

Expand All @@ -35,16 +71,13 @@ export const ConfigProvider: FC<ConfigProviderProps> = props => {

return (
<ConfigContext.Provider
value={{
...parentConfig,
...config,
}}
value={mergeProps(defaultConfigRef.current, parentConfig, config)}
>
{children}
</ConfigContext.Provider>
)
}

export function useConfig() {
return useContext(ConfigContext) ?? getDefaultConfig()
return useContext(ConfigContext)
}
51 changes: 51 additions & 0 deletions src/components/config-provider/index.en.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,58 @@
# ConfigProvider

Configure locale messages and custom icons globally.

## When to use

- You want to use other languages than English
- You want to use your own icon set instead of `antd-mobile-icons`

## Demos

<code src="./demos/demo1.tsx" ></code>

<code src="./demos/demo2.tsx" ></code>

## ConfigProvider

### Props

| Name | Description | Type | Default |
| ------ | --------------- | ------------ | ------- |
| locale | Locale messages | `Locale` | [base] |
| icons | Custom icon set | `IconConfig` | `{}` |

## IconConfig

Default icons are all from `antd-mobile-icons` package, except for SpinLoading which is a `antd-mobile` component.

### Props

| Name | Related components | Description | Default |
| -------------------- | ------------------------------ | ------------------ | --------------------- |
| CheckListActive | CheckList | Check mark | CheckOutline |
| CollapseArrow | Collapse | Expand/collapse | DownOutline |
| DropdownItemArrow | DropdownItem | Down arrow | DownFill |
| FormItemHelp | FormItem | Help indicator | QuestionCircleOutline |
| ImageUploaderUpload | ImageUploader | Upload button | AddOutline |
| ImageUploaderDelete | ImageUploader | Delete button | CloseOutline |
| InputClear | Input, SearchBar, VirtualInput | Clear button | CloseCircleFill |
| NavBarBackArrow | NavBar | Back button | LeftOutline |
| NoticeBarClose | NoticeBar | Close button | CloseOutline |
| NoticeBarNotice | NoticeBar | Notice | SoundOutline |
| NumberKeyboardClose | NumberKeyboard | Close/hide button | DownOutline |
| NumberKeyboardDelete | NumberKeyboard | Delete button | TextDeletionOutline |
| PopupClose | Popup, CenterPopup | Close button | CloseOutline |
| ResultSuccess | Result, ResultPage | Success status | CheckCircleFill |
| ResultError | Result, ResultPage | Error status | CloseCircleFill |
| ResultInfo | Result, ResultPage | Information status | InformationCircleFill |
| ResultWaiting | Result, ResultPage | Waiting status | ClockCircleFill |
| ResultWarning | Result, ResultPage | Warning status | ExclamationCircleFill |
| SearchBarSearch | SearchBar | Search | SearchOutline |
| StepperPlus | Stepper | Plus button | AddOutline |
| StepperMinus | Stepper | Minus button | MinusOutline |
| ToastSuccess | Toast | Success status | CheckOutline |
| ToastFail | Toast | Fail status | CloseOutline |
| ToastLoading | Toast | Loading status | SpinLoading |

[base]: https://github.com/ant-design/ant-design-mobile/blob/master/src/locales/base.ts
51 changes: 51 additions & 0 deletions src/components/config-provider/index.zh.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,58 @@
# ConfigProvider 配置

用于全局配置本地化文案和个性化图标。

## 何时使用

- 您想使用除英文之外的语言。
- 您想使用自己的图标集,而不是内置的 `antd-mobile-icons`

## 示例

<code src="./demos/demo1.tsx" ></code>

<code src="./demos/demo2.tsx" ></code>

## ConfigProvider

### 属性

| 属性 | 说明 | 类型 | 默认值 |
| ------ | ---------- | ------------ | ------ |
| locale | 本地化文案 | `Locale` | [base] |
| icons | 自定义图标 | `IconConfig` | `{}` |

## IconConfig

除了 SpinLoading 是一个 `antd-mobile` 组件外,其余默认图标都取自 `antd-mobile-icons` 包。

### 属性

| 属性 | 相关组件 | 说明 | 默认值 |
| -------------------- | ------------------------------ | --------------- | --------------------- |
| CheckListActive | CheckList | 选中标记 | CheckOutline |
| CollapseArrow | Collapse | 展开收起箭头 | DownOutline |
| DropdownItemArrow | DropdownItem | 下拉箭头 | DownFill |
| FormItemHelp | FormItem | 帮助提示 | QuestionCircleOutline |
| ImageUploaderUpload | ImageUploader | 上传按钮 | AddOutline |
| ImageUploaderDelete | ImageUploader | 删除按钮 | CloseOutline |
| InputClear | Input, SearchBar, VirtualInput | 清除按钮 | CloseCircleFill |
| NavBarBackArrow | NavBar | 返回按钮 | LeftOutline |
| NoticeBarClose | NoticeBar | 关闭按钮 | CloseOutline |
| NoticeBarNotice | NoticeBar | 左侧图标 | SoundOutline |
| NumberKeyboardClose | NumberKeyboard | 收起按钮 | DownOutline |
| NumberKeyboardDelete | NumberKeyboard | 删除按钮 | TextDeletionOutline |
| PopupClose | Popup, CenterPopup | 关闭按钮 | CloseOutline |
| ResultSuccess | Result, ResultPage | 成功状态 | CheckCircleFill |
| ResultError | Result, ResultPage | 错误状态 | CloseCircleFill |
| ResultInfo | Result, ResultPage | 信息状态 | InformationCircleFill |
| ResultWaiting | Result, ResultPage | 等待状态 | ClockCircleFill |
| ResultWarning | Result, ResultPage | 警告状态 | ExclamationCircleFill |
| SearchBarSearch | SearchBar | 搜索图标 | SearchOutline |
| StepperPlus | Stepper | 增加按钮 | AddOutline |
| StepperMinus | Stepper | 减少按钮 | MinusOutline |
| ToastSuccess | Toast | 成功状态 | CheckOutline |
| ToastFail | Toast | 失败状态 | CloseOutline |
| ToastLoading | Toast | 加载状态 | SpinLoading |

[base]: https://github.com/ant-design/ant-design-mobile/blob/master/src/locales/base.ts
4 changes: 2 additions & 2 deletions src/components/config-provider/tests/config-provider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe('ConfigProvider', () => {
})
})

test('useConfig should only has `locale`', () => {
test('useConfig should only has `locale` and `icons`', () => {
let config: ReturnType<typeof useConfig>

const Demo = () => {
Expand All @@ -109,6 +109,6 @@ describe('ConfigProvider', () => {
}
render(<Demo />)

expect(Object.keys(config!)).toEqual(['locale'])
expect(Object.keys(config!)).toEqual(['locale', 'icons'])

Check warning on line 112 in src/components/config-provider/tests/config-provider.test.tsx

View workflow job for this annotation

GitHub Actions / check

Forbidden non-null assertion

Check warning on line 112 in src/components/config-provider/tests/config-provider.test.tsx

View workflow job for this annotation

GitHub Actions / check

Forbidden non-null assertion
})
})
8 changes: 6 additions & 2 deletions src/components/dropdown/item.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import classNames from 'classnames'
import React from 'react'
import type { FC, ReactNode } from 'react'
import { DownFill } from 'antd-mobile-icons'
import { NativeProps, withNativeProps } from '../../utils/native-props'
import { useShouldRender } from '../../utils/should-render'
import { DownFill } from 'antd-mobile-icons'
import { useConfig } from '../config-provider'

const classPrefix = `adm-dropdown-item`

Expand All @@ -20,6 +21,9 @@ export type DropdownItemProps = {
} & NativeProps

const Item: FC<DropdownItemProps> = props => {
const {
icons: { DropdownItemArrow = DownFill },
} = useConfig()
const cls = classNames(classPrefix, {
[`${classPrefix}-active`]: props.active,
[`${classPrefix}-highlight`]: props.highlight ?? props.active,
Expand All @@ -35,7 +39,7 @@ const Item: FC<DropdownItemProps> = props => {
[`${classPrefix}-title-arrow-active`]: props.active,
})}
>
{props.arrow === undefined ? <DownFill /> : props.arrow}
{props.arrow === undefined ? <DropdownItemArrow /> : props.arrow}
</span>
</div>
</div>
Expand Down
7 changes: 5 additions & 2 deletions src/components/form/form-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ const FormItemLayout: FC<FormItemLayoutProps> = props => {

const context = useContext(FormContext)

const { locale } = useConfig()
const {
locale,
icons: { FormItemHelp = QuestionCircleOutline },
} = useConfig()

const hasFeedback =
props.hasFeedback !== undefined ? props.hasFeedback : context.hasFeedback
Expand Down Expand Up @@ -162,7 +165,7 @@ const FormItemLayout: FC<FormItemLayoutProps> = props => {
e.preventDefault()
}}
>
<QuestionCircleOutline />
<FormItemHelp />
</span>
</Popover>
)}
Expand Down
22 changes: 18 additions & 4 deletions src/components/image-uploader/image-uploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ const classPrefix = `adm-image-uploader`
const defaultProps = {
disableUpload: false,
deletable: true,
deleteIcon: <CloseOutline className={`${classPrefix}-cell-delete-icon`} />,
showUpload: true,
multiple: false,
maxCount: 0,
Expand All @@ -91,8 +90,23 @@ const defaultProps = {

export const ImageUploader = forwardRef<ImageUploaderRef, ImageUploaderProps>(
(p, ref) => {
const { locale } = useConfig()
const props = mergeProps(defaultProps, p)
const {
locale,
icons: {
ImageUploaderDelete = CloseOutline,
ImageUploaderUpload = AddOutline,
},
} = useConfig()

const props = mergeProps(
{
deleteIcon: (
<ImageUploaderDelete className={`${classPrefix}-cell-delete-icon`} />
),
},
defaultProps,
p
)
const { columns } = props
const [value, setValue] = usePropsValue(props)

Expand Down Expand Up @@ -312,7 +326,7 @@ export const ImageUploader = forwardRef<ImageUploaderRef, ImageUploaderProps>(
aria-label={locale.ImageUploader.upload}
>
<span className={`${classPrefix}-upload-button-icon`}>
<AddOutline />
<ImageUploaderUpload />
</span>
</span>
)}
Expand Down
Loading

0 comments on commit a10882d

Please sign in to comment.