mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-01 06:49:32 +08:00
commit
78705e34f0
@ -15,13 +15,45 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 4.19.2
|
||||
|
||||
`2022-03-13`
|
||||
|
||||
- 🐞 Fix Dropdown not auto adjust placement when position on the edge of window. [#34390](https://github.com/ant-design/ant-design/pull/34390)
|
||||
- 💄 Change PageHeader elements margin from `12px` to `8px` inside `extra`. [#34428](https://github.com/ant-design/ant-design/pull/34428)
|
||||
- 🛠 Export css variable function in `antd/es/config-provider` folder to enable ssr requirement. [#34436](https://github.com/ant-design/ant-design/pull/34436)
|
||||
- 🛠 Refactor Menu with React hooks. [#34433](https://github.com/ant-design/ant-design/pull/34433)
|
||||
- Input
|
||||
- 💄 Fix Input font-size when `size` is large. [#34381](https://github.com/ant-design/ant-design/pull/34381)
|
||||
- 💄 Fix Input.Group wrong border when status is error. [#34412](https://github.com/ant-design/ant-design/pull/34412)
|
||||
- Form
|
||||
- 🐞 Fix Form.Item removed in `form.validateFields` throw `Can't perform a React state update on an unmounted component` warning. [#34405](https://github.com/ant-design/ant-design/pull/34405)
|
||||
- 🐞 Fix to Form that `initialValues` would change if `preserve` is false. [#34411](https://github.com/ant-design/ant-design/pull/34411)
|
||||
- Tooltip
|
||||
- 💄 Fix Tooltip width in Safari. [#34415](https://github.com/ant-design/ant-design/pull/34415) [@jiandandkl](https://github.com/jiandandkl)
|
||||
- 💄 Fix arrow size of Tooltip/Popover/Popconfirm. [#34407](https://github.com/ant-design/ant-design/pull/34407)
|
||||
- 💄 Remove Collapse bottom border in simple style. [#34366](https://github.com/ant-design/ant-design/pull/34366) [@PanStar](https://github.com/PanStar)
|
||||
- TypeScript
|
||||
- 🤖 Fix Input `data-*` type definition. [#34410](https://github.com/ant-design/ant-design/pull/34410) [@GitKou](https://github.com/GitKou)
|
||||
- 🤖 Fix Transfer `footer` type definition. [#34337](https://github.com/ant-design/ant-design/pull/34337) [@zomixi](https://github.com/zomixi)
|
||||
|
||||
## 4.19.1
|
||||
|
||||
`2022-03-08`
|
||||
|
||||
- 🐞 Fix less compile error related to custom status. [#34350](https://github.com/ant-design/ant-design/pull/34350)
|
||||
- 🐞 Fix error `ReferenceError: colorPalette is not defined` when customize theme.
|
||||
- 🐞 Fix error `Error: Invalid class or id selector syntax` when import `antd/dist/antd.css`.
|
||||
- 🐞 Fix Input.Passowrd icon color in site. [#34354](https://github.com/ant-design/ant-design/pull/34354)
|
||||
- 🐞 Fix ConfigProvider `csp` sometime not effect on Icon. [#34356](https://github.com/ant-design/ant-design/pull/34356)
|
||||
|
||||
## 4.19.0
|
||||
|
||||
`2022-03-08`
|
||||
|
||||
- 💄 Optimize arrow style for some components. [#33710](https://github.com/ant-design/ant-design/pull/33710)
|
||||
|
||||
![image](https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png)
|
||||
<img src="https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png" width="500" />
|
||||
|
||||
- Input
|
||||
- 🛠 Refactor Input with rc-input. [#34206](https://github.com/ant-design/ant-design/pull/34206)
|
||||
@ -33,6 +65,7 @@ timeline: true
|
||||
- ⌨️ Table adds `aria-sort` attribute for screen readers. [#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1)
|
||||
- 🐞 Fix Table filters select-all Checkbox not changed when select item. [#34295](https://github.com/ant-design/ant-design/pull/34295)
|
||||
- 🆕 Data entry components add `status` prop to support custom status.
|
||||
|
||||
- Transfer [#34098](https://github.com/ant-design/ant-design/pull/34098)
|
||||
- AutoComplete [#34096](https://github.com/ant-design/ant-design/pull/34096)
|
||||
- TreeSelect [#34093](https://github.com/ant-design/ant-design/pull/34093)
|
||||
@ -43,7 +76,7 @@ timeline: true
|
||||
- InputNumber [#34042](https://github.com/ant-design/ant-design/pull/34042)
|
||||
- Input [#33995](https://github.com/ant-design/ant-design/pull/33995)
|
||||
|
||||
![image](https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png)
|
||||
<img src="https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png" width="500" />
|
||||
|
||||
- 🆕 InputNumber supports `controls={{ upIcon, downIcon }}` to customize icon up and down. [#33914](https://github.com/ant-design/ant-design/pull/33914) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🆕 Notification `placement` support `top` / `bottom` [#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585)
|
||||
|
@ -13,26 +13,59 @@ timeline: true
|
||||
- 次版本号:每月发布一个带有新特性的向下兼容的版本。
|
||||
- 主版本号:含有破坏性更新和新特性,不在发布周期内。
|
||||
|
||||
---
|
||||
--
|
||||
|
||||
## 4.19.2
|
||||
|
||||
`2022-03-13`
|
||||
|
||||
- 🐞 修复 Dropdown 在边界情况下不会自动调整展示位置的问题。[#34390](https://github.com/ant-design/ant-design/pull/34390)
|
||||
- 💄 缩小 PageHeader `extra` 内元素间距为 `8px`。[#34428](https://github.com/ant-design/ant-design/pull/34428)
|
||||
- 🛠 导出 antd/es/config-provider 目录下的 css variable 函数以支持 ssr 的需求。[#34436](https://github.com/ant-design/ant-design/pull/34436)
|
||||
- 🛠 使用 React hooks 重构 Menu。[#34433](https://github.com/ant-design/ant-design/pull/34433)
|
||||
- Input
|
||||
- 💄 修复大尺寸 Input 的字号问题。[#34381](https://github.com/ant-design/ant-design/pull/34381)
|
||||
- 💄 修复 Input.Group 多余的错误边框样式。[#34412](https://github.com/ant-design/ant-design/pull/34412)
|
||||
- Form
|
||||
- 🐞 修复 Form.Item 在 `form.validateFields` 中移除时抛出 `Can't perform a React state update on an unmounted component` 警告的问题。[#34405](https://github.com/ant-design/ant-design/pull/34405)
|
||||
- 🐞 修复 Form 组件当 `preserve` 为 `false` 时 `initialValues` 会被更改的问题。[#34411](https://github.com/ant-design/ant-design/pull/34411)
|
||||
- Tooltip
|
||||
- 💄 修复 Tooltip 在 Safari 下的内容宽度问题。[#34415](https://github.com/ant-design/ant-design/pull/34415) [@jiandandkl](https://github.com/jiandandkl)
|
||||
- 💄 修复 Tooltip/Popover/Popconfirm 等组件箭头大小问题。[#34407](https://github.com/ant-design/ant-design/pull/34407)
|
||||
- 💄 优化 Collapse 简洁模式的底边框。[#34366](https://github.com/ant-design/ant-design/pull/34366) [@PanStar](https://github.com/PanStar)
|
||||
- TypeScript
|
||||
- 🤖 修复 Input 不支持 `data-*` TS 定义的问题。[#34410](https://github.com/ant-design/ant-design/pull/34410) [@GitKou](https://github.com/GitKou)
|
||||
- 🤖 修复 Transfer 的 `footer` 类型定义。[#34337](https://github.com/ant-design/ant-design/pull/34337) [@zomixi](https://github.com/zomixi)
|
||||
|
||||
## 4.19.1
|
||||
|
||||
`2022-03-08`
|
||||
|
||||
- 🐞 修复自定义状态相关的 less 编译错误。[#34350](htps://github.com/ant-dign/ant-design/pull/34350)
|
||||
- 🐞 修复使用定制主题时 less 编译提示 `ReferenceError: colorPalette is not defined` 错误。
|
||||
- 🐞 修复引入 `antd/dist/antd.css` 时提示 `Error: Invalid class or id selector syntax` 错误。
|
||||
- 🐞 修复 Input.Passowrd 图标颜色错误。[#34354](https://github.com/ant-design/ant-design/pull/34354)
|
||||
- 🐞 修复 ConfigProvider `csp` 有时在 Icon 上不会生效的问题。[#34356](https://github.com/ant-design/ant-design/pull/34356)
|
||||
|
||||
## 4.19.0
|
||||
|
||||
`2022-03-08`
|
||||
|
||||
- 💄 优化部分组件箭头样式。 [#33710](https://github.com/ant-design/ant-design/pull/33710)
|
||||
- 💄 优化部分组件箭头样式。[#33710](https://github.com/ant-design/ant-design/pull/33710)
|
||||
|
||||
![image](https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png)
|
||||
<img src="https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png" width="500" />
|
||||
|
||||
- Input
|
||||
- 🛠 引入 rc-input 重构 Input 组件为 function component。[#34206](https://github.com/ant-design/ant-design/pull/34206)
|
||||
- 注意:由于从 class component 变为 function component,Input 组件的 `ref` 类型及内容已经更新,可以通过 `import { InputRef } from 'antd'` 引入。其中的 `input` 属性作为获取 DOM 的途径被保留,同时支持 `focus` 和 `blur` 等文档中支持的方法。
|
||||
- 🆕 新增 `clearIcon` 属性,支持自定义清除按钮。 [#34325](https://github.com/ant-design/ant-design/pull/34325)
|
||||
- 🆕 新增 `clearIcon` 属性,支持自定义清除按钮。[#34325](https://github.com/ant-design/ant-design/pull/34325)
|
||||
- Table
|
||||
- 🆕 `column.filterSearch` 属性现在支持返回一个函数用于自定义搜索条件。[#34085](https://github.com/ant-design/ant-design/pull/34085) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🆕 `column.filterDropdown({ clearFilters })` 支持参数 `clearFilters({ confirm: false, closeDropdown: false })` 控制筛选。[#34120](https://github.com/ant-design/ant-design/pull/34120) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- ⌨️ 增加 `aria-sort` 属性以优化屏幕阅读器的使用体验。 [#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1)
|
||||
- 🐞 修复 Table 列筛选器中选择全部 Checkbox 状态问题。 [#34295](https://github.com/ant-design/ant-design/pull/34295)
|
||||
- ⌨️ 增加 `aria-sort` 属性以优化屏幕阅读器的使用体验。[#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1)
|
||||
- 🐞 修复 Table 列筛选器中选择全部 Checkbox 状态问题。[#34295](https://github.com/ant-design/ant-design/pull/34295)
|
||||
- 🆕 表单组件新增 `status` 属性以支持自定义状态。
|
||||
|
||||
- Transfer [#34098](https://github.com/ant-design/ant-design/pull/34098)
|
||||
- AutoComplete [#34096](https://github.com/ant-design/ant-design/pull/34096)
|
||||
- TreeSelect [#34093](https://github.com/ant-design/ant-design/pull/34093)
|
||||
@ -43,18 +76,18 @@ timeline: true
|
||||
- InputNumber [#34042](https://github.com/ant-design/ant-design/pull/34042)
|
||||
- Input [#33995](https://github.com/ant-design/ant-design/pull/33995)
|
||||
|
||||
![image](https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png)
|
||||
<img src="https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png" width="500" />
|
||||
|
||||
- 🆕 InputNumber 组件支持 `controls={{ upIcon, downIcon }}` 用于自定义上下图标。[#33914](https://github.com/ant-design/ant-design/pull/33914) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🆕 Notification 组件弹窗位置新增支持 `top` / `bottom`。 [#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🆕 Select、Cascader、DatePicker 等组件新增 `placement` 用于自定义弹层方向。 [#33641](https://github.com/ant-design/ant-design/pull/33541) [@ONLY-yours](https://github.com/ONLY-yours)
|
||||
- 🆕 Dropdown 组件支持 `arrow={{ pointAtCenter: true }}` 用于指向元素正中间,并且新增 `top` `bottom` 两种 `placement` 位置。 [#33658](https://github.com/ant-design/ant-design/pull/33658)
|
||||
- 🆕 Skeleton.Input 添加 `block` 属性。 [#33672](https://github.com/ant-design/ant-design/pull/33672) [@woochanleee](https://github.com/woochanleee)
|
||||
- 🆕 合并 TimePicker `disabledHours`、`disabledMinutes`、`disabledSeconds` 至 `disabledTime` 以保持与 DatePicker 接口一致性。 [#33503](https://github.com/ant-design/ant-design/pull/33503)
|
||||
- 💄 修改部分边框颜色和进度条的背景色为透明色以适应有色背景。 [#33506](https://github.com/ant-design/ant-design/pull/33506)
|
||||
- 💄 Space 支持自定义 children 的 `key`。 [#33607](https://github.com/ant-design/ant-design/pull/33607) [@qin20](https://github.com/qin20)
|
||||
- 🐞 修复 Typography.Title 进入编辑模式时大小不一致的问题。 [#34169](https://github.com/ant-design/ant-design/pull/34169) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🐞 修复 Form.Item 抛出 `React does not recognize the requiredMark prop on a DOM element` 的问题。 [#34323](https://github.com/ant-design/ant-design/pull/34323)
|
||||
- 🆕 Notification 组件弹窗位置新增支持 `top` / `bottom`。[#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🆕 Select、Cascader、DatePicker 等组件新增 `placement` 用于自定义弹层方向。[#33641](https://github.com/ant-design/ant-design/pull/33541) [@ONLY-yours](https://github.com/ONLY-yours)
|
||||
- 🆕 Dropdown 组件支持 `arrow={{ pointAtCenter: true }}` 用于指向元素正中间,并且新增 `top` `bottom` 两种 `placement` 位置。[#33658](https://github.com/ant-design/ant-design/pull/33658)
|
||||
- 🆕 Skeleton.Input 添加 `block` 属性。[#33672](https://github.com/ant-design/ant-design/pull/33672) [@woochanleee](https://github.com/woochanleee)
|
||||
- 🆕 合并 TimePicker `disabledHours`、`disabledMinutes`、`disabledSeconds` 至 `disabledTime` 以保持与 DatePicker 接口一致性。[#33503](https://github.com/ant-design/ant-design/pull/33503)
|
||||
- 💄 修改部分边框颜色和进度条的背景色为透明色以适应有色背景。[#33506](https://github.com/ant-design/ant-design/pull/33506)
|
||||
- 💄 Space 支持自定义 children 的 `key`。[#33607](https://github.com/ant-design/ant-design/pull/33607) [@qin20](https://github.com/qin20)
|
||||
- 🐞 修复 Typography.Title 进入编辑模式时大小不一致的问题。[#34169](https://github.com/ant-design/ant-design/pull/34169) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🐞 修复 Form.Item 抛出 `React does not recognize the requiredMark prop on a DOM element` 的问题。[#34323](https://github.com/ant-design/ant-design/pull/34323)
|
||||
|
||||
## 4.18.9
|
||||
|
||||
@ -135,7 +168,7 @@ timeline: true
|
||||
|
||||
- Typography
|
||||
- ⚡️ 优化 Typography 在配置 `tooltip` 时优先使用原生省略样式以提升性能。[#33669](https://github.com/ant-design/ant-design/pull/33669)
|
||||
- 🐞 重构 Typography `ellipsis` 逻辑以修复 `children` 如果消费上游 Context 会报错的问题。 [#33725](https://github.com/ant-design/ant-design/pull/33725)
|
||||
- 🐞 重构 Typography `ellipsis` 逻辑以修复 `children` 如果消费上游 Context 会报错的问题。[#33725](https://github.com/ant-design/ant-design/pull/33725)
|
||||
- Icon
|
||||
- 🐞 修复 `<Icon component={HomeOutlined} />` 和 `<HomeOutlined />` 不对齐的问题。[#33709](https://github.com/ant-design/ant-design/pull/33709)
|
||||
- 🐞 修复 `<Icon component={SyncOutlined} spin />` 抖动的问题。[#33726](https://github.com/ant-design/ant-design/pull/33726) [@JX-Zhuang](https://github.com/JX-Zhuang)
|
||||
@ -361,7 +394,7 @@ timeline: true
|
||||
- 🐞 修复 Button `ghost` 鼠标悬停样式。[#32289](https://github.com/ant-design/ant-design/pull/32289)
|
||||
- 🐞 修复 Button 配置 `loading` 时,无法触发 Tooltip 的问题。[#32158](https://github.com/ant-design/ant-design/pull/32158)
|
||||
- Pagination
|
||||
- 🆕 Pagination 支持定制 `selectComponentClass`。 [#32132](https://github.com/ant-design/ant-design/pull/32132) [@JounQin](https://github.com/JounQin)
|
||||
- 🆕 Pagination 支持定制 `selectComponentClass`。[#32132](https://github.com/ant-design/ant-design/pull/32132) [@JounQin](https://github.com/JounQin)
|
||||
- 💄 Pagination `simple` 属性下中翻页 input 增加 box-shadow。[#32528](https://github.com/ant-design/ant-design/pull/32528) [@chen-jingjie](https://github.com/chen-jingjie)
|
||||
- Upload
|
||||
- 🐞 修复 Upload `listStyle="picture"` 下加载中样式错位的问题。[#32664](https://github.com/ant-design/ant-design/pull/32664)
|
||||
@ -414,7 +447,7 @@ timeline: true
|
||||
- 🤖 修复 Switch `id` 属性定义。[#32237](https://github.com/ant-design/ant-design/pull/32237) [@M-ZubairAhmed](https://github.com/M-ZubairAhmed)
|
||||
- 🤖 修复 Button 的 `type` 的 TS 类型定义。[#32004](https://github.com/ant-design/ant-design/pull/32004) [@jaredleechn](https://github.com/jaredleechn)
|
||||
- 🤖 完备 Pagination 的 `locale` TS 类型定义。[[#32128](https://github.com/ant-design/ant-design/pull/32128) [@JounQin](https://github.com/JounQin)
|
||||
- 🤖 完善并导出 DropdownButton 的 `DropdownButtonType` TS 类型定义。 [[#31957](https://github.com/ant-design/ant-design/pull/31957) [@Dreamerryao](https://github.com/Dreamerryao)
|
||||
- 🤖 完善并导出 DropdownButton 的 `DropdownButtonType` TS 类型定义。[[#31957](https://github.com/ant-design/ant-design/pull/31957) [@Dreamerryao](https://github.com/Dreamerryao)
|
||||
- 🤖 调整 List 组件 `rowKey` 类型为 React.key。[#32033](https://github.com/ant-design/ant-design/pull/32033) [@lironhl](https://github.com/lironhl)
|
||||
- 🐞 修复 DatePicker `ref` 类型。[#31993](https://github.com/ant-design/ant-design/pull/31993) [@acfasj](https://github.com/acfasj)
|
||||
- 🤖 更新 Drawer 中 `levelMove` 类型定义。[#30714](https://github.com/ant-design/ant-design/pull/30714) [@g0shed](https://github.com/g0shed)
|
||||
@ -463,7 +496,7 @@ timeline: true
|
||||
- 🐞 修复 Progress 环形进度条 `success.strokeColor` 不生效的问题。[#31589](https://github.com/ant-design/ant-design/pull/31589)
|
||||
- 🐞 修复 Select 组件没有忽略 `getRawInputElement` 属性导致的类型报错问题。[#31566](https://github.com/ant-design/ant-design/pull/31566) [@aoilti](https://github.com/aoilti)
|
||||
- 🐞 修复 Pagination 的 `totalBoundaryShowSizeChanger` 属性类型错误。[#31549](https://github.com/ant-design/ant-design/pull/31549) [@Monty-Ma](https://github.com/Monty-Ma)
|
||||
- 🐞 修复 Skeleton.Avatar `className` 重复应用的问题。 [#31536](https://github.com/ant-design/ant-design/pull/31536) [@Greatshock](https://github.com/Greatshock)
|
||||
- 🐞 修复 Skeleton.Avatar `className` 重复应用的问题。[#31536](https://github.com/ant-design/ant-design/pull/31536) [@Greatshock](https://github.com/Greatshock)
|
||||
- 🌐 国际化
|
||||
- 🇹🇷 为 Image 组件中 `预览` 文案增加土耳其语翻译。[#31593](https://github.com/ant-design/ant-design/pull/31593) [@mburakkalkan](https://github.com/mburakkalkan)
|
||||
- 🇰🇷 修复韩语中的错别字。[#31575](https://github.com/ant-design/ant-design/pull/31575) [@chatoo2412](https://github.com/chatoo2412)
|
||||
@ -784,7 +817,7 @@ timeline: true
|
||||
- 🐞 修复 Modal 页脚里使用 href 按钮导致的间距丢失问题。[#29681](https://github.com/ant-design/ant-design/pull/29681) [@n0ruSh](https://github.com/n0ruSh)
|
||||
- 💄 修复 Input 组件配置附件元素时禁用样式异常的问题。[#29670](https://github.com/ant-design/ant-design/pull/29670)
|
||||
- 💄 优化 Form.Item 提示信息的鼠标显示样式。[#29650](https://github.com/ant-design/ant-design/pull/29650)
|
||||
- 🇨🇿 修复 cs_CZ 语言环境中的错字。 [#29675](https://github.com/ant-design/ant-design/pull/29675) [@jvaclavik](https://github.com/jvaclavik)
|
||||
- 🇨🇿 修复 cs_CZ 语言环境中的错字。[#29675](https://github.com/ant-design/ant-design/pull/29675) [@jvaclavik](https://github.com/jvaclavik)
|
||||
- 🇨🇦 添加 fr_CA 语言。[#29748](https://github.com/ant-design/ant-design/pull/29748) [@liufenghua808](https://github.com/liufenghua808)
|
||||
|
||||
## 4.13.1
|
||||
@ -884,7 +917,7 @@ timeline: true
|
||||
- TypeScript
|
||||
- 🤖 更新 Table TypeScript 定义 `dataSource` 至 `readonly`。[#29084](https://github.com/ant-design/ant-design/pull/29084)
|
||||
- Less
|
||||
- 💄 增加 less 变量 `@progress-info-text-color`。 [#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan)
|
||||
- 💄 增加 less 变量 `@progress-info-text-color`。[#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan)
|
||||
|
||||
## 4.11.3
|
||||
|
||||
@ -1023,7 +1056,7 @@ timeline: true
|
||||
- 🆕 多选模式下 `maxTagCount` 支持 `responsive`。[#28520](https://github.com/ant-design/ant-design/pull/28520)
|
||||
- 🆕 Slider 新增 range.draggableTrack 以支持范围刻度整体可拖拽。[#28592](https://github.com/ant-design/ant-design/pull/28592)
|
||||
- 🆕 `message` 新增 `onClick` 回调,会在消息被点击时触发。[#28148](https://github.com/ant-design/ant-design/pull/28148) [@ZeroTo0ne](https://github.com/ant-design/ant-design/pull/28148)
|
||||
- 🆕 Descriptions 上可以统一设置 `labelStyle` 和 `contentStyle`。 [#28613](https://github.com/ant-design/ant-design/pull/28613)
|
||||
- 🆕 Descriptions 上可以统一设置 `labelStyle` 和 `contentStyle`。[#28613](https://github.com/ant-design/ant-design/pull/28613)
|
||||
- 🆕 Form 的 `scrollToFirstError` 属性支持设置滚动的位置参数。[#28272](https://github.com/ant-design/ant-design/pull/28272) [@vouis](https://github.com/vouis)
|
||||
- 🆕 Steps 新增 reponsive 属性用于关闭响应式样式。[#28459](https://github.com/ant-design/ant-design/pull/28459)
|
||||
- 🌐 国际化
|
||||
@ -1414,7 +1447,7 @@ timeline: true
|
||||
- 🐞 修复 Form 使用 `help` 时出现的同构问题。[#26542](https://github.com/ant-design/ant-design/pull/26542)
|
||||
- 🐞 修复 Avatar 在 `display: none` 时不会正确缩放 fallback 文字的问题。[#26522](https://github.com/ant-design/ant-design/pull/26522) [@zhangyu1818](https://github.com/zhangyu1818)
|
||||
- TypeScript
|
||||
- 🤖 Col 增加 `ColSize` 增加 `flex` 的定义。 [#26578](https://github.com/ant-design/ant-design/pull/26578) [@blaiz](https://github.com/blaiz)
|
||||
- 🤖 Col 增加 `ColSize` 增加 `flex` 的定义。[#26578](https://github.com/ant-design/ant-design/pull/26578) [@blaiz](https://github.com/blaiz)
|
||||
- 🤖 修复 Tooltip/Popover `children` 定义不接受 ReactNode 的问题。[#26534](https://github.com/ant-design/ant-design/pull/26534)
|
||||
|
||||
## 4.6.2
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import useState from 'rc-util/lib/hooks/useState';
|
||||
import Button from '../button';
|
||||
import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/button';
|
||||
import useDestroyed from './hooks/useDestroyed';
|
||||
|
||||
export interface ActionButtonProps {
|
||||
type?: LegacyButtonType;
|
||||
@ -21,8 +21,7 @@ function isThenable(thing?: PromiseLike<any>): boolean {
|
||||
const ActionButton: React.FC<ActionButtonProps> = props => {
|
||||
const clickedRef = React.useRef<boolean>(false);
|
||||
const ref = React.useRef<any>();
|
||||
const isDestroyed = useDestroyed();
|
||||
const [loading, setLoading] = React.useState<ButtonProps['loading']>(false);
|
||||
const [loading, setLoading] = useState<ButtonProps['loading']>(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
let timeoutId: any;
|
||||
@ -45,9 +44,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
||||
setLoading(true);
|
||||
returnValueOfOnOk!.then(
|
||||
(...args: any[]) => {
|
||||
if (!isDestroyed()) {
|
||||
setLoading(false);
|
||||
}
|
||||
setLoading(false, true);
|
||||
close(...args);
|
||||
clickedRef.current = false;
|
||||
},
|
||||
@ -56,9 +53,7 @@ const ActionButton: React.FC<ActionButtonProps> = props => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(e);
|
||||
// See: https://github.com/ant-design/ant-design/issues/6183
|
||||
if (!isDestroyed()) {
|
||||
setLoading(false);
|
||||
}
|
||||
setLoading(false, true);
|
||||
clickedRef.current = false;
|
||||
},
|
||||
);
|
||||
|
@ -1,20 +0,0 @@
|
||||
import { mount } from 'enzyme';
|
||||
import React from 'react';
|
||||
import useDestroyed from '../hooks/useDestroyed';
|
||||
|
||||
describe('useMounted', () => {
|
||||
it('should work properly', () => {
|
||||
let isDestroyed = null;
|
||||
|
||||
const AutoUnmounted = () => {
|
||||
isDestroyed = useDestroyed();
|
||||
|
||||
return <div>Mounted</div>;
|
||||
};
|
||||
|
||||
const wrapper = mount(<AutoUnmounted />);
|
||||
expect(isDestroyed()).toBeFalsy();
|
||||
wrapper.unmount();
|
||||
expect(isDestroyed()).toBeTruthy();
|
||||
});
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
export default function getDataOrAriaProps(props: any) {
|
||||
return Object.keys(props).reduce((prev: any, key: string) => {
|
||||
if (
|
||||
(key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role') &&
|
||||
key.substr(0, 7) !== 'data-__'
|
||||
(key.startsWith('data-') || key.startsWith('aria-') || key === 'role') &&
|
||||
!key.startsWith('data-__')
|
||||
) {
|
||||
prev[key] = props[key];
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export default function useDestroyed() {
|
||||
const mountedRef = React.useRef<boolean>(true);
|
||||
|
||||
React.useEffect(
|
||||
() => () => {
|
||||
mountedRef.current = false;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
return () => !mountedRef.current;
|
||||
}
|
@ -33,6 +33,10 @@ export interface AffixProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface InternalAffixProps extends AffixProps {
|
||||
affixPrefixCls: string;
|
||||
}
|
||||
|
||||
enum AffixStatus {
|
||||
None,
|
||||
Prepare,
|
||||
@ -47,7 +51,7 @@ export interface AffixState {
|
||||
prevTarget: Window | HTMLElement | null;
|
||||
}
|
||||
|
||||
class Affix extends React.Component<AffixProps, AffixState> {
|
||||
class Affix extends React.Component<InternalAffixProps, AffixState> {
|
||||
static contextType = ConfigContext;
|
||||
|
||||
state: AffixState = {
|
||||
@ -250,14 +254,20 @@ class Affix extends React.Component<AffixProps, AffixState> {
|
||||
|
||||
// =================== Render ===================
|
||||
render() {
|
||||
const { getPrefixCls } = this.context;
|
||||
const { affixStyle, placeholderStyle } = this.state;
|
||||
const { prefixCls, children } = this.props;
|
||||
const { affixPrefixCls, children } = this.props;
|
||||
const className = classNames({
|
||||
[getPrefixCls('affix', prefixCls)]: !!affixStyle,
|
||||
[affixPrefixCls]: !!affixStyle,
|
||||
});
|
||||
|
||||
let props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']);
|
||||
let props = omit(this.props, [
|
||||
'prefixCls',
|
||||
'offsetTop',
|
||||
'offsetBottom',
|
||||
'target',
|
||||
'onChange',
|
||||
'affixPrefixCls',
|
||||
]);
|
||||
// Omit this since `onTestUpdatePosition` only works on test.
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
props = omit(props as typeof props & { onTestUpdatePosition: any }, ['onTestUpdatePosition']);
|
||||
@ -286,7 +296,20 @@ class Affix extends React.Component<AffixProps, AffixState> {
|
||||
}
|
||||
}
|
||||
|
||||
const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => <Affix {...props} ref={ref} />);
|
||||
const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => {
|
||||
const { prefixCls: customizePrefixCls } = props;
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
|
||||
const affixPrefixCls = getPrefixCls('affix', customizePrefixCls);
|
||||
|
||||
const AffixProps: InternalAffixProps = {
|
||||
...props,
|
||||
|
||||
affixPrefixCls,
|
||||
};
|
||||
|
||||
return <Affix {...AffixProps} ref={ref} />;
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
AffixFC.displayName = 'Affix';
|
||||
|
@ -21,7 +21,7 @@ Alert component for feedback.
|
||||
| banner | Whether to show as banner | boolean | false | |
|
||||
| closable | Whether Alert can be closed | boolean | - | |
|
||||
| closeText | Close text to show | ReactNode | - | |
|
||||
| closeIcon | Custom close icon | ReactNode | <CloseOutlined /> | 4.17.0 |
|
||||
| closeIcon | Custom close icon | ReactNode | `<CloseOutlined />` | 4.17.0 |
|
||||
| description | Additional content of Alert | ReactNode | - | |
|
||||
| icon | Custom icon, effective when `showIcon` is true | ReactNode | - | |
|
||||
| message | Content of Alert | ReactNode | - | |
|
||||
|
@ -22,7 +22,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/8emPa3fjl/Alert.svg
|
||||
| banner | 是否用作顶部公告 | boolean | false | |
|
||||
| closable | 默认不显示关闭按钮 | boolean | - | |
|
||||
| closeText | 自定义关闭按钮 | ReactNode | - | |
|
||||
| closeIcon | 自定义关闭 Icon | ReactNode | <CloseOutlined /> | 4.17.0 |
|
||||
| closeIcon | 自定义关闭 Icon | ReactNode | `<CloseOutlined />` | 4.17.0 |
|
||||
| description | 警告提示的辅助性文字介绍 | ReactNode | - | |
|
||||
| icon | 自定义图标,`showIcon` 为 true 时有效 | ReactNode | - | |
|
||||
| message | 警告提示内容 | ReactNode | - | |
|
||||
|
@ -24,6 +24,7 @@ Cascade selection box.
|
||||
| allowClear | Whether allow clear | boolean | true | |
|
||||
| autoFocus | If get focus when component mounted | boolean | false | |
|
||||
| bordered | Whether has border style | boolean | true | |
|
||||
| clearIcon | The custom clear icon | ReactNode | - | |
|
||||
| changeOnSelect | (Work on single select) Change value on each selection if set to true, see above demo for details | boolean | false | |
|
||||
| className | The additional css class | string | - | |
|
||||
| defaultValue | Initial selected value | string\[] \| number\[] | \[] | |
|
||||
@ -53,6 +54,7 @@ Cascade selection box.
|
||||
| onChange | Callback when finishing cascader select | (value, selectedOptions) => void | - | |
|
||||
| onDropdownVisibleChange | Callback when popup shown or hidden | (value) => void | - | 4.17.0 |
|
||||
| multiple | Support multiple or not | boolean | - | 4.17.0 |
|
||||
| removeIcon | The custom remove icon | ReactNode | - | |
|
||||
| searchValue | Set search value,Need work with `showSearch` | string | - | 4.17.0 |
|
||||
| onSearch | The callback function triggered when input changed | (search: string) => void | - | 4.17.0 |
|
||||
| dropdownMenuColumnStyle | The style of the drop-down menu column | CSSProperties | - | |
|
||||
|
@ -25,6 +25,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
|
||||
| allowClear | 是否支持清除 | boolean | true | |
|
||||
| autoFocus | 自动获取焦点 | boolean | false | |
|
||||
| bordered | 是否有边框 | boolean | true | |
|
||||
| clearIcon | 自定义的选择框清空图标 | ReactNode | - | |
|
||||
| changeOnSelect | (单选时生效)当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false | |
|
||||
| className | 自定义类名 | string | - | |
|
||||
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] | |
|
||||
@ -54,6 +55,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
|
||||
| onChange | 选择完成后的回调 | (value, selectedOptions) => void | - | |
|
||||
| onDropdownVisibleChange | 显示/隐藏浮层的回调 | (value) => void | - | 4.17.0 |
|
||||
| multiple | 支持多选节点 | boolean | - | 4.17.0 |
|
||||
| removeIcon | 自定义的多选框清除图标 | ReactNode | - | |
|
||||
| searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 4.17.0 |
|
||||
| onSearch | 监听搜索,返回输入的值 | (search: string) => void | - | 4.17.0 |
|
||||
| dropdownMenuColumnStyle | 下拉菜单列的样式 | CSSProperties | - | |
|
||||
|
@ -120,6 +120,11 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
// hide the last border-bottom in borderless mode
|
||||
&-borderless > &-item:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&-borderless > &-item > &-content {
|
||||
background-color: transparent;
|
||||
border-top: 0;
|
||||
|
@ -13802,7 +13802,7 @@ exports[`ConfigProvider components Input configProvider componentSize large 1`]
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
class="config-input"
|
||||
class="config-input config-input-lg"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
@ -21055,6 +21055,7 @@ exports[`ConfigProvider components Select configProvider 1`] = `
|
||||
>
|
||||
<div
|
||||
class="config-select-item config-select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
@ -21182,6 +21183,7 @@ exports[`ConfigProvider components Select configProvider componentSize large 1`]
|
||||
>
|
||||
<div
|
||||
class="config-select-item config-select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
@ -21309,6 +21311,7 @@ exports[`ConfigProvider components Select configProvider componentSize middle 1`
|
||||
>
|
||||
<div
|
||||
class="config-select-item config-select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
@ -21436,6 +21439,7 @@ exports[`ConfigProvider components Select configProvider virtual and dropdownMat
|
||||
>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
@ -21563,6 +21567,7 @@ exports[`ConfigProvider components Select normal 1`] = `
|
||||
>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
@ -21690,6 +21695,7 @@ exports[`ConfigProvider components Select prefixCls 1`] = `
|
||||
>
|
||||
<div
|
||||
class="prefix-Select-item prefix-Select-item-group"
|
||||
title="grp"
|
||||
>
|
||||
grp
|
||||
</div>
|
||||
|
@ -16,17 +16,30 @@ describe('ConfigProvider.Icon', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('basic', () => {
|
||||
const wrapper = mount(
|
||||
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
||||
<SmileOutlined />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
describe('csp', () => {
|
||||
it('raw', () => {
|
||||
mount(
|
||||
<ConfigProvider csp={{ nonce: 'little' }}>
|
||||
<SmileOutlined />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
const styleNode = document.querySelector('style');
|
||||
const styleNode = document.querySelector('style');
|
||||
expect(styleNode.nonce).toEqual('little');
|
||||
});
|
||||
|
||||
expect(wrapper.exists('.bamboo-smile')).toBeTruthy();
|
||||
expect(styleNode.nonce).toEqual('light');
|
||||
it('mix with iconPrefixCls', () => {
|
||||
const wrapper = mount(
|
||||
<ConfigProvider iconPrefixCls="bamboo" csp={{ nonce: 'light' }}>
|
||||
<SmileOutlined />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
const styleNode = document.querySelector('style');
|
||||
|
||||
expect(wrapper.exists('.bamboo-smile')).toBeTruthy();
|
||||
expect(styleNode.nonce).toEqual('light');
|
||||
});
|
||||
});
|
||||
|
||||
it('nest', () => {
|
||||
|
@ -9,7 +9,7 @@ import devWarning from '../_util/devWarning';
|
||||
|
||||
const dynamicStyleMark = `-ant-${Date.now()}-${Math.random()}`;
|
||||
|
||||
export function registerTheme(globalPrefixCls: string, theme: Theme) {
|
||||
export function getStyle(globalPrefixCls: string, theme: Theme) {
|
||||
const variables: Record<string, string> = {};
|
||||
|
||||
const formatColor = (
|
||||
@ -88,15 +88,18 @@ export function registerTheme(globalPrefixCls: string, theme: Theme) {
|
||||
key => `--${globalPrefixCls}-${key}: ${variables[key]};`,
|
||||
);
|
||||
|
||||
if (canUseDom()) {
|
||||
updateCSS(
|
||||
`
|
||||
return `
|
||||
:root {
|
||||
${cssList.join('\n')}
|
||||
}
|
||||
`,
|
||||
`${dynamicStyleMark}-dynamic-theme`,
|
||||
);
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function registerTheme(globalPrefixCls: string, theme: Theme) {
|
||||
const style = getStyle(globalPrefixCls, theme);
|
||||
|
||||
if (canUseDom()) {
|
||||
updateCSS(style, `${dynamicStyleMark}-dynamic-theme`);
|
||||
} else {
|
||||
devWarning(false, 'ConfigProvider', 'SSR do not support dynamic theme with css variables.');
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
|
||||
|
||||
const memoIconContextValue = React.useMemo(
|
||||
() => ({ prefixCls: iconPrefixCls, csp }),
|
||||
[iconPrefixCls],
|
||||
[iconPrefixCls, csp],
|
||||
);
|
||||
|
||||
let childNode = children;
|
||||
@ -238,7 +238,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = props => {
|
||||
);
|
||||
}
|
||||
|
||||
if (iconPrefixCls) {
|
||||
if (iconPrefixCls || csp) {
|
||||
childNode = (
|
||||
<IconContext.Provider value={memoIconContextValue}>{childNode}</IconContext.Provider>
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3780,6 +3780,7 @@ exports[`renders ./components/date-picker/demo/status.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-bottom:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-status-warning"
|
||||
@ -3822,6 +3823,179 @@ exports[`renders ./components/date-picker/demo/status.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-bottom:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-range ant-picker-status-error"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-picker-input ant-picker-input-active"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="Start date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-range-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="to"
|
||||
class="ant-picker-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="swap-right"
|
||||
class="anticon anticon-swap-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="swap-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-input"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="End date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-active-bar"
|
||||
style="left:0;width:0;position:absolute"
|
||||
/>
|
||||
<span
|
||||
class="ant-picker-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="calendar"
|
||||
class="anticon anticon-calendar"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="calendar"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-range ant-picker-status-warning"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-picker-input ant-picker-input-active"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="Start date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-range-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="to"
|
||||
class="ant-picker-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="swap-right"
|
||||
class="anticon anticon-swap-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="swap-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-input"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="End date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-active-bar"
|
||||
style="left:0;width:0;position:absolute"
|
||||
/>
|
||||
<span
|
||||
class="ant-picker-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="calendar"
|
||||
class="anticon anticon-calendar"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="calendar"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -21,6 +21,8 @@ const Status: React.FC = () => (
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<DatePicker status="error" style={{ width: '100%' }} />
|
||||
<DatePicker status="warning" style={{ width: '100%' }} />
|
||||
<DatePicker.RangePicker status="error" style={{ width: '100%' }} />
|
||||
<DatePicker.RangePicker status="warning" style={{ width: '100%' }} />
|
||||
</Space>
|
||||
);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
|
||||
import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined';
|
||||
import { RangePicker as RCRangePicker } from 'rc-picker';
|
||||
import { GenerateConfig } from 'rc-picker/lib/generate/index';
|
||||
import { PickerMode } from 'rc-picker/lib/interface';
|
||||
import enUS from '../locale/en_US';
|
||||
import { ConfigContext, ConfigConsumerProps } from '../../config-provider';
|
||||
import SizeContext from '../../config-provider/SizeContext';
|
||||
@ -13,6 +14,8 @@ import LocaleReceiver from '../../locale-provider/LocaleReceiver';
|
||||
import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util';
|
||||
import { RangePickerProps, PickerLocale, getTimeProps, Components } from '.';
|
||||
import { PickerComponentClass } from './interface';
|
||||
import { FormItemStatusContext } from '../../form/context';
|
||||
import { getFeedbackIcon, getMergedStatus, getStatusClassNames } from '../../_util/statusUtils';
|
||||
|
||||
export default function generateRangePicker<DateType>(
|
||||
generateConfig: GenerateConfig<DateType>,
|
||||
@ -36,6 +39,23 @@ export default function generateRangePicker<DateType>(
|
||||
}
|
||||
};
|
||||
|
||||
renderFeedback = (prefixCls: string) => (
|
||||
<FormItemStatusContext.Consumer>
|
||||
{({ hasFeedback, status: contextStatus }) => {
|
||||
const { status: customStatus } = this.props;
|
||||
const status = getMergedStatus(contextStatus, customStatus);
|
||||
return hasFeedback && getFeedbackIcon(prefixCls, status);
|
||||
}}
|
||||
</FormItemStatusContext.Consumer>
|
||||
);
|
||||
|
||||
renderSuffix = (prefixCls: string, mergedPicker?: PickerMode) => (
|
||||
<>
|
||||
{mergedPicker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
|
||||
{this.renderFeedback(prefixCls)}
|
||||
</>
|
||||
);
|
||||
|
||||
renderPicker = (contextLocale: PickerLocale) => {
|
||||
const locale = { ...contextLocale, ...this.props.locale };
|
||||
const { getPrefixCls, direction, getPopupContainer } = this.context;
|
||||
@ -47,6 +67,7 @@ export default function generateRangePicker<DateType>(
|
||||
size: customizeSize,
|
||||
bordered = true,
|
||||
placeholder,
|
||||
status: customStatus,
|
||||
...restProps
|
||||
} = this.props;
|
||||
const { format, showTime, picker } = this.props as any;
|
||||
@ -67,39 +88,48 @@ export default function generateRangePicker<DateType>(
|
||||
const mergedSize = customizeSize || size;
|
||||
|
||||
return (
|
||||
<RCRangePicker<DateType>
|
||||
separator={
|
||||
<span aria-label="to" className={`${prefixCls}-separator`}>
|
||||
<SwapRightOutlined />
|
||||
</span>
|
||||
}
|
||||
ref={this.pickerRef}
|
||||
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
|
||||
placeholder={getRangePlaceholder(picker, locale, placeholder)}
|
||||
suffixIcon={picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />}
|
||||
clearIcon={<CloseCircleFilled />}
|
||||
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
|
||||
nextIcon={<span className={`${prefixCls}-next-icon`} />}
|
||||
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
|
||||
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
|
||||
allowClear
|
||||
transitionName={`${rootPrefixCls}-slide-up`}
|
||||
{...restProps}
|
||||
{...additionalOverrideProps}
|
||||
className={classNames(
|
||||
{
|
||||
[`${prefixCls}-${mergedSize}`]: mergedSize,
|
||||
[`${prefixCls}-borderless`]: !bordered,
|
||||
},
|
||||
className,
|
||||
<FormItemStatusContext.Consumer>
|
||||
{({ hasFeedback, status: contextStatus }) => (
|
||||
<RCRangePicker<DateType>
|
||||
separator={
|
||||
<span aria-label="to" className={`${prefixCls}-separator`}>
|
||||
<SwapRightOutlined />
|
||||
</span>
|
||||
}
|
||||
ref={this.pickerRef}
|
||||
dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
|
||||
placeholder={getRangePlaceholder(picker, locale, placeholder)}
|
||||
suffixIcon={this.renderSuffix(prefixCls, picker)}
|
||||
clearIcon={<CloseCircleFilled />}
|
||||
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
|
||||
nextIcon={<span className={`${prefixCls}-next-icon`} />}
|
||||
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
|
||||
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
|
||||
allowClear
|
||||
transitionName={`${rootPrefixCls}-slide-up`}
|
||||
{...restProps}
|
||||
{...additionalOverrideProps}
|
||||
className={classNames(
|
||||
{
|
||||
[`${prefixCls}-${mergedSize}`]: mergedSize,
|
||||
[`${prefixCls}-borderless`]: !bordered,
|
||||
},
|
||||
getStatusClassNames(
|
||||
prefixCls,
|
||||
getMergedStatus(contextStatus, customStatus),
|
||||
hasFeedback,
|
||||
),
|
||||
className,
|
||||
)}
|
||||
locale={locale!.lang}
|
||||
prefixCls={prefixCls}
|
||||
getPopupContainer={customGetPopupContainer || getPopupContainer}
|
||||
generateConfig={generateConfig}
|
||||
components={Components}
|
||||
direction={direction}
|
||||
/>
|
||||
)}
|
||||
locale={locale!.lang}
|
||||
prefixCls={prefixCls}
|
||||
getPopupContainer={customGetPopupContainer || getPopupContainer}
|
||||
generateConfig={generateConfig}
|
||||
components={Components}
|
||||
direction={direction}
|
||||
/>
|
||||
</FormItemStatusContext.Consumer>
|
||||
);
|
||||
}}
|
||||
</SizeContext.Consumer>
|
||||
|
@ -18,6 +18,7 @@ import { TimePickerLocale } from '../../time-picker';
|
||||
import generateSinglePicker from './generateSinglePicker';
|
||||
import generateRangePicker from './generateRangePicker';
|
||||
import { tuple } from '../../_util/type';
|
||||
import { InputStatus } from '../../_util/statusUtils';
|
||||
|
||||
export const Components = { button: PickerButton, rangeItem: PickerTag };
|
||||
|
||||
@ -81,6 +82,7 @@ type InjectDefaultProps<Props> = Omit<
|
||||
size?: SizeType;
|
||||
placement?: DataPickerPlacement;
|
||||
bordered?: boolean;
|
||||
status?: InputStatus;
|
||||
};
|
||||
|
||||
export type PickerLocale = {
|
||||
|
@ -79,4 +79,24 @@ describe('Dropdown', () => {
|
||||
expect.stringContaining("[antd: Dropdown] You are using 'topCenter'"),
|
||||
);
|
||||
});
|
||||
|
||||
// zombieJ: when replaced with react test lib, it may be mock fully content
|
||||
it('dropdown should support auto adjust placement', () => {
|
||||
const wrapper = mount(
|
||||
<Dropdown overlay={<div>menu</div>} visible>
|
||||
<button type="button">button</button>
|
||||
</Dropdown>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('Trigger').prop('builtinPlacements')).toEqual(
|
||||
expect.objectContaining({
|
||||
bottomLeft: expect.objectContaining({
|
||||
overflow: {
|
||||
adjustX: 1,
|
||||
adjustY: 1,
|
||||
},
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -189,6 +189,7 @@ const Dropdown: DropdownInterface = props => {
|
||||
|
||||
const builtinPlacements = getPlacements({
|
||||
arrowPointAtCenter: typeof arrow === 'object' && arrow.pointAtCenter,
|
||||
autoAdjustOverflow: true,
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -5,6 +5,7 @@ import { Field, FormInstance, FieldContext, ListContext } from 'rc-field-form';
|
||||
import { FieldProps } from 'rc-field-form/lib/Field';
|
||||
import { Meta, NamePath } from 'rc-field-form/lib/interface';
|
||||
import { supportRef } from 'rc-util/lib/ref';
|
||||
import useState from 'rc-util/lib/hooks/useState';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import Row from '../grid/row';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
@ -132,7 +133,7 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
||||
const [subFieldErrors, setSubFieldErrors] = useFrameState<Record<string, FieldError>>({});
|
||||
|
||||
// >>>>> Current field errors
|
||||
const [meta, setMeta] = React.useState<Meta>(() => genEmptyMeta());
|
||||
const [meta, setMeta] = useState<Meta>(() => genEmptyMeta());
|
||||
|
||||
const onMetaChange = (nextMeta: Meta & { destroy?: boolean }) => {
|
||||
// This keyInfo is not correct when field is removed
|
||||
@ -141,7 +142,7 @@ function FormItem<Values = any>(props: FormItemProps<Values>): React.ReactElemen
|
||||
const keyInfo = listContext?.getKey(nextMeta.name);
|
||||
|
||||
// Destroy will reset all the meta
|
||||
setMeta(nextMeta.destroy ? genEmptyMeta() : nextMeta);
|
||||
setMeta(nextMeta.destroy ? genEmptyMeta() : nextMeta, true);
|
||||
|
||||
// Bump to parent since noStyle
|
||||
if (noStyle && notifyParentMetaChange) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7872,6 +7872,137 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row ant-form-item ant-form-item-has-feedback ant-form-item-has-error"
|
||||
>
|
||||
<div
|
||||
class="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-6"
|
||||
>
|
||||
<label
|
||||
class=""
|
||||
title="Error"
|
||||
>
|
||||
Error
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="ant-col ant-form-item-control ant-col-xs-24 ant-col-sm-14"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input"
|
||||
>
|
||||
<div
|
||||
class="ant-form-item-control-input-content"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-range ant-picker-status-error ant-picker-has-feedback"
|
||||
style="width:100%"
|
||||
>
|
||||
<div
|
||||
class="ant-picker-input ant-picker-input-active"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="Start date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-range-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="to"
|
||||
class="ant-picker-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="swap-right"
|
||||
class="anticon anticon-swap-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="swap-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-input"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="End date"
|
||||
readonly=""
|
||||
size="12"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-active-bar"
|
||||
style="left:0;width:0;position:absolute"
|
||||
/>
|
||||
<span
|
||||
class="ant-picker-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="calendar"
|
||||
class="anticon anticon-calendar"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="calendar"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-picker-feedback-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="close-circle"
|
||||
class="anticon anticon-close-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="close-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-row ant-form-item ant-form-item-has-feedback ant-form-item-has-error"
|
||||
>
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import Form from '..';
|
||||
import Input from '../../input';
|
||||
import Button from '../../button';
|
||||
@ -204,4 +206,52 @@ describe('Form.List', () => {
|
||||
const wrapper = mount(<Form.ErrorList />);
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('no warning when reset in validate', async () => {
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const Demo = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
React.useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
list: [1],
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.List name="list">
|
||||
{fields =>
|
||||
fields.map(field => (
|
||||
<Form.Item key={field.key} {...field}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
))
|
||||
}
|
||||
</Form.List>
|
||||
<button
|
||||
id="validate"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
form.validateFields().then(() => {
|
||||
form.resetFields();
|
||||
});
|
||||
}}
|
||||
>
|
||||
Validate
|
||||
</button>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const { container } = render(<Demo />);
|
||||
fireEvent.click(container.querySelector('button'));
|
||||
|
||||
await sleep();
|
||||
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import omit from 'rc-util/lib/omit';
|
||||
import { Meta } from 'rc-field-form/lib/interface';
|
||||
import { FormProvider as RcFormProvider } from 'rc-field-form';
|
||||
import { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
|
||||
import { FC, PropsWithChildren, useMemo } from 'react';
|
||||
import { ColProps } from '../grid/col';
|
||||
import { FormLabelAlign } from './interface';
|
||||
import { RequiredMark } from './Form';
|
||||
@ -57,3 +58,11 @@ export interface FormItemStatusContextProps {
|
||||
}
|
||||
|
||||
export const FormItemStatusContext = React.createContext<FormItemStatusContextProps>({});
|
||||
|
||||
export const NoFormStatus: FC<PropsWithChildren<{}>> = ({ children }: PropsWithChildren<{}>) => {
|
||||
const emptyContext = useMemo(() => ({}), []);
|
||||
|
||||
return (
|
||||
<FormItemStatusContext.Provider value={emptyContext}>{children}</FormItemStatusContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -96,6 +96,10 @@ ReactDOM.render(
|
||||
<TimePicker style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Error" hasFeedback validateStatus="error">
|
||||
<DatePicker.RangePicker style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="Error" hasFeedback validateStatus="error">
|
||||
<Select placeholder="I'm Select" allowClear>
|
||||
<Option value="1">Option 1</Option>
|
||||
|
@ -6,7 +6,7 @@ import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
||||
import { FormItemStatusContext } from '../form/context';
|
||||
import { FormItemStatusContext, NoFormStatus } from '../form/context';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import {
|
||||
getFeedbackIcon,
|
||||
@ -168,9 +168,9 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
|
||||
element = (
|
||||
<div className={mergedGroupClassName} style={props.style}>
|
||||
<div className={mergedWrapperClassName}>
|
||||
{addonBeforeNode}
|
||||
{addonBeforeNode && <NoFormStatus>{addonBeforeNode}</NoFormStatus>}
|
||||
{cloneElement(element, { style: null })}
|
||||
{addonAfterNode}
|
||||
{addonAfterNode && <NoFormStatus>{addonAfterNode}</NoFormStatus>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
export interface GroupProps {
|
||||
className?: string;
|
||||
@ -15,35 +16,33 @@ export interface GroupProps {
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
const Group: React.FC<GroupProps> = props => (
|
||||
<ConfigConsumer>
|
||||
{({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const { prefixCls: customizePrefixCls, className = '' } = props;
|
||||
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
||||
const cls = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-lg`]: props.size === 'large',
|
||||
[`${prefixCls}-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-compact`]: props.compact,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
return (
|
||||
<span
|
||||
className={cls}
|
||||
style={props.style}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
>
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
}}
|
||||
</ConfigConsumer>
|
||||
);
|
||||
const Group: React.FC<GroupProps> = props => {
|
||||
const { getPrefixCls, direction } = useContext(ConfigContext);
|
||||
const { prefixCls: customizePrefixCls, className = '' } = props;
|
||||
const prefixCls = getPrefixCls('input-group', customizePrefixCls);
|
||||
const cls = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-lg`]: props.size === 'large',
|
||||
[`${prefixCls}-sm`]: props.size === 'small',
|
||||
[`${prefixCls}-compact`]: props.compact,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
|
||||
return (
|
||||
<span
|
||||
className={cls}
|
||||
style={props.style}
|
||||
onMouseEnter={props.onMouseEnter}
|
||||
onMouseLeave={props.onMouseLeave}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
>
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default Group;
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
InputStatus,
|
||||
} from '../_util/statusUtils';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { FormItemStatusContext } from '../form/context';
|
||||
import { FormItemStatusContext, NoFormStatus } from '../form/context';
|
||||
import { hasPrefixSuffix } from './utils';
|
||||
import devWarning from '../_util/devWarning';
|
||||
|
||||
@ -118,6 +118,7 @@ export interface InputProps
|
||||
size?: SizeType;
|
||||
status?: InputStatus;
|
||||
bordered?: boolean;
|
||||
[key: `data-${string}`]: string;
|
||||
}
|
||||
|
||||
const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||
@ -130,6 +131,8 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||
onFocus,
|
||||
suffix,
|
||||
allowClear,
|
||||
addonAfter,
|
||||
addonBefore,
|
||||
...rest
|
||||
} = props;
|
||||
const { getPrefixCls, direction, input } = React.useContext(ConfigContext);
|
||||
@ -146,7 +149,7 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||
const mergedStatus = getMergedStatus(contextStatus, customStatus);
|
||||
|
||||
// ===================== Focus warning =====================
|
||||
const inputHasPrefixSuffix = hasPrefixSuffix(props);
|
||||
const inputHasPrefixSuffix = hasPrefixSuffix(props) || !!hasFeedback;
|
||||
const prevHasPrefixSuffix = useRef<boolean>(inputHasPrefixSuffix);
|
||||
useEffect(() => {
|
||||
if (inputHasPrefixSuffix && !prevHasPrefixSuffix.current) {
|
||||
@ -197,8 +200,6 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||
</>
|
||||
);
|
||||
|
||||
const withPrefixSuffix = hasPrefixSuffix(props) || hasFeedback;
|
||||
|
||||
// Allow clear
|
||||
let mergedAllowClear;
|
||||
if (typeof allowClear === 'object' && allowClear?.clearIcon) {
|
||||
@ -217,14 +218,16 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||
onFocus={handleFocus}
|
||||
suffix={suffixNode}
|
||||
allowClear={mergedAllowClear}
|
||||
addonAfter={addonAfter && <NoFormStatus>{addonAfter}</NoFormStatus>}
|
||||
addonBefore={addonBefore && <NoFormStatus>{addonBefore}</NoFormStatus>}
|
||||
inputClassName={classNames(
|
||||
!withPrefixSuffix && {
|
||||
{
|
||||
[`${prefixCls}-sm`]: mergedSize === 'small',
|
||||
[`${prefixCls}-lg`]: mergedSize === 'large',
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
[`${prefixCls}-borderless`]: !bordered,
|
||||
},
|
||||
!withPrefixSuffix && getStatusClassNames(prefixCls, mergedStatus),
|
||||
!inputHasPrefixSuffix && getStatusClassNames(prefixCls, mergedStatus),
|
||||
)}
|
||||
affixWrapperClassName={classNames(
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ exports[`Input.Password rtl render component should be rendered correctly in RTL
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-rtl"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
@ -163,7 +163,7 @@ exports[`Input.Password should support size 1`] = `
|
||||
>
|
||||
<input
|
||||
action="click"
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
type="password"
|
||||
value=""
|
||||
/>
|
||||
|
@ -5009,7 +5009,7 @@ exports[`renders ./components/input/demo/borderless-debug.md extend context corr
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-borderless"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-borderless"
|
||||
placeholder="Unbordered"
|
||||
type="text"
|
||||
value=""
|
||||
@ -5053,7 +5053,7 @@ exports[`renders ./components/input/demo/borderless-debug.md extend context corr
|
||||
¥
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-borderless"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
@ -5072,7 +5072,7 @@ exports[`renders ./components/input/demo/borderless-debug.md extend context corr
|
||||
¥
|
||||
</span>
|
||||
<input
|
||||
class="ant-input ant-input-disabled"
|
||||
class="ant-input ant-input-disabled ant-input-borderless"
|
||||
disabled=""
|
||||
type="text"
|
||||
value=""
|
||||
@ -9161,7 +9161,7 @@ exports[`renders ./components/input/demo/search-input.md extend context correctl
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="input search text"
|
||||
type="text"
|
||||
value=""
|
||||
@ -9224,7 +9224,7 @@ exports[`renders ./components/input/demo/search-input.md extend context correctl
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="input search text"
|
||||
type="text"
|
||||
value=""
|
||||
@ -9485,7 +9485,7 @@ Array [
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="large size"
|
||||
type="text"
|
||||
value=""
|
||||
@ -9555,7 +9555,7 @@ Array [
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-sm"
|
||||
placeholder="small size"
|
||||
type="text"
|
||||
value=""
|
||||
|
@ -1226,7 +1226,7 @@ exports[`renders ./components/input/demo/borderless-debug.md correctly 1`] = `
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-borderless"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-borderless"
|
||||
placeholder="Unbordered"
|
||||
type="text"
|
||||
value=""
|
||||
@ -1270,7 +1270,7 @@ exports[`renders ./components/input/demo/borderless-debug.md correctly 1`] = `
|
||||
¥
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-borderless"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
@ -1289,7 +1289,7 @@ exports[`renders ./components/input/demo/borderless-debug.md correctly 1`] = `
|
||||
¥
|
||||
</span>
|
||||
<input
|
||||
class="ant-input ant-input-disabled"
|
||||
class="ant-input ant-input-disabled ant-input-borderless"
|
||||
disabled=""
|
||||
type="text"
|
||||
value=""
|
||||
@ -2935,7 +2935,7 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="input search text"
|
||||
type="text"
|
||||
value=""
|
||||
@ -2998,7 +2998,7 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
|
||||
class="ant-input-affix-wrapper ant-input-affix-wrapper-lg"
|
||||
>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="input search text"
|
||||
type="text"
|
||||
value=""
|
||||
@ -3259,7 +3259,7 @@ Array [
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-lg"
|
||||
placeholder="large size"
|
||||
type="text"
|
||||
value=""
|
||||
@ -3329,7 +3329,7 @@ Array [
|
||||
</span>
|
||||
</span>
|
||||
<input
|
||||
class="ant-input"
|
||||
class="ant-input ant-input-sm"
|
||||
placeholder="small size"
|
||||
type="text"
|
||||
value=""
|
||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import Form from '../../form';
|
||||
import Input from '..';
|
||||
import Input, { InputProps, InputRef } from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
|
||||
@ -29,7 +29,7 @@ describe('Input', () => {
|
||||
});
|
||||
|
||||
it('select()', () => {
|
||||
const ref = React.createRef();
|
||||
const ref = React.createRef<InputRef>();
|
||||
mount(<Input ref={ref} />);
|
||||
ref.current?.select();
|
||||
});
|
||||
@ -55,7 +55,7 @@ describe('Input', () => {
|
||||
describe('focus trigger warning', () => {
|
||||
it('not trigger', () => {
|
||||
const wrapper = mount(<Input suffix="bamboo" />);
|
||||
wrapper.find('input').instance().focus();
|
||||
(wrapper.find('input').instance() as any).focus();
|
||||
wrapper.setProps({
|
||||
suffix: 'light',
|
||||
});
|
||||
@ -63,7 +63,7 @@ describe('Input', () => {
|
||||
});
|
||||
it('trigger warning', () => {
|
||||
const wrapper = mount(<Input />);
|
||||
wrapper.find('input').first().getDOMNode().focus();
|
||||
wrapper.find('input').first().getDOMNode<HTMLInputElement>().focus();
|
||||
wrapper.setProps({
|
||||
suffix: 'light',
|
||||
});
|
||||
@ -77,11 +77,11 @@ describe('Input', () => {
|
||||
it('set mouse cursor position', () => {
|
||||
const defaultValue = '11111';
|
||||
const valLength = defaultValue.length;
|
||||
const ref = React.createRef();
|
||||
const ref = React.createRef<InputRef>();
|
||||
const wrapper = mount(<Input ref={ref} autoFocus defaultValue={defaultValue} />);
|
||||
ref.current?.setSelectionRange(valLength, valLength);
|
||||
expect(wrapper.find('input').first().getDOMNode().selectionStart).toEqual(5);
|
||||
expect(wrapper.find('input').first().getDOMNode().selectionEnd).toEqual(5);
|
||||
expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().selectionStart).toEqual(5);
|
||||
expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().selectionEnd).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
||||
@ -106,8 +106,12 @@ describe('prefix and suffix', () => {
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -143,6 +147,7 @@ describe('Input setting hidden', () => {
|
||||
showCount
|
||||
allowClear
|
||||
prefix="11"
|
||||
// @ts-ignore
|
||||
suffix="22"
|
||||
addonBefore="http://"
|
||||
addonAfter=".com"
|
||||
@ -162,10 +167,10 @@ describe('Input setting hidden', () => {
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(wrapper.find('.input').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-search').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-textarea').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-password').at(0).getDOMNode().hidden).toBe(true);
|
||||
expect(wrapper.find('.input').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-search').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-textarea').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
|
||||
expect(wrapper.find('.input-password').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -250,17 +255,18 @@ describe('Input allowClear', () => {
|
||||
it('should change type when click', () => {
|
||||
const wrapper = mount(<Input allowClear />);
|
||||
wrapper.find('input').simulate('change', { target: { value: '111' } });
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('111');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('111');
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
|
||||
});
|
||||
|
||||
it('should not show icon if value is undefined, null or empty string', () => {
|
||||
// @ts-ignore
|
||||
const wrappers = [null, undefined, ''].map(val => mount(<Input allowClear value={val} />));
|
||||
wrappers.forEach(wrapper => {
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
|
||||
expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy();
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
@ -268,41 +274,43 @@ describe('Input allowClear', () => {
|
||||
|
||||
it('should not show icon if defaultValue is undefined, null or empty string', () => {
|
||||
const wrappers = [null, undefined, ''].map(val =>
|
||||
// @ts-ignore
|
||||
mount(<Input allowClear defaultValue={val} />),
|
||||
);
|
||||
wrappers.forEach(wrapper => {
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
|
||||
expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy();
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger event correctly', () => {
|
||||
let argumentEventObject;
|
||||
let argumentEventObject: React.ChangeEvent<HTMLInputElement> | undefined;
|
||||
|
||||
let argumentEventObjectValue;
|
||||
const onChange = e => {
|
||||
const onChange: InputProps['onChange'] = e => {
|
||||
argumentEventObject = e;
|
||||
argumentEventObjectValue = e.target.value;
|
||||
};
|
||||
const wrapper = mount(<Input allowClear defaultValue="111" onChange={onChange} />);
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
|
||||
expect(argumentEventObject.type).toBe('click');
|
||||
expect(argumentEventObject?.type).toBe('click');
|
||||
expect(argumentEventObjectValue).toBe('');
|
||||
expect(wrapper.find('input').at(0).getDOMNode().value).toBe('');
|
||||
expect(wrapper.find('input').at(0).getDOMNode<HTMLInputElement>().value).toBe('');
|
||||
});
|
||||
|
||||
it('should trigger event correctly on controlled mode', () => {
|
||||
let argumentEventObject;
|
||||
let argumentEventObject: React.ChangeEvent<HTMLInputElement> | undefined;
|
||||
let argumentEventObjectValue;
|
||||
const onChange = e => {
|
||||
const onChange: InputProps['onChange'] = e => {
|
||||
argumentEventObject = e;
|
||||
argumentEventObjectValue = e.target.value;
|
||||
};
|
||||
const wrapper = mount(<Input allowClear value="111" onChange={onChange} />);
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
|
||||
expect(argumentEventObject.type).toBe('click');
|
||||
expect(argumentEventObject?.type).toBe('click');
|
||||
expect(argumentEventObjectValue).toBe('');
|
||||
expect(wrapper.find('input').at(0).getDOMNode().value).toBe('111');
|
||||
expect(wrapper.find('input').at(0).getDOMNode<HTMLInputElement>().value).toBe('111');
|
||||
});
|
||||
|
||||
it('should focus input after clear', () => {
|
||||
@ -332,12 +340,12 @@ describe('Input allowClear', () => {
|
||||
const wrapper = mount(<Input allowClear defaultValue="value" onBlur={onBlur} />, {
|
||||
attachTo: document.body,
|
||||
});
|
||||
wrapper.find('input').getDOMNode().focus();
|
||||
wrapper.find('input').getDOMNode<HTMLInputElement>().focus();
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseDown');
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseUp');
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('focus');
|
||||
wrapper.find('.ant-input-clear-icon').at(0).getDOMNode().click();
|
||||
wrapper.find('.ant-input-clear-icon').at(0).getDOMNode<HTMLInputElement>().click();
|
||||
expect(onBlur).not.toBeCalled();
|
||||
wrapper.unmount();
|
||||
});
|
||||
@ -359,12 +367,12 @@ describe('Input allowClear', () => {
|
||||
|
||||
const wrapper = mount(<App />);
|
||||
|
||||
wrapper.find('input').getDOMNode().focus();
|
||||
wrapper.find('input').getDOMNode<HTMLInputElement>().focus();
|
||||
wrapper.find('input').simulate('change', { target: { value: '111' } });
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('111');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('111');
|
||||
|
||||
wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
|
||||
expect(wrapper.find('input').getDOMNode().value).toEqual('');
|
||||
expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
|
||||
|
||||
wrapper.unmount();
|
||||
});
|
||||
@ -375,10 +383,11 @@ describe('Input allowClear', () => {
|
||||
});
|
||||
|
||||
it('should display boolean value as string', () => {
|
||||
// @ts-ignore
|
||||
const wrapper = mount(<Input value />);
|
||||
expect(wrapper.find('input').first().getDOMNode().value).toBe('true');
|
||||
expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().value).toBe('true');
|
||||
wrapper.setProps({ value: false });
|
||||
expect(wrapper.find('input').first().getDOMNode().value).toBe('false');
|
||||
expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().value).toBe('false');
|
||||
});
|
||||
|
||||
it('should support custom clearIcon', () => {
|
||||
@ -386,3 +395,19 @@ describe('Input allowClear', () => {
|
||||
expect(wrapper.find('.ant-input-clear-icon').text()).toBe('clear');
|
||||
});
|
||||
});
|
||||
|
||||
describe('typescript types ', () => {
|
||||
it('InputProps type should support data-* attributes', () => {
|
||||
const props: InputProps = {
|
||||
value: 123,
|
||||
|
||||
// expect no ts error here
|
||||
'data-testid': 'test-id',
|
||||
'data-id': '12345',
|
||||
};
|
||||
const wrapper = mount(<Input {...props} />);
|
||||
const input = wrapper.find('input').first().getDOMNode();
|
||||
expect(input.getAttribute('data-testid')).toBe('test-id');
|
||||
expect(input.getAttribute('data-id')).toBe('12345');
|
||||
});
|
||||
});
|
@ -25,7 +25,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-password-icon {
|
||||
&-password-icon.@{iconfont-css-prefix} {
|
||||
color: @text-color-secondary;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
@ -1164,7 +1164,7 @@ exports[`renders ./components/list/demo/loadmore.md extend context correctly 1`]
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/list/demo/resposive.md extend context correctly 1`] = `
|
||||
exports[`renders ./components/list/demo/responsive.md extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-list ant-list-split ant-list-grid"
|
||||
>
|
||||
|
@ -1164,7 +1164,7 @@ exports[`renders ./components/list/demo/loadmore.md correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
|
||||
exports[`renders ./components/list/demo/responsive.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-list ant-list-split ant-list-grid"
|
||||
>
|
||||
|
@ -3,15 +3,14 @@ import RcMenu, { ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
||||
import classNames from 'classnames';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined';
|
||||
import memoize from 'memoize-one';
|
||||
import SubMenu, { SubMenuProps } from './SubMenu';
|
||||
import Item, { MenuItemProps } from './MenuItem';
|
||||
import { ConfigConsumer, ConfigConsumerProps, DirectionType } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import devWarning from '../_util/devWarning';
|
||||
import { SiderContext, SiderContextProps } from '../layout/Sider';
|
||||
import collapseMotion from '../_util/motion';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import MenuContext, { MenuTheme, MenuContextProps } from './MenuContext';
|
||||
import MenuContext, { MenuTheme } from './MenuContext';
|
||||
import MenuDivider from './MenuDivider';
|
||||
|
||||
export { MenuDividerProps } from './MenuDivider';
|
||||
@ -37,108 +36,87 @@ type InternalMenuProps = MenuProps &
|
||||
collapsedWidth?: string | number;
|
||||
};
|
||||
|
||||
class InternalMenu extends React.Component<InternalMenuProps> {
|
||||
static defaultProps: Partial<MenuProps> = {
|
||||
theme: 'light', // or dark
|
||||
};
|
||||
function InternalMenu(props: InternalMenuProps) {
|
||||
const { getPrefixCls, getPopupContainer, direction } = React.useContext(ConfigContext);
|
||||
|
||||
constructor(props: InternalMenuProps) {
|
||||
super(props);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
devWarning(
|
||||
!('inlineCollapsed' in props && props.mode !== 'inline'),
|
||||
'Menu',
|
||||
'`inlineCollapsed` should only be used when `mode` is inline.',
|
||||
);
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
theme = 'light',
|
||||
expandIcon,
|
||||
_internalDisableMenuItemTitleTooltip,
|
||||
inlineCollapsed,
|
||||
siderCollapsed,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
devWarning(
|
||||
!(props.siderCollapsed !== undefined && 'inlineCollapsed' in props),
|
||||
'Menu',
|
||||
'`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.',
|
||||
);
|
||||
}
|
||||
const passedProps = omit(restProps, ['collapsedWidth']);
|
||||
|
||||
getInlineCollapsed() {
|
||||
const { inlineCollapsed, siderCollapsed } = this.props;
|
||||
// ======================== Warning ==========================
|
||||
devWarning(
|
||||
!('inlineCollapsed' in props && props.mode !== 'inline'),
|
||||
'Menu',
|
||||
'`inlineCollapsed` should only be used when `mode` is inline.',
|
||||
);
|
||||
|
||||
devWarning(
|
||||
!(props.siderCollapsed !== undefined && 'inlineCollapsed' in props),
|
||||
'Menu',
|
||||
'`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.',
|
||||
);
|
||||
|
||||
// ======================== Collapsed ========================
|
||||
// Inline Collapsed
|
||||
const mergedInlineCollapsed = React.useMemo(() => {
|
||||
if (siderCollapsed !== undefined) {
|
||||
return siderCollapsed;
|
||||
}
|
||||
return inlineCollapsed;
|
||||
}
|
||||
}, [inlineCollapsed, siderCollapsed]);
|
||||
|
||||
getMemoizedContextValue = memoize(
|
||||
(
|
||||
cls: string,
|
||||
collapsed: boolean | undefined,
|
||||
the: MenuTheme | undefined,
|
||||
dir: DirectionType,
|
||||
disableMenuItemTitleTooltip: boolean | undefined,
|
||||
): MenuContextProps => ({
|
||||
prefixCls: cls,
|
||||
inlineCollapsed: collapsed || false,
|
||||
antdMenuTheme: the,
|
||||
direction: dir,
|
||||
firstLevel: true,
|
||||
disableMenuItemTitleTooltip,
|
||||
}),
|
||||
);
|
||||
|
||||
renderMenu = ({ getPopupContainer, getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
theme,
|
||||
expandIcon,
|
||||
_internalDisableMenuItemTitleTooltip,
|
||||
...restProps
|
||||
} = this.props;
|
||||
|
||||
const passedProps = omit(restProps, ['siderCollapsed', 'collapsedWidth']);
|
||||
const inlineCollapsed = this.getInlineCollapsed();
|
||||
|
||||
const defaultMotions = {
|
||||
horizontal: { motionName: `${rootPrefixCls}-slide-up` },
|
||||
inline: collapseMotion,
|
||||
other: { motionName: `${rootPrefixCls}-zoom-big` },
|
||||
};
|
||||
|
||||
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
||||
const menuClassName = classNames(`${prefixCls}-${theme}`, className);
|
||||
|
||||
// TODO: refactor menu with function component
|
||||
const contextValue = this.getMemoizedContextValue(
|
||||
prefixCls,
|
||||
inlineCollapsed,
|
||||
theme,
|
||||
direction,
|
||||
_internalDisableMenuItemTitleTooltip,
|
||||
);
|
||||
|
||||
return (
|
||||
<MenuContext.Provider value={contextValue}>
|
||||
<RcMenu
|
||||
getPopupContainer={getPopupContainer}
|
||||
overflowedIndicator={<EllipsisOutlined />}
|
||||
overflowedIndicatorPopupClassName={`${prefixCls}-${theme}`}
|
||||
{...passedProps}
|
||||
inlineCollapsed={inlineCollapsed}
|
||||
className={menuClassName}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
defaultMotions={defaultMotions}
|
||||
expandIcon={cloneElement(expandIcon, {
|
||||
className: `${prefixCls}-submenu-expand-icon`,
|
||||
})}
|
||||
/>
|
||||
</MenuContext.Provider>
|
||||
);
|
||||
const defaultMotions = {
|
||||
horizontal: { motionName: `${rootPrefixCls}-slide-up` },
|
||||
inline: collapseMotion,
|
||||
other: { motionName: `${rootPrefixCls}-zoom-big` },
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ConfigConsumer>{this.renderMenu}</ConfigConsumer>;
|
||||
}
|
||||
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
||||
const menuClassName = classNames(`${prefixCls}-${theme}`, className);
|
||||
|
||||
// ======================== Context ==========================
|
||||
const contextValue = React.useMemo(
|
||||
() => ({
|
||||
prefixCls,
|
||||
inlineCollapsed: mergedInlineCollapsed || false,
|
||||
antdMenuTheme: theme,
|
||||
direction,
|
||||
firstLevel: true,
|
||||
disableMenuItemTitleTooltip: _internalDisableMenuItemTitleTooltip,
|
||||
}),
|
||||
[prefixCls, mergedInlineCollapsed, theme, direction, _internalDisableMenuItemTitleTooltip],
|
||||
);
|
||||
|
||||
// ========================= Render ==========================
|
||||
return (
|
||||
<MenuContext.Provider value={contextValue}>
|
||||
<RcMenu
|
||||
getPopupContainer={getPopupContainer}
|
||||
overflowedIndicator={<EllipsisOutlined />}
|
||||
overflowedIndicatorPopupClassName={`${prefixCls}-${theme}`}
|
||||
{...passedProps}
|
||||
inlineCollapsed={mergedInlineCollapsed}
|
||||
className={menuClassName}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
defaultMotions={defaultMotions}
|
||||
expandIcon={cloneElement(expandIcon, {
|
||||
className: `${prefixCls}-submenu-expand-icon`,
|
||||
})}
|
||||
/>
|
||||
</MenuContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// We should keep this as ref-able
|
||||
|
@ -58,30 +58,48 @@ Array [
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -272,30 +290,48 @@ Array [
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -624,252 +660,274 @@ exports[`renders ./components/page-header/demo/content.md extend context correct
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-dropdown-trigger"
|
||||
style="border:none;padding:0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="ellipsis"
|
||||
class="anticon anticon-ellipsis"
|
||||
role="img"
|
||||
style="font-size:20px;vertical-align:top"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="ellipsis"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-dropdown"
|
||||
style="opacity:0;pointer-events:none"
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<ul
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||
data-menu-list="true"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="http://www.alipay.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
1st menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="http://www.taobao.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
2nd menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="http://www.tmall.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
3rd menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display:none"
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-icon-only ant-dropdown-trigger"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="more"
|
||||
class="anticon anticon-more"
|
||||
role="img"
|
||||
style="font-size:20px"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="more"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
<path
|
||||
d="M456 231a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-dropdown"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<ul
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||
data-menu-list="true"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<a
|
||||
href="http://www.alipay.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
1st menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<a
|
||||
href="http://www.taobao.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
2nd menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<a
|
||||
href="http://www.tmall.com/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
3rd menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display:none"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0;pointer-events:none"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1004,30 +1062,48 @@ exports[`renders ./components/page-header/demo/ghost.md extend context correctly
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -1212,30 +1288,48 @@ exports[`renders ./components/page-header/demo/responsive.md extend context corr
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
@ -58,30 +58,48 @@ Array [
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -272,30 +290,48 @@ Array [
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -624,56 +660,78 @@ exports[`renders ./components/page-header/demo/content.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default ant-dropdown-trigger"
|
||||
style="border:none;padding:0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="ellipsis"
|
||||
class="anticon anticon-ellipsis"
|
||||
role="img"
|
||||
style="font-size:20px;vertical-align:top"
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="ellipsis"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-text ant-btn-icon-only ant-dropdown-trigger"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="more"
|
||||
class="anticon anticon-more"
|
||||
role="img"
|
||||
style="font-size:20px"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="more"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M456 231a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0zm0 280a56 56 0 10112 0 56 56 0 10-112 0z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -802,30 +860,48 @@ exports[`renders ./components/page-header/demo/ghost.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@ -1010,30 +1086,48 @@ exports[`renders ./components/page-header/demo/responsive.md correctly 1`] = `
|
||||
<span
|
||||
class="ant-page-header-heading-extra"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Operation
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Primary
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
|
@ -15,7 +15,7 @@ Show all props provided by PageHeader.
|
||||
|
||||
```jsx
|
||||
import { PageHeader, Menu, Dropdown, Button, Tag, Typography, Row } from 'antd';
|
||||
import { EllipsisOutlined } from '@ant-design/icons';
|
||||
import { MoreOutlined } from '@ant-design/icons';
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
|
||||
@ -40,20 +40,8 @@ const menu = (
|
||||
);
|
||||
|
||||
const DropdownMenu = () => (
|
||||
<Dropdown key="more" overlay={menu}>
|
||||
<Button
|
||||
style={{
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
<EllipsisOutlined
|
||||
style={{
|
||||
fontSize: 20,
|
||||
verticalAlign: 'top',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
<Dropdown key="more" overlay={menu} placement="bottomRight">
|
||||
<Button type="text" icon={<MoreOutlined style={{ fontSize: 20 }} />} />
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import useState from 'rc-util/lib/hooks/useState';
|
||||
import ArrowLeftOutlined from '@ant-design/icons/ArrowLeftOutlined';
|
||||
import ArrowRightOutlined from '@ant-design/icons/ArrowRightOutlined';
|
||||
import ResizeObserver from 'rc-resize-observer';
|
||||
@ -7,9 +8,9 @@ import { ConfigConsumer, ConfigConsumerProps, DirectionType } from '../config-pr
|
||||
import { TagType } from '../tag';
|
||||
import Breadcrumb, { BreadcrumbProps } from '../breadcrumb';
|
||||
import Avatar, { AvatarProps } from '../avatar';
|
||||
import Space from '../space';
|
||||
import TransButton from '../_util/transButton';
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import useDestroyed from '../_util/hooks/useDestroyed';
|
||||
|
||||
export interface PageHeaderProps {
|
||||
backIcon?: React.ReactNode;
|
||||
@ -104,7 +105,11 @@ const renderTitle = (
|
||||
{tags && <span className={`${headingPrefixCls}-tags`}>{tags}</span>}
|
||||
</div>
|
||||
)}
|
||||
{extra && <span className={`${headingPrefixCls}-extra`}>{extra}</span>}
|
||||
{extra && (
|
||||
<span className={`${headingPrefixCls}-extra`}>
|
||||
<Space>{extra}</Space>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -121,12 +126,9 @@ const renderChildren = (prefixCls: string, children: React.ReactNode) => (
|
||||
);
|
||||
|
||||
const PageHeader: React.FC<PageHeaderProps> = props => {
|
||||
const [compact, updateCompact] = React.useState(false);
|
||||
const isDestroyed = useDestroyed();
|
||||
const [compact, updateCompact] = useState(false);
|
||||
const onResize = ({ width }: { width: number }) => {
|
||||
if (!isDestroyed()) {
|
||||
updateCompact(width < 768);
|
||||
}
|
||||
updateCompact(width < 768, true);
|
||||
};
|
||||
return (
|
||||
<ConfigConsumer>
|
||||
|
@ -87,13 +87,8 @@
|
||||
white-space: nowrap;
|
||||
|
||||
> * {
|
||||
margin-left: @margin-sm;
|
||||
white-space: unset;
|
||||
}
|
||||
|
||||
> *:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,3 +3,4 @@ import './index.less';
|
||||
// style dependencies
|
||||
import '../../breadcrumb/style';
|
||||
import '../../avatar/style';
|
||||
import '../../space/style';
|
||||
|
@ -13,7 +13,6 @@ import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue'
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import { getTransitionName } from '../_util/motion';
|
||||
import ActionButton from '../_util/ActionButton';
|
||||
import useDestroyed from '../_util/hooks/useDestroyed';
|
||||
|
||||
export interface PopconfirmProps extends AbstractTooltipProps {
|
||||
title: React.ReactNode | RenderFunction;
|
||||
@ -49,15 +48,13 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
||||
defaultValue: props.defaultVisible,
|
||||
});
|
||||
|
||||
const isDestroyed = useDestroyed();
|
||||
// const isDestroyed = useDestroyed();
|
||||
|
||||
const settingVisible = (
|
||||
value: boolean,
|
||||
e?: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||
) => {
|
||||
if (!isDestroyed()) {
|
||||
setVisible(value);
|
||||
}
|
||||
setVisible(value, true);
|
||||
props.onVisibleChange?.(value, e);
|
||||
};
|
||||
|
||||
|
@ -3815,6 +3815,7 @@ exports[`renders ./components/select/demo/optgroup.md extend context correctly 1
|
||||
>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-group"
|
||||
title="Manager"
|
||||
>
|
||||
Manager
|
||||
</div>
|
||||
@ -3854,6 +3855,7 @@ exports[`renders ./components/select/demo/optgroup.md extend context correctly 1
|
||||
</div>
|
||||
<div
|
||||
class="ant-select-item ant-select-item-group"
|
||||
title="Engineer"
|
||||
>
|
||||
Engineer
|
||||
</div>
|
||||
|
@ -7,11 +7,11 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `dropdownRender` 对下拉菜单进行自由扩展。
|
||||
使用 `dropdownRender` 对下拉菜单进行自由扩展。自定义内容点击时会关闭浮层,如果不喜欢关闭,可以添加 `onMouseDown={e => e.preventDefault()}` 进行阻止(更多详情见 [#13448](https://github.com/ant-design/ant-design/issues/13448))。
|
||||
|
||||
## en-US
|
||||
|
||||
Customize the dropdown menu via `dropdownRender`.
|
||||
Customize the dropdown menu via `dropdownRender`. Dropdown menu will be closed if click `dropdownRender` area, you can prevent it by wrapping `onMouseDown={e => e.preventDefault()}` (see more at [#13448](https://github.com/ant-design/ant-design/issues/13448)).
|
||||
|
||||
```jsx
|
||||
import React, { useState } from 'react';
|
||||
|
@ -37,7 +37,7 @@ Select component to select value from options.
|
||||
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | |
|
||||
| dropdownRender | Customize dropdown content | (originNode: ReactNode) => ReactNode | - | |
|
||||
| dropdownStyle | The style of dropdown menu | CSSProperties | - | |
|
||||
| fieldNames | Customize node title, key, options field name | object | { label: `label`, key: `key`, options: `options` } | 4.17.0 |
|
||||
| fieldNames | Customize node label, value, options field name | object | { label: `label`, value: `value`, options: `options` } | 4.17.0 |
|
||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| function(inputValue, option) | true | |
|
||||
| filterSort | Sort function for search options sorting, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction | (optionA: Option, optionB: Option) => number | - | 4.9.0 |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [Example](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |
|
||||
@ -113,7 +113,7 @@ It's caused by option with different `label` and `value`. You can use `optionFil
|
||||
|
||||
### The dropdown is closed when click `dropdownRender` area?
|
||||
|
||||
See the instruction in [dropdownRender example](#components-select-demo-custom-dropdown-menu).
|
||||
Dropdown menu will be closed if click `dropdownRender` area, you can prevent it by wrapping `onMouseDown={e => e.preventDefault()}` (see more at [#13448](https://github.com/ant-design/ant-design/issues/13448)).
|
||||
|
||||
### Why sometime customize Option cause scroll break?
|
||||
|
||||
|
@ -38,7 +38,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
||||
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
|
||||
| dropdownRender | 自定义下拉框内容 | (originNode: ReactNode) => ReactNode | - | |
|
||||
| dropdownStyle | 下拉菜单的 style 属性 | CSSProperties | - | |
|
||||
| fieldNames | 自定义节点 label、key、options 的字段 | object | { label: `label`, key: `key`, options: `options` } | 4.17.0 |
|
||||
| fieldNames | 自定义节点 label、value、options 的字段 | object | { label: `label`, value: `value`, options: `options` } | 4.17.0 |
|
||||
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true,反之则返回 false | boolean \| function(inputValue, option) | true | |
|
||||
| filterSort | 搜索时对筛选结果项的排序函数, 类似[Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)里的 compareFunction | (optionA: Option, optionB: Option) => number | - | 4.9.0 |
|
||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |
|
||||
@ -114,7 +114,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
||||
|
||||
### 点击 `dropdownRender` 里的内容浮层关闭怎么办?
|
||||
|
||||
看下 [dropdownRender 例子](#components-select-demo-custom-dropdown-menu) 里的说明。
|
||||
自定义内容点击时会关闭浮层,如果不喜欢关闭,可以添加 `onMouseDown={e => e.preventDefault()}` 进行阻止(更多详情见 [#13448](https://github.com/ant-design/ant-design/issues/13448))。
|
||||
|
||||
### 自定义 Option 样式导致滚动异常怎么办?
|
||||
|
||||
|
@ -25,56 +25,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
.select-status-base(@prefix-cls) {
|
||||
.@{prefix-cls} {
|
||||
&-status-error {
|
||||
.select-status-color(@error-color, @error-color, @select-background, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
.@{select-prefix-cls} {
|
||||
&-status-error {
|
||||
.select-status-color(@error-color, @error-color, @select-background, @error-color-hover, @error-color-outline);
|
||||
}
|
||||
|
||||
&-status-warning {
|
||||
.select-status-color(@warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline);
|
||||
}
|
||||
&-status-warning {
|
||||
.select-status-color(@warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline);
|
||||
}
|
||||
|
||||
&-status-success {
|
||||
.@{prefix-cls}-feedback-icon {
|
||||
color: @success-color;
|
||||
&-status-success {
|
||||
.@{select-prefix-cls}-feedback-icon {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-validating {
|
||||
.@{select-prefix-cls}-feedback-icon {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-error,
|
||||
&-status-warning,
|
||||
&-status-success,
|
||||
&-status-validating {
|
||||
&.@{select-prefix-cls}-has-feedback {
|
||||
//.@{prefix-cls}-arrow,
|
||||
.@{select-prefix-cls}-clear {
|
||||
right: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-validating {
|
||||
.@{prefix-cls}-feedback-icon {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-status-error,
|
||||
&-status-warning,
|
||||
&-status-success,
|
||||
&-status-validating {
|
||||
&.@{prefix-cls}-has-feedback {
|
||||
//.@{prefix-cls}-arrow,
|
||||
.@{prefix-cls}-clear {
|
||||
right: 32px;
|
||||
}
|
||||
|
||||
.@{prefix-cls}-selection-selected-value {
|
||||
padding-right: 42px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-feedback-icon {
|
||||
font-size: @font-size-base;
|
||||
text-align: center;
|
||||
visibility: visible;
|
||||
animation: zoomIn 0.3s @ease-out-back;
|
||||
pointer-events: none;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 8px;
|
||||
.@{select-prefix-cls}-selection-selected-value {
|
||||
padding-right: 42px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-status-base(@select-prefix-cls);
|
||||
&-feedback-icon {
|
||||
font-size: @font-size-base;
|
||||
text-align: center;
|
||||
visibility: visible;
|
||||
animation: zoomIn 0.3s @ease-out-back;
|
||||
pointer-events: none;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ When part of the page is waiting for asynchronous data or during a rendering pro
|
||||
| delay | Specifies a delay in milliseconds for loading state (prevent flush) | number (milliseconds) | - |
|
||||
| indicator | React node of the spinning indicator | ReactNode | - |
|
||||
| size | The size of Spin, options: `small`, `default` and `large` | string | `default` |
|
||||
| spinning | Whether Spin is spinning | boolean | true |
|
||||
| spinning | Whether Spin is visible | boolean | true |
|
||||
| tip | Customize description content when Spin has children | ReactNode | - |
|
||||
| wrapperClassName | The className of wrapper when Spin has children | string | - |
|
||||
|
||||
|
@ -516,7 +516,7 @@
|
||||
// Tooltip background color
|
||||
@tooltip-bg: rgba(0, 0, 0, 0.75);
|
||||
// Tooltip arrow width
|
||||
@tooltip-arrow-width: 5px;
|
||||
@tooltip-arrow-width: 8px * sqrt(2);
|
||||
// Tooltip distance with trigger
|
||||
@tooltip-distance: @tooltip-arrow-width - 1px + 4px;
|
||||
// Tooltip arrow color
|
||||
@ -532,7 +532,7 @@
|
||||
@popover-min-width: 177px;
|
||||
@popover-min-height: 32px;
|
||||
// Popover arrow width
|
||||
@popover-arrow-width: 6px;
|
||||
@popover-arrow-width: @tooltip-arrow-width;
|
||||
// Popover arrow color
|
||||
@popover-arrow-color: @popover-bg;
|
||||
// Popover outer arrow width
|
||||
|
@ -62,7 +62,7 @@ const columns = [
|
||||
| --- | --- | --- | --- | --- |
|
||||
| bordered | Whether to show all table borders | boolean | false | |
|
||||
| columns | Columns of table | [ColumnsType](#Column)\[] | - | |
|
||||
| components | Override default table elements | [TableComponents](https://git.io/fANxz) | - | |
|
||||
| components | Override default table elements | [TableComponents](https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129) | - | |
|
||||
| dataSource | Data record array to be displayed | object\[] | - | |
|
||||
| expandable | Config expandable content | [expandable](#expandable) | - | |
|
||||
| footer | Table footer renderer | function(currentPageData) | - | |
|
||||
|
@ -69,7 +69,7 @@ const columns = [
|
||||
| --- | --- | --- | --- | --- |
|
||||
| bordered | 是否展示外边框和列边框 | boolean | false | |
|
||||
| columns | 表格列的配置描述,具体项见下表 | [ColumnsType](#Column)\[] | - | |
|
||||
| components | 覆盖默认的 table 元素 | [TableComponents](https://git.io/fANxz) | - | |
|
||||
| components | 覆盖默认的 table 元素 | [TableComponents](https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129) | - | |
|
||||
| dataSource | 数据数组 | object\[] | - | |
|
||||
| expandable | 配置展开属性 | [expandable](#expandable) | - | |
|
||||
| footer | 表格尾部 | function(currentPageData) | - | |
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -901,6 +901,7 @@ exports[`renders ./components/time-picker/demo/status.md correctly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-bottom:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-status-warning"
|
||||
@ -945,6 +946,183 @@ exports[`renders ./components/time-picker/demo/status.md correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-bottom:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-range ant-picker-status-error"
|
||||
>
|
||||
<div
|
||||
class="ant-picker-input ant-picker-input-active"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="Start time"
|
||||
readonly=""
|
||||
size="10"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-range-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="to"
|
||||
class="ant-picker-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="swap-right"
|
||||
class="anticon anticon-swap-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="swap-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-input"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="End time"
|
||||
readonly=""
|
||||
size="10"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-active-bar"
|
||||
style="left:0;width:0;position:absolute"
|
||||
/>
|
||||
<span
|
||||
class="ant-picker-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="clock-circle"
|
||||
class="anticon anticon-clock-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="clock-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
|
||||
/>
|
||||
<path
|
||||
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-picker ant-picker-range ant-picker-status-warning"
|
||||
>
|
||||
<div
|
||||
class="ant-picker-input ant-picker-input-active"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="Start time"
|
||||
readonly=""
|
||||
size="10"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-range-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="to"
|
||||
class="ant-picker-separator"
|
||||
>
|
||||
<span
|
||||
aria-label="swap-right"
|
||||
class="anticon anticon-swap-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="swap-right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M873.1 596.2l-164-208A32 32 0 00684 376h-64.8c-6.7 0-10.4 7.7-6.3 13l144.3 183H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h695.9c26.8 0 41.7-30.8 25.2-51.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-input"
|
||||
>
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="End time"
|
||||
readonly=""
|
||||
size="10"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-picker-active-bar"
|
||||
style="left:0;width:0;position:absolute"
|
||||
/>
|
||||
<span
|
||||
class="ant-picker-suffix"
|
||||
>
|
||||
<span
|
||||
aria-label="clock-circle"
|
||||
class="anticon anticon-clock-circle"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="clock-circle"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"
|
||||
/>
|
||||
<path
|
||||
d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8H488c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.8-11.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
@ -21,6 +21,8 @@ const Status: React.FC = () => (
|
||||
<Space direction="vertical">
|
||||
<TimePicker status="error" />
|
||||
<TimePicker status="warning" />
|
||||
<TimePicker.RangePicker status="error" />
|
||||
<TimePicker.RangePicker status="warning" />
|
||||
</Space>
|
||||
);
|
||||
|
||||
|
@ -41,7 +41,7 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/vJmo00mmgR/Timeline.svg
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| color | 指定圆圈颜色 `blue`, `red`, `green`, `gray`,或自定义的色值 | string | `blue` |
|
||||
| color | 指定圆圈颜色 `blue`、`red`、`green`、`gray`,或自定义的色值 | string | `blue` |
|
||||
| dot | 自定义时间轴点 | ReactNode | - |
|
||||
| label | 设置标签 | ReactNode | - |
|
||||
| position | 自定义节点位置 | `left` \| `right` | - |
|
||||
|
@ -19,6 +19,7 @@
|
||||
z-index: @zindex-tooltip;
|
||||
display: block;
|
||||
width: max-content;
|
||||
width: intrinsic;
|
||||
max-width: @tooltip-max-width;
|
||||
visibility: visible;
|
||||
|
||||
|
@ -79,7 +79,9 @@ export interface TransferProps<RecordType> {
|
||||
showSearch?: boolean;
|
||||
filterOption?: (inputValue: string, item: RecordType) => boolean;
|
||||
locale?: Partial<TransferLocale>;
|
||||
footer?: (props: TransferListProps<RecordType>) => React.ReactNode;
|
||||
footer?: (props: TransferListProps<RecordType>, info?: {
|
||||
direction: TransferDirection;
|
||||
}) => React.ReactNode;
|
||||
rowKey?: (record: RecordType) => string;
|
||||
onSearch?: (direction: TransferDirection, value: string) => void;
|
||||
onScroll?: (direction: TransferDirection, e: React.SyntheticEvent<HTMLUListElement>) => void;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
@transfer-prefix-cls: ~'@{ant-prefix}-transfer';
|
||||
|
||||
.status-color(@color) {
|
||||
.transfer-status-color(@color) {
|
||||
.@{transfer-prefix-cls}-list {
|
||||
border-color: @color;
|
||||
|
||||
@ -22,10 +22,10 @@
|
||||
|
||||
.@{transfer-prefix-cls} {
|
||||
&-status-error {
|
||||
.status-color(@error-color);
|
||||
.transfer-status-color(@error-color);
|
||||
}
|
||||
|
||||
&-status-warning {
|
||||
.status-color(@warning-color);
|
||||
.transfer-status-color(@warning-color);
|
||||
}
|
||||
}
|
||||
|
@ -110,8 +110,8 @@ class SearchTree extends React.Component {
|
||||
const loop = data =>
|
||||
data.map(item => {
|
||||
const index = item.title.indexOf(searchValue);
|
||||
const beforeStr = item.title.substr(0, index);
|
||||
const afterStr = item.title.substr(index + searchValue.length);
|
||||
const beforeStr = item.title.substring(0, index);
|
||||
const afterStr = item.title.slice(index + searchValue.length);
|
||||
const title =
|
||||
index > -1 ? (
|
||||
<span>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { composeRef } from 'rc-util/lib/ref';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import devWarning from '../_util/devWarning';
|
||||
|
||||
export interface TypographyProps {
|
||||
@ -31,37 +31,27 @@ const Typography: React.ForwardRefRenderFunction<{}, InternalTypographyProps> =
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
let mergedRef = ref;
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
|
||||
let mergedRef = ref;
|
||||
if (setContentRef) {
|
||||
devWarning(false, 'Typography', '`setContentRef` is deprecated. Please use `ref` instead.');
|
||||
mergedRef = composeRef(ref, setContentRef);
|
||||
}
|
||||
|
||||
const Component = component as any;
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
const componentClassName = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
return (
|
||||
<ConfigConsumer>
|
||||
{({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const Component = component as any;
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
const componentClassName = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
return (
|
||||
<Component
|
||||
className={componentClassName}
|
||||
aria-label={ariaLabel}
|
||||
ref={mergedRef}
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}}
|
||||
</ConfigConsumer>
|
||||
<Component className={componentClassName} aria-label={ariaLabel} ref={mergedRef} {...restProps}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
@ -70,6 +60,6 @@ const RefTypography = React.forwardRef(Typography);
|
||||
RefTypography.displayName = 'Typography';
|
||||
|
||||
// es default export should use const instead of let
|
||||
const ExportTypography = (RefTypography as unknown) as React.FC<TypographyProps>;
|
||||
const ExportTypography = RefTypography as unknown as React.FC<TypographyProps>;
|
||||
|
||||
export default ExportTypography;
|
||||
|
@ -217,6 +217,9 @@
|
||||
|
||||
// Fix Editable Textarea flash in Firefox
|
||||
textarea {
|
||||
// https://stackoverflow.com/a/7695964/3040605
|
||||
height: 1em;
|
||||
margin: 0 !important;
|
||||
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||
-moz-transition: none;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ class PicturesWall extends React.Component {
|
||||
icon = <LoadingOutlined />; // or icon = 'uploading...';
|
||||
} else {
|
||||
fileSufIconList.forEach(item => {
|
||||
if (item.suf.includes(file.name.substr(file.name.lastIndexOf('.')))) {
|
||||
if (item.suf.includes(file.name.slice(file.name.lastIndexOf('.')))) {
|
||||
icon = item.type;
|
||||
}
|
||||
});
|
||||
|
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "4.19.0",
|
||||
"version": "4.19.2",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
"keywords": [
|
||||
@ -127,12 +127,12 @@
|
||||
"rc-dialog": "~8.6.0",
|
||||
"rc-drawer": "~4.4.2",
|
||||
"rc-dropdown": "~3.3.2",
|
||||
"rc-field-form": "~1.23.0",
|
||||
"rc-field-form": "~1.24.0",
|
||||
"rc-image": "~5.2.5",
|
||||
"rc-input": "^0.0.1-alpha.5",
|
||||
"rc-input": "~0.0.1-alpha.5",
|
||||
"rc-input-number": "~7.3.0",
|
||||
"rc-mentions": "~1.6.1",
|
||||
"rc-menu": "~9.2.1",
|
||||
"rc-menu": "~9.3.2",
|
||||
"rc-motion": "^2.4.4",
|
||||
"rc-notification": "~4.5.7",
|
||||
"rc-pagination": "~3.1.9",
|
||||
@ -140,7 +140,7 @@
|
||||
"rc-progress": "~3.2.1",
|
||||
"rc-rate": "~2.9.0",
|
||||
"rc-resize-observer": "^1.2.0",
|
||||
"rc-select": "~14.0.0-alpha.15",
|
||||
"rc-select": "~14.0.2",
|
||||
"rc-slider": "~10.0.0-alpha.4",
|
||||
"rc-steps": "~4.1.0",
|
||||
"rc-switch": "~3.2.0",
|
||||
@ -152,7 +152,7 @@
|
||||
"rc-tree-select": "~5.1.1",
|
||||
"rc-trigger": "^5.2.10",
|
||||
"rc-upload": "~4.3.0",
|
||||
"rc-util": "^5.14.0",
|
||||
"rc-util": "^5.19.3",
|
||||
"scroll-into-view-if-needed": "^2.2.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -164,7 +164,7 @@
|
||||
"@qixian.cs/github-contributors-list": "^1.0.3",
|
||||
"@stackblitz/sdk": "^1.3.0",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/react": "^12.1.4",
|
||||
"@types/enzyme": "^3.10.5",
|
||||
"@types/gtag.js": "^0.0.8",
|
||||
"@types/jest": "^27.0.0",
|
||||
@ -228,7 +228,7 @@
|
||||
"intersection-observer": "^0.12.0",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jest": "^27.0.3",
|
||||
"jest-axe": "^5.0.1",
|
||||
"jest-axe": "^6.0.0",
|
||||
"jest-environment-node": "^27.4.4",
|
||||
"jest-image-snapshot": "^4.5.1",
|
||||
"jest-puppeteer": "^6.0.0",
|
||||
|
@ -2,7 +2,7 @@
|
||||
const chalk = require('chalk');
|
||||
const path = require('path');
|
||||
const fetch = require('isomorphic-fetch');
|
||||
const simpleGit = require('simple-git/promise');
|
||||
const simpleGit = require('simple-git');
|
||||
|
||||
const cwd = process.cwd();
|
||||
const git = simpleGit(cwd);
|
||||
|
@ -1,6 +1,6 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const simpleGit = require('simple-git/promise');
|
||||
const simpleGit = require('simple-git');
|
||||
const _ = require('lodash');
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
@ -7,7 +7,7 @@ const fetch = require('isomorphic-fetch');
|
||||
const open = require('open');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const simpleGit = require('simple-git/promise');
|
||||
const simpleGit = require('simple-git');
|
||||
const inquirer = require('inquirer');
|
||||
|
||||
const { JSDOM } = jsdom;
|
||||
|
@ -192,7 +192,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
|
||||
location: { pathname, query },
|
||||
} = this.props;
|
||||
const currentProtocol = `${window.location.protocol}//`;
|
||||
const currentHref = window.location.href.substr(currentProtocol.length);
|
||||
const currentHref = window.location.href.slice(currentProtocol.length);
|
||||
|
||||
if (utils.isLocalStorageNameSupported()) {
|
||||
localStorage.setItem('locale', utils.isZhCN(pathname) ? 'en-US' : 'zh-CN');
|
||||
|
Loading…
Reference in New Issue
Block a user